mirror of
https://gitlab.com/PronounsPage/PronounsPage.git
synced 2025-08-03 11:07:00 -04:00
228 lines
8.5 KiB
TypeScript
228 lines
8.5 KiB
TypeScript
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: '<speak>text</speak>',
|
||
},
|
||
{
|
||
description: 'slashes describe IPA phonemes',
|
||
pronunciationString: '/ðeɪ/',
|
||
ssml: '<speak><phoneme alphabet="ipa" ph="ðeɪ"></phoneme></speak>',
|
||
},
|
||
{
|
||
description: 'simple text and slashes can be combined',
|
||
pronunciationString: '/ðeɪ/ are',
|
||
ssml: '<speak><phoneme alphabet="ipa" ph="ðeɪ"></phoneme> are</speak>',
|
||
},
|
||
{
|
||
description: 'slashes can be escaped at front',
|
||
pronunciationString: String.raw`w\/o, n/A`,
|
||
ssml: '<speak>w/o, n/A</speak>',
|
||
},
|
||
{
|
||
description: 'slashes can be escaped at back',
|
||
pronunciationString: String.raw`w/o, n\/A`,
|
||
ssml: '<speak>w/o, n/A</speak>',
|
||
},
|
||
{
|
||
description: 'provided HTML is escaped',
|
||
pronunciationString: '<break time="1s"/>',
|
||
ssml: '<speak><break time="1s"/></speak>',
|
||
},
|
||
])('$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: '<break time="1s"/>',
|
||
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);
|
||
});
|
||
});
|