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); }); });