import { describe, expect, test } from 'vitest';
import {
escapeControlSymbols,
unescapeControlSymbols,
convertPronunciationStringToSsml,
convertPronunciationStringToNarakeetFormat,
escapePronunciationString,
isGrantedForUser,
} from '../src/helpers.ts';
import type { PermissionArea } from '~/src/helpers.ts';
const controlSymbols = [
{
description: 'slashes',
unescaped: 'w/o n/A',
escaped: 'w`/o n`/A',
},
{
description: 'ampersands',
unescaped: 'me & you',
escaped: 'me `& you',
},
{
description: 'backticks',
unescaped: '`code` in markdown',
escaped: '``code`` in markdown',
},
{
description: 'commas',
unescaped: 'me, you',
escaped: 'me`, you',
},
{
description: 'pipes',
unescaped: '0 | 1',
escaped: '0 `| 1',
},
];
describe('when escaping control symbols', () => {
test('safely handles null', () => {
expect(escapeControlSymbols(null)).toBeNull();
});
test.each(controlSymbols)('$description get escaped with `', ({ unescaped, escaped }) => {
expect(escapeControlSymbols(unescaped)).toBe(escaped);
});
});
describe('when unescaping control symbols', () => {
test('safely handles null', () => {
expect(unescapeControlSymbols(null)).toBeNull();
});
test.each(controlSymbols)('$description get unescaped', ({ unescaped, escaped }) => {
expect(unescapeControlSymbols(escaped)).toBe(unescaped);
});
});
describe('when escaping pronunciation to SSML', () => {
test.each([
{
description: 'slashes get escaped',
text: 'w/o n/A',
pronunciationString: String.raw`w\/o n\/A`,
},
{
description: 'backslashes get escaped',
text: String.raw`\n is the symbol for a newline, \t for a tab`,
pronunciationString: String.raw`\\n is the symbol for a newline, \\t for a tab`,
},
])('$description', ({ text, pronunciationString }) => {
expect(escapePronunciationString(text)).toBe(pronunciationString);
});
});
describe('when converting pronunciation', () => {
test.each([
{
description: 'simple text is passed as-is',
pronunciationString: 'text',
ssml: 'text',
},
{
description: 'slashes describe IPA phonemes',
pronunciationString: '/ðeɪ/',
ssml: '',
},
{
description: 'simple text and slashes can be combined',
pronunciationString: '/ðeɪ/ are',
ssml: ' are',
},
{
description: 'slashes can be escaped at front',
pronunciationString: String.raw`w\/o, n/A`,
ssml: 'w/o, n/A',
},
{
description: 'slashes can be escaped at back',
pronunciationString: String.raw`w/o, n\/A`,
ssml: 'w/o, n/A',
},
{
description: 'provided HTML is escaped',
pronunciationString: '',
ssml: '<break time="1s"/>',
},
])('$description', ({ pronunciationString, ssml }) => {
expect(convertPronunciationStringToSsml(pronunciationString)).toBe(ssml);
});
});
describe('when converting pronunciation to Narakeet format', () => {
test.each([
{
description: 'simple text is passed as-is',
pronunciationString: 'text',
narakeet: 'text',
},
{
description: 'slashes describe IPA phonemes',
pronunciationString: '/ðeɪ/',
narakeet: '[ðeɪ]{ipa}',
},
{
description: 'simple text and slashes can be combined',
pronunciationString: '/ðeɪ/ are',
narakeet: '[ðeɪ]{ipa} are',
},
{
description: 'slashes can be escaped at front',
pronunciationString: String.raw`w\/o, n/A`,
narakeet: 'w/o, n/A',
},
{
description: 'slashes can be escaped at back',
pronunciationString: String.raw`w/o, n\/A`,
narakeet: 'w/o, n/A',
},
{
description: 'provided HTML is escaped',
pronunciationString: '',
narakeet: '<break time="1s"/>',
},
])('$description', ({ pronunciationString, narakeet }) => {
expect(convertPronunciationStringToNarakeetFormat(pronunciationString)).toBe(narakeet);
});
});
class GrantTest {
constructor(
public readonly givenRoles: string,
public readonly requestedLocale: string,
public readonly requestedArea: PermissionArea,
public readonly granted: boolean,
) {}
}
describe('access control', () => {
const SUPER_ADMIN = '*';
const LOCALE_ADMIN = 'pl-*|fr-nouns';
const SUPER_ADMIN_PLUS_RESTRICTED = '*|*-code';
const SECTION_ADMIN = '*-terms';
const EXTERNAL_CONTRIBUTOR = '*-external';
const GUEST = '';
test.each([
new GrantTest(SUPER_ADMIN, 'en', '*', true),
new GrantTest(SUPER_ADMIN, 'en', 'panel', true),
new GrantTest(SUPER_ADMIN, 'en', 'nouns', true),
new GrantTest(SUPER_ADMIN, 'en', 'code', false), // restricted area
new GrantTest(SUPER_ADMIN, 'en', 'external', true),
new GrantTest(SUPER_ADMIN, 'en', '', true),
new GrantTest(SUPER_ADMIN_PLUS_RESTRICTED, 'en', '*', true),
new GrantTest(SUPER_ADMIN_PLUS_RESTRICTED, 'en', 'panel', true),
new GrantTest(SUPER_ADMIN_PLUS_RESTRICTED, 'en', 'nouns', true),
new GrantTest(SUPER_ADMIN_PLUS_RESTRICTED, 'en', 'code', true),
new GrantTest(SUPER_ADMIN_PLUS_RESTRICTED, 'en', 'external', true),
new GrantTest(SUPER_ADMIN_PLUS_RESTRICTED, 'en', '', true),
new GrantTest(LOCALE_ADMIN, 'en', '*', false), // super-admin area
new GrantTest(LOCALE_ADMIN, 'en', 'panel', false), // wrong locale
new GrantTest(LOCALE_ADMIN, 'en', 'nouns', false),
new GrantTest(LOCALE_ADMIN, 'en', 'code', false),
new GrantTest(LOCALE_ADMIN, 'en', 'external', false),
new GrantTest(LOCALE_ADMIN, 'en', '', false),
new GrantTest(LOCALE_ADMIN, 'pl', 'panel', true),
new GrantTest(LOCALE_ADMIN, 'pl', 'nouns', true),
new GrantTest(LOCALE_ADMIN, 'pl', 'code', false), // restricted area
new GrantTest(LOCALE_ADMIN, 'pl', 'external', true),
new GrantTest(LOCALE_ADMIN, 'pl', '', true),
new GrantTest(LOCALE_ADMIN, 'fr', 'nouns', true),
new GrantTest(LOCALE_ADMIN, 'fr', 'inclusive', false), // wrong area
new GrantTest(LOCALE_ADMIN, 'fr', '', true),
new GrantTest(SECTION_ADMIN, 'en', '*', false),
new GrantTest(SECTION_ADMIN, 'en', 'panel', true),
new GrantTest(SECTION_ADMIN, 'en', 'nouns', false),
new GrantTest(SECTION_ADMIN, 'en', 'terms', true),
new GrantTest(SECTION_ADMIN, 'en', 'code', false),
new GrantTest(SECTION_ADMIN, 'en', 'external', false),
new GrantTest(SECTION_ADMIN, 'pl', '*', false),
new GrantTest(SECTION_ADMIN, 'pl', 'panel', true),
new GrantTest(SECTION_ADMIN, 'pl', 'nouns', false),
new GrantTest(SECTION_ADMIN, 'pl', 'terms', true),
new GrantTest(SECTION_ADMIN, 'pl', 'code', false),
new GrantTest(SECTION_ADMIN, 'pl', 'external', false),
new GrantTest(EXTERNAL_CONTRIBUTOR, 'en', '*', false),
new GrantTest(EXTERNAL_CONTRIBUTOR, 'en', 'panel', false),
new GrantTest(EXTERNAL_CONTRIBUTOR, 'en', 'nouns', false),
new GrantTest(EXTERNAL_CONTRIBUTOR, 'en', 'code', false),
new GrantTest(EXTERNAL_CONTRIBUTOR, 'en', 'external', true),
new GrantTest(EXTERNAL_CONTRIBUTOR, 'en', '', false),
new GrantTest(GUEST, 'en', '*', false),
new GrantTest(GUEST, 'en', 'panel', false),
new GrantTest(GUEST, 'en', 'nouns', false),
new GrantTest(GUEST, 'en', 'code', false),
new GrantTest(GUEST, 'en', 'external', false),
new GrantTest(GUEST, 'en', '', false),
])('user with roles $givenRoles requesting $requestedArea in $requestedLocale', ({ givenRoles, requestedLocale, requestedArea, granted }) => {
expect(isGrantedForUser({ roles: givenRoles }, requestedLocale, requestedArea)).toBe(granted);
});
});