diff --git a/frontend/src/components/form/api/ApiColorField.vue b/frontend/src/components/form/api/ApiColorField.vue new file mode 100644 index 0000000000..99adae9d08 --- /dev/null +++ b/frontend/src/components/form/api/ApiColorField.vue @@ -0,0 +1,44 @@ + + + + + + + diff --git a/frontend/src/components/form/api/__tests__/ApiColorField.spec.js b/frontend/src/components/form/api/__tests__/ApiColorField.spec.js new file mode 100644 index 0000000000..e95f15325b --- /dev/null +++ b/frontend/src/components/form/api/__tests__/ApiColorField.spec.js @@ -0,0 +1,92 @@ +import ApiColorField from '../ApiColorField.vue' +import { fireEvent, screen, waitFor } from '@testing-library/vue' +import { render } from '@/test/renderWithVuetify.js' +import user from '@testing-library/user-event' +import { ApiMock } from '@/components/form/api/__tests__/ApiMock' +import { extend } from 'vee-validate' +import { regex } from 'vee-validate/dist/rules' +import { ColorSpace, sRGB } from 'colorjs.io/fn' + +extend('regex', regex) + +ColorSpace.register(sRGB) +describe('An ApiColorField', () => { + let apiMock + + const FIELD_PATH = 'test-field/123' + const FIELD_LABEL = 'Test field' + const COLOR_1 = '#FF0000' + const COLOR_2 = '#FAFFAF' + + beforeEach(() => { + apiMock = ApiMock.create() + }) + + afterEach(() => { + jest.restoreAllMocks() + }) + + test('triggers api.patch and status update if input changes', async () => { + // given + apiMock.get().thenReturn(ApiMock.success(COLOR_1).forPath(FIELD_PATH)) + apiMock.patch().thenReturn(ApiMock.success(COLOR_2)) + render(ApiColorField, { + props: { + autoSave: false, + path: FIELD_PATH, + uri: 'test-field/123', + label: FIELD_LABEL, + required: true, + }, + mocks: { + api: apiMock.getMocks(), + }, + }) + + // when + const inputField = await screen.findByLabelText(FIELD_LABEL) + inputField.value = COLOR_2 + await fireEvent.input(inputField) + // click the button to open the picker + // click the save button + await waitFor(async () => { + await user.click(screen.getByLabelText('Speichern')) + }) + + // then + await waitFor(async () => { + const inputField = await screen.findByLabelText(FIELD_LABEL) + expect(inputField.value).toBe(COLOR_2) + expect(apiMock.getMocks().patch).toBeCalledTimes(1) + }) + }) + + test('updates state if value in store is refreshed and has new value', async () => { + // given + apiMock.get().thenReturn(ApiMock.networkError().forPath(FIELD_PATH)) + render(ApiColorField, { + props: { + autoSave: false, + path: FIELD_PATH, + uri: 'test-field/123', + label: FIELD_LABEL, + required: true, + }, + mocks: { + api: apiMock.getMocks(), + }, + }) + await screen.findByText('A network error occurred.') + expect((await screen.findByLabelText(FIELD_LABEL)).value).not.toBe(COLOR_1) + const retryButton = await screen.findByText('Erneut versuchen') + apiMock.get().thenReturn(ApiMock.success(COLOR_1).forPath(FIELD_PATH)) + + // when + await user.click(retryButton) + + // then + await waitFor(async () => { + expect((await screen.findByLabelText(FIELD_LABEL)).value).toBe(COLOR_1) + }) + }) +}) diff --git a/frontend/src/components/form/api/__tests__/ApiColorPicker.spec.js b/frontend/src/components/form/api/__tests__/ApiColorPicker.spec.js index 77e958f948..52d430a272 100644 --- a/frontend/src/components/form/api/__tests__/ApiColorPicker.spec.js +++ b/frontend/src/components/form/api/__tests__/ApiColorPicker.spec.js @@ -5,9 +5,11 @@ import user from '@testing-library/user-event' import { ApiMock } from '@/components/form/api/__tests__/ApiMock' import { extend } from 'vee-validate' import { regex } from 'vee-validate/dist/rules' +import { ColorSpace, sRGB } from 'colorjs.io/fn' extend('regex', regex) +ColorSpace.register(sRGB) describe('An ApiColorPicker', () => { let apiMock @@ -49,12 +51,16 @@ describe('An ApiColorPicker', () => { const canvas = container.querySelector('canvas') await user.click(canvas, { clientX: 10, clientY: 10 }) // click the save button - await user.click(screen.getByLabelText('Speichern')) + await waitFor(async () => { + await user.click(screen.getByLabelText('Speichern')) + }) // then - const inputField = await screen.findByLabelText(FIELD_LABEL) - expect(inputField.value).toBe(COLOR_2) - expect(apiMock.getMocks().patch).toBeCalledTimes(1) + await waitFor(async () => { + const inputField = await screen.findByLabelText(FIELD_LABEL) + expect(inputField.value).toBe(COLOR_2) + expect(apiMock.getMocks().patch).toBeCalledTimes(1) + }) }) test('updates state if value in store is refreshed and has new value', async () => { diff --git a/frontend/src/components/form/base/ColorPicker/ColorSwatch.vue b/frontend/src/components/form/base/ColorPicker/ColorSwatch.vue index 7e53e4adb8..6959e6245d 100644 --- a/frontend/src/components/form/base/ColorPicker/ColorSwatch.vue +++ b/frontend/src/components/form/base/ColorPicker/ColorSwatch.vue @@ -1,12 +1,14 @@