-
@@ -88,66 +62,50 @@ test('toggle', async () => {
`);
});
-test('home page', async () => {
- const history = createMemoryHistory();
-
+test('open navigation', async () => {
const { container } = render(
-
+
- ,
+ ,
);
- await screen.findByTestId('page-home-mock');
-
- expect(formatHtml(container.outerHTML)).toMatchInlineSnapshot(`
- "
- "
- `);
-});
-
-test('not found', async () => {
- const history = createMemoryHistory();
- history.push('/unknown');
-
- const { container } = render(
-
-
- ,
- );
+ const navigationToggle = await screen.findByTestId('navigation-toggle');
- await screen.findByTestId('page-not-found-mock');
+ await act(() => userEvent.click(navigationToggle));
expect(formatHtml(container.outerHTML)).toMatchInlineSnapshot(`
"
-
-
@@ -156,134 +114,46 @@ test('not found', async () => {
});
test('pet list', async () => {
- const history = createMemoryHistory();
- history.push('/pet');
-
- const { container } = render(
-
-
- ,
- );
-
- await screen.findByTestId('page-pet-list-mock');
-
- expect(formatHtml(container.outerHTML)).toMatchInlineSnapshot(`
- "
- "
- `);
-});
-
-test('pet create', async () => {
- const history = createMemoryHistory();
- history.push('/pet/create');
-
- const { container } = render(
-
-
- ,
- );
-
- await screen.findByTestId('page-pet-create-mock');
-
- expect(formatHtml(container.outerHTML)).toMatchInlineSnapshot(`
- "
- "
- `);
-});
-
-test('pet read', async () => {
- const history = createMemoryHistory();
- history.push('/pet/4d783b77-eb09-4603-b99b-f590b605eaa9');
-
- const { container } = render(
-
-
- ,
- );
-
- await screen.findByTestId('page-pet-read-mock');
-
- expect(formatHtml(container.outerHTML)).toMatchInlineSnapshot(`
- "
- "
- `);
-});
-
-test('pet update', async () => {
- const history = createMemoryHistory();
- history.push('/pet/4d783b77-eb09-4603-b99b-f590b605eaa9/update');
-
const { container } = render(
-
+
- ,
+ ,
);
- await screen.findByTestId('page-pet-update-mock');
+ await screen.findByTestId('routes-mock');
expect(formatHtml(container.outerHTML)).toMatchInlineSnapshot(`
"
-
-
diff --git a/tests/client/client.test.ts b/tests/client/client.test.ts
new file mode 100644
index 0000000..7b0121d
--- /dev/null
+++ b/tests/client/client.test.ts
@@ -0,0 +1,1239 @@
+import { describe, expect, test } from 'vitest';
+import type { Fetch } from '../../src/client/client';
+import {
+ createCreateClient,
+ createDeleteClient,
+ createListClient,
+ createReadClient,
+ createUpdateClient,
+} from '../../src/client/client';
+import {
+ modelRequestSchema,
+ modelResponseSchema,
+ modelListRequestSchema,
+ modelListResponseSchema,
+} from '../../src/model/model';
+import { useFunctionMock } from '@chubbyts/chubbyts-function-mock/dist/function-mock';
+import { z } from 'zod';
+
+const dummyModelRequestSchema = z.object({
+ ...modelRequestSchema.shape,
+ name: z.string(),
+});
+
+type DummyModelRequest = z.infer
;
+
+const dummyModelResponseSchema = z.object({
+ ...modelResponseSchema.shape,
+ ...dummyModelRequestSchema.shape,
+});
+
+type DummyModelResponse = z.infer;
+
+const dummyModelListRequestSchema = z.object({
+ ...modelListRequestSchema.shape,
+ filters: z
+ .object({
+ name: z.string().optional(),
+ })
+ .strict()
+ .optional(),
+});
+
+type DummyModelListRequest = z.infer;
+
+const dummyModelListResponseSchema = z.object({
+ ...modelListResponseSchema.shape,
+ filters: z
+ .object({
+ name: z.string().optional(),
+ })
+ .strict()
+ .optional(),
+ items: z.array(dummyModelResponseSchema),
+});
+
+type DummyModelListResponse = z.infer;
+
+describe('createListClient', () => {
+ test('success', async () => {
+ const dummyModelRequest: DummyModelRequest = {
+ name: 'Dummy',
+ };
+
+ const dummyModelResponse: DummyModelResponse = {
+ id: '4d783b77-eb09-4603-b99b-f590b605eaa9',
+ createdAt: '2022-06-12T20:08:24.793Z',
+ ...dummyModelRequest,
+ _links: {},
+ };
+
+ const dummyModelListRequest: DummyModelListRequest = { filters: { name: 'Dummy' } };
+
+ const dummyModelListResponse: DummyModelListResponse = {
+ offset: 0,
+ limit: 20,
+ filters: {},
+ sort: {},
+ count: 1,
+ items: [dummyModelResponse],
+ ...dummyModelListRequest,
+ _links: {},
+ };
+
+ const [fetch, fetchMocks] = useFunctionMock([
+ {
+ parameters: [
+ 'https://petstore.test/api/models?filters%5Bname%5D=Dummy',
+ {
+ method: 'GET',
+ headers: {
+ Accept: 'application/json',
+ },
+ },
+ ],
+ return: Promise.resolve({
+ status: 200,
+ json: () => Promise.resolve(dummyModelListResponse),
+ } as Response),
+ },
+ ]);
+
+ const listClient = createListClient(
+ fetch,
+ 'https://petstore.test/api/models',
+ dummyModelListRequestSchema,
+ dummyModelListResponseSchema,
+ );
+
+ expect(await listClient({ filters: { name: 'Dummy' } })).toEqual(dummyModelListResponse);
+
+ expect(fetchMocks.length).toBe(0);
+ });
+
+ test('bad request', async () => {
+ const [fetch, fetchMocks] = useFunctionMock([
+ {
+ parameters: [
+ 'https://petstore.test/api/models?filters%5Bname%5D=Dummy',
+ {
+ method: 'GET',
+ headers: {
+ Accept: 'application/json',
+ },
+ },
+ ],
+ return: Promise.resolve({
+ status: 400,
+ json: () =>
+ Promise.resolve({
+ title: 'Bad Request',
+ detail: 'Sorting value',
+ instance: '0123456789abcdef',
+ invalidParameters: [{ name: 'name', reason: 'unknown field', details: { key: 'value1' } }],
+ }),
+ } as Response),
+ },
+ ]);
+
+ const listClient = createListClient(
+ fetch,
+ 'https://petstore.test/api/models',
+ dummyModelListRequestSchema,
+ dummyModelListResponseSchema,
+ );
+
+ expect(await listClient({ filters: { name: 'Dummy' } })).toMatchInlineSnapshot(`
+ BadRequest {
+ "detail": "Sorting value",
+ "instance": "0123456789abcdef",
+ "invalidParameters": [
+ {
+ "details": {
+ "key": "value1",
+ },
+ "name": "name",
+ "reason": "unknown field",
+ },
+ ],
+ "title": "Bad Request",
+ }
+ `);
+
+ expect(fetchMocks.length).toBe(0);
+ });
+
+ test('internal server error', async () => {
+ const [fetch, fetchMocks] = useFunctionMock([
+ {
+ parameters: [
+ 'https://petstore.test/api/models?filters%5Bname%5D=Dummy',
+ {
+ method: 'GET',
+ headers: {
+ Accept: 'application/json',
+ },
+ },
+ ],
+ return: Promise.resolve({
+ status: 500,
+ json: () =>
+ Promise.resolve({
+ title: 'Internal Server Error',
+ instance: '0123456789abcdef',
+ }),
+ } as Response),
+ },
+ ]);
+
+ const listClient = createListClient(
+ fetch,
+ 'https://petstore.test/api/models',
+ dummyModelListRequestSchema,
+ dummyModelListResponseSchema,
+ );
+
+ expect(await listClient({ filters: { name: 'Dummy' } })).toMatchInlineSnapshot(`
+ InternalServerError {
+ "detail": undefined,
+ "instance": "0123456789abcdef",
+ "title": "Internal Server Error",
+ }
+ `);
+
+ expect(fetchMocks.length).toBe(0);
+ });
+
+ test('network error', async () => {
+ const [fetch, fetchMocks] = useFunctionMock([
+ {
+ parameters: [
+ 'https://petstore.test/api/models?filters%5Bname%5D=Dummy',
+ {
+ method: 'GET',
+ headers: {
+ Accept: 'application/json',
+ },
+ },
+ ],
+ error: new Error('Failed to fetch'),
+ },
+ ]);
+
+ const listClient = createListClient(
+ fetch,
+ 'https://petstore.test/api/models',
+ dummyModelListRequestSchema,
+ dummyModelListResponseSchema,
+ );
+
+ expect(await listClient({ filters: { name: 'Dummy' } })).toMatchInlineSnapshot(`
+ NetworkError {
+ "detail": undefined,
+ "instance": undefined,
+ "title": "Failed to fetch",
+ }
+ `);
+
+ expect(fetchMocks.length).toBe(0);
+ });
+
+ test('unknown response', async () => {
+ const [fetch, fetchMocks] = useFunctionMock([
+ {
+ parameters: [
+ 'https://petstore.test/api/models?filters%5Bname%5D=Dummy',
+ {
+ method: 'GET',
+ headers: {
+ Accept: 'application/json',
+ },
+ },
+ ],
+ return: Promise.resolve({
+ status: 418,
+ json: () => Promise.resolve({}),
+ } as Response),
+ },
+ ]);
+
+ const listClient = createListClient(
+ fetch,
+ 'https://petstore.test/api/models',
+ dummyModelListRequestSchema,
+ dummyModelListResponseSchema,
+ );
+
+ try {
+ await listClient({ filters: { name: 'Dummy' } });
+ throw new Error('expect fail');
+ } catch (e) {
+ expect(e).toMatchInlineSnapshot('[Error: Unknown response]');
+ }
+
+ expect(fetchMocks.length).toBe(0);
+ });
+});
+
+describe('createCreateClient', () => {
+ test('success', async () => {
+ const dummyModelRequest: DummyModelRequest = {
+ name: 'Dummy',
+ };
+
+ const dummyModelResponse: DummyModelResponse = {
+ id: '4d783b77-eb09-4603-b99b-f590b605eaa9',
+ createdAt: '2022-06-12T20:08:24.793Z',
+ ...dummyModelRequest,
+ _links: {},
+ };
+
+ const [fetch, fetchMocks] = useFunctionMock([
+ {
+ parameters: [
+ 'https://petstore.test/api/models',
+ {
+ method: 'POST',
+ headers: {
+ Accept: 'application/json',
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(dummyModelRequest),
+ },
+ ],
+ return: Promise.resolve({
+ status: 201,
+ json: () => Promise.resolve(dummyModelResponse),
+ } as Response),
+ },
+ ]);
+
+ const createClient = createCreateClient(
+ fetch,
+ 'https://petstore.test/api/models',
+ dummyModelRequestSchema,
+ dummyModelResponseSchema,
+ );
+
+ expect(await createClient(dummyModelRequest)).toEqual(dummyModelResponse);
+
+ expect(fetchMocks.length).toBe(0);
+ });
+
+ test('bad request', async () => {
+ const dummyModelRequest: DummyModelRequest = {
+ name: 'Dummy',
+ };
+
+ const [fetch, fetchMocks] = useFunctionMock([
+ {
+ parameters: [
+ 'https://petstore.test/api/models',
+ {
+ method: 'POST',
+ headers: {
+ Accept: 'application/json',
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(dummyModelRequest),
+ },
+ ],
+ return: Promise.resolve({
+ status: 400,
+ json: () =>
+ Promise.resolve({
+ title: 'Bad Request',
+ detail: 'name',
+ instance: '0123456789abcdef',
+ invalidParameters: [{ name: 'name', reason: 'empty', details: { key: 'value1' } }],
+ }),
+ } as Response),
+ },
+ ]);
+
+ const createClient = createCreateClient(
+ fetch,
+ 'https://petstore.test/api/models',
+ dummyModelRequestSchema,
+ dummyModelResponseSchema,
+ );
+
+ expect(await createClient(dummyModelRequest)).toMatchInlineSnapshot(`
+ BadRequest {
+ "detail": "name",
+ "instance": "0123456789abcdef",
+ "invalidParameters": [
+ {
+ "details": {
+ "key": "value1",
+ },
+ "name": "name",
+ "reason": "empty",
+ },
+ ],
+ "title": "Bad Request",
+ }
+ `);
+
+ expect(fetchMocks.length).toBe(0);
+ });
+
+ test('unprocessable entity', async () => {
+ const dummyModelRequest: DummyModelRequest = {
+ name: 'Dummy',
+ };
+
+ const [fetch, fetchMocks] = useFunctionMock([
+ {
+ parameters: [
+ 'https://petstore.test/api/models',
+ {
+ method: 'POST',
+ headers: {
+ Accept: 'application/json',
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(dummyModelRequest),
+ },
+ ],
+ return: Promise.resolve({
+ status: 422,
+ json: () =>
+ Promise.resolve({
+ title: 'Unprocessable Entity',
+ detail: 'name',
+ instance: '0123456789abcdef',
+ invalidParameters: [{ name: 'name', reason: 'empty', details: { key: 'value1' } }],
+ }),
+ } as Response),
+ },
+ ]);
+
+ const createClient = createCreateClient(
+ fetch,
+ 'https://petstore.test/api/models',
+ dummyModelRequestSchema,
+ dummyModelResponseSchema,
+ );
+
+ expect(await createClient(dummyModelRequest)).toMatchInlineSnapshot(`
+ UnprocessableEntity {
+ "detail": "name",
+ "instance": "0123456789abcdef",
+ "invalidParameters": [
+ {
+ "details": {
+ "key": "value1",
+ },
+ "name": "name",
+ "reason": "empty",
+ },
+ ],
+ "title": "Unprocessable Entity",
+ }
+ `);
+
+ expect(fetchMocks.length).toBe(0);
+ });
+
+ test('internal server error', async () => {
+ const dummyModelRequest: DummyModelRequest = {
+ name: 'Dummy',
+ };
+
+ const [fetch, fetchMocks] = useFunctionMock([
+ {
+ parameters: [
+ 'https://petstore.test/api/models',
+ {
+ method: 'POST',
+ headers: {
+ Accept: 'application/json',
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(dummyModelRequest),
+ },
+ ],
+ return: Promise.resolve({
+ status: 500,
+ json: () =>
+ Promise.resolve({
+ title: 'Internal Server Error',
+ instance: '0123456789abcdef',
+ }),
+ } as Response),
+ },
+ ]);
+
+ const createClient = createCreateClient(
+ fetch,
+ 'https://petstore.test/api/models',
+ dummyModelRequestSchema,
+ dummyModelResponseSchema,
+ );
+
+ expect(await createClient(dummyModelRequest)).toMatchInlineSnapshot(`
+ InternalServerError {
+ "detail": undefined,
+ "instance": "0123456789abcdef",
+ "title": "Internal Server Error",
+ }
+ `);
+
+ expect(fetchMocks.length).toBe(0);
+ });
+
+ test('network error', async () => {
+ const dummyModelRequest: DummyModelRequest = {
+ name: 'Dummy',
+ };
+
+ const [fetch, fetchMocks] = useFunctionMock([
+ {
+ parameters: [
+ 'https://petstore.test/api/models',
+ {
+ method: 'POST',
+ headers: {
+ Accept: 'application/json',
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(dummyModelRequest),
+ },
+ ],
+ error: new Error('Failed to fetch'),
+ },
+ ]);
+
+ const createClient = createCreateClient(
+ fetch,
+ 'https://petstore.test/api/models',
+ dummyModelRequestSchema,
+ dummyModelResponseSchema,
+ );
+
+ expect(await createClient(dummyModelRequest)).toMatchInlineSnapshot(`
+ NetworkError {
+ "detail": undefined,
+ "instance": undefined,
+ "title": "Failed to fetch",
+ }
+ `);
+
+ expect(fetchMocks.length).toBe(0);
+ });
+
+ test('unknown response', async () => {
+ const dummyModelRequest: DummyModelRequest = {
+ name: 'Dummy',
+ };
+
+ const [fetch, fetchMocks] = useFunctionMock([
+ {
+ parameters: [
+ 'https://petstore.test/api/models',
+ {
+ method: 'POST',
+ headers: {
+ Accept: 'application/json',
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(dummyModelRequest),
+ },
+ ],
+ return: Promise.resolve({
+ status: 418,
+ json: () => Promise.resolve({}),
+ } as Response),
+ },
+ ]);
+
+ const createClient = createCreateClient(
+ fetch,
+ 'https://petstore.test/api/models',
+ dummyModelRequestSchema,
+ dummyModelResponseSchema,
+ );
+
+ try {
+ await createClient(dummyModelRequest);
+ throw new Error('expect fail');
+ } catch (e) {
+ expect(e).toMatchInlineSnapshot('[Error: expect fail]');
+ }
+
+ expect(fetchMocks.length).toBe(0);
+ });
+});
+
+describe('createReadClient', () => {
+ test('success', async () => {
+ const dummyModelRequest: DummyModelRequest = {
+ name: 'Dummy',
+ };
+
+ const dummyModelResponse: DummyModelResponse = {
+ id: '4d783b77-eb09-4603-b99b-f590b605eaa9',
+ createdAt: '2022-06-12T20:08:24.793Z',
+ ...dummyModelRequest,
+ _links: {},
+ };
+
+ const [fetch, fetchMocks] = useFunctionMock([
+ {
+ parameters: [
+ `https://petstore.test/api/models/${dummyModelResponse.id}`,
+ {
+ method: 'GET',
+ headers: {
+ Accept: 'application/json',
+ },
+ },
+ ],
+ return: Promise.resolve({
+ status: 200,
+ json: () => Promise.resolve(dummyModelResponse),
+ } as Response),
+ },
+ ]);
+
+ const readClient = createReadClient(fetch, 'https://petstore.test/api/models', dummyModelResponseSchema);
+
+ expect(await readClient('4d783b77-eb09-4603-b99b-f590b605eaa9')).toEqual(dummyModelResponse);
+
+ expect(fetchMocks.length).toBe(0);
+ });
+
+ test('not found', async () => {
+ const [fetch, fetchMocks] = useFunctionMock([
+ {
+ parameters: [
+ 'https://petstore.test/api/models/4d783b77-eb09-4603-b99b-f590b605eaa9',
+ {
+ method: 'GET',
+ headers: {
+ Accept: 'application/json',
+ },
+ },
+ ],
+ return: Promise.resolve({
+ status: 404,
+ json: () =>
+ Promise.resolve({
+ title: 'Not Found',
+ detail: 'There is no model with id "4d783b77-eb09-4603-b99b-f590b605eaa9"',
+ instance: '0123456789abcdef',
+ }),
+ } as Response),
+ },
+ ]);
+
+ const readClient = createReadClient(fetch, 'https://petstore.test/api/models', dummyModelResponseSchema);
+
+ expect(await readClient('4d783b77-eb09-4603-b99b-f590b605eaa9')).toMatchInlineSnapshot(`
+ NotFound {
+ "detail": "There is no model with id "4d783b77-eb09-4603-b99b-f590b605eaa9"",
+ "instance": "0123456789abcdef",
+ "title": "Not Found",
+ }
+ `);
+
+ expect(fetchMocks.length).toBe(0);
+ });
+
+ test('internal server error', async () => {
+ const [fetch, fetchMocks] = useFunctionMock([
+ {
+ parameters: [
+ 'https://petstore.test/api/models/4d783b77-eb09-4603-b99b-f590b605eaa9',
+ {
+ method: 'GET',
+ headers: {
+ Accept: 'application/json',
+ },
+ },
+ ],
+ return: Promise.resolve({
+ status: 500,
+ json: () =>
+ Promise.resolve({
+ title: 'Internal Server Error',
+ instance: '0123456789abcdef',
+ }),
+ } as Response),
+ },
+ ]);
+
+ const readClient = createReadClient(fetch, 'https://petstore.test/api/models', dummyModelResponseSchema);
+
+ expect(await readClient('4d783b77-eb09-4603-b99b-f590b605eaa9')).toMatchInlineSnapshot(`
+ InternalServerError {
+ "detail": undefined,
+ "instance": "0123456789abcdef",
+ "title": "Internal Server Error",
+ }
+ `);
+
+ expect(fetchMocks.length).toBe(0);
+ });
+
+ test('network error', async () => {
+ const [fetch, fetchMocks] = useFunctionMock([
+ {
+ parameters: [
+ 'https://petstore.test/api/models/4d783b77-eb09-4603-b99b-f590b605eaa9',
+ {
+ method: 'GET',
+ headers: {
+ Accept: 'application/json',
+ },
+ },
+ ],
+ error: new Error('Failed to fetch'),
+ },
+ ]);
+
+ const readClient = createReadClient(fetch, 'https://petstore.test/api/models', dummyModelResponseSchema);
+
+ expect(await readClient('4d783b77-eb09-4603-b99b-f590b605eaa9')).toMatchInlineSnapshot(`
+ NetworkError {
+ "detail": undefined,
+ "instance": undefined,
+ "title": "Failed to fetch",
+ }
+ `);
+
+ expect(fetchMocks.length).toBe(0);
+ });
+
+ test('unknown response', async () => {
+ const [fetch, fetchMocks] = useFunctionMock([
+ {
+ parameters: [
+ 'https://petstore.test/api/models/4d783b77-eb09-4603-b99b-f590b605eaa9',
+ {
+ method: 'GET',
+ headers: {
+ Accept: 'application/json',
+ },
+ },
+ ],
+ return: Promise.resolve({
+ status: 418,
+ json: () => Promise.resolve({}),
+ } as Response),
+ },
+ ]);
+
+ const readClient = createReadClient(fetch, 'https://petstore.test/api/models', dummyModelResponseSchema);
+
+ try {
+ await readClient('4d783b77-eb09-4603-b99b-f590b605eaa9');
+ throw new Error('expect fail');
+ } catch (e) {
+ expect(e).toMatchInlineSnapshot('[Error: expect fail]');
+ }
+
+ expect(fetchMocks.length).toBe(0);
+ });
+});
+
+describe('createUpdateClient', () => {
+ test('success', async () => {
+ const dummyModelRequest: DummyModelRequest = {
+ name: 'Dummy',
+ };
+
+ const dummyModelResponse: DummyModelResponse = {
+ id: '4d783b77-eb09-4603-b99b-f590b605eaa9',
+ createdAt: '2022-06-12T20:08:24.793Z',
+ ...dummyModelRequest,
+ _links: {},
+ };
+
+ const [fetch, fetchMocks] = useFunctionMock([
+ {
+ parameters: [
+ `https://petstore.test/api/models/${dummyModelResponse.id}`,
+ {
+ method: 'PUT',
+ headers: {
+ Accept: 'application/json',
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(dummyModelRequest),
+ },
+ ],
+ return: Promise.resolve({
+ status: 200,
+ json: () => Promise.resolve(dummyModelResponse),
+ } as Response),
+ },
+ ]);
+
+ const updateClient = createUpdateClient(
+ fetch,
+ 'https://petstore.test/api/models',
+ dummyModelRequestSchema,
+ dummyModelResponseSchema,
+ );
+
+ expect(await updateClient('4d783b77-eb09-4603-b99b-f590b605eaa9', dummyModelRequest)).toEqual(dummyModelResponse);
+
+ expect(fetchMocks.length).toBe(0);
+ });
+
+ test('bad request', async () => {
+ const dummyModelRequest: DummyModelRequest = {
+ name: 'Dummy',
+ };
+
+ const [fetch, fetchMocks] = useFunctionMock([
+ {
+ parameters: [
+ 'https://petstore.test/api/models/4d783b77-eb09-4603-b99b-f590b605eaa9',
+ {
+ method: 'PUT',
+ headers: {
+ Accept: 'application/json',
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(dummyModelRequest),
+ },
+ ],
+ return: Promise.resolve({
+ status: 400,
+ json: () =>
+ Promise.resolve({
+ title: 'Bad Request',
+ detail: 'name',
+ instance: '0123456789abcdef',
+ invalidParameters: [{ name: 'name', reason: 'empty', details: { key: 'value1' } }],
+ }),
+ } as Response),
+ },
+ ]);
+
+ const updateClient = createUpdateClient(
+ fetch,
+ 'https://petstore.test/api/models',
+ dummyModelRequestSchema,
+ dummyModelResponseSchema,
+ );
+
+ expect(await updateClient('4d783b77-eb09-4603-b99b-f590b605eaa9', dummyModelRequest)).toMatchInlineSnapshot(`
+ BadRequest {
+ "detail": "name",
+ "instance": "0123456789abcdef",
+ "invalidParameters": [
+ {
+ "details": {
+ "key": "value1",
+ },
+ "name": "name",
+ "reason": "empty",
+ },
+ ],
+ "title": "Bad Request",
+ }
+ `);
+
+ expect(fetchMocks.length).toBe(0);
+ });
+
+ test('not found', async () => {
+ const dummyModelRequest: DummyModelRequest = {
+ name: 'Dummy',
+ };
+
+ const [fetch, fetchMocks] = useFunctionMock([
+ {
+ parameters: [
+ 'https://petstore.test/api/models/4d783b77-eb09-4603-b99b-f590b605eaa9',
+ {
+ method: 'PUT',
+ headers: {
+ Accept: 'application/json',
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(dummyModelRequest),
+ },
+ ],
+ return: Promise.resolve({
+ status: 404,
+ json: () =>
+ Promise.resolve({
+ title: 'Not Found',
+ detail: 'There is no model with id "4d783b77-eb09-4603-b99b-f590b605eaa9"',
+ instance: '0123456789abcdef',
+ }),
+ } as Response),
+ },
+ ]);
+
+ const updateClient = createUpdateClient(
+ fetch,
+ 'https://petstore.test/api/models',
+ dummyModelRequestSchema,
+ dummyModelResponseSchema,
+ );
+
+ expect(await updateClient('4d783b77-eb09-4603-b99b-f590b605eaa9', dummyModelRequest)).toMatchInlineSnapshot(`
+ NotFound {
+ "detail": "There is no model with id "4d783b77-eb09-4603-b99b-f590b605eaa9"",
+ "instance": "0123456789abcdef",
+ "title": "Not Found",
+ }
+ `);
+
+ expect(fetchMocks.length).toBe(0);
+ });
+
+ test('unprocessable entity', async () => {
+ const dummyModelRequest: DummyModelRequest = {
+ name: 'Dummy',
+ };
+
+ const [fetch, fetchMocks] = useFunctionMock([
+ {
+ parameters: [
+ 'https://petstore.test/api/models/4d783b77-eb09-4603-b99b-f590b605eaa9',
+ {
+ method: 'PUT',
+ headers: {
+ Accept: 'application/json',
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(dummyModelRequest),
+ },
+ ],
+ return: Promise.resolve({
+ status: 422,
+ json: () =>
+ Promise.resolve({
+ title: 'Unprocessable Entity',
+ detail: 'name',
+ instance: '0123456789abcdef',
+ invalidParameters: [{ name: 'name', reason: 'empty', details: { key: 'value1' } }],
+ }),
+ } as Response),
+ },
+ ]);
+
+ const updateClient = createUpdateClient(
+ fetch,
+ 'https://petstore.test/api/models',
+ dummyModelRequestSchema,
+ dummyModelResponseSchema,
+ );
+
+ expect(await updateClient('4d783b77-eb09-4603-b99b-f590b605eaa9', dummyModelRequest)).toMatchInlineSnapshot(`
+ UnprocessableEntity {
+ "detail": "name",
+ "instance": "0123456789abcdef",
+ "invalidParameters": [
+ {
+ "details": {
+ "key": "value1",
+ },
+ "name": "name",
+ "reason": "empty",
+ },
+ ],
+ "title": "Unprocessable Entity",
+ }
+ `);
+
+ expect(fetchMocks.length).toBe(0);
+ });
+
+ test('internal server error', async () => {
+ const dummyModelRequest: DummyModelRequest = {
+ name: 'Dummy',
+ };
+
+ const [fetch, fetchMocks] = useFunctionMock([
+ {
+ parameters: [
+ 'https://petstore.test/api/models/4d783b77-eb09-4603-b99b-f590b605eaa9',
+ {
+ method: 'PUT',
+ headers: {
+ Accept: 'application/json',
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(dummyModelRequest),
+ },
+ ],
+ return: Promise.resolve({
+ status: 500,
+ json: () =>
+ Promise.resolve({
+ title: 'Internal Server Error',
+ instance: '0123456789abcdef',
+ }),
+ } as Response),
+ },
+ ]);
+
+ const updateClient = createUpdateClient(
+ fetch,
+ 'https://petstore.test/api/models',
+ dummyModelRequestSchema,
+ dummyModelResponseSchema,
+ );
+
+ expect(await updateClient('4d783b77-eb09-4603-b99b-f590b605eaa9', dummyModelRequest)).toMatchInlineSnapshot(`
+ InternalServerError {
+ "detail": undefined,
+ "instance": "0123456789abcdef",
+ "title": "Internal Server Error",
+ }
+ `);
+
+ expect(fetchMocks.length).toBe(0);
+ });
+
+ test('network error', async () => {
+ const dummyModelRequest: DummyModelRequest = {
+ name: 'Dummy',
+ };
+
+ const [fetch, fetchMocks] = useFunctionMock([
+ {
+ parameters: [
+ 'https://petstore.test/api/models/4d783b77-eb09-4603-b99b-f590b605eaa9',
+ {
+ method: 'PUT',
+ headers: {
+ Accept: 'application/json',
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(dummyModelRequest),
+ },
+ ],
+ error: new Error('Failed to fetch'),
+ },
+ ]);
+
+ const updateClient = createUpdateClient(
+ fetch,
+ 'https://petstore.test/api/models',
+ dummyModelRequestSchema,
+ dummyModelResponseSchema,
+ );
+
+ expect(await updateClient('4d783b77-eb09-4603-b99b-f590b605eaa9', dummyModelRequest)).toMatchInlineSnapshot(`
+ NetworkError {
+ "detail": undefined,
+ "instance": undefined,
+ "title": "Failed to fetch",
+ }
+ `);
+
+ expect(fetchMocks.length).toBe(0);
+ });
+
+ test('unknown response', async () => {
+ const dummyModelRequest: DummyModelRequest = {
+ name: 'Dummy',
+ };
+
+ const [fetch, fetchMocks] = useFunctionMock([
+ {
+ parameters: [
+ 'https://petstore.test/api/models/4d783b77-eb09-4603-b99b-f590b605eaa9',
+ {
+ method: 'PUT',
+ headers: {
+ Accept: 'application/json',
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(dummyModelRequest),
+ },
+ ],
+ return: Promise.resolve({
+ status: 418,
+ json: () => Promise.resolve({}),
+ } as Response),
+ },
+ ]);
+
+ const updateClient = createUpdateClient(
+ fetch,
+ 'https://petstore.test/api/models',
+ dummyModelRequestSchema,
+ dummyModelResponseSchema,
+ );
+
+ try {
+ await updateClient('4d783b77-eb09-4603-b99b-f590b605eaa9', dummyModelRequest);
+ throw new Error('expect fail');
+ } catch (e) {
+ expect(e).toMatchInlineSnapshot('[Error: expect fail]');
+ }
+
+ expect(fetchMocks.length).toBe(0);
+ });
+});
+
+describe('createDeleteClient', () => {
+ test('success', async () => {
+ const [fetch, fetchMocks] = useFunctionMock([
+ {
+ parameters: [
+ 'https://petstore.test/api/models/4d783b77-eb09-4603-b99b-f590b605eaa9',
+ {
+ method: 'DELETE',
+ headers: {
+ Accept: 'application/json',
+ },
+ },
+ ],
+ return: Promise.resolve({
+ status: 204,
+ json: () => Promise.resolve(undefined),
+ } as Response),
+ },
+ ]);
+
+ const deleteClient = createDeleteClient(fetch, 'https://petstore.test/api/models');
+
+ expect(await deleteClient('4d783b77-eb09-4603-b99b-f590b605eaa9')).toBeUndefined();
+
+ expect(fetchMocks.length).toBe(0);
+ });
+
+ test('not found', async () => {
+ const [fetch, fetchMocks] = useFunctionMock([
+ {
+ parameters: [
+ 'https://petstore.test/api/models/4d783b77-eb09-4603-b99b-f590b605eaa9',
+ {
+ method: 'DELETE',
+ headers: {
+ Accept: 'application/json',
+ },
+ },
+ ],
+ return: Promise.resolve({
+ status: 404,
+ json: () =>
+ Promise.resolve({
+ title: 'Not Found',
+ detail: 'There is no model with id "4d783b77-eb09-4603-b99b-f590b605eaa9"',
+ instance: '0123456789abcdef',
+ }),
+ } as Response),
+ },
+ ]);
+
+ const deleteClient = createDeleteClient(fetch, 'https://petstore.test/api/models');
+
+ expect(await deleteClient('4d783b77-eb09-4603-b99b-f590b605eaa9')).toMatchInlineSnapshot(`
+ NotFound {
+ "detail": "There is no model with id "4d783b77-eb09-4603-b99b-f590b605eaa9"",
+ "instance": "0123456789abcdef",
+ "title": "Not Found",
+ }
+ `);
+
+ expect(fetchMocks.length).toBe(0);
+ });
+
+ test('internal server error', async () => {
+ const [fetch, fetchMocks] = useFunctionMock([
+ {
+ parameters: [
+ 'https://petstore.test/api/models/4d783b77-eb09-4603-b99b-f590b605eaa9',
+ {
+ method: 'DELETE',
+ headers: {
+ Accept: 'application/json',
+ },
+ },
+ ],
+ return: Promise.resolve({
+ status: 500,
+ json: () =>
+ Promise.resolve({
+ title: 'Internal Server Error',
+ instance: '0123456789abcdef',
+ }),
+ } as Response),
+ },
+ ]);
+
+ const deleteClient = createDeleteClient(fetch, 'https://petstore.test/api/models');
+
+ expect(await deleteClient('4d783b77-eb09-4603-b99b-f590b605eaa9')).toMatchInlineSnapshot(`
+ InternalServerError {
+ "detail": undefined,
+ "instance": "0123456789abcdef",
+ "title": "Internal Server Error",
+ }
+ `);
+
+ expect(fetchMocks.length).toBe(0);
+ });
+
+ test('network error', async () => {
+ const [fetch, fetchMocks] = useFunctionMock([
+ {
+ parameters: [
+ 'https://petstore.test/api/models/4d783b77-eb09-4603-b99b-f590b605eaa9',
+ {
+ method: 'DELETE',
+ headers: {
+ Accept: 'application/json',
+ },
+ },
+ ],
+ error: new Error('Failed to fetch'),
+ },
+ ]);
+
+ const deleteClient = createDeleteClient(fetch, 'https://petstore.test/api/models');
+
+ expect(await deleteClient('4d783b77-eb09-4603-b99b-f590b605eaa9')).toMatchInlineSnapshot(`
+ NetworkError {
+ "detail": undefined,
+ "instance": undefined,
+ "title": "Failed to fetch",
+ }
+ `);
+
+ expect(fetchMocks.length).toBe(0);
+ });
+
+ test('unknown response', async () => {
+ const [fetch, fetchMocks] = useFunctionMock([
+ {
+ parameters: [
+ 'https://petstore.test/api/models/4d783b77-eb09-4603-b99b-f590b605eaa9',
+ {
+ method: 'DELETE',
+ headers: {
+ Accept: 'application/json',
+ },
+ },
+ ],
+ return: Promise.resolve({
+ status: 418,
+ json: () => Promise.resolve({}),
+ } as Response),
+ },
+ ]);
+
+ const deleteClient = createDeleteClient(fetch, 'https://petstore.test/api/models');
+
+ try {
+ await deleteClient('4d783b77-eb09-4603-b99b-f590b605eaa9');
+ throw new Error('expect fail');
+ } catch (e) {
+ expect(e).toMatchInlineSnapshot('[Error: expect fail]');
+ }
+
+ expect(fetchMocks.length).toBe(0);
+ });
+});
diff --git a/tests/client/error.test.ts b/tests/client/error.test.ts
new file mode 100644
index 0000000..1c2fe96
--- /dev/null
+++ b/tests/client/error.test.ts
@@ -0,0 +1,79 @@
+import { describe, expect, test } from 'vitest';
+import type { InvalidParameter } from '../../src/client/error';
+import { BadRequest, NetworkError, UnprocessableEntity, createInvalidParametersByName } from '../../src/client/error';
+
+describe('createInvalidParametersByName', () => {
+ test('with network error', () => {
+ const invalidParametersByName = createInvalidParametersByName(new NetworkError({ title: 'network error' }));
+
+ expect(invalidParametersByName.size).toBe(0);
+ });
+
+ test('with bad request and without invalid parameters', () => {
+ const invalidParametersByName = createInvalidParametersByName(new BadRequest({ title: 'bad request' }));
+
+ expect(invalidParametersByName.size).toBe(0);
+ });
+
+ test('with bad request and with invalid parameters', () => {
+ const invalidParameters: Array = [
+ { name: 'name', reason: 'wrong type', details: { key: 'value1' } },
+ { name: 'name', reason: 'not empty', details: { key: 'value2' } },
+ { name: 'description', reason: 'to long', details: { key: 'value3' } },
+ ];
+
+ const invalidParametersByName = createInvalidParametersByName(
+ new BadRequest({ title: 'bad request', invalidParameters }),
+ );
+
+ expect(invalidParametersByName.has('name')).toBeTruthy();
+
+ const InvalidParametersOfName = invalidParametersByName.get('name');
+
+ expect(InvalidParametersOfName).toBeInstanceOf(Array);
+ expect(InvalidParametersOfName).toHaveLength(2);
+
+ expect(InvalidParametersOfName instanceof Array ? InvalidParametersOfName[0] : null).toBe(invalidParameters[0]);
+ expect(InvalidParametersOfName instanceof Array ? InvalidParametersOfName[1] : null).toBe(invalidParameters[1]);
+
+ const InvalidParametersOfDescription = invalidParametersByName.get('description');
+
+ expect(InvalidParametersOfDescription).toBeInstanceOf(Array);
+ expect(InvalidParametersOfDescription).toHaveLength(1);
+
+ expect(InvalidParametersOfDescription instanceof Array ? InvalidParametersOfDescription[0] : null).toBe(
+ invalidParameters[2],
+ );
+ });
+
+ test('with unprocessable entity and with invalid parameters', () => {
+ const invalidParameters: Array = [
+ { name: 'name', reason: 'wrong type', details: { key: 'value1' } },
+ { name: 'name', reason: 'not empty', details: { key: 'value2' } },
+ { name: 'description', reason: 'to long', details: { key: 'value3' } },
+ ];
+
+ const invalidParametersByName = createInvalidParametersByName(
+ new UnprocessableEntity({ title: 'unprocessable entity', invalidParameters }),
+ );
+
+ expect(invalidParametersByName.has('name')).toBeTruthy();
+
+ const InvalidParametersOfName = invalidParametersByName.get('name');
+
+ expect(InvalidParametersOfName).toBeInstanceOf(Array);
+ expect(InvalidParametersOfName).toHaveLength(2);
+
+ expect(InvalidParametersOfName instanceof Array ? InvalidParametersOfName[0] : null).toBe(invalidParameters[0]);
+ expect(InvalidParametersOfName instanceof Array ? InvalidParametersOfName[1] : null).toBe(invalidParameters[1]);
+
+ const InvalidParametersOfDescription = invalidParametersByName.get('description');
+
+ expect(InvalidParametersOfDescription).toBeInstanceOf(Array);
+ expect(InvalidParametersOfDescription).toHaveLength(1);
+
+ expect(InvalidParametersOfDescription instanceof Array ? InvalidParametersOfDescription[0] : null).toBe(
+ invalidParameters[2],
+ );
+ });
+});
diff --git a/tests/client/pet.test.ts b/tests/client/pet.test.ts
new file mode 100644
index 0000000..82d934b
--- /dev/null
+++ b/tests/client/pet.test.ts
@@ -0,0 +1,10 @@
+import { test, expect } from 'vitest';
+import { listPetsClient, createPetClient, readPetClient, updatePetClient, deletePetClient } from '../../src/client/pet';
+
+test('functions', () => {
+ expect(typeof listPetsClient).toBe('function');
+ expect(typeof createPetClient).toBe('function');
+ expect(typeof readPetClient).toBe('function');
+ expect(typeof updatePetClient).toBe('function');
+ expect(typeof deletePetClient).toBe('function');
+});
diff --git a/tests/component/form/pet-filter-form.test.tsx b/tests/component/form/pet-filter-form.test.tsx
deleted file mode 100644
index 58e9c9a..0000000
--- a/tests/component/form/pet-filter-form.test.tsx
+++ /dev/null
@@ -1,94 +0,0 @@
-import { render, screen } from '@testing-library/react';
-import { PetFilterForm } from '../../../src/component/form/pet-filter-form';
-import userEvent from '@testing-library/user-event';
-import { vi } from 'vitest';
-import { test, expect } from 'vitest';
-import { PetFilters } from '../../../src/model/model';
-import { formatHtml } from '../../formatter';
-import { BadRequest, InvalidParameter } from '../../../src/api-client/error';
-
-test('without error', () => {
- const submitPetFilter = (filters: PetFilters) => { };
-
- const defaultPetFilters = { name: 'aa' };
-
- const { container } = render(
- ,
- );
-
- expect(formatHtml(container.outerHTML)).toMatchInlineSnapshot(`
- "
- "
- `);
-});
-
-test('with error', () => {
- const submitPetFilter = (filters: PetFilters) => { };
-
- const invalidParameters: Array = [{ name: 'name', reason: 'Should not be empty' }];
-
- const badRequest = new BadRequest({
- title: 'title',
- invalidParameters: invalidParameters,
- });
-
- const { container } = render();
-
- expect(formatHtml(container.outerHTML)).toMatchInlineSnapshot(`
- "
- "
- `);
-});
-
-test('submit', async () => {
- const submitPetFilter = vi.fn((filters: PetFilters) => {
- expect(filters.name).toEqual('aa');
- });
-
- const defaultPetFilters = { name: 'aa' };
-
- render();
-
- const submitButton = await screen.findByTestId('submit-pet-filter');
-
- await userEvent.click(submitButton);
-
- expect(submitPetFilter.mock.calls.length).toBe(1);
-});
-
-test('submit empty', async () => {
- const submitPetFilter = vi.fn((filters: PetFilters) => {
- expect(filters.name).toBeUndefined();
- });
-
- const defaultPetFilters = { name: '' };
-
- render();
-
- const submitButton = await screen.findByTestId('submit-pet-filter');
-
- await userEvent.click(submitButton);
-
- expect(submitPetFilter.mock.calls.length).toBe(1);
-});
diff --git a/tests/component/form/pet-form.test.tsx b/tests/component/form/pet-form.test.tsx
deleted file mode 100644
index a116703..0000000
--- a/tests/component/form/pet-form.test.tsx
+++ /dev/null
@@ -1,337 +0,0 @@
-import { render, screen } from '@testing-library/react';
-import { PetForm } from '../../../src/component/form/pet-form';
-import userEvent from '@testing-library/user-event';
-import { vi } from 'vitest';
-import { test, expect } from 'vitest';
-import { PetRequest } from '../../../src/model/model';
-import { formatHtml } from '../../formatter';
-import { InvalidParameter, UnprocessableEntity } from '../../../src/api-client/error';
-
-test('empty', () => {
- const submitPet = (pet: PetRequest): void => { };
-
- const { container } = render();
-
- expect(formatHtml(container.outerHTML)).toMatchInlineSnapshot(`
- "
- "
- `);
-});
-
-test('without error', () => {
- const submitPet = (pet: PetRequest): void => { };
-
- const defaultPet = {
- id: '4d783b77-eb09-4603-b99b-f590b605eaa9',
- createdAt: '2005-08-15T15:52:01+00:00',
- name: 'Brownie',
- vaccinations: [{ name: 'Rabies' }],
- };
-
- const { container } = render();
-
- expect(formatHtml(container.outerHTML)).toMatchInlineSnapshot(`
- "
- "
- `);
-});
-
-test('with error', () => {
- const submitPet = (pet: PetRequest): void => { };
-
- const defaultPet = {
- id: '4d783b77-eb09-4603-b99b-f590b605eaa9',
- createdAt: '2005-08-15T15:52:01+00:00',
- name: '',
- vaccinations: [{ name: '' }],
- };
-
- const invalidParameters: Array = [
- { name: 'name', reason: 'Should not be empty' },
- { name: 'vaccinations[0].name', reason: 'Should not be empty' },
- ];
-
- const unprocessableEntity = new UnprocessableEntity({
- title: 'title',
- invalidParameters: invalidParameters,
- });
-
- const { container } = render(
- ,
- );
-
- expect(formatHtml(container.outerHTML)).toMatchInlineSnapshot(`
- "
- "
- `);
-});
-
-test('add vaccination', async () => {
- const submitPet = (pet: PetRequest): void => { };
-
- const defaultPet = {
- id: '4d783b77-eb09-4603-b99b-f590b605eaa9',
- createdAt: '2005-08-15T15:52:01+00:00',
- name: 'Brownie',
- vaccinations: [{ name: 'Rabies' }],
- };
-
- const { container } = render();
-
- const submitButton = await screen.findByTestId('add-vaccination');
-
- await userEvent.click(submitButton);
-
- expect(formatHtml(container.outerHTML)).toMatchInlineSnapshot(`
- "
- "
- `);
-});
-
-test('remove vaccination', async () => {
- const submitPet = (pet: PetRequest): void => { };
-
- const defaultPet = {
- id: '4d783b77-eb09-4603-b99b-f590b605eaa9',
- createdAt: '2005-08-15T15:52:01+00:00',
- name: 'Brownie',
- vaccinations: [{ name: 'Rabies' }],
- };
-
- const { container } = render();
-
- const submitButton = await screen.findByTestId('remove-vaccination-0');
-
- await userEvent.click(submitButton);
-
- expect(formatHtml(container.outerHTML)).toMatchInlineSnapshot(`
- "
- "
- `);
-});
-
-test('submit minimal', async () => {
- let submitPet = (pet: PetRequest) => { };
-
- const submitPetMock = vi.fn((pet: PetRequest) => {
- submitPet(pet);
- });
-
- await new Promise(async (resolve) => {
- submitPet = (pet: PetRequest) => {
- expect(pet.name).toBe('Brownie');
- expect(pet.tag).toBeUndefined();
-
- resolve(undefined);
- };
-
- const defaultPet = {
- id: '4d783b77-eb09-4603-b99b-f590b605eaa9',
- createdAt: '2005-08-15T15:52:01+00:00',
- name: 'Brownie',
- tag: '',
- };
-
- render();
-
- const submitButton = await screen.findByTestId('submit-pet');
-
- await userEvent.click(submitButton);
- });
-
- expect(submitPetMock.mock.calls.length).toBe(1);
-});
-
-// @todo fix test
-test('submit maximal', async () => {
- let submitPet = (pet: PetRequest) => { };
-
- const submitPetMock = vi.fn((pet: PetRequest) => {
- submitPet(pet);
- });
-
- await new Promise(async (resolve) => {
- submitPet = (pet: PetRequest) => {
- expect(pet.name).toBe('Brownie');
- expect(pet.tag).toBe('0001-000');
- expect(pet.vaccinations).toHaveLength(1);
- expect(pet.vaccinations ? pet.vaccinations[0].name : '').toBe('Rabies');
-
- resolve(undefined);
- };
-
- const defaultPet = {
- id: '4d783b77-eb09-4603-b99b-f590b605eaa9',
- createdAt: '2005-08-15T15:52:01+00:00',
- name: 'Brownie',
- tag: '0001-000',
- vaccinations: [{ name: 'Rabies' }],
- };
-
- render();
-
- const submitButton = await screen.findByTestId('submit-pet');
-
- await userEvent.click(submitButton);
- });
-
- expect(submitPetMock.mock.calls.length).toBe(1);
-});
diff --git a/tests/component/form/text-field.test.tsx b/tests/component/form/text-field.test.tsx
deleted file mode 100644
index af7adff..0000000
--- a/tests/component/form/text-field.test.tsx
+++ /dev/null
@@ -1,28 +0,0 @@
-import { render } from '@testing-library/react';
-import { TextField } from '../../../src/component/form/text-field';
-import { UseFormRegister } from 'react-hook-form';
-import { test, expect } from 'vitest';
-import { formatHtml } from '../../formatter';
-import { InvalidParameter } from '../../../src/api-client/error';
-
-test('default', () => {
- const register = ((name: string) => ({ name })) as UseFormRegister;
-
- const invalidParameters: Array = [{ name: 'name', reason: 'Should not be empty' }];
-
- const { container } = render(
- ,
- );
-
- expect(formatHtml(container.outerHTML)).toMatchInlineSnapshot(`
- "
- "
- `);
-});
diff --git a/tests/component/page/home.test.tsx b/tests/component/page/home.test.tsx
index 2363194..d6657a6 100644
--- a/tests/component/page/home.test.tsx
+++ b/tests/component/page/home.test.tsx
@@ -1,22 +1,16 @@
-import { createMemoryHistory } from 'history';
+// eslint-disable-next-line @typescript-eslint/no-unused-vars
+import React from 'react';
import { render } from '@testing-library/react';
-import { Router } from 'react-router-dom';
import Home from '../../../src/component/page/home';
import { test, expect } from 'vitest';
import { formatHtml } from '../../formatter';
test('default', () => {
- const history = createMemoryHistory();
-
- const { container } = render(
-
-
- ,
- );
+ const { container } = render();
expect(formatHtml(container.outerHTML)).toMatchInlineSnapshot(`
"
"
`);
diff --git a/tests/component/page/not-found.test.tsx b/tests/component/page/not-found.test.tsx
index 0f5047b..8122a27 100644
--- a/tests/component/page/not-found.test.tsx
+++ b/tests/component/page/not-found.test.tsx
@@ -1,22 +1,16 @@
-import { createMemoryHistory } from 'history';
+// eslint-disable-next-line @typescript-eslint/no-unused-vars
+import React from 'react';
import { render } from '@testing-library/react';
-import { Router } from 'react-router-dom';
import NotFound from '../../../src/component/page/not-found';
import { test, expect } from 'vitest';
import { formatHtml } from '../../formatter';
test('default', () => {
- const history = createMemoryHistory();
-
- const { container } = render(
-
-
- ,
- );
+ const { container } = render();
expect(formatHtml(container.outerHTML)).toMatchInlineSnapshot(`
"
"
`);
diff --git a/tests/component/page/pet/create.test.tsx b/tests/component/page/pet/create.test.tsx
index f5b5f72..4812270 100644
--- a/tests/component/page/pet/create.test.tsx
+++ b/tests/component/page/pet/create.test.tsx
@@ -1,60 +1,70 @@
-import { createMemoryHistory } from 'history';
-import { render, screen } from '@testing-library/react';
-import { Router } from 'react-router-dom';
-import Create from '../../../../src/component/page/pet/create';
-import { PetFormProps } from '../../../../src/component/form/pet-form';
-import userEvent from '@testing-library/user-event';
-import { vi } from 'vitest';
-import { test, expect } from 'vitest';
-import { PetRequest } from '../../../../src/model/model';
+// eslint-disable-next-line @typescript-eslint/no-unused-vars
+import React from 'react';
+import { MemoryRouter, Route, Routes } from 'react-router-dom';
+import { expect, test, vi } from 'vitest';
+import { act, render, screen } from '@testing-library/react';
+import type { PetFormProps } from '../../../../src/component/form/pet-form';
+import type { PetRequest, PetResponse } from '../../../../model/pet';
+import type { createPetClient } from '../../../../src/client/pet';
import { formatHtml } from '../../../formatter';
-import { HttpError, UnprocessableEntity } from '../../../../src/api-client/error';
+import { UnprocessableEntity } from '../../../../src/client/error';
+import { userEvent } from '@testing-library/user-event';
+import Create from '../../../../src/component/page/pet/create';
-let mockCreatePet = (pet: PetRequest) => { };
+let mockCreatePetClient: typeof createPetClient;
-vi.mock('../../../../src/api-client/pet', () => {
+vi.mock('../../../../src/client/pet', () => {
return {
- CreatePet: (pet: PetRequest) => {
- return mockCreatePet(pet);
+ createPetClient: (pet: PetRequest) => {
+ return mockCreatePetClient(pet);
},
};
});
vi.mock('../../../../src/component/form/pet-form', () => {
return {
- PetForm: ({ submitPet }: PetFormProps) => {
+ PetForm: (props: PetFormProps) => {
const onSubmit = () => {
- submitPet({ ...({} as PetRequest), name: 'Brownie' });
+ props.submitPet({ name: 'Brownie', vaccinations: [] });
};
- return ;
- },
- };
-});
-
-vi.mock('../../../../src/component/partial/http-error', () => {
- return {
- HttpError: ({ httpError }: { httpError: HttpError; }) => {
- return httpError: {httpError.title}
;
+ return (
+
+ );
},
};
});
-test('default', () => {
- const history = createMemoryHistory();
-
+test('default', async () => {
const { container } = render(
-
-
- ,
+
+
+ } />
+
+ ,
);
+ await screen.findByTestId('page-pet-create');
+
expect(formatHtml(container.outerHTML)).toMatchInlineSnapshot(`
"
"
@@ -62,31 +72,44 @@ test('default', () => {
});
test('unprocessable entity', async () => {
- mockCreatePet = async (pet: PetRequest) => {
- return new Promise((resolve) => resolve(new UnprocessableEntity({ title: 'title' })));
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
+ mockCreatePetClient = async (_: PetRequest) => {
+ return new Promise((resolve) =>
+ resolve(new UnprocessableEntity({ title: 'unprocessable entity' })),
+ );
};
- const history = createMemoryHistory();
-
const { container } = render(
-
-
- ,
+
+
+ } />
+
+ ,
);
- const testButton = await screen.findByTestId('test-button');
+ const testButton = await screen.findByTestId('pet-form-submit');
- await userEvent.click(testButton);
+ await act(async () => userEvent.click(testButton));
- await screen.findByText(/httpError/);
+ await screen.findByTestId('http-error');
expect(formatHtml(container.outerHTML)).toMatchInlineSnapshot(`
"
-
httpError: title
-
Create Pet
-
List
+
+
Pet Create
+
List
"
@@ -94,23 +117,33 @@ test('unprocessable entity', async () => {
});
test('successful', async () => {
- mockCreatePet = async (pet: PetRequest) => {
- return new Promise((resolve) => resolve(pet));
+ mockCreatePetClient = async (petRequest: PetRequest) => {
+ const petResponse: PetResponse = {
+ id: '4d783b77-eb09-4603-b99b-f590b605eaa9',
+ createdAt: '2005-08-15T15:52:01+00:00',
+ ...petRequest,
+ _links: {},
+ };
+ return new Promise((resolve) => resolve(petResponse));
};
- const history = createMemoryHistory();
-
- render(
-
-
- ,
+ const { container } = render(
+
+
+ } />
+ } />
+
+ ,
);
- expect(history.location.pathname).toBe('/');
+ const testButton = await screen.findByTestId('pet-form-submit');
- const testButton = await screen.findByTestId('test-button');
+ await act(async () => userEvent.click(testButton));
- await userEvent.click(testButton);
+ await screen.findByTestId('page-pet-list');
- expect(history.location.pathname).toBe('/pet');
+ expect(formatHtml(container.outerHTML)).toMatchInlineSnapshot(`
+ "
+ "
+ `);
});
diff --git a/tests/component/page/pet/list.test.tsx b/tests/component/page/pet/list.test.tsx
index 30895a3..3091c41 100644
--- a/tests/component/page/pet/list.test.tsx
+++ b/tests/component/page/pet/list.test.tsx
@@ -1,156 +1,107 @@
-import { createMemoryHistory } from 'history';
-import { render, screen } from '@testing-library/react';
-import { Router } from 'react-router-dom';
+// eslint-disable-next-line @typescript-eslint/no-unused-vars
+import React from 'react';
import List from '../../../../src/component/page/pet/list';
-import { PetFilterFormProps } from '../../../../src/component/form/pet-filter-form';
-import userEvent from '@testing-library/user-event';
-import { beforeEach, vi } from 'vitest';
-import { test, expect } from 'vitest';
-import { PetList } from '../../../../src/model/model';
+import type { PetFiltersFormProps } from '../../../../src/component/form/pet-filters-form';
+import { vi, test, expect } from 'vitest';
+import type { PetListRequest, PetListResponse } from '../../../../src/model/pet';
import { formatHtml } from '../../../formatter';
-import { BadRequest, HttpError, NotFound } from '../../../../src/api-client/error';
-import { PaginationProps } from '../../../../src/component/partial/pagination';
+import type { deletePetClient, listPetsClient } from '../../../../src/client/pet';
+import type { PaginationProps } from '../../../../src/component/partial/pagination';
+import { BadRequest, NetworkError } from '../../../../src/client/error';
+import { userEvent } from '@testing-library/user-event';
+import { act, render, screen } from '@testing-library/react';
+import { MemoryRouter, Route, Routes } from 'react-router-dom';
-let mockListPets = (queryString: string) => { };
-let mockDeletePet = (id: string) => { };
+let mockDeletePetClient: typeof deletePetClient;
+let mockListPetsClient: typeof listPetsClient;
-vi.mock('../../../../src/api-client/pet', () => {
+vi.mock('../../../../src/client/pet', () => {
return {
- ListPets: (queryString: string) => {
- return mockListPets(queryString);
+ deletePetClient: (id: string) => {
+ return mockDeletePetClient(id);
},
- DeletePet: (id: string) => {
- return mockDeletePet(id);
+ listPetsClient: (petListRequest: PetListRequest) => {
+ return mockListPetsClient(petListRequest);
},
};
});
-beforeEach(() => {
- mockListPets = (queryString: string) => { };
- mockDeletePet = (id: string) => { };
-});
-
-vi.mock('../../../../src/component/form/pet-filter-form', () => {
+vi.mock('../../../../src/component/form/pet-filters-form', () => {
return {
- PetFilterForm: ({ submitPetFilter }: PetFilterFormProps) => {
- const onSubmit = () => {
- submitPetFilter({ name: 'Bro' });
+ PetFiltersForm: (props: PetFiltersFormProps) => {
+ const onClick = () => {
+ props.submitPetFilters({ name: 'Brownie' });
};
- return ;
- },
- };
-});
-
-vi.mock('../../../../src/component/partial/http-error', () => {
- return {
- HttpError: ({ httpError }: { httpError: HttpError; }) => {
- return httpError: {httpError.title}
;
+ return (
+
+ );
},
};
});
vi.mock('../../../../src/component/partial/pagination', () => {
return {
- Pagination: ({ submitPage, currentPage, totalPages, maxPages }: PaginationProps) => {
- const submit = () => {
- submitPage(2);
+ Pagination: (props: PaginationProps) => {
+ const onClick = () => {
+ props.submitPage(2);
};
return (
+ data-testid="pagination-next"
+ data-current-page={props.currentPage}
+ data-total-pages={props.totalPages}
+ data-max-pages={props.maxPages}
+ onClick={onClick}
+ />
);
},
};
});
-test('bad request', async () => {
- mockListPets = async (queryString: string) => {
- return new Promise((resolve) => resolve(new BadRequest({ title: 'title' })));
- };
-
- const history = createMemoryHistory();
-
- const { container } = render(
-
-
- ,
- );
-
- await screen.findByTestId('page-pet-list');
-
- expect(formatHtml(container.outerHTML)).toMatchInlineSnapshot(`
- "
-
-
httpError: title
-
List Pets
-
-
- "
- `);
-});
-
-test('default', async () => {
- const petList = {
- offset: 0,
- limit: 1,
- count: 2,
- items: [
- {
- id: '4d783b77-eb09-4603-b99b-f590b605eaa9',
- createdAt: '2005-08-15T15:52:01+00:00',
- updatedAt: '2005-08-15T15:55:01+00:00',
- name: 'Brownie',
- tag: '0001-000',
- vaccinations: [{ name: 'Rabies' }],
- _links: {
- read: {
- href: '/api/pets/4d783b77-eb09-4603-b99b-f590b605eaa9',
- attributes: {
- method: 'GET',
- },
- },
- update: {
- href: '/api/pets/4d783b77-eb09-4603-b99b-f590b605eaa9',
- attributes: {
- method: 'PUT',
- },
- },
- delete: {
- href: '/api/pets/4d783b77-eb09-4603-b99b-f590b605eaa9',
- attributes: {
- method: 'DELETE',
- },
- },
- },
- },
- ],
- _links: {
- create: {
- href: '/api/pets',
- attributes: {
- method: 'POST',
+test('default minimal', async () => {
+ mockListPetsClient = async (petListRequest: PetListRequest) => {
+ expect(petListRequest).toEqual({
+ offset: 0,
+ limit: 10,
+ filters: {},
+ sort: {},
+ });
+
+ return {
+ offset: 0,
+ limit: 10,
+ filters: {},
+ sort: {},
+ count: 1,
+ items: [
+ {
+ id: '4d783b77-eb09-4603-b99b-f590b605eaa9',
+ createdAt: '2005-08-15T15:52:01+00:00',
+ updatedAt: '2005-08-15T15:55:01+00:00',
+ name: 'Brownie',
+ vaccinations: [],
+ _links: {},
},
- },
- },
- };
-
- mockListPets = async (queryString: string) => {
- return new Promise((resolve) => resolve(petList));
+ ],
+ _links: {},
+ };
};
- const history = createMemoryHistory();
+ mockDeletePetClient = async () => undefined;
const { container } = render(
-
-
- ,
+
+
+ } />
+
+ ,
);
await screen.findByTestId('page-pet-list');
@@ -158,64 +109,98 @@ test('default', async () => {
expect(formatHtml(container.outerHTML)).toMatchInlineSnapshot(`
"
-
List Pets
+
Pet List
-
Create
-
-
-
- Id |
- CreatedAt |
- UpdatedAt |
-
- Name (
- A-Z
-
- |
- Z-A
-
- | --- )
- |
- Tag |
- Actions |
-
-
-
-
- 4d783b77-eb09-4603-b99b-f590b605eaa9 |
- 15.08.2005 - 17:52:01 |
- 15.08.2005 - 17:55:01 |
- Brownie |
- 0001-000 |
-
- ReadUpdate
- |
-
-
-
+
+
+
+
+
+
+ 4d783b77-eb09-4603-b99b-f590b605eaa9
+
+
+ 15.08.2005 - 17:52:01
+
+
+ 15.08.2005 - 17:55:01
+
+
+ Brownie
+
+
+
+
+
+
+
+
+
+
@@ -223,35 +208,26 @@ test('default', async () => {
`);
});
-test('no actions', async () => {
- const petList = {
- offset: 0,
- limit: 1,
- count: 2,
- items: [
- {
- id: '4d783b77-eb09-4603-b99b-f590b605eaa9',
- createdAt: '2005-08-15T15:52:01+00:00',
- updatedAt: '2005-08-15T15:55:01+00:00',
- name: 'Brownie',
- tag: '0001-000',
- vaccinations: [{ name: 'Rabies' }],
- _links: {},
- },
- ],
- _links: {},
- };
-
- mockListPets = async (queryString: string) => {
- return new Promise((resolve) => resolve(petList));
+test('bad request', async () => {
+ mockListPetsClient = async (petListRequest: PetListRequest) => {
+ expect(petListRequest).toEqual({
+ offset: 0,
+ limit: 10,
+ filters: {},
+ sort: {},
+ });
+
+ return new Promise((resolve) => resolve(new BadRequest({ title: 'bad request' })));
};
- const history = createMemoryHistory();
+ mockDeletePetClient = async () => undefined;
const { container } = render(
-
-
- ,
+
+
+ } />
+
+ ,
);
await screen.findByTestId('page-pet-list');
@@ -259,203 +235,180 @@ test('no actions', async () => {
expect(formatHtml(container.outerHTML)).toMatchInlineSnapshot(`
"
-
List Pets
-
-
-
-
-
- Id |
- CreatedAt |
- UpdatedAt |
-
- Name (
- A-Z
-
- |
- Z-A
-
- | --- )
- |
- Tag |
- Actions |
-
-
-
-
- 4d783b77-eb09-4603-b99b-f590b605eaa9 |
- 15.08.2005 - 17:52:01 |
- 15.08.2005 - 17:55:01 |
- Brownie |
- 0001-000 |
- |
-
-
-
-
+
+
Pet List
"
`);
});
-test('submit bad request', async () => {
- const petList = {
- offset: 0,
- limit: 1,
- count: 2,
- items: [
- {
- id: '4d783b77-eb09-4603-b99b-f590b605eaa9',
- createdAt: '2005-08-15T15:52:01+00:00',
- updatedAt: '2005-08-15T15:55:01+00:00',
- name: 'Brownie',
- tag: '0001-000',
- vaccinations: [{ name: 'Rabies' }],
- _links: {
- read: {
- href: '/api/pets/4d783b77-eb09-4603-b99b-f590b605eaa9',
- attributes: {
- method: 'GET',
- },
- },
- update: {
- href: '/api/pets/4d783b77-eb09-4603-b99b-f590b605eaa9',
- attributes: {
- method: 'PUT',
- },
+test('default maximal', async () => {
+ mockListPetsClient = async (petListRequest: PetListRequest) => {
+ expect(petListRequest).toEqual({
+ offset: 0,
+ limit: 10,
+ filters: {},
+ sort: {},
+ });
+
+ return {
+ offset: 0,
+ limit: 10,
+ filters: {},
+ sort: {},
+ count: 1,
+ items: [
+ {
+ id: '4d783b77-eb09-4603-b99b-f590b605eaa9',
+ createdAt: '2005-08-15T15:52:01+00:00',
+ updatedAt: '2005-08-15T15:55:01+00:00',
+ name: 'Brownie',
+ tag: '0001-000',
+ vaccinations: [{ name: 'Rabies' }],
+ _links: {
+ read: { href: '/api/pets/4d783b77-eb09-4603-b99b-f590b605eaa9' },
+ update: { href: '/api/pets/4d783b77-eb09-4603-b99b-f590b605eaa9' },
+ delete: { href: '/api/pets/4d783b77-eb09-4603-b99b-f590b605eaa9' },
},
- delete: {
- href: '/api/pets/4d783b77-eb09-4603-b99b-f590b605eaa9',
- attributes: {
- method: 'DELETE',
- },
- },
- },
- },
- ],
- _links: {
- create: {
- href: '/api/pets',
- attributes: {
- method: 'POST',
},
+ ],
+ _links: {
+ create: { href: '/api/pets' },
},
- },
+ };
};
- mockListPets = async (queryString: string) => {
- return new Promise
((resolve) => resolve(petList));
- };
-
- const history = createMemoryHistory();
+ mockDeletePetClient = async () => undefined;
- const { container, rerender } = render(
-
-
- ,
+ const { container } = render(
+
+
+ } />
+
+ ,
);
await screen.findByTestId('page-pet-list');
- mockListPets = async (queryString: string) => {
- return new Promise((resolve) => resolve(new BadRequest({ title: 'title' })));
- };
-
- const testButton = await screen.findByTestId('test-filter-button');
-
- await userEvent.click(testButton);
-
- expect(history.location.pathname).toBe('/pet');
- expect(history.location.search).toBe('?page=1&filters%5Bname%5D=Bro');
-
- rerender(
-
-
- ,
- );
-
- await screen.findByText(/httpError/);
-
expect(formatHtml(container.outerHTML)).toMatchInlineSnapshot(`
"
-
httpError: title
-
List Pets
+
Pet List
-
Create
-
-
-
- Id |
- CreatedAt |
- UpdatedAt |
-
- Name (Create
+ |
- Tag |
- Actions |
-
-
-
-
- 4d783b77-eb09-4603-b99b-f590b605eaa9 |
- 15.08.2005 - 17:52:01 |
- 15.08.2005 - 17:55:01 |
- Brownie |
- 0001-000 |
-
- ReadUpdate
- |
-
-
-
-
+ UpdatedAt
+
+
+ Name (||)
+
+
+ Tag
+
+
+ Actions
+
+
+
+
+
+
+ 4d783b77-eb09-4603-b99b-f590b605eaa9
+
+
+ 15.08.2005 - 17:52:01
+
+
+ 15.08.2005 - 17:55:01
+
+
+ Brownie
+
+
+ 0001-000
+
+
+
+
+
+
+
+
+
@@ -463,478 +416,330 @@ test('submit bad request', async () => {
`);
});
-test('submit filter', async () => {
- const petList = {
- offset: 0,
- limit: 1,
- count: 2,
- items: [
- {
- id: '4d783b77-eb09-4603-b99b-f590b605eaa9',
- createdAt: '2005-08-15T15:52:01+00:00',
- updatedAt: '2005-08-15T15:55:01+00:00',
- name: 'Brownie',
- tag: '0001-000',
- vaccinations: [{ name: 'Rabies' }],
- _links: {
- read: {
- href: '/api/pets/4d783b77-eb09-4603-b99b-f590b605eaa9',
- attributes: {
- method: 'GET',
- },
- },
- update: {
- href: '/api/pets/4d783b77-eb09-4603-b99b-f590b605eaa9',
- attributes: {
- method: 'PUT',
- },
- },
- delete: {
- href: '/api/pets/4d783b77-eb09-4603-b99b-f590b605eaa9',
- attributes: {
- method: 'DELETE',
- },
+test('delete error', async () => {
+ mockListPetsClient = async (petListRequest: PetListRequest) => {
+ expect(petListRequest).toEqual({
+ offset: 0,
+ limit: 10,
+ filters: {},
+ sort: {},
+ });
+
+ return {
+ offset: 0,
+ limit: 10,
+ filters: {},
+ sort: {},
+ count: 1,
+ items: [
+ {
+ id: '4d783b77-eb09-4603-b99b-f590b605eaa9',
+ createdAt: '2005-08-15T15:52:01+00:00',
+ updatedAt: '2005-08-15T15:55:01+00:00',
+ name: 'Brownie',
+ tag: '0001-000',
+ vaccinations: [{ name: 'Rabies' }],
+ _links: {
+ read: { href: '/api/pets/4d783b77-eb09-4603-b99b-f590b605eaa9' },
+ update: { href: '/api/pets/4d783b77-eb09-4603-b99b-f590b605eaa9' },
+ delete: { href: '/api/pets/4d783b77-eb09-4603-b99b-f590b605eaa9' },
},
},
+ ],
+ _links: {
+ create: { href: '/api/pets' },
},
- ],
- _links: {
- create: {
- href: '/api/pets',
- attributes: {
- method: 'POST',
- },
- },
- },
+ };
};
- mockListPets = async (queryString: string) => {
- return new Promise
((resolve) => resolve(petList));
- };
+ mockDeletePetClient = async (id: string) => {
+ expect(id).toBe('4d783b77-eb09-4603-b99b-f590b605eaa9');
- const history = createMemoryHistory();
+ return new NetworkError({ title: 'network error' });
+ };
render(
-
-
- ,
+
+
+ } />
+
+ ,
);
await screen.findByTestId('page-pet-list');
- const testButton = await screen.findByTestId('test-filter-button');
+ const removeButton = await screen.findByTestId('remove-pet-0');
- await userEvent.click(testButton);
+ await act(async () => userEvent.click(removeButton));
- expect(history.location.pathname).toBe('/pet');
- expect(history.location.search).toBe('?page=1&filters%5Bname%5D=Bro');
+ await screen.findByTestId('http-error');
+
+ expect(formatHtml((await screen.findByTestId('http-error')).outerHTML)).toMatchInlineSnapshot(`
+ "
+ "
+ `);
});
-test('sort', async () => {
- const petList = {
- offset: 0,
- limit: 1,
- count: 2,
- items: [
- {
- id: '4d783b77-eb09-4603-b99b-f590b605eaa9',
- createdAt: '2005-08-15T15:52:01+00:00',
- updatedAt: '2005-08-15T15:55:01+00:00',
- name: 'Brownie',
- tag: '0001-000',
- vaccinations: [{ name: 'Rabies' }],
- _links: {
- read: {
- href: '/api/pets/4d783b77-eb09-4603-b99b-f590b605eaa9',
- attributes: {
- method: 'GET',
- },
- },
- update: {
- href: '/api/pets/4d783b77-eb09-4603-b99b-f590b605eaa9',
- attributes: {
- method: 'PUT',
+test('delete success', async () => {
+ const petListCalls: Array<{ parameters: [PetListRequest]; return: Promise }> = [
+ {
+ parameters: [
+ {
+ offset: 0,
+ limit: 10,
+ filters: {},
+ sort: {},
+ },
+ ],
+ return: Promise.resolve({
+ offset: 0,
+ limit: 10,
+ filters: {},
+ sort: {},
+ count: 1,
+ items: [
+ {
+ id: '4d783b77-eb09-4603-b99b-f590b605eaa9',
+ createdAt: '2005-08-15T15:52:01+00:00',
+ updatedAt: '2005-08-15T15:55:01+00:00',
+ name: 'Brownie',
+ tag: '0001-000',
+ vaccinations: [{ name: 'Rabies' }],
+ _links: {
+ read: { href: '/api/pets/4d783b77-eb09-4603-b99b-f590b605eaa9' },
+ update: { href: '/api/pets/4d783b77-eb09-4603-b99b-f590b605eaa9' },
+ delete: { href: '/api/pets/4d783b77-eb09-4603-b99b-f590b605eaa9' },
},
},
- delete: {
- href: '/api/pets/4d783b77-eb09-4603-b99b-f590b605eaa9',
- attributes: {
- method: 'DELETE',
+ ],
+ _links: {
+ create: { href: '/api/pets' },
+ },
+ }),
+ },
+ {
+ parameters: [
+ {
+ offset: 0,
+ limit: 10,
+ filters: {},
+ sort: {},
+ },
+ ],
+ return: Promise.resolve({
+ offset: 0,
+ limit: 10,
+ filters: {},
+ sort: {},
+ count: 1,
+ items: [
+ {
+ id: '4d783b77-eb09-4603-b99b-f590b605eaa9',
+ createdAt: '2005-08-15T15:52:01+00:00',
+ updatedAt: '2005-08-15T15:55:01+00:00',
+ name: 'Brownie',
+ tag: '0001-000',
+ vaccinations: [{ name: 'Rabies' }],
+ _links: {
+ read: { href: '/api/pets/4d783b77-eb09-4603-b99b-f590b605eaa9' },
+ update: { href: '/api/pets/4d783b77-eb09-4603-b99b-f590b605eaa9' },
+ delete: { href: '/api/pets/4d783b77-eb09-4603-b99b-f590b605eaa9' },
},
},
+ ],
+ _links: {
+ create: { href: '/api/pets' },
},
- },
- ],
- _links: {
- create: {
- href: '/api/pets',
- attributes: {
- method: 'POST',
- },
- },
+ }),
},
- };
-
- mockListPets = async (queryString: string) => {
- return new Promise((resolve) => resolve(petList));
- };
-
- const history = createMemoryHistory();
-
- render(
-
-
- ,
- );
-
- await screen.findByTestId('page-pet-list');
-
- expect(history.location.pathname).toBe('/');
+ ];
- const sortNameDescLink = await screen.findByTestId('sort-pet-name-desc');
+ mockListPetsClient = async (petListRequest: PetListRequest) => {
+ const petListCall = petListCalls.shift();
+ if (!petListCall) {
+ throw new Error('Missing call');
+ }
- await userEvent.click(sortNameDescLink);
+ expect(petListRequest).toEqual(petListCall.parameters[0]);
- expect(history.location.pathname).toBe('/pet');
- expect(history.location.search).toBe('?page=1&sort%5Bname%5D=desc');
-});
-
-test('next', async () => {
- const petList = {
- offset: 0,
- limit: 1,
- count: 2,
- items: [
- {
- id: '4d783b77-eb09-4603-b99b-f590b605eaa9',
- createdAt: '2005-08-15T15:52:01+00:00',
- updatedAt: '2005-08-15T15:55:01+00:00',
- name: 'Brownie',
- tag: '0001-000',
- vaccinations: [{ name: 'Rabies' }],
- _links: {
- read: {
- href: '/api/pets/4d783b77-eb09-4603-b99b-f590b605eaa9',
- attributes: {
- method: 'GET',
- },
- },
- update: {
- href: '/api/pets/4d783b77-eb09-4603-b99b-f590b605eaa9',
- attributes: {
- method: 'PUT',
- },
- },
- delete: {
- href: '/api/pets/4d783b77-eb09-4603-b99b-f590b605eaa9',
- attributes: {
- method: 'DELETE',
- },
- },
- },
- },
- ],
- _links: {
- create: {
- href: '/api/pets',
- attributes: {
- method: 'POST',
- },
- },
- },
+ return petListCall.return;
};
- mockListPets = async (queryString: string) => {
- return new Promise((resolve) => resolve(petList));
- };
+ mockDeletePetClient = async (id: string) => {
+ expect(id).toBe('4d783b77-eb09-4603-b99b-f590b605eaa9');
- const history = createMemoryHistory();
+ return undefined;
+ };
render(
-
-
- ,
+
+
+ } />
+
+ ,
);
await screen.findByTestId('page-pet-list');
- expect(history.location.pathname).toBe('/');
-
- const testButton = await screen.findByTestId('test-pagination-button');
-
- await userEvent.click(testButton);
+ const removeButton = await screen.findByTestId('remove-pet-0');
- expect(history.location.pathname).toBe('/pet');
- expect(history.location.search).toBe('?page=2');
+ await act(async () => userEvent.click(removeButton));
});
-test('delete not found', async () => {
- const petList = {
- offset: 0,
- limit: 1,
- count: 2,
- items: [
- {
- id: '4d783b77-eb09-4603-b99b-f590b605eaa9',
- createdAt: '2005-08-15T15:52:01+00:00',
- updatedAt: '2005-08-15T15:55:01+00:00',
- name: 'Brownie',
- tag: '0001-000',
- vaccinations: [{ name: 'Rabies' }],
- _links: {
- read: {
- href: '/api/pets/4d783b77-eb09-4603-b99b-f590b605eaa9',
- attributes: {
- method: 'GET',
- },
- },
- update: {
- href: '/api/pets/4d783b77-eb09-4603-b99b-f590b605eaa9',
- attributes: {
- method: 'PUT',
+test('submit', async () => {
+ const petListCalls: Array<{ parameters: [PetListRequest]; return: Promise }> = [
+ {
+ parameters: [
+ {
+ offset: 0,
+ limit: 10,
+ filters: {},
+ sort: {},
+ },
+ ],
+ return: Promise.resolve({
+ offset: 0,
+ limit: 10,
+ filters: {},
+ sort: {},
+ count: 1,
+ items: [
+ {
+ id: '4d783b77-eb09-4603-b99b-f590b605eaa9',
+ createdAt: '2005-08-15T15:52:01+00:00',
+ updatedAt: '2005-08-15T15:55:01+00:00',
+ name: 'Brownie',
+ tag: '0001-000',
+ vaccinations: [{ name: 'Rabies' }],
+ _links: {
+ read: { href: '/api/pets/4d783b77-eb09-4603-b99b-f590b605eaa9' },
+ update: { href: '/api/pets/4d783b77-eb09-4603-b99b-f590b605eaa9' },
+ delete: { href: '/api/pets/4d783b77-eb09-4603-b99b-f590b605eaa9' },
},
},
- delete: {
- href: '/api/pets/4d783b77-eb09-4603-b99b-f590b605eaa9',
- attributes: {
- method: 'DELETE',
+ ],
+ _links: {
+ create: { href: '/api/pets' },
+ },
+ }),
+ },
+ {
+ parameters: [
+ {
+ offset: 0,
+ limit: 10,
+ filters: {},
+ sort: { name: 'desc' },
+ },
+ ],
+ return: Promise.resolve({
+ offset: 0,
+ limit: 10,
+ filters: {},
+ sort: { name: 'desc' },
+ count: 1,
+ items: [
+ {
+ id: '4d783b77-eb09-4603-b99b-f590b605eaa9',
+ createdAt: '2005-08-15T15:52:01+00:00',
+ updatedAt: '2005-08-15T15:55:01+00:00',
+ name: 'Blacky',
+ tag: '0002-000',
+ vaccinations: [{ name: 'Rabies' }],
+ _links: {
+ read: { href: '/api/pets/4d783b77-eb09-4603-b99b-f590b605eaa9' },
+ update: { href: '/api/pets/4d783b77-eb09-4603-b99b-f590b605eaa9' },
+ delete: { href: '/api/pets/4d783b77-eb09-4603-b99b-f590b605eaa9' },
},
},
+ ],
+ _links: {
+ create: { href: '/api/pets' },
},
- },
- ],
- _links: {
- create: {
- href: '/api/pets',
- attributes: {
- method: 'POST',
- },
- },
+ }),
},
- };
-
- mockListPets = async (queryString: string) => {
- return new Promise((resolve) => resolve(petList));
- };
-
- const history = createMemoryHistory();
-
- const { container } = render(
-
-
- ,
- );
-
- await screen.findByTestId('page-pet-list');
-
- mockDeletePet = async (id: string) => {
- return new Promise((resolve) => resolve(new NotFound({ title: 'title' })));
- };
-
- const removePetButton = await screen.findByTestId('remove-pet-0');
-
- await userEvent.click(removePetButton);
-
- await screen.findByText(/httpError/);
-
- expect(formatHtml(container.outerHTML)).toMatchInlineSnapshot(`
- "
-
-
httpError: title
-
List Pets
-
-
Create
-
-
-
- Id |
- CreatedAt |
- UpdatedAt |
-
- Name (
- A-Z
-
- |
- Z-A
-
- | --- )
- |
- Tag |
- Actions |
-
-
-
-
- 4d783b77-eb09-4603-b99b-f590b605eaa9 |
- 15.08.2005 - 17:52:01 |
- 15.08.2005 - 17:55:01 |
- Brownie |
- 0001-000 |
-
- ReadUpdate
- |
-
-
-
-
-
-
-
- "
- `);
-});
-
-test('delete success', async () => {
- const petList = {
- offset: 0,
- limit: 1,
- count: 2,
- items: [
- {
- id: '4d783b77-eb09-4603-b99b-f590b605eaa9',
- createdAt: '2005-08-15T15:52:01+00:00',
- updatedAt: '2005-08-15T15:55:01+00:00',
- name: 'Brownie',
- tag: '0001-000',
- vaccinations: [{ name: 'Rabies' }],
+ {
+ parameters: [
+ {
+ offset: 0,
+ limit: 10,
+ filters: { name: 'Brownie' },
+ sort: { name: 'desc' },
+ },
+ ],
+ return: Promise.resolve({
+ offset: 0,
+ limit: 10,
+ filters: { name: 'Brownie' },
+ sort: { name: 'desc' },
+ count: 0,
+ items: [],
_links: {
- read: {
- href: '/api/pets/4d783b77-eb09-4603-b99b-f590b605eaa9',
- attributes: {
- method: 'GET',
- },
- },
- update: {
- href: '/api/pets/4d783b77-eb09-4603-b99b-f590b605eaa9',
- attributes: {
- method: 'PUT',
- },
- },
- delete: {
- href: '/api/pets/4d783b77-eb09-4603-b99b-f590b605eaa9',
- attributes: {
- method: 'DELETE',
- },
- },
+ create: { href: '/api/pets' },
},
- },
- ],
- _links: {
- create: {
- href: '/api/pets',
- attributes: {
- method: 'POST',
+ }),
+ },
+ {
+ parameters: [
+ {
+ offset: 10,
+ limit: 10,
+ filters: { name: 'Brownie' },
+ sort: { name: 'desc' },
},
- },
+ ],
+ return: Promise.resolve({
+ offset: 10,
+ limit: 10,
+ filters: { name: 'Brownie' },
+ sort: { name: 'desc' },
+ count: 0,
+ items: [],
+ _links: {
+ create: { href: '/api/pets' },
+ },
+ }),
},
- };
+ ];
+
+ mockListPetsClient = async (petListRequest: PetListRequest) => {
+ const petListCall = petListCalls.shift();
+ if (!petListCall) {
+ throw new Error('Missing call');
+ }
+
+ expect(petListRequest).toEqual(petListCall.parameters[0]);
- mockListPets = async (queryString: string) => {
- return new Promise((resolve) => resolve(petList));
+ return petListCall.return;
};
- const history = createMemoryHistory();
+ mockDeletePetClient = async () => undefined;
- const { container } = render(
-
-
- ,
+ render(
+
+
+ } />
+
+ ,
);
await screen.findByTestId('page-pet-list');
- mockDeletePet = async (id: string) => {
- return new Promise((resolve) => resolve());
- };
+ const petSortNameSubmitButton = await screen.findByTestId('pet-sort-name-desc');
- const petListNoItem = {
- offset: 0,
- limit: 1,
- count: 2,
- items: [],
- _links: {
- create: {
- href: '/api/pets',
- attributes: {
- method: 'POST',
- },
- },
- },
- };
+ await act(async () => userEvent.click(petSortNameSubmitButton));
- mockListPets = async (queryString: string) => {
- return new Promise((resolve) => resolve(petListNoItem));
- };
+ await screen.findByTestId('page-pet-list');
- const removePetButton = await screen.findByTestId('remove-pet-0');
+ const petFiltersFormSubmitButton = await screen.findByTestId('pet-filters-form-submit');
- await userEvent.click(removePetButton);
+ await act(async () => userEvent.click(petFiltersFormSubmitButton));
- expect(formatHtml(container.outerHTML)).toMatchInlineSnapshot(`
- "
- "
- `);
+ await screen.findByTestId('page-pet-list');
+
+ const paginationNextButton = await screen.findByTestId('pagination-next');
+
+ await act(async () => userEvent.click(paginationNextButton));
});
diff --git a/tests/component/page/pet/read.test.tsx b/tests/component/page/pet/read.test.tsx
index c59e174..fc08430 100644
--- a/tests/component/page/pet/read.test.tsx
+++ b/tests/component/page/pet/read.test.tsx
@@ -1,43 +1,37 @@
-import { createMemoryHistory } from 'history';
-import { render, screen } from '@testing-library/react';
-import { Router } from 'react-router-dom';
+// eslint-disable-next-line @typescript-eslint/no-unused-vars
+import React from 'react';
import Read from '../../../../src/component/page/pet/read';
-import { vi } from 'vitest';
-import { test, expect } from 'vitest';
-import { PetResponse } from '../../../../src/model/model';
+import { vi, test, expect } from 'vitest';
import { formatHtml } from '../../../formatter';
-import { HttpError, NotFound } from '../../../../src/api-client/error';
-
-let mockReadPet = (id: string) => { };
+import { NotFound } from '../../../../src/client/error';
+import type { readPetClient } from '../../../../src/client/pet';
+import { MemoryRouter, Route, Routes } from 'react-router-dom';
+import { render, screen } from '@testing-library/react';
+import type { PetResponse } from '../../../../model/pet';
-vi.mock('../../../../src/api-client/pet', () => {
- return {
- ReadPet: (id: string) => {
- return mockReadPet(id);
- },
- };
-});
+let mockReadPetClient: typeof readPetClient;
-vi.mock('../../../../src/component/partial/http-error', () => {
+vi.mock('../../../../src/client/pet', () => {
return {
- HttpError: ({ httpError }: { httpError: HttpError; }) => {
- return httpError: {httpError.title}
;
+ readPetClient: (id: string) => {
+ return mockReadPetClient(id);
},
};
});
test('not found', async () => {
- mockReadPet = async (id: string) => {
+ mockReadPetClient = async (id: string) => {
+ expect(id).toBe('4d783b77-eb09-4603-b99b-f590b605eaa9');
+
return new Promise((resolve) => resolve(new NotFound({ title: 'title' })));
};
- const history = createMemoryHistory();
- history.push('/pet/4d783b77-eb09-4603-b99b-f590b605eaa9');
-
const { container } = render(
-
-
- ,
+
+
+ } />
+
+ ,
);
await screen.findByTestId('page-pet-read');
@@ -45,32 +39,44 @@ test('not found', async () => {
expect(formatHtml(container.outerHTML)).toMatchInlineSnapshot(`
"
-
httpError: title
-
Read Pet
+
+
Pet Read
+
List
"
`);
});
-test('minimal', async () => {
- const pet = {
+test('success without vaccinations', async () => {
+ const petResponse: PetResponse = {
id: '4d783b77-eb09-4603-b99b-f590b605eaa9',
createdAt: '2005-08-15T15:52:01+00:00',
+ updatedAt: '2005-08-15T15:55:01+00:00',
name: 'Brownie',
+ tag: '0001-000',
+ vaccinations: [],
+ _links: {},
};
- mockReadPet = async (id: string) => {
- return new Promise((resolve) => resolve(pet));
- };
+ mockReadPetClient = async (id: string) => {
+ expect(id).toBe('4d783b77-eb09-4603-b99b-f590b605eaa9');
- const history = createMemoryHistory();
- history.push('/pet/4d783b77-eb09-4603-b99b-f590b605eaa9');
+ return new Promise((resolve) => resolve(petResponse));
+ };
const { container } = render(
-
-
- ,
+
+
+ } />
+
+ ,
);
await screen.findByTestId('page-pet-read');
@@ -78,51 +84,57 @@ test('minimal', async () => {
expect(formatHtml(container.outerHTML)).toMatchInlineSnapshot(`
"
-
Read Pet
+
Pet Read
- - Id
- - 4d783b77-eb09-4603-b99b-f590b605eaa9
- - CreatedAt
- - 15.08.2005 - 17:52:01
- - UpdatedAt
-
- - Name
- - Brownie
- - Tag
-
- - Vaccinations
-
+ - Id
+ - 4d783b77-eb09-4603-b99b-f590b605eaa9
+ - CreatedAt
+ - 15.08.2005 - 17:52:01
+ - UpdatedAt
+ - 15.08.2005 - 17:55:01
+ - Name
+ - Brownie
+ - Tag
+ - 0001-000
+ - Vaccinations
+
-
List
+
List
"
`);
});
-test('maximal', async () => {
- const pet = {
+test('success with vaccinations', async () => {
+ const petResponse: PetResponse = {
id: '4d783b77-eb09-4603-b99b-f590b605eaa9',
createdAt: '2005-08-15T15:52:01+00:00',
updatedAt: '2005-08-15T15:55:01+00:00',
name: 'Brownie',
tag: '0001-000',
vaccinations: [{ name: 'Rabies' }],
+ _links: {},
};
- mockReadPet = async (id: string) => {
- return new Promise((resolve) => resolve(pet));
- };
+ mockReadPetClient = async (id: string) => {
+ expect(id).toBe('4d783b77-eb09-4603-b99b-f590b605eaa9');
- const history = createMemoryHistory();
- history.push('/pet/4d783b77-eb09-4603-b99b-f590b605eaa9');
+ return new Promise((resolve) => resolve(petResponse));
+ };
const { container } = render(
-
-
- ,
+
+
+ } />
+
+ ,
);
await screen.findByTestId('page-pet-read');
@@ -130,28 +142,32 @@ test('maximal', async () => {
expect(formatHtml(container.outerHTML)).toMatchInlineSnapshot(`
"
-
Read Pet
+
Pet Read
- - Id
- - 4d783b77-eb09-4603-b99b-f590b605eaa9
- - CreatedAt
- - 15.08.2005 - 17:52:01
- - UpdatedAt
- - 15.08.2005 - 17:55:01
- - Name
- - Brownie
- - Tag
- - 0001-000
- - Vaccinations
- -
+
- Id
+ - 4d783b77-eb09-4603-b99b-f590b605eaa9
+ - CreatedAt
+ - 15.08.2005 - 17:52:01
+ - UpdatedAt
+ - 15.08.2005 - 17:55:01
+ - Name
+ - Brownie
+ - Tag
+ - 0001-000
+ - Vaccinations
+ -
-
List
+
List
"
diff --git a/tests/component/page/pet/update.test.tsx b/tests/component/page/pet/update.test.tsx
index dd761d0..dc0da39 100644
--- a/tests/component/page/pet/update.test.tsx
+++ b/tests/component/page/pet/update.test.tsx
@@ -1,61 +1,62 @@
-import { createMemoryHistory } from 'history';
-import { render, screen } from '@testing-library/react';
-import { Router } from 'react-router-dom';
-import { PetFormProps } from '../../../../src/component/form/pet-form';
+// eslint-disable-next-line @typescript-eslint/no-unused-vars
+import React from 'react';
import Update from '../../../../src/component/page/pet/update';
-import userEvent from '@testing-library/user-event';
-import { vi } from 'vitest';
-import { test, expect } from 'vitest';
-import { PetRequest, PetResponse } from '../../../../src/model/model';
+import type { PetFormProps } from '../../../../src/component/form/pet-form';
+import { vi, test, expect } from 'vitest';
+import type { PetRequest, PetResponse } from '../../../../src/model/pet';
import { formatHtml } from '../../../formatter';
-import { HttpError, NotFound, UnprocessableEntity } from '../../../../src/api-client/error';
+import { NotFound, UnprocessableEntity } from '../../../../src/client/error';
+import type { readPetClient, updatePetClient } from '../../../../src/client/pet';
+import { MemoryRouter, Route, Routes } from 'react-router-dom';
+import { act, render, screen } from '@testing-library/react';
+import { userEvent } from '@testing-library/user-event';
-let mockReadPet = (id: string) => { };
-let mockUpdatePet = (id: string, pet: PetRequest) => { };
+let mockReadPetClient: typeof readPetClient;
+let mockUpdatePetClient: typeof updatePetClient;
-vi.mock('../../../../src/api-client/pet', () => {
+vi.mock('../../../../src/client/pet', () => {
return {
- ReadPet: (id: string) => {
- return mockReadPet(id);
+ readPetClient: (id: string) => {
+ return mockReadPetClient(id);
},
- UpdatePet: (id: string, pet: PetRequest) => {
- return mockUpdatePet(id, pet);
+ updatePetClient: (id: string, pet: PetRequest) => {
+ return mockUpdatePetClient(id, pet);
},
};
});
vi.mock('../../../../src/component/form/pet-form', () => {
return {
- PetForm: ({ submitPet }: PetFormProps) => {
+ PetForm: (props: PetFormProps) => {
const onSubmit = () => {
- submitPet({ ...({} as PetRequest), name: 'Brownie' });
+ props.submitPet({ name: 'Brownie', vaccinations: [] });
};
- return ;
- },
- };
-});
-
-vi.mock('../../../../src/component/partial/http-error', () => {
- return {
- HttpError: ({ httpError }: { httpError: HttpError; }) => {
- return httpError: {httpError.title}
;
+ return (
+
+ );
},
};
});
test('not found', async () => {
- mockReadPet = async (id: string) => {
+ mockReadPetClient = async (id: string) => {
+ expect(id).toBe('4d783b77-eb09-4603-b99b-f590b605eaa9');
+
return new Promise((resolve) => resolve(new NotFound({ title: 'title' })));
};
- const history = createMemoryHistory();
- history.push('/pet/4d783b77-eb09-4603-b99b-f590b605eaa9');
-
const { container } = render(
-
-
- ,
+
+
+ } />
+
+ ,
);
await screen.findByTestId('page-pet-update');
@@ -63,33 +64,44 @@ test('not found', async () => {
expect(formatHtml(container.outerHTML)).toMatchInlineSnapshot(`
"
-
httpError: title
-
Update Pet
-
List
+
+
Pet Update
+
List
"
`);
});
-test('minimal', async () => {
- const pet = {
+test('default', async () => {
+ const petResponse: PetResponse = {
id: '4d783b77-eb09-4603-b99b-f590b605eaa9',
createdAt: '2005-08-15T15:52:01+00:00',
+ updatedAt: '2005-08-15T15:55:01+00:00',
name: 'Brownie',
+ tag: '0001-000',
+ vaccinations: [{ name: 'Rabies' }],
+ _links: {},
};
- mockReadPet = async (id: string) => {
- return new Promise((resolve) => resolve(pet));
- };
+ mockReadPetClient = async (id: string) => {
+ expect(id).toBe('4d783b77-eb09-4603-b99b-f590b605eaa9');
- const history = createMemoryHistory();
- history.push('/pet/4d783b77-eb09-4603-b99b-f590b605eaa9');
+ return new Promise((resolve) => resolve(petResponse));
+ };
const { container } = render(
-
-
- ,
+
+
+ } />
+
+ ,
);
await screen.findByTestId('page-pet-update');
@@ -97,9 +109,17 @@ test('minimal', async () => {
expect(formatHtml(container.outerHTML)).toMatchInlineSnapshot(`
"
"
@@ -107,46 +127,61 @@ test('minimal', async () => {
});
test('unprocessable entity', async () => {
- const pet = {
+ const petResponse: PetResponse = {
id: '4d783b77-eb09-4603-b99b-f590b605eaa9',
createdAt: '2005-08-15T15:52:01+00:00',
updatedAt: '2005-08-15T15:55:01+00:00',
name: 'Brownie',
+ tag: '0001-000',
vaccinations: [{ name: 'Rabies' }],
+ _links: {},
};
- mockReadPet = async (id: string) => {
- return new Promise((resolve) => resolve(pet));
- };
+ mockReadPetClient = async (id: string) => {
+ expect(id).toBe('4d783b77-eb09-4603-b99b-f590b605eaa9');
- mockUpdatePet = async (id: string, pet: PetRequest) => {
- return new Promise((resolve) => resolve(new UnprocessableEntity({ title: 'title' })));
+ return new Promise((resolve) => resolve(petResponse));
};
- const history = createMemoryHistory();
- history.push('/pet/4d783b77-eb09-4603-b99b-f590b605eaa9');
+ mockUpdatePetClient = async (id: string) => {
+ expect(id).toBe('4d783b77-eb09-4603-b99b-f590b605eaa9');
+
+ return new Promise((resolve) =>
+ resolve(new UnprocessableEntity({ title: 'unprocessable entity' })),
+ );
+ };
const { container } = render(
-
-
- ,
+
+
+ } />
+
+ ,
);
- await screen.findByTestId('page-pet-update');
-
- const testButton = await screen.findByTestId('test-button');
+ const testButton = await screen.findByTestId('pet-form-submit');
- await userEvent.click(testButton);
+ await act(async () => userEvent.click(testButton));
- await screen.findByText(/httpError/);
+ await screen.findByTestId('http-error');
expect(formatHtml(container.outerHTML)).toMatchInlineSnapshot(`
"
-
httpError: title
-
Update Pet
-
List
+
+
Pet Update
+
List
"
@@ -154,38 +189,51 @@ test('unprocessable entity', async () => {
});
test('successful', async () => {
- const pet = {
- id: '4d783b77-eb09-4603-b99b-f590b605eaa9',
- createdAt: '2005-08-15T15:52:01+00:00',
- updatedAt: '2005-08-15T15:55:01+00:00',
+ const petRequest: PetRequest = {
name: 'Brownie',
+ tag: '0001-000',
vaccinations: [{ name: 'Rabies' }],
};
- mockReadPet = async (id: string) => {
- return new Promise((resolve) => resolve(pet));
+ const petResponse: PetResponse = {
+ id: '4d783b77-eb09-4603-b99b-f590b605eaa9',
+ createdAt: '2005-08-15T15:52:01+00:00',
+ updatedAt: '2005-08-15T15:55:01+00:00',
+ ...petRequest,
+ _links: {},
};
- mockUpdatePet = async (id: string, pet: PetRequest) => {
- return new Promise((resolve) => resolve(pet));
+ mockReadPetClient = async (id: string) => {
+ expect(id).toBe('4d783b77-eb09-4603-b99b-f590b605eaa9');
+
+ return new Promise((resolve) => resolve(petResponse));
};
- const history = createMemoryHistory();
- history.push('/pet/4d783b77-eb09-4603-b99b-f590b605eaa9');
+ mockUpdatePetClient = async (id: string, petRequest: PetRequest) => {
+ expect(id).toBe('4d783b77-eb09-4603-b99b-f590b605eaa9');
- render(
-
-
- ,
- );
+ expect(petRequest).toEqual(petRequest);
- await screen.findByTestId('page-pet-update');
+ return new Promise((resolve) => resolve(petResponse));
+ };
- expect(history.location.pathname).toBe('/pet/4d783b77-eb09-4603-b99b-f590b605eaa9');
+ const { container } = render(
+
+
+ } />
+ } />
+
+ ,
+ );
- const testButton = await screen.findByTestId('test-button');
+ const testButton = await screen.findByTestId('pet-form-submit');
await userEvent.click(testButton);
- expect(history.location.pathname).toBe('/pet');
+ await screen.findByTestId('page-pet-list');
+
+ expect(formatHtml(container.outerHTML)).toMatchInlineSnapshot(`
+ "
+ "
+ `);
});
diff --git a/tests/component/partial/http-error.test.tsx b/tests/component/partial/http-error.test.tsx
index b14ea8e..f9fd877 100644
--- a/tests/component/partial/http-error.test.tsx
+++ b/tests/component/partial/http-error.test.tsx
@@ -1,8 +1,10 @@
+// eslint-disable-next-line @typescript-eslint/no-unused-vars
+import React from 'react';
import { render } from '@testing-library/react';
import { HttpError as HttpErrorPartial } from '../../../src/component/partial/http-error';
import { test, expect } from 'vitest';
import { formatHtml } from '../../formatter';
-import { HttpError, HttpErrorWithInvalidParameters } from '../../../src/api-client/error';
+import { BadRequestOrUnprocessableEntity, HttpError } from '../../../src/client/error';
test('minimal', () => {
const httpError = new HttpError({
@@ -13,14 +15,16 @@ test('minimal', () => {
expect(formatHtml(container.outerHTML)).toMatchInlineSnapshot(`
"
"
`);
});
test('maximal', () => {
- const httpError = new HttpErrorWithInvalidParameters({
+ const httpError = new BadRequestOrUnprocessableEntity({
title: 'This is the title',
detail: 'This is the detail',
instance: 'This is the instance',
@@ -31,8 +35,8 @@ test('maximal', () => {
expect(formatHtml(container.outerHTML)).toMatchInlineSnapshot(`
"
-
-
This is the title
+
+
This is the title
This is the detail
This is the instance
diff --git a/tests/component/partial/pagination.test.tsx b/tests/component/partial/pagination.test.tsx
index e02c17e..eb9eed7 100644
--- a/tests/component/partial/pagination.test.tsx
+++ b/tests/component/partial/pagination.test.tsx
@@ -1,11 +1,13 @@
+// eslint-disable-next-line @typescript-eslint/no-unused-vars
+import React from 'react';
import { render, screen } from '@testing-library/react';
-import userEvent from '@testing-library/user-event';
+import { userEvent } from '@testing-library/user-event';
import { test, expect } from 'vitest';
import { formatHtml } from '../../formatter';
import { Pagination } from '../../../src/component/partial/pagination';
test('max pages 1', () => {
- const submitPage = (page: number): void => { };
+ const submitPage = (): void => {};
const { container } = render();
@@ -16,7 +18,7 @@ test('max pages 1', () => {
});
test('total pages 1', () => {
- const submitPage = (page: number): void => { };
+ const submitPage = (): void => {};
const { container } = render();
@@ -27,22 +29,40 @@ test('total pages 1', () => {
});
test('current 1', () => {
- const submitPage = (page: number): void => { };
+ const submitPage = (): void => {};
const { container } = render();
expect(formatHtml(container.outerHTML)).toMatchInlineSnapshot(`
"
-
"
@@ -50,24 +70,46 @@ test('current 1', () => {
});
test('current 4', () => {
- const submitPage = (page: number): void => { };
+ const submitPage = (): void => {};
const { container } = render();
expect(formatHtml(container.outerHTML)).toMatchInlineSnapshot(`
"
-
"
@@ -75,24 +117,46 @@ test('current 4', () => {
});
test('current 7', () => {
- const submitPage = (page: number): void => { };
+ const submitPage = (): void => {};
const { container } = render();
expect(formatHtml(container.outerHTML)).toMatchInlineSnapshot(`
"
-
"
@@ -100,22 +164,40 @@ test('current 7', () => {
});
test('current 10', () => {
- const submitPage = (page: number): void => { };
+ const submitPage = (): void => {};
const { container } = render();
expect(formatHtml(container.outerHTML)).toMatchInlineSnapshot(`
"
-
"
diff --git a/tests/denormalizer/invalid-parameter-by-name-denormalizer.test.ts b/tests/denormalizer/invalid-parameter-by-name-denormalizer.test.ts
deleted file mode 100644
index 14be9d5..0000000
--- a/tests/denormalizer/invalid-parameter-by-name-denormalizer.test.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-import { InvalidParameter } from '../../src/api-client/error';
-import InvalidParameterByNameDenormalizer from '../../src/denormalizer/invalid-parameter-by-name-denormalizer';
-import { test, expect } from 'vitest';
-
-test('default', () => {
- const invalidParameters: Array = [
- { name: 'name', reason: 'wrong type', details: { key: 'value1' } },
- { name: 'name', reason: 'not empty', details: { key: 'value2' } },
- { name: 'description', reason: 'to long', details: { key: 'value3' } },
- ];
-
- const invalidParameterByName = InvalidParameterByNameDenormalizer(invalidParameters);
-
- expect(invalidParameterByName.has('name')).toBeTruthy();
-
- const InvalidParametersOfName = invalidParameterByName.get('name');
-
- expect(InvalidParametersOfName).toBeInstanceOf(Array);
- expect(InvalidParametersOfName).toHaveLength(2);
-
- expect(InvalidParametersOfName instanceof Array ? InvalidParametersOfName[0] : null).toBe(invalidParameters[0]);
- expect(InvalidParametersOfName instanceof Array ? InvalidParametersOfName[1] : null).toBe(invalidParameters[1]);
-
- const InvalidParametersOfDescription = invalidParameterByName.get('description');
-
- expect(InvalidParametersOfDescription).toBeInstanceOf(Array);
- expect(InvalidParametersOfDescription).toHaveLength(1);
-
- expect(InvalidParametersOfDescription instanceof Array ? InvalidParametersOfDescription[0] : null).toBe(
- invalidParameters[2],
- );
-});
diff --git a/tests/hook/use-model-resource.ts.test.ts b/tests/hook/use-model-resource.ts.test.ts
new file mode 100644
index 0000000..03e6665
--- /dev/null
+++ b/tests/hook/use-model-resource.ts.test.ts
@@ -0,0 +1,312 @@
+import { describe, expect, test } from 'vitest';
+import { useModelResource } from '../../src/hook/use-model-resource';
+import { useFunctionMock } from '@chubbyts/chubbyts-function-mock/dist/function-mock';
+import type { CreateClient, ReadClient, DeleteClient, ListClient, UpdateClient } from '../../src/client/client';
+import type { ModelListRequest, ModelListResponse, ModelRequest, ModelResponse } from '../../src/model/model';
+import { BadRequest } from '../../src/client/error';
+import { renderHook, act } from '@testing-library/react';
+
+describe('useModelResource', () => {
+ describe('list', () => {
+ test('missing client', async () => {
+ const { result } = renderHook(() => useModelResource({}));
+
+ try {
+ await result.current.actions.listModel({});
+ throw new Error('expect failed');
+ } catch (e) {
+ expect(e).toMatchInlineSnapshot('[Error: Missing listClient]');
+ }
+ });
+
+ test('error', async () => {
+ const clientHttpError = new BadRequest({ title: 'bad request' });
+
+ const [listClient, listClientMocks] = useFunctionMock>([
+ { parameters: [{}], return: Promise.resolve(clientHttpError) },
+ ]);
+
+ const { result } = renderHook(() => useModelResource({ listClient }));
+
+ expect(result.current.modelList).toBeUndefined();
+ expect(result.current.httpError).toBeUndefined();
+
+ await act(async () => {
+ expect(await result.current.actions.listModel({})).toBe(false);
+ });
+
+ expect(result.current.modelList).toBeUndefined();
+ expect(result.current.httpError).toBe(clientHttpError);
+
+ expect(listClientMocks.length).toBe(0);
+ });
+
+ test('success', async () => {
+ const modelListResponse: ModelListResponse = {
+ offset: 0,
+ limit: 10,
+ filters: {},
+ sort: {},
+ count: 0,
+ items: [],
+ _links: {},
+ };
+
+ const [listClient, listClientMocks] = useFunctionMock>([
+ { parameters: [{}], return: Promise.resolve(modelListResponse) },
+ ]);
+
+ const { result } = renderHook(() => useModelResource({ listClient }));
+
+ expect(result.current.modelList).toBeUndefined();
+ expect(result.current.httpError).toBeUndefined();
+
+ await act(async () => {
+ expect(await result.current.actions.listModel({})).toBe(true);
+ });
+
+ expect(result.current.modelList).toBe(modelListResponse);
+ expect(result.current.httpError).toBeUndefined();
+
+ expect(listClientMocks.length).toBe(0);
+ });
+ });
+
+ describe('create', () => {
+ test('missing client', async () => {
+ const { result } = renderHook(() => useModelResource({}));
+
+ try {
+ await result.current.actions.createModel({});
+ throw new Error('expect failed');
+ } catch (e) {
+ expect(e).toMatchInlineSnapshot('[Error: Missing createClient]');
+ }
+ });
+
+ test('error', async () => {
+ const clientHttpError = new BadRequest({ title: 'bad request' });
+
+ const [createClient, createClientMocks] = useFunctionMock>([
+ { parameters: [{}], return: Promise.resolve(clientHttpError) },
+ ]);
+
+ const { result } = renderHook(() => useModelResource({ createClient }));
+
+ expect(result.current.model).toBeUndefined();
+ expect(result.current.httpError).toBeUndefined();
+
+ await act(async () => {
+ expect(await result.current.actions.createModel({})).toBe(false);
+ });
+
+ expect(result.current.model).toBeUndefined();
+ expect(result.current.httpError).toBe(clientHttpError);
+
+ expect(createClientMocks.length).toBe(0);
+ });
+
+ test('success', async () => {
+ const modelResponse: ModelResponse = {
+ id: 'ddbb7edb-8c53-4586-9844-769e1c830719',
+ createdAt: '2022-06-12T20:08:24.793Z',
+ _links: {},
+ };
+
+ const [createClient, createClientMocks] = useFunctionMock>([
+ { parameters: [{}], return: Promise.resolve(modelResponse) },
+ ]);
+
+ const { result } = renderHook(() => useModelResource({ createClient }));
+
+ expect(result.current.model).toBeUndefined();
+ expect(result.current.httpError).toBeUndefined();
+
+ await act(async () => {
+ expect(await result.current.actions.createModel({})).toBe(true);
+ });
+
+ expect(result.current.model).toBe(modelResponse);
+ expect(result.current.httpError).toBeUndefined();
+
+ expect(createClientMocks.length).toBe(0);
+ });
+ });
+
+ describe('read', () => {
+ test('missing client', async () => {
+ const { result } = renderHook(() => useModelResource({}));
+
+ try {
+ await result.current.actions.readModel('ddbb7edb-8c53-4586-9844-769e1c830719');
+ throw new Error('expect failed');
+ } catch (e) {
+ expect(e).toMatchInlineSnapshot('[Error: Missing readClient]');
+ }
+ });
+
+ test('error', async () => {
+ const clientHttpError = new BadRequest({ title: 'bad request' });
+
+ const [readClient, readClientMocks] = useFunctionMock>([
+ { parameters: ['ddbb7edb-8c53-4586-9844-769e1c830719'], return: Promise.resolve(clientHttpError) },
+ ]);
+
+ const { result } = renderHook(() => useModelResource({ readClient }));
+
+ expect(result.current.model).toBeUndefined();
+ expect(result.current.httpError).toBeUndefined();
+
+ await act(async () => {
+ expect(await result.current.actions.readModel('ddbb7edb-8c53-4586-9844-769e1c830719')).toBe(false);
+ });
+
+ expect(result.current.model).toBeUndefined();
+ expect(result.current.httpError).toBe(clientHttpError);
+
+ expect(readClientMocks.length).toBe(0);
+ });
+
+ test('success', async () => {
+ const modelResponse: ModelResponse = {
+ id: 'ddbb7edb-8c53-4586-9844-769e1c830719',
+ createdAt: '2022-06-12T20:08:24.793Z',
+ _links: {},
+ };
+
+ const [readClient, readClientMocks] = useFunctionMock>([
+ { parameters: ['ddbb7edb-8c53-4586-9844-769e1c830719'], return: Promise.resolve(modelResponse) },
+ ]);
+
+ const { result } = renderHook(() => useModelResource({ readClient }));
+
+ expect(result.current.model).toBeUndefined();
+ expect(result.current.httpError).toBeUndefined();
+
+ await act(async () => {
+ expect(await result.current.actions.readModel('ddbb7edb-8c53-4586-9844-769e1c830719')).toBe(true);
+ });
+
+ expect(result.current.model).toBe(modelResponse);
+ expect(result.current.httpError).toBeUndefined();
+
+ expect(readClientMocks.length).toBe(0);
+ });
+ });
+
+ describe('update', () => {
+ test('missing client', async () => {
+ const { result } = renderHook(() => useModelResource({}));
+
+ try {
+ await result.current.actions.updateModel('ddbb7edb-8c53-4586-9844-769e1c830719', {});
+ throw new Error('expect failed');
+ } catch (e) {
+ expect(e).toMatchInlineSnapshot('[Error: Missing updateClient]');
+ }
+ });
+
+ test('error', async () => {
+ const clientHttpError = new BadRequest({ title: 'bad request' });
+
+ const [updateClient, updateClientMocks] = useFunctionMock>([
+ { parameters: ['ddbb7edb-8c53-4586-9844-769e1c830719', {}], return: Promise.resolve(clientHttpError) },
+ ]);
+
+ const { result } = renderHook(() => useModelResource({ updateClient }));
+
+ expect(result.current.model).toBeUndefined();
+ expect(result.current.httpError).toBeUndefined();
+
+ await act(async () => {
+ expect(await result.current.actions.updateModel('ddbb7edb-8c53-4586-9844-769e1c830719', {})).toBe(false);
+ });
+
+ expect(result.current.model).toBeUndefined();
+ expect(result.current.httpError).toBe(clientHttpError);
+
+ expect(updateClientMocks.length).toBe(0);
+ });
+
+ test('success', async () => {
+ const modelResponse: ModelResponse = {
+ id: 'ddbb7edb-8c53-4586-9844-769e1c830719',
+ createdAt: '2022-06-12T20:08:24.793Z',
+ _links: {},
+ };
+
+ const [updateClient, updateClientMocks] = useFunctionMock>([
+ { parameters: ['ddbb7edb-8c53-4586-9844-769e1c830719', {}], return: Promise.resolve(modelResponse) },
+ ]);
+
+ const { result } = renderHook(() => useModelResource({ updateClient }));
+
+ expect(result.current.model).toBeUndefined();
+ expect(result.current.httpError).toBeUndefined();
+
+ await act(async () => {
+ expect(await result.current.actions.updateModel('ddbb7edb-8c53-4586-9844-769e1c830719', {})).toBe(true);
+ });
+
+ expect(result.current.model).toBe(modelResponse);
+ expect(result.current.httpError).toBeUndefined();
+
+ expect(updateClientMocks.length).toBe(0);
+ });
+ });
+
+ describe('delete', () => {
+ test('missing client', async () => {
+ const { result } = renderHook(() => useModelResource({}));
+
+ try {
+ await result.current.actions.deleteModel('ddbb7edb-8c53-4586-9844-769e1c830719');
+ throw new Error('expect failed');
+ } catch (e) {
+ expect(e).toMatchInlineSnapshot('[Error: Missing deleteClient]');
+ }
+ });
+
+ test('error', async () => {
+ const clientHttpError = new BadRequest({ title: 'bad request' });
+
+ const [deleteClient, deleteClientMocks] = useFunctionMock([
+ { parameters: ['ddbb7edb-8c53-4586-9844-769e1c830719'], return: Promise.resolve(clientHttpError) },
+ ]);
+
+ const { result } = renderHook(() => useModelResource({ deleteClient }));
+
+ expect(result.current.model).toBeUndefined();
+ expect(result.current.httpError).toBeUndefined();
+
+ await act(async () => {
+ expect(await result.current.actions.deleteModel('ddbb7edb-8c53-4586-9844-769e1c830719')).toBe(false);
+ });
+
+ expect(result.current.model).toBeUndefined();
+ expect(result.current.httpError).toBe(clientHttpError);
+
+ expect(deleteClientMocks.length).toBe(0);
+ });
+
+ test('success', async () => {
+ const [deleteClient, deleteClientMocks] = useFunctionMock([
+ { parameters: ['ddbb7edb-8c53-4586-9844-769e1c830719'], return: Promise.resolve(undefined) },
+ ]);
+
+ const { result } = renderHook(() => useModelResource({ deleteClient }));
+
+ expect(result.current.model).toBeUndefined();
+ expect(result.current.httpError).toBeUndefined();
+
+ await act(async () => {
+ expect(await result.current.actions.deleteModel('ddbb7edb-8c53-4586-9844-769e1c830719')).toBe(true);
+ });
+
+ expect(result.current.model).toBeUndefined();
+ expect(result.current.httpError).toBeUndefined();
+
+ expect(deleteClientMocks.length).toBe(0);
+ });
+ });
+});
diff --git a/tests/hook/use-store.test.ts b/tests/hook/use-store.test.ts
new file mode 100644
index 0000000..bdef69c
--- /dev/null
+++ b/tests/hook/use-store.test.ts
@@ -0,0 +1,27 @@
+import { expect, test } from 'vitest';
+import { useStore } from '../../src/hook/use-store';
+import { renderHook, act } from '@testing-library/react';
+
+type Dummy = {
+ key1: string;
+ key2: string;
+ key3: string;
+};
+
+test('useStore', async () => {
+ const dummy: Dummy = {
+ key1: 'value1',
+ key2: 'value2',
+ key3: 'value3',
+ };
+
+ const { result } = renderHook(() => useStore(dummy));
+
+ expect(result.current[0]).toEqual(dummy);
+
+ act(() => {
+ result.current[1]('key2', 'value22');
+ });
+
+ expect(result.current[0]).toEqual({ ...dummy, key2: 'value22' });
+});
diff --git a/tests/routes.test.tsx b/tests/routes.test.tsx
new file mode 100644
index 0000000..c2f3617
--- /dev/null
+++ b/tests/routes.test.tsx
@@ -0,0 +1,133 @@
+// eslint-disable-next-line @typescript-eslint/no-unused-vars
+import React, { useEffect } from 'react';
+import { test, expect, vi } from 'vitest';
+import { formatHtml } from './formatter';
+import Routes from '../src/routes';
+import { render, screen } from '@testing-library/react';
+import { MemoryRouter } from 'react-router-dom';
+
+vi.mock('../src/component/page/home', () => {
+ return {
+ default: () => ,
+ };
+});
+
+vi.mock('../src/component/page/pet/list', () => {
+ return {
+ default: () => ,
+ };
+});
+
+vi.mock('../src/component/page/pet/create', () => {
+ return {
+ default: () => ,
+ };
+});
+
+vi.mock('../src/component/page/pet/read', () => {
+ return {
+ default: () => ,
+ };
+});
+
+vi.mock('../src/component/page/pet/update', () => {
+ return {
+ default: () => ,
+ };
+});
+
+vi.mock('../src/component/page/not-found', () => {
+ return {
+ default: () => ,
+ };
+});
+
+test('home page', async () => {
+ const { container } = render(
+
+
+ ,
+ );
+
+ await screen.findByTestId('page-home-mock');
+
+ expect(formatHtml(container.outerHTML)).toMatchInlineSnapshot(`
+ "
+ "
+ `);
+});
+
+test('not found', async () => {
+ const { container } = render(
+
+
+ ,
+ );
+
+ await screen.findByTestId('page-not-found-mock');
+
+ expect(formatHtml(container.outerHTML)).toMatchInlineSnapshot(`
+ "
+ "
+ `);
+});
+
+test('pet list', async () => {
+ const { container } = render(
+
+
+ ,
+ );
+
+ await screen.findByTestId('page-pet-list-mock');
+
+ expect(formatHtml(container.outerHTML)).toMatchInlineSnapshot(`
+ "
+ "
+ `);
+});
+
+test('pet create', async () => {
+ const { container } = render(
+
+
+ ,
+ );
+
+ await screen.findByTestId('page-pet-create-mock');
+
+ expect(formatHtml(container.outerHTML)).toMatchInlineSnapshot(`
+ "
+ "
+ `);
+});
+
+test('pet read', async () => {
+ const { container } = render(
+
+
+ ,
+ );
+
+ await screen.findByTestId('page-pet-read-mock');
+
+ expect(formatHtml(container.outerHTML)).toMatchInlineSnapshot(`
+ "
+ "
+ `);
+});
+
+test('pet update', async () => {
+ const { container } = render(
+
+
+ ,
+ );
+
+ await screen.findByTestId('page-pet-update-mock');
+
+ expect(formatHtml(container.outerHTML)).toMatchInlineSnapshot(`
+ "
+ "
+ `);
+});
diff --git a/tsconfig.json b/tsconfig.json
index ae20d8f..bbf2dd8 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,25 +1,29 @@
{
"compilerOptions": {
- "target": "ESNext",
+ "target": "ES2020",
"useDefineForClassFields": true,
- "lib": ["DOM", "DOM.Iterable", "ESNext"],
- "allowJs": false,
- "skipLibCheck": true,
- "esModuleInterop": false,
- "allowSyntheticDefaultImports": true,
- "strict": true,
- "forceConsistentCasingInFileNames": true,
"module": "ESNext",
- "moduleResolution": "Node",
+ "lib": [
+ "ES2020",
+ "DOM",
+ "DOM.Iterable"
+ ],
+ "skipLibCheck": true,
+/* Bundler mode */
+"moduleResolution": "bundler",
+"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
- "jsx": "react-jsx"
+ "jsx": "react-jsx",
+ /* Linting */
+ "strict": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "noFallthroughCasesInSwitch": true
},
"include": [
- "src",
- "tests",
- "vitest.setup.ts"
+ "src"
],
"references": [{ "path": "./tsconfig.node.json" }]
}
diff --git a/tsconfig.node.json b/tsconfig.node.json
index 9d31e2a..97ede7e 100644
--- a/tsconfig.node.json
+++ b/tsconfig.node.json
@@ -1,9 +1,11 @@
{
"compilerOptions": {
"composite": true,
+ "skipLibCheck": true,
"module": "ESNext",
- "moduleResolution": "Node",
- "allowSyntheticDefaultImports": true
+ "moduleResolution": "bundler",
+ "allowSyntheticDefaultImports": true,
+ "strict": true
},
"include": ["vite.config.ts"]
}
diff --git a/vite.config.ts b/vite.config.ts
index d051386..b8793bf 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -1,24 +1,24 @@
///
///
-// Official Vitest example: https://stackblitz.com/github/vitest-dev/vitest/tree/main/examples/react-testing-lib?file=src%2Futils%2Ftest-utils.tsx
-
-import { defineConfig } from "vitest/config";
-import react from "@vitejs/plugin-react";
+import { defineConfig } from 'vitest/config';
+import react from '@vitejs/plugin-react';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
test: {
globals: true,
- environment: "jsdom",
- setupFiles: "./vitest.setup.ts",
+ environment: 'jsdom',
+ setupFiles: './vitest.setup.ts',
include: ['tests/**/*.test.*'],
coverage: {
all: true,
clean: true,
reporter: ['text', 'html', 'lcov'],
provider: 'v8',
- }
+ include: ['src'],
+ exclude: ['src/index.tsx', 'src/vite-env.d.ts'],
+ },
},
});