brain/scripts/test/o365-calendar.test.js

122 lines
3.8 KiB
JavaScript

const { describe, it } = require('node:test');
const assert = require('node:assert/strict');
const { parseEventToMeeting, formatEventChoice, isRecurring } = require('../lib/o365-calendar.js');
describe('parseEventToMeeting', () => {
it('extracts meeting data from Graph API event', () => {
const event = {
id: 'AAMkAG123',
subject: 'IT Team Weekly',
start: { dateTime: '2026-04-14T09:00:00', timeZone: 'Europe/Berlin' },
end: { dateTime: '2026-04-14T10:00:00', timeZone: 'Europe/Berlin' },
body: { content: '<p>Agenda: Status updates</p>', contentType: 'html' },
attendees: [
{
emailAddress: { name: 'Christopher Klein', address: 'c.klein@krah.de' },
type: 'required'
},
{
emailAddress: { name: 'Philip Losch', address: 'p.losch@krah.de' },
type: 'required'
}
],
seriesMasterId: 'AAMkSeries456'
};
const result = parseEventToMeeting(event);
assert.equal(result.id, 'AAMkAG123');
assert.equal(result.title, 'IT Team Weekly');
assert.equal(result.date, '2026-04-14');
assert.equal(result.start, '09:00');
assert.equal(result.end, '10:00');
assert.equal(result.bodyText, 'Agenda: Status updates');
assert.equal(result.attendees.length, 2);
assert.equal(result.attendees[0].email, 'c.klein@krah.de');
assert.equal(result.attendees[0].name, 'Christopher Klein');
assert.equal(result.isRecurring, true);
});
it('handles event without attendees', () => {
const event = {
id: 'AAMkAG789',
subject: 'Focus Time',
start: { dateTime: '2026-04-14T14:00:00', timeZone: 'Europe/Berlin' },
end: { dateTime: '2026-04-14T15:00:00', timeZone: 'Europe/Berlin' },
body: { content: '', contentType: 'text' },
attendees: []
};
const result = parseEventToMeeting(event);
assert.equal(result.attendees.length, 0);
assert.equal(result.isRecurring, false);
assert.equal(result.bodyText, '');
});
});
describe('formatEventChoice', () => {
it('formats event for selection list', () => {
const meeting = {
title: 'IT Team Weekly',
date: '2026-04-14',
start: '09:00',
end: '10:00'
};
const result = formatEventChoice(meeting);
assert.equal(result, '📅 09:00-10:00 IT Team Weekly');
});
});
describe('isRecurring', () => {
it('returns true when seriesMasterId exists', () => {
assert.equal(isRecurring({ seriesMasterId: 'ABC' }), true);
});
it('returns false when no seriesMasterId', () => {
assert.equal(isRecurring({}), false);
assert.equal(isRecurring({ seriesMasterId: null }), false);
});
});
const { extractJoinUrlFromBody, getEventById } = require('../lib/o365-calendar.js');
describe('extractJoinUrlFromBody', () => {
it('extracts teams meeting join URL from body html', () => {
const html = '<a href="https://teams.microsoft.com/l/meetup-join/19%3aabc/0?context=foo">Join</a>';
assert.equal(
extractJoinUrlFromBody(html),
'https://teams.microsoft.com/l/meetup-join/19%3aabc/0?context=foo'
);
});
it('returns null when no teams url present', () => {
assert.equal(extractJoinUrlFromBody('<p>nothing</p>'), null);
});
});
describe('getEventById', () => {
it('throws TypeError when eventId is empty string', async () => {
await assert.rejects(
() => getEventById(''),
{ name: 'TypeError', message: /eventId must be a non-empty string/ }
);
});
it('throws TypeError when eventId is not a string', async () => {
await assert.rejects(
() => getEventById(null),
{ name: 'TypeError', message: /eventId must be a non-empty string/ }
);
});
it('throws TypeError when eventId is whitespace only', async () => {
await assert.rejects(
() => getEventById(' '),
{ name: 'TypeError', message: /eventId must be a non-empty string/ }
);
});
});