setup mocks + request handlers for languages

This commit is contained in:
Mads Rasmussen
2024-02-01 08:25:35 +01:00
parent 76530fb983
commit 403560d58c
13 changed files with 226 additions and 201 deletions

View File

@@ -8,7 +8,7 @@ import { handlers as documentTypeHandlers } from './handlers/document-type/index
import { handlers as examineManagementHandlers } from './handlers/examine-management.handlers.js';
import { handlers as healthCheckHandlers } from './handlers/health-check.handlers.js';
import { handlers as installHandlers } from './handlers/install.handlers.js';
import { handlers as languageHandlers } from './handlers/language.handlers.js';
import { handlers as languageHandlers } from './handlers/language/index.js';
import { handlers as logViewerHandlers } from './handlers/log-viewer.handlers.js';
import { handlers as mediaHandlers } from './handlers/media/index.js';
import { handlers as mediaTypeHandlers } from './handlers/media-type/index.js';

View File

@@ -16,16 +16,16 @@ import type {
class UmbDataTypeMockDB extends UmbEntityMockDbBase<UmbMockDataTypeModel> {
tree = new UmbMockEntityTreeManager<UmbMockDataTypeModel>(this, folderTreeItemMapper);
folder = new UmbMockEntityFolderManager<UmbMockDataTypeModel>(this, createMockDataTypeFolderMapper);
item = new UmbMockEntityItemManager<UmbMockDataTypeModel>(this, dataTypeItemMapper);
detail = new UmbMockEntityDetailManager<UmbMockDataTypeModel>(this, createMockDataTypeMapper, dataTypeDetailMapper);
folder = new UmbMockEntityFolderManager<UmbMockDataTypeModel>(this, createFolderMockMapper);
item = new UmbMockEntityItemManager<UmbMockDataTypeModel>(this, itemResponseMapper);
detail = new UmbMockEntityDetailManager<UmbMockDataTypeModel>(this, createDetailMockMapper, detailResponseMapper);
constructor(data: Array<UmbMockDataTypeModel>) {
super(data);
}
}
const createMockDataTypeFolderMapper = (request: CreateFolderRequestModel): UmbMockDataTypeModel => {
const createFolderMockMapper = (request: CreateFolderRequestModel): UmbMockDataTypeModel => {
return {
name: request.name,
id: request.id ? request.id : UmbId.new(),
@@ -37,7 +37,7 @@ const createMockDataTypeFolderMapper = (request: CreateFolderRequestModel): UmbM
};
};
const createMockDataTypeMapper = (request: CreateDataTypeRequestModel): UmbMockDataTypeModel => {
const createDetailMockMapper = (request: CreateDataTypeRequestModel): UmbMockDataTypeModel => {
return {
id: request.id ? request.id : UmbId.new(),
parentId: request.parentId,
@@ -50,7 +50,7 @@ const createMockDataTypeMapper = (request: CreateDataTypeRequestModel): UmbMockD
};
};
const dataTypeDetailMapper = (item: UmbMockDataTypeModel): DataTypeResponseModel => {
const detailResponseMapper = (item: UmbMockDataTypeModel): DataTypeResponseModel => {
return {
id: item.id,
parentId: item.parentId,
@@ -61,7 +61,7 @@ const dataTypeDetailMapper = (item: UmbMockDataTypeModel): DataTypeResponseModel
};
};
const dataTypeItemMapper = (item: UmbMockDataTypeModel): DataTypeItemResponseModel => {
const itemResponseMapper = (item: UmbMockDataTypeModel): DataTypeItemResponseModel => {
return {
id: item.id,
name: item.name,

View File

@@ -0,0 +1,19 @@
import type { LanguageItemResponseModel, LanguageResponseModel } from '@umbraco-cms/backoffice/backend-api';
export type UmbMockLanguageModel = LanguageResponseModel & LanguageItemResponseModel;
export const data: Array<UmbMockLanguageModel> = [
{
name: 'English',
isoCode: 'en',
isDefault: true,
isMandatory: true,
},
{
name: 'Danish',
isoCode: 'da',
isDefault: false,
isMandatory: false,
fallbackIsoCode: 'en',
},
];

View File

@@ -0,0 +1,48 @@
import { UmbMockCultureItemManager } from '../utils/culture/culture-item.manager.js';
import { UmbCultureMockDbBase } from '../utils/culture/culture-base.js';
import { UmbMockCultureDetailManager } from '../utils/culture/culture-detail.manager.js';
import type { UmbMockLanguageModel } from './language.data.js';
import { data } from './language.data.js';
import type {
CreateLanguageRequestModel,
LanguageItemResponseModel,
LanguageResponseModel,
} from '@umbraco-cms/backoffice/backend-api';
class UmbLanguageMockDB extends UmbCultureMockDbBase<UmbMockLanguageModel> {
item = new UmbMockCultureItemManager<UmbMockLanguageModel>(this, itemResponseMapper);
detail = new UmbMockCultureDetailManager<UmbMockLanguageModel>(this, createDetailMockMapper, detailResponseMapper);
constructor(data: Array<UmbMockLanguageModel>) {
super(data);
}
}
const createDetailMockMapper = (request: CreateLanguageRequestModel): UmbMockLanguageModel => {
return {
fallbackIsoCode: request.fallbackIsoCode,
isDefault: request.isDefault,
isMandatory: request.isMandatory,
isoCode: request.isoCode,
name: request.name,
};
};
const detailResponseMapper = (item: UmbMockLanguageModel): LanguageResponseModel => {
return {
fallbackIsoCode: item.fallbackIsoCode,
isDefault: item.isDefault,
isMandatory: item.isMandatory,
isoCode: item.isoCode,
name: item.name,
};
};
const itemResponseMapper = (item: UmbMockLanguageModel): LanguageItemResponseModel => {
return {
isoCode: item.isoCode,
name: item.name,
};
};
export const umbLanguageMockDb = new UmbLanguageMockDB(data);

View File

@@ -1,115 +0,0 @@
import { UmbMockDBBase } from './utils/mock-db-base.js';
import type { LanguageResponseModel } from '@umbraco-cms/backoffice/backend-api';
// Temp mocked database
class UmbLanguagesData extends UmbMockDBBase<LanguageResponseModel> {
constructor(data: LanguageResponseModel[]) {
super(data);
}
// skip can be number or null
getAll(skip = 0, take = this.data.length): Array<LanguageResponseModel> {
return this.data.slice(skip, take);
}
getByKey(isoCode: string) {
return this.data.find((item) => item.isoCode === isoCode);
}
getItems(isoCodes: Array<string>) {
return this.data.filter((item) => isoCodes.indexOf(item.isoCode || '') !== -1);
}
insert(language: LanguageResponseModel) {
const foundIndex = this.data.findIndex((item) => item.isoCode === language.isoCode);
if (foundIndex !== -1) {
throw new Error('Language with same iso code already exists');
}
this.data.push(language);
}
// TODO: this should and can only take a single save item.
save(isoCode: string, saveItems: Array<LanguageResponseModel>) {
saveItems.forEach((saveItem) => {
const foundIndex = this.data.findIndex((item) => item.isoCode === isoCode);
if (foundIndex !== -1) {
// update
this.data[foundIndex] = saveItem;
this.updateData(saveItem);
} else {
// Set all other languages to not default
if (saveItem.isDefault) {
this.data.forEach((item) => {
if (saveItem !== item) {
item.isDefault = false;
}
});
}
this.data.push(saveItem);
}
});
return this.data;
}
delete(isoCodes: Array<string>) {
isoCodes.forEach((isoCode) => {
const foundIndex = this.data.findIndex((item) => item.isoCode === isoCode);
if (foundIndex !== -1) {
this.data.splice(foundIndex, 1);
}
});
return isoCodes;
}
updateData(updateItem: LanguageResponseModel) {
const itemIndex = this.data.findIndex((item) => item.isoCode === updateItem.isoCode);
const item = this.data[itemIndex];
if (!item) return;
const itemKeys = Object.keys(item);
const newItem = {};
// Set all other languages to not default
if (updateItem.isDefault) {
this.data.forEach((item) => {
if (updateItem !== item) {
item.isDefault = false;
}
});
}
for (const [key] of Object.entries(updateItem)) {
if (itemKeys.indexOf(key) !== -1) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
newItem[key] = updateItem[key];
}
}
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
this.data[itemIndex] = newItem;
}
}
export const MockData: Array<LanguageResponseModel> = [
{
name: 'English',
isoCode: 'en',
isDefault: true,
isMandatory: true,
},
{
name: 'Danish',
isoCode: 'da',
isDefault: false,
isMandatory: false,
fallbackIsoCode: 'en',
},
];
export const umbLanguagesData = new UmbLanguagesData(MockData);

View File

@@ -0,0 +1,26 @@
import { UmbMockDBBase } from '../mock-db-base.js';
export abstract class UmbCultureMockDbBase<
MockItemType extends { isoCode: string },
> extends UmbMockDBBase<MockItemType> {
constructor(data: Array<MockItemType>) {
super(data);
}
create(item: MockItemType) {
this.data.push(item);
}
read(isoCode: string) {
return this.data.find((item) => item.isoCode === isoCode);
}
update(isoCode: string, updatedItem: MockItemType) {
const itemIndex = this.data.findIndex((item) => item.isoCode === isoCode);
this.data[itemIndex] = updatedItem;
}
delete(isoCode: string) {
this.data = this.data.filter((item) => item.isoCode !== isoCode);
}
}

View File

@@ -0,0 +1,46 @@
import type { UmbCultureMockDbBase } from './culture-base.js';
export class UmbMockCultureDetailManager<MockType extends { isoCode: string }> {
#db: UmbCultureMockDbBase<MockType>;
#createMockItemMapper: (request: any) => MockType;
#readResponseMapper: (mockItem: MockType) => any;
constructor(
db: UmbCultureMockDbBase<MockType>,
createMockItemMapper: (request: any) => MockType,
readResponseMapper: (mockItem: MockType) => any,
) {
this.#db = db;
this.#createMockItemMapper = createMockItemMapper;
this.#readResponseMapper = readResponseMapper;
}
create(request: any) {
const mockItem = this.#createMockItemMapper(request);
// create mock item in mock db
this.#db.create(mockItem);
return mockItem.isoCode;
}
read(id: string) {
const item = this.#db.read(id);
if (!item) throw new Error('Item not found');
const mappedItem = this.#readResponseMapper(item);
return mappedItem;
}
update(isoCode: string, item: any) {
const mockItem = this.#db.read(isoCode);
const updatedMockItem = {
...mockItem,
...item,
} as unknown as MockType;
this.#db.update(isoCode, updatedMockItem);
}
delete(isoCode: string) {
this.#db.delete(isoCode);
}
}

View File

@@ -0,0 +1,16 @@
import type { UmbMockDBBase } from '../mock-db-base.js';
export class UmbMockCultureItemManager<T extends { isoCode: string }> {
#db: UmbMockDBBase<T>;
#itemReadMapper: (item: T) => any;
constructor(db: UmbMockDBBase<T>, itemReadMapper: (item: T) => any) {
this.#db = db;
this.#itemReadMapper = itemReadMapper;
}
getItems(isoCodes: Array<string>) {
const items = this.#db.getAll().filter((item) => isoCodes.includes(item.isoCode));
return items.map((item) => this.#itemReadMapper(item));
}
}

View File

@@ -1,78 +0,0 @@
const { rest } = window.MockServiceWorker;
import { umbLanguagesData } from '../data/languages.data.js';
import type { LanguageResponseModel, ProblemDetails } from '@umbraco-cms/backoffice/backend-api';
import { umbracoPath } from '@umbraco-cms/backoffice/utils';
// TODO: add schema
export const handlers = [
rest.get(umbracoPath('/language/item'), (req, res, ctx) => {
const isoCodes = req.url.searchParams.getAll('isoCode');
if (!isoCodes) return;
const items = umbLanguagesData.getItems(isoCodes);
return res(ctx.status(200), ctx.json(items));
}),
rest.get(umbracoPath('/language'), (req, res, ctx) => {
const skip = req.url.searchParams.get('skip');
const skipNumber = skip ? Number.parseInt(skip) : undefined;
const take = req.url.searchParams.get('take');
const takeNumber = take ? Number.parseInt(take) : undefined;
const items = umbLanguagesData.getAll(skipNumber, takeNumber);
const response = {
total: items.length,
items,
};
return res(ctx.status(200), ctx.json(response));
}),
rest.get(umbracoPath('/language/:id'), (req, res, ctx) => {
const id = req.params.id as string;
if (!id) return;
const item = umbLanguagesData.getByKey(id);
return res(ctx.status(200), ctx.json(item));
}),
rest.post<LanguageResponseModel>(umbracoPath('/language'), async (req, res, ctx) => {
const data = await req.json();
if (!data) return;
try {
umbLanguagesData.insert(data);
return res(ctx.status(201));
} catch (error) {
return res(
ctx.status(400),
ctx.json<ProblemDetails>({
status: 400,
type: 'validation',
detail: 'Something went wrong',
errors: {
isoCode: ['Language with same iso code already exists'],
},
}),
);
}
}),
rest.put<LanguageResponseModel>(umbracoPath('/language/:id'), async (req, res, ctx) => {
const id = req.params.id as string;
if (!id) return;
const data = await req.json();
if (!data) return;
umbLanguagesData.save(id, [data]);
return res(ctx.status(200));
}),
rest.delete(umbracoPath('/language/:id'), async (req, res, ctx) => {
return res(ctx.status(200));
}),
];

View File

@@ -0,0 +1,45 @@
const { rest } = window.MockServiceWorker;
import { umbLanguageMockDb } from '../../data/language/language.db.js';
import { UMB_SLUG } from './slug.js';
import type { CreateLanguageRequestModel, UpdateLanguageRequestModel } from '@umbraco-cms/backoffice/backend-api';
import { umbracoPath } from '@umbraco-cms/backoffice/utils';
export const detailHandlers = [
rest.post(umbracoPath(`${UMB_SLUG}`), async (req, res, ctx) => {
const requestBody = (await req.json()) as CreateLanguageRequestModel;
if (!requestBody) return res(ctx.status(400, 'no body found'));
const id = umbLanguageMockDb.detail.create(requestBody);
return res(
ctx.status(201),
ctx.set({
Location: req.url.href + '/' + id,
'Umb-Generated-Resource': id,
}),
);
}),
rest.get(umbracoPath(`${UMB_SLUG}/:id`), (req, res, ctx) => {
const id = req.params.id as string;
if (!id) return res(ctx.status(400));
const response = umbLanguageMockDb.detail.read(id);
return res(ctx.status(200), ctx.json(response));
}),
rest.put(umbracoPath(`${UMB_SLUG}/:id`), async (req, res, ctx) => {
const id = req.params.id as string;
if (!id) return res(ctx.status(400));
const requestBody = (await req.json()) as UpdateLanguageRequestModel;
if (!requestBody) return res(ctx.status(400, 'no body found'));
umbLanguageMockDb.detail.update(id, requestBody);
return res(ctx.status(200));
}),
rest.delete(umbracoPath(`${UMB_SLUG}/:id`), (req, res, ctx) => {
const id = req.params.id as string;
if (!id) return res(ctx.status(400));
umbLanguageMockDb.detail.delete(id);
return res(ctx.status(200));
}),
];

View File

@@ -0,0 +1,4 @@
import { detailHandlers } from './detail.handlers.js';
import { itemHandlers } from './item.handlers.js';
export const handlers = [...itemHandlers, ...detailHandlers];

View File

@@ -0,0 +1,13 @@
const { rest } = window.MockServiceWorker;
import { umbLanguageMockDb } from '../../data/language/language.db.js';
import { UMB_SLUG } from './slug.js';
import { umbracoPath } from '@umbraco-cms/backoffice/utils';
export const itemHandlers = [
rest.get(umbracoPath(`${UMB_SLUG}/item`), (req, res, ctx) => {
const isoCodes = req.url.searchParams.getAll('id');
if (!isoCodes) return;
const items = umbLanguageMockDb.item.getItems(isoCodes);
return res(ctx.status(200), ctx.json(items));
}),
];

View File

@@ -0,0 +1 @@
export const UMB_SLUG = '/data-type';