mirror of
https://github.com/logto-io/logto.git
synced 2024-12-30 20:33:54 -05:00
chore(test): complete custom phrase API guard and add ITs (#3772)
This commit is contained in:
parent
64a01f18d8
commit
7c2af46cf6
5 changed files with 121 additions and 0 deletions
|
@ -34,6 +34,7 @@ export default function customPhraseRoutes<T extends AuthedRouter>(
|
||||||
'/custom-phrases',
|
'/custom-phrases',
|
||||||
koaGuard({
|
koaGuard({
|
||||||
response: CustomPhrases.guard.array(),
|
response: CustomPhrases.guard.array(),
|
||||||
|
status: [200],
|
||||||
}),
|
}),
|
||||||
async (ctx, next) => {
|
async (ctx, next) => {
|
||||||
ctx.body = await findAllCustomPhrases();
|
ctx.body = await findAllCustomPhrases();
|
||||||
|
@ -47,6 +48,7 @@ export default function customPhraseRoutes<T extends AuthedRouter>(
|
||||||
koaGuard({
|
koaGuard({
|
||||||
params: object({ languageTag: languageTagGuard }),
|
params: object({ languageTag: languageTagGuard }),
|
||||||
response: CustomPhrases.guard,
|
response: CustomPhrases.guard,
|
||||||
|
status: [200],
|
||||||
}),
|
}),
|
||||||
async (ctx, next) => {
|
async (ctx, next) => {
|
||||||
const {
|
const {
|
||||||
|
@ -65,6 +67,7 @@ export default function customPhraseRoutes<T extends AuthedRouter>(
|
||||||
params: object({ languageTag: languageTagGuard }),
|
params: object({ languageTag: languageTagGuard }),
|
||||||
body: translationGuard,
|
body: translationGuard,
|
||||||
response: CustomPhrases.guard,
|
response: CustomPhrases.guard,
|
||||||
|
status: [200],
|
||||||
}),
|
}),
|
||||||
async (ctx, next) => {
|
async (ctx, next) => {
|
||||||
const {
|
const {
|
||||||
|
@ -89,6 +92,7 @@ export default function customPhraseRoutes<T extends AuthedRouter>(
|
||||||
'/custom-phrases/:languageTag',
|
'/custom-phrases/:languageTag',
|
||||||
koaGuard({
|
koaGuard({
|
||||||
params: object({ languageTag: languageTagGuard }),
|
params: object({ languageTag: languageTagGuard }),
|
||||||
|
status: [204],
|
||||||
}),
|
}),
|
||||||
async (ctx, next) => {
|
async (ctx, next) => {
|
||||||
const {
|
const {
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@jest/types": "^29.1.2",
|
"@jest/types": "^29.1.2",
|
||||||
"@logto/connector-kit": "workspace:^1.1.0",
|
"@logto/connector-kit": "workspace:^1.1.0",
|
||||||
|
"@logto/language-kit": "workspace:^1.0.0",
|
||||||
"@logto/js": "^2.0.1",
|
"@logto/js": "^2.0.1",
|
||||||
"@logto/node": "^2.0.0",
|
"@logto/node": "^2.0.0",
|
||||||
"@logto/schemas": "workspace:^1.1.0",
|
"@logto/schemas": "workspace:^1.1.0",
|
||||||
|
|
17
packages/integration-tests/src/api/custom-phrase.ts
Normal file
17
packages/integration-tests/src/api/custom-phrase.ts
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
import type { CustomPhrase, Translation } from '@logto/schemas';
|
||||||
|
|
||||||
|
import { authedAdminApi } from './api.js';
|
||||||
|
|
||||||
|
export const listCustomPhrases = async () =>
|
||||||
|
authedAdminApi.get('custom-phrases').json<CustomPhrase[]>();
|
||||||
|
|
||||||
|
export const getCustomPhrase = async (languageTag: string) =>
|
||||||
|
authedAdminApi.get(`custom-phrases/${languageTag}`).json<CustomPhrase>();
|
||||||
|
|
||||||
|
export const createOrUpdateCustomPhrase = async (languageTag: string, translation: Translation) =>
|
||||||
|
authedAdminApi
|
||||||
|
.put({ url: `custom-phrases/${languageTag}`, json: translation })
|
||||||
|
.json<CustomPhrase>();
|
||||||
|
|
||||||
|
export const deleteCustomPhrase = async (languageTag: string) =>
|
||||||
|
authedAdminApi.delete(`custom-phrases/${languageTag}`).json();
|
|
@ -0,0 +1,96 @@
|
||||||
|
import { HTTPError } from 'got';
|
||||||
|
|
||||||
|
import {
|
||||||
|
listCustomPhrases,
|
||||||
|
getCustomPhrase,
|
||||||
|
createOrUpdateCustomPhrase,
|
||||||
|
deleteCustomPhrase,
|
||||||
|
} from '#src/api/custom-phrase.js';
|
||||||
|
|
||||||
|
const mockZhTranslation = {
|
||||||
|
input: {
|
||||||
|
email: '邮箱',
|
||||||
|
password: '密码',
|
||||||
|
username: '用户名',
|
||||||
|
phone_number: '手机号码',
|
||||||
|
confirm_password: '确认密码',
|
||||||
|
search_region_code: '搜索区号',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const mockZhTranslationUpdated = {
|
||||||
|
...mockZhTranslation,
|
||||||
|
description: {
|
||||||
|
email: '邮箱',
|
||||||
|
phone_number: '手机号码',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const mockEnUsTranslation = {
|
||||||
|
input: {
|
||||||
|
email: 'email',
|
||||||
|
password: 'password',
|
||||||
|
username: 'username',
|
||||||
|
phone_number: 'phone_number',
|
||||||
|
confirm_password: 'confirm password',
|
||||||
|
search_region_code: 'search region code',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('custom-phrase flow', () => {
|
||||||
|
it('failed create a non built-in custom phrase with invalid language tag (zh-ZH)', async () => {
|
||||||
|
await expect(createOrUpdateCustomPhrase('zh-ZH', mockZhTranslation)).rejects.toThrow(HTTPError);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('create a non built-in custom phrase (zh)', async () => {
|
||||||
|
await createOrUpdateCustomPhrase('zh', mockZhTranslation);
|
||||||
|
const { translation: zhTranslation } = await getCustomPhrase('zh');
|
||||||
|
expect(zhTranslation).toEqual(mockZhTranslation);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('customize a built-in custom phrase (en-US)', async () => {
|
||||||
|
await createOrUpdateCustomPhrase('en-US', mockEnUsTranslation);
|
||||||
|
const { translation: enUsTranslation } = await getCustomPhrase('en-US');
|
||||||
|
expect(enUsTranslation).toEqual(mockEnUsTranslation);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('update an existing custom phrase', async () => {
|
||||||
|
await createOrUpdateCustomPhrase('zh', mockZhTranslationUpdated);
|
||||||
|
const { translation: zhTranslationNew } = await getCustomPhrase('zh');
|
||||||
|
expect(zhTranslationNew).toEqual(mockZhTranslationUpdated);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('failed to get a custom phrase with invalid language tag (zh-ZH)', async () => {
|
||||||
|
await expect(getCustomPhrase('zh-ZH')).rejects.toThrow(HTTPError);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('failed to get a custom phrase with non-existing record', async () => {
|
||||||
|
await expect(getCustomPhrase('zh-TW')).rejects.toThrow(HTTPError);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('get all custom phrases', async () => {
|
||||||
|
const allCustomPhrases = await listCustomPhrases();
|
||||||
|
expect(allCustomPhrases.find(({ languageTag }) => languageTag === 'zh')?.translation).toEqual(
|
||||||
|
mockZhTranslationUpdated
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
allCustomPhrases.find(({ languageTag }) => languageTag === 'en-US')?.translation
|
||||||
|
).toEqual(mockEnUsTranslation);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('failed to delete a custom phrase with invalid language tag (zh-ZH)', async () => {
|
||||||
|
await expect(deleteCustomPhrase('zh-ZH')).rejects.toThrow(HTTPError);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('failed to delete a custom phrase with non-existing record', async () => {
|
||||||
|
await expect(deleteCustomPhrase('zh-TW')).rejects.toThrow(HTTPError);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('delete all custom phrases', async () => {
|
||||||
|
await deleteCustomPhrase('zh');
|
||||||
|
await deleteCustomPhrase('en-US');
|
||||||
|
const allCustomPhrases = await listCustomPhrases();
|
||||||
|
expect(allCustomPhrases.find(({ languageTag }) => languageTag === 'zh')).toBeUndefined();
|
||||||
|
expect(allCustomPhrases.find(({ languageTag }) => languageTag === 'en-US')).toBeUndefined();
|
||||||
|
});
|
||||||
|
});
|
|
@ -3408,6 +3408,9 @@ importers:
|
||||||
'@logto/js':
|
'@logto/js':
|
||||||
specifier: ^2.0.1
|
specifier: ^2.0.1
|
||||||
version: 2.0.1
|
version: 2.0.1
|
||||||
|
'@logto/language-kit':
|
||||||
|
specifier: workspace:^1.0.0
|
||||||
|
version: link:../toolkit/language-kit
|
||||||
'@logto/node':
|
'@logto/node':
|
||||||
specifier: ^2.0.0
|
specifier: ^2.0.0
|
||||||
version: 2.0.0
|
version: 2.0.0
|
||||||
|
|
Loading…
Reference in a new issue