mirror of
https://github.com/sysadminsmedia/homebox.git
synced 2026-01-05 12:25:25 +01:00
298 lines
12 KiB
TypeScript
298 lines
12 KiB
TypeScript
import { describe, expect, test } from "vitest";
|
|
import type { ItemTemplateOut } from "../../types/data-contracts";
|
|
import type { UserClient } from "../../user";
|
|
import { factories } from "../factories";
|
|
import { sharedUserClient } from "../test-utils";
|
|
|
|
describe("templates lifecycle (create, update, delete)", () => {
|
|
/**
|
|
* useTemplate sets up a template resource for testing, and returns a function
|
|
* that can be used to delete the template from the backend server.
|
|
*/
|
|
async function useTemplate(api: UserClient): Promise<[ItemTemplateOut, () => Promise<void>]> {
|
|
const { response, data } = await api.templates.create(factories.template());
|
|
expect(response.status).toBe(201);
|
|
|
|
const cleanup = async () => {
|
|
const { response } = await api.templates.delete(data.id);
|
|
expect(response.status).toBe(204);
|
|
};
|
|
|
|
return [data, cleanup];
|
|
}
|
|
|
|
test("user should be able to create a template", async () => {
|
|
const api = await sharedUserClient();
|
|
|
|
const templateData = factories.template();
|
|
|
|
const { response, data } = await api.templates.create(templateData);
|
|
|
|
expect(response.status).toBe(201);
|
|
expect(data.id).toBeTruthy();
|
|
|
|
// Ensure we can get the template
|
|
const { response: getResponse, data: getData } = await api.templates.get(data.id);
|
|
|
|
expect(getResponse.status).toBe(200);
|
|
expect(getData.id).toBe(data.id);
|
|
expect(getData.name).toBe(templateData.name);
|
|
expect(getData.description).toBe(templateData.description);
|
|
expect(getData.defaultQuantity).toBe(templateData.defaultQuantity);
|
|
expect(getData.defaultInsured).toBe(templateData.defaultInsured);
|
|
expect(getData.defaultName).toBe(templateData.defaultName);
|
|
expect(getData.defaultDescription).toBe(templateData.defaultDescription);
|
|
expect(getData.defaultManufacturer).toBe(templateData.defaultManufacturer);
|
|
expect(getData.defaultModelNumber).toBe(templateData.defaultModelNumber);
|
|
|
|
// Cleanup
|
|
const { response: deleteResponse } = await api.templates.delete(data.id);
|
|
expect(deleteResponse.status).toBe(204);
|
|
});
|
|
|
|
test("user should be able to get all templates", async () => {
|
|
const api = await sharedUserClient();
|
|
const [_, cleanup] = await useTemplate(api);
|
|
|
|
const { response, data } = await api.templates.getAll();
|
|
|
|
expect(response.status).toBe(200);
|
|
expect(Array.isArray(data)).toBe(true);
|
|
expect(data.length).toBeGreaterThanOrEqual(1);
|
|
|
|
await cleanup();
|
|
});
|
|
|
|
test("user should be able to update a template", async () => {
|
|
const api = await sharedUserClient();
|
|
const [template, cleanup] = await useTemplate(api);
|
|
|
|
const updateData = {
|
|
id: template.id,
|
|
name: "updated-template-name",
|
|
description: "updated-description",
|
|
notes: "updated-notes",
|
|
defaultQuantity: 5,
|
|
defaultInsured: true,
|
|
defaultName: "Updated Default Name",
|
|
defaultDescription: "Updated Default Description",
|
|
defaultManufacturer: "Updated Manufacturer",
|
|
defaultModelNumber: "MODEL-999",
|
|
defaultLifetimeWarranty: true,
|
|
defaultWarrantyDetails: "Lifetime coverage",
|
|
defaultLocationId: null,
|
|
defaultTagIds: null,
|
|
includeWarrantyFields: true,
|
|
includePurchaseFields: true,
|
|
includeSoldFields: false,
|
|
fields: [],
|
|
};
|
|
|
|
const { response, data } = await api.templates.update(template.id, updateData);
|
|
expect(response.status).toBe(200);
|
|
expect(data.id).toBe(template.id);
|
|
|
|
// Ensure the template was updated
|
|
const { response: getResponse, data: getData } = await api.templates.get(template.id);
|
|
expect(getResponse.status).toBe(200);
|
|
expect(getData.name).toBe(updateData.name);
|
|
expect(getData.description).toBe(updateData.description);
|
|
expect(getData.notes).toBe(updateData.notes);
|
|
expect(getData.defaultQuantity).toBe(updateData.defaultQuantity);
|
|
expect(getData.defaultInsured).toBe(updateData.defaultInsured);
|
|
expect(getData.defaultName).toBe(updateData.defaultName);
|
|
expect(getData.defaultDescription).toBe(updateData.defaultDescription);
|
|
expect(getData.defaultManufacturer).toBe(updateData.defaultManufacturer);
|
|
expect(getData.defaultModelNumber).toBe(updateData.defaultModelNumber);
|
|
expect(getData.defaultLifetimeWarranty).toBe(updateData.defaultLifetimeWarranty);
|
|
expect(getData.includeWarrantyFields).toBe(updateData.includeWarrantyFields);
|
|
expect(getData.includePurchaseFields).toBe(updateData.includePurchaseFields);
|
|
|
|
await cleanup();
|
|
});
|
|
|
|
test("user should be able to delete a template", async () => {
|
|
const api = await sharedUserClient();
|
|
const [template, _] = await useTemplate(api);
|
|
|
|
const { response } = await api.templates.delete(template.id);
|
|
expect(response.status).toBe(204);
|
|
|
|
// Ensure we can't get the template
|
|
const { response: getResponse } = await api.templates.get(template.id);
|
|
expect(getResponse.status).toBe(404);
|
|
});
|
|
|
|
test("user should be able to create a template with custom fields", async () => {
|
|
const api = await sharedUserClient();
|
|
const NIL_UUID = "00000000-0000-0000-0000-000000000000";
|
|
|
|
const templateData = factories.template();
|
|
templateData.fields = [
|
|
{ id: NIL_UUID, name: "Custom Field 1", type: "text", textValue: "Value 1" },
|
|
{ id: NIL_UUID, name: "Custom Field 2", type: "text", textValue: "Value 2" },
|
|
];
|
|
|
|
const { response, data } = await api.templates.create(templateData);
|
|
|
|
expect(response.status).toBe(201);
|
|
expect(data.fields).toHaveLength(2);
|
|
expect(data.fields![0]!.name).toBe("Custom Field 1");
|
|
expect(data.fields![0]!.textValue).toBe("Value 1");
|
|
expect(data.fields![1]!.name).toBe("Custom Field 2");
|
|
expect(data.fields![1]!.textValue).toBe("Value 2");
|
|
|
|
// Cleanup
|
|
const { response: deleteResponse } = await api.templates.delete(data.id);
|
|
expect(deleteResponse.status).toBe(204);
|
|
});
|
|
|
|
test("user should be able to update template custom fields", async () => {
|
|
const api = await sharedUserClient();
|
|
const NIL_UUID = "00000000-0000-0000-0000-000000000000";
|
|
|
|
// Create template with a field
|
|
const templateData = factories.template();
|
|
templateData.fields = [{ id: NIL_UUID, name: "Original Field", type: "text", textValue: "Original Value" }];
|
|
|
|
const { response: createResponse, data: createdTemplate } = await api.templates.create(templateData);
|
|
expect(createResponse.status).toBe(201);
|
|
expect(createdTemplate.fields).toHaveLength(1);
|
|
|
|
// Update with modified and new fields
|
|
const updateData = {
|
|
id: createdTemplate.id,
|
|
name: createdTemplate.name,
|
|
description: createdTemplate.description,
|
|
notes: createdTemplate.notes,
|
|
defaultQuantity: createdTemplate.defaultQuantity,
|
|
defaultInsured: createdTemplate.defaultInsured,
|
|
defaultName: createdTemplate.defaultName,
|
|
defaultDescription: createdTemplate.defaultDescription,
|
|
defaultManufacturer: createdTemplate.defaultManufacturer,
|
|
defaultModelNumber: createdTemplate.defaultModelNumber,
|
|
defaultLifetimeWarranty: createdTemplate.defaultLifetimeWarranty,
|
|
defaultWarrantyDetails: createdTemplate.defaultWarrantyDetails,
|
|
defaultLocationId: null,
|
|
defaultTagIds: null,
|
|
includeWarrantyFields: createdTemplate.includeWarrantyFields,
|
|
includePurchaseFields: createdTemplate.includePurchaseFields,
|
|
includeSoldFields: createdTemplate.includeSoldFields,
|
|
fields: [
|
|
{ id: createdTemplate.fields![0]!.id, name: "Updated Field", type: "text", textValue: "Updated Value" },
|
|
{ id: NIL_UUID, name: "New Field", type: "text", textValue: "New Value" },
|
|
],
|
|
};
|
|
|
|
const { response: updateResponse, data: updatedTemplate } = await api.templates.update(
|
|
createdTemplate.id,
|
|
updateData
|
|
);
|
|
expect(updateResponse.status).toBe(200);
|
|
expect(updatedTemplate.fields).toHaveLength(2);
|
|
|
|
// Cleanup
|
|
const { response: deleteResponse } = await api.templates.delete(createdTemplate.id);
|
|
expect(deleteResponse.status).toBe(204);
|
|
});
|
|
});
|
|
|
|
describe("templates with location and tags", () => {
|
|
test("user should be able to create a template with a default location", async () => {
|
|
const api = await sharedUserClient();
|
|
|
|
// First create a location
|
|
const locationData = factories.location();
|
|
const { response: locResponse, data: location } = await api.locations.create(locationData);
|
|
expect(locResponse.status).toBe(201);
|
|
|
|
// Create template with the location
|
|
const templateData = factories.template();
|
|
templateData.defaultLocationId = location.id;
|
|
|
|
const { response, data } = await api.templates.create(templateData);
|
|
|
|
expect(response.status).toBe(201);
|
|
expect(data.defaultLocation).toBeTruthy();
|
|
expect(data.defaultLocation?.id).toBe(location.id);
|
|
expect(data.defaultLocation?.name).toBe(location.name);
|
|
|
|
// Cleanup
|
|
await api.templates.delete(data.id);
|
|
await api.locations.delete(location.id);
|
|
});
|
|
|
|
test("user should be able to create a template with default tags", async () => {
|
|
const api = await sharedUserClient();
|
|
|
|
// First create some tags
|
|
const { response: tag1Response, data: tag1 } = await api.tags.create(factories.tag());
|
|
expect(tag1Response.status).toBe(201);
|
|
|
|
const { response: tag2Response, data: tag2 } = await api.tags.create(factories.tag());
|
|
expect(tag2Response.status).toBe(201);
|
|
|
|
// Create template with tags
|
|
const templateData = factories.template();
|
|
templateData.defaultTagIds = [tag1.id, tag2.id];
|
|
|
|
const { response, data } = await api.templates.create(templateData);
|
|
|
|
expect(response.status).toBe(201);
|
|
expect(data.defaultTags).toHaveLength(2);
|
|
expect(data.defaultTags.map(l => l.id)).toContain(tag1.id);
|
|
expect(data.defaultTags.map(l => l.id)).toContain(tag2.id);
|
|
|
|
// Cleanup
|
|
await api.templates.delete(data.id);
|
|
await api.tags.delete(tag1.id);
|
|
await api.tags.delete(tag2.id);
|
|
});
|
|
|
|
test("user should be able to update template to remove location", async () => {
|
|
const api = await sharedUserClient();
|
|
|
|
// Create a location
|
|
const { response: locResponse, data: location } = await api.locations.create(factories.location());
|
|
expect(locResponse.status).toBe(201);
|
|
|
|
// Create template with location
|
|
const templateData = factories.template();
|
|
templateData.defaultLocationId = location.id;
|
|
|
|
const { response: createResponse, data: template } = await api.templates.create(templateData);
|
|
expect(createResponse.status).toBe(201);
|
|
expect(template.defaultLocation).toBeTruthy();
|
|
|
|
// Update to remove location
|
|
const updateData = {
|
|
id: template.id,
|
|
name: template.name,
|
|
description: template.description,
|
|
notes: template.notes,
|
|
defaultQuantity: template.defaultQuantity,
|
|
defaultInsured: template.defaultInsured,
|
|
defaultName: template.defaultName,
|
|
defaultDescription: template.defaultDescription,
|
|
defaultManufacturer: template.defaultManufacturer,
|
|
defaultModelNumber: template.defaultModelNumber,
|
|
defaultLifetimeWarranty: template.defaultLifetimeWarranty,
|
|
defaultWarrantyDetails: template.defaultWarrantyDetails,
|
|
defaultLocationId: null,
|
|
defaultTagIds: null,
|
|
includeWarrantyFields: template.includeWarrantyFields,
|
|
includePurchaseFields: template.includePurchaseFields,
|
|
includeSoldFields: template.includeSoldFields,
|
|
fields: [],
|
|
};
|
|
|
|
const { response: updateResponse, data: updated } = await api.templates.update(template.id, updateData);
|
|
expect(updateResponse.status).toBe(200);
|
|
expect(updated.defaultLocation).toBeNull();
|
|
|
|
// Cleanup
|
|
await api.templates.delete(template.id);
|
|
await api.locations.delete(location.id);
|
|
});
|
|
});
|