mirror of
https://github.com/bewcloud/bewcloud.git
synced 2026-03-11 08:54:49 +00:00
772 lines
29 KiB
TypeScript
772 lines
29 KiB
TypeScript
import { assertEquals, assertMatch } from '@std/assert';
|
|
|
|
import { generateVCard, getIdFromVCard, parseVCard, splitTextIntoVCards, updateVCard } from './contacts.ts';
|
|
|
|
Deno.test('that getIdFromVCard works', () => {
|
|
const tests: { input: string; expected?: string; shouldBeUUID?: boolean }[] = [
|
|
{
|
|
input: `BEGIN:VCARD
|
|
VERSION:4.0
|
|
UID:12345-abcde-67890
|
|
FN:John Doe
|
|
END:VCARD`,
|
|
expected: '12345-abcde-67890',
|
|
},
|
|
{
|
|
input: `BEGIN:VCARD
|
|
VERSION:3.0
|
|
FN:Jane Smith
|
|
UID:jane-smith-uuid
|
|
EMAIL:jane@example.com
|
|
END:VCARD`,
|
|
expected: 'jane-smith-uuid',
|
|
},
|
|
{
|
|
input: `BEGIN:VCARD
|
|
VERSION:4.0
|
|
FN:No UID Contact
|
|
EMAIL:nouid@example.com
|
|
END:VCARD`,
|
|
shouldBeUUID: true,
|
|
},
|
|
{
|
|
input: `BEGIN:VCARD
|
|
VERSION:4.0
|
|
UID: spaced-uid
|
|
FN:Spaced UID
|
|
END:VCARD`,
|
|
expected: 'spaced-uid',
|
|
},
|
|
];
|
|
|
|
for (const test of tests) {
|
|
const output = getIdFromVCard(test.input);
|
|
if (test.expected) {
|
|
assertEquals(output, test.expected);
|
|
} else if (test.shouldBeUUID) {
|
|
// Check that it's a valid UUID format
|
|
assertMatch(output, /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i);
|
|
}
|
|
}
|
|
});
|
|
|
|
Deno.test('that splitTextIntoVCards works', () => {
|
|
const tests: { input: string; expected: string[] }[] = [
|
|
{
|
|
input: `BEGIN:VCARD
|
|
VERSION:4.0
|
|
UID:1
|
|
FN:John Doe
|
|
END:VCARD
|
|
BEGIN:VCARD
|
|
VERSION:4.0
|
|
UID:2
|
|
FN:Jane Smith
|
|
END:VCARD`,
|
|
expected: [
|
|
`BEGIN:VCARD
|
|
VERSION:4.0
|
|
UID:1
|
|
FN:John Doe
|
|
END:VCARD`,
|
|
`BEGIN:VCARD
|
|
VERSION:4.0
|
|
UID:2
|
|
FN:Jane Smith
|
|
END:VCARD`,
|
|
],
|
|
},
|
|
{
|
|
input: `BEGIN:VCARD
|
|
VERSION:3.0
|
|
FN:Single Contact
|
|
EMAIL:single@example.com
|
|
END:VCARD`,
|
|
expected: [
|
|
`BEGIN:VCARD
|
|
VERSION:3.0
|
|
FN:Single Contact
|
|
EMAIL:single@example.com
|
|
END:VCARD`,
|
|
],
|
|
},
|
|
{
|
|
input: '',
|
|
expected: [],
|
|
},
|
|
{
|
|
input: `BEGIN:VCARD
|
|
VERSION:4.0
|
|
FN:Incomplete Contact`,
|
|
expected: [],
|
|
},
|
|
{
|
|
input: `BEGIN:VCARD
|
|
VERSION:3.0
|
|
FN:Single Contact
|
|
EMAIL:single@example.com
|
|
PHOTO;VALUE=URI:data:image/jpeg;base64\,/9j/4AAQSkZJRgABAQAAAQABAAD/4gIoSUN
|
|
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
|
|
//9k=
|
|
END:VCARD`,
|
|
expected: [
|
|
`BEGIN:VCARD
|
|
VERSION:3.0
|
|
FN:Single Contact
|
|
EMAIL:single@example.com
|
|
PHOTO;VALUE=URI:data:image/jpeg;base64\,/9j/4AAQSkZJRgABAQAAAQABAAD/4gIoSUN
|
|
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
|
|
//9k=
|
|
END:VCARD`,
|
|
],
|
|
},
|
|
];
|
|
|
|
for (const test of tests) {
|
|
const output = splitTextIntoVCards(test.input);
|
|
assertEquals(output, test.expected);
|
|
}
|
|
});
|
|
|
|
Deno.test('that generateVCard works', () => {
|
|
const tests: { input: { contactId: string; firstName: string; lastName?: string }; expected: string }[] = [
|
|
{
|
|
input: { contactId: 'test-123', firstName: 'John', lastName: 'Doe' },
|
|
expected: `BEGIN:VCARD
|
|
VERSION:4.0
|
|
N:Doe;John;
|
|
FN:John Doe
|
|
UID:test-123
|
|
END:VCARD`,
|
|
},
|
|
{
|
|
input: { contactId: 'single-name', firstName: 'Madonna' },
|
|
expected: `BEGIN:VCARD
|
|
VERSION:4.0
|
|
N:;Madonna;
|
|
FN:Madonna
|
|
UID:single-name
|
|
END:VCARD`,
|
|
},
|
|
{
|
|
input: { contactId: 'special-chars', firstName: 'John,Test', lastName: 'Doe\nSmith' },
|
|
expected: `BEGIN:VCARD
|
|
VERSION:4.0
|
|
N:Doe\\nSmith;John\\,Test;
|
|
FN:John\\,Test Doe\\nSmith
|
|
UID:special-chars
|
|
END:VCARD`,
|
|
},
|
|
];
|
|
|
|
for (const test of tests) {
|
|
const output = generateVCard(test.input.contactId, test.input.firstName, test.input.lastName);
|
|
assertEquals(output, test.expected);
|
|
}
|
|
});
|
|
|
|
Deno.test('that updateVCard works', () => {
|
|
const tests: {
|
|
input: {
|
|
vCard: string;
|
|
updates: {
|
|
firstName?: string;
|
|
lastName?: string;
|
|
email?: string;
|
|
phone?: string;
|
|
notes?: string;
|
|
};
|
|
};
|
|
expected: string;
|
|
}[] = [
|
|
{
|
|
input: {
|
|
vCard: `BEGIN:VCARD
|
|
VERSION:4.0
|
|
UID:test-123
|
|
N:Doe;John;
|
|
FN:John Doe
|
|
END:VCARD`,
|
|
updates: { firstName: 'Jane', lastName: 'Smith' },
|
|
},
|
|
expected: `BEGIN:VCARD
|
|
VERSION:4.0
|
|
UID:test-123
|
|
N:Smith;Jane;
|
|
FN:Jane Smith
|
|
END:VCARD`,
|
|
},
|
|
{
|
|
input: {
|
|
vCard: `BEGIN:VCARD
|
|
VERSION:4.0
|
|
UID:test-456
|
|
N:Doe;John;
|
|
FN:John Doe
|
|
EMAIL:old@example.com
|
|
TEL:+1234567890
|
|
END:VCARD`,
|
|
updates: { email: 'new@example.com', phone: '+9876543210' },
|
|
},
|
|
expected: `BEGIN:VCARD
|
|
VERSION:4.0
|
|
UID:test-456
|
|
N:Doe;John;
|
|
FN:John Doe
|
|
EMAIL:new@example.com
|
|
TEL:+9876543210
|
|
END:VCARD`,
|
|
},
|
|
{
|
|
input: {
|
|
vCard: `BEGIN:VCARD
|
|
VERSION:4.0
|
|
UID:test-789
|
|
N:Doe;John;
|
|
FN:John Doe
|
|
END:VCARD`,
|
|
updates: { email: 'added@example.com', phone: '+1111111111', notes: 'Test notes' },
|
|
},
|
|
expected: `BEGIN:VCARD
|
|
VERSION:4.0
|
|
UID:test-789
|
|
N:Doe;John;
|
|
FN:John Doe
|
|
EMAIL;TYPE=HOME:added@example.com
|
|
TEL;TYPE=HOME:+1111111111
|
|
NOTE:Test notes
|
|
END:VCARD`,
|
|
},
|
|
{
|
|
input: {
|
|
vCard: `BEGIN:VCARD
|
|
VERSION:4.0
|
|
UID:test-special
|
|
N:Doe;John;
|
|
FN:John Doe
|
|
NOTE:Old notes
|
|
END:VCARD`,
|
|
updates: { notes: 'New notes\nwith newlines, and commas' },
|
|
},
|
|
expected: `BEGIN:VCARD
|
|
VERSION:4.0
|
|
UID:test-special
|
|
N:Doe;John;
|
|
FN:John Doe
|
|
NOTE:New notes\\nwith newlines\\, and commas
|
|
END:VCARD`,
|
|
},
|
|
{
|
|
input: {
|
|
vCard: `BEGIN:VCARD
|
|
VERSION:4.0
|
|
UID:test-carriage
|
|
N:Doe;John;
|
|
FN:John Doe
|
|
END:VCARD`,
|
|
updates: { notes: 'Notes with\r\ncarriage returns' },
|
|
},
|
|
expected: `BEGIN:VCARD
|
|
VERSION:4.0
|
|
UID:test-carriage
|
|
N:Doe;John;
|
|
FN:John Doe
|
|
NOTE:Notes with\\ncarriage returns
|
|
END:VCARD`,
|
|
},
|
|
];
|
|
|
|
for (const test of tests) {
|
|
const output = updateVCard(test.input.vCard, test.input.updates);
|
|
assertEquals(output, test.expected);
|
|
}
|
|
});
|
|
|
|
Deno.test('that parseVCard works', () => {
|
|
const tests: {
|
|
input: string;
|
|
expected: Array<{
|
|
uid?: string;
|
|
firstName?: string;
|
|
lastName?: string;
|
|
middleNames?: string[];
|
|
title?: string;
|
|
email?: string;
|
|
phone?: string;
|
|
notes?: string;
|
|
}>;
|
|
}[] = [
|
|
{
|
|
input: `BEGIN:VCARD
|
|
VERSION:4.0
|
|
UID:test-123
|
|
N:Doe;John;Middle;Jr
|
|
FN:John Middle Doe Jr
|
|
EMAIL;TYPE=HOME:john@example.com
|
|
TEL;TYPE=HOME:+1234567890
|
|
NOTE:Test contact notes
|
|
END:VCARD`,
|
|
expected: [{
|
|
uid: 'test-123',
|
|
firstName: 'John',
|
|
lastName: 'Doe',
|
|
middleNames: ['Middle'],
|
|
title: 'Jr',
|
|
email: 'john@example.com',
|
|
phone: '+1234567890',
|
|
notes: 'Test contact notes',
|
|
}],
|
|
},
|
|
{
|
|
input: `BEGIN:VCARD
|
|
VERSION:3.0
|
|
UID:test-456
|
|
N:Smith;Jane;;
|
|
FN:Jane Smith
|
|
EMAIL:jane@example.com
|
|
TEL:+9876543210
|
|
END:VCARD`,
|
|
expected: [{
|
|
uid: 'test-456',
|
|
firstName: 'Jane',
|
|
lastName: 'Smith',
|
|
middleNames: [],
|
|
title: '',
|
|
email: 'jane@example.com',
|
|
phone: '+9876543210',
|
|
}],
|
|
},
|
|
{
|
|
input: `BEGIN:VCARD
|
|
VERSION:4.0
|
|
UID:multi-1
|
|
N:Doe;John;
|
|
FN:John Doe
|
|
END:VCARD
|
|
BEGIN:VCARD
|
|
VERSION:4.0
|
|
UID:multi-2
|
|
N:Smith;Jane;
|
|
FN:Jane Smith
|
|
EMAIL;PREF=1:jane@example.com
|
|
END:VCARD`,
|
|
expected: [
|
|
{
|
|
uid: 'multi-1',
|
|
firstName: 'John',
|
|
lastName: 'Doe',
|
|
middleNames: [],
|
|
title: '',
|
|
},
|
|
{
|
|
uid: 'multi-2',
|
|
firstName: 'Jane',
|
|
lastName: 'Smith',
|
|
middleNames: [],
|
|
title: '',
|
|
email: 'jane@example.com',
|
|
},
|
|
],
|
|
},
|
|
{
|
|
input: `BEGIN:VCARD
|
|
VERSION:4.0
|
|
UID:escaped-contact
|
|
N:Test;Contact;
|
|
FN:Contact Test
|
|
NOTE:Notes with\\nescaped newlines\\, and commas
|
|
END:VCARD`,
|
|
expected: [{
|
|
uid: 'escaped-contact',
|
|
firstName: 'Contact',
|
|
lastName: 'Test',
|
|
middleNames: [],
|
|
title: '',
|
|
notes: 'Notes with\nescaped newlines, and commas',
|
|
}],
|
|
},
|
|
{
|
|
input: `BEGIN:VCARD
|
|
VERSION:2.1
|
|
UID:version-21
|
|
N:Old;Format;
|
|
FN:Format Old
|
|
EMAIL:old@example.com
|
|
TEL:+1111111111
|
|
END:VCARD`,
|
|
expected: [{
|
|
uid: 'version-21',
|
|
firstName: 'Format',
|
|
lastName: 'Old',
|
|
middleNames: [],
|
|
title: '',
|
|
email: 'old@example.com',
|
|
phone: '+1111111111',
|
|
}],
|
|
},
|
|
{
|
|
input: `BEGIN:VCARD
|
|
VERSION:4.0
|
|
UID:email-variations
|
|
N:Test;Email;
|
|
FN:Email Test
|
|
EMAIL:direct@example.com
|
|
EMAIL;TYPE=WORK:work@example.com
|
|
TEL:+1234567890
|
|
TEL;TYPE=WORK:+9876543210
|
|
END:VCARD`,
|
|
expected: [{
|
|
uid: 'email-variations',
|
|
firstName: 'Email',
|
|
lastName: 'Test',
|
|
middleNames: [],
|
|
title: '',
|
|
email: 'direct@example.com', // Only first email is captured
|
|
phone: '+1234567890', // Only first phone is captured
|
|
}],
|
|
},
|
|
{
|
|
input: `BEGIN:VCARD
|
|
VERSION:5.0
|
|
UID:invalid-version
|
|
N:Invalid;Version;
|
|
FN:Version Invalid
|
|
END:VCARD`,
|
|
expected: [{
|
|
uid: 'invalid-version',
|
|
firstName: 'Version',
|
|
lastName: 'Invalid',
|
|
middleNames: [],
|
|
title: '',
|
|
}],
|
|
},
|
|
{
|
|
input: `BEGIN:VCARD
|
|
VERSION:4.0
|
|
UID:no-first-name
|
|
N:LastOnly;;
|
|
FN:LastOnly
|
|
END:VCARD`,
|
|
expected: [{ uid: 'no-first-name' }],
|
|
},
|
|
{
|
|
input: `BEGIN:VCARD
|
|
VERSION:4.0
|
|
UID:empty-uid
|
|
N:Test;Empty;
|
|
FN:Empty Test
|
|
END:VCARD`,
|
|
expected: [{
|
|
firstName: 'Empty',
|
|
lastName: 'Test',
|
|
middleNames: [],
|
|
title: '',
|
|
uid: 'empty-uid',
|
|
}],
|
|
},
|
|
];
|
|
|
|
for (const test of tests) {
|
|
const output = parseVCard(test.input);
|
|
assertEquals(output, test.expected);
|
|
}
|
|
});
|
|
|
|
Deno.test('that parseVCard handles edge cases', () => {
|
|
const edgeCases: { input: string; description: string; expected: any[] }[] = [
|
|
{
|
|
input: '',
|
|
description: 'empty string',
|
|
expected: [],
|
|
},
|
|
{
|
|
input: 'Not a vCard at all',
|
|
description: 'invalid format',
|
|
expected: [],
|
|
},
|
|
{
|
|
input: `BEGIN:VCARD
|
|
VERSION:4.0
|
|
UID:incomplete`,
|
|
description: 'incomplete vCard without END',
|
|
expected: [],
|
|
},
|
|
{
|
|
input: `BEGIN:VCARD
|
|
VERSION:4.0
|
|
UID:missing-required
|
|
FN:Missing Required Fields
|
|
END:VCARD`,
|
|
description: 'vCard without N field',
|
|
expected: [{ uid: 'missing-required' }],
|
|
},
|
|
{
|
|
input: `BEGIN:VCARD
|
|
VERSION:4.0
|
|
UID:empty-fields
|
|
N:;;;
|
|
FN:Empty Fields
|
|
EMAIL:
|
|
TEL:
|
|
NOTE:
|
|
END:VCARD`,
|
|
description: 'vCard with empty field values',
|
|
expected: [{ uid: 'empty-fields', notes: '' }],
|
|
},
|
|
];
|
|
|
|
for (const test of edgeCases) {
|
|
const output = parseVCard(test.input);
|
|
assertEquals(output, test.expected, `Failed for: ${test.description}`);
|
|
}
|
|
});
|