From 7324dc2f8e054fed0b6927c3c967822f3e5e325f Mon Sep 17 00:00:00 2001 From: mariusheine Date: Tue, 18 Jul 2023 06:00:16 +0000 Subject: [PATCH 1/3] add handling of partial patch payload --- src/useFind.ts | 12 +++++++----- src/useGet.ts | 2 +- test/useFind.test.ts | 30 ++++++++++++++++++++++++++++++ test/useGet.test.ts | 33 +++++++++++++++++++++++++++++++++ 4 files changed, 71 insertions(+), 6 deletions(-) diff --git a/src/useFind.ts b/src/useFind.ts index 0255ca7..00f2031 100644 --- a/src/useFind.ts +++ b/src/useFind.ts @@ -34,18 +34,20 @@ function loadServiceEventHandlers< }; const onItemChanged = (changedItem: M): void => { + const existingItem = data.value.find((item) => getId(item) === getId(changedItem)); + const newItem = { ...existingItem, ...changedItem }; // ignore items not matching the query or when no params are set - if (!params.value || (params.value.query !== undefined && !sift(params.value.query)(changedItem))) { + if (!params.value || (params.value.query !== undefined && !sift(params.value.query)(newItem))) { // remove item from the list if they have been on it before - data.value = data.value.filter((item) => getId(item) !== getId(changedItem)); + data.value = data.value.filter((item) => getId(item) !== getId(newItem)); return; } - const itemIndex = data.value.findIndex((item) => getId(item) === getId(changedItem)); + const itemIndex = data.value.findIndex((item) => getId(item) === getId(newItem)); if (itemIndex === -1) { - data.value = [...data.value, changedItem]; + data.value = [...data.value, newItem]; } else { - data.value = [...data.value.slice(0, itemIndex), changedItem, ...data.value.slice(itemIndex + 1)]; + data.value = [...data.value.slice(0, itemIndex), newItem, ...data.value.slice(itemIndex + 1)]; } }; diff --git a/src/useGet.ts b/src/useGet.ts index 3d5b475..a75a0dc 100644 --- a/src/useGet.ts +++ b/src/useGet.ts @@ -27,7 +27,7 @@ function loadServiceEventHandlers< const onItemChanged = (item: M): void => { if (_id.value === getId(item)) { - data.value = item; + data.value = { ...data.value, ...item }; } }; diff --git a/test/useFind.test.ts b/test/useFind.test.ts index 49c962c..891846d 100644 --- a/test/useFind.test.ts +++ b/test/useFind.test.ts @@ -13,6 +13,7 @@ const testModel: TestModel = { _id: '111', mood: '😀', action: '🧘', categor const additionalTestModel: TestModel = { _id: 'aaa', mood: '🤩', action: '🏄', category: 'sport' }; const additionalTestModel2: TestModel = { _id: 'bbb', mood: '', action: '', category: 'sport' }; const changedTestModel: TestModel = { ...testModel, mood: '😅', action: '🏋️', category: 'sport' }; +const partialChangedTestModel: Partial = { _id: '111', action: '🏋️', category: 'sport' }; const testModels: TestModel[] = [testModel, additionalTestModel2]; describe('Find composition', () => { @@ -843,6 +844,35 @@ describe('Find composition', () => { expect(findComposition && findComposition.data.value).toStrictEqual([changedTestModel]); }); + it('should handle "patch" events with partial responses properly', async () => { + expect.assertions(2); + + // given + const emitter = eventHelper(); + const feathersMock = { + service: () => ({ + find: vi.fn(() => testModels), + on: emitter.on, + off: vi.fn(), + }), + on: vi.fn(), + off: vi.fn(), + } as unknown as Application; + const useFind = useFindOriginal(feathersMock); + let findComposition = null as UseFind | null; + mountComposition(() => { + findComposition = useFind('testModels'); + }); + await nextTick(); + + // when + emitter.emit('patched', partialChangedTestModel); + + // then + expect(findComposition).toBeTruthy(); + expect(findComposition && findComposition.data.value).toContainEqual({ ...testModel, ...partialChangedTestModel }); + }); + it('should listen to "remove" events', async () => { expect.assertions(2); diff --git a/test/useGet.test.ts b/test/useGet.test.ts index a3b2efb..6844703 100644 --- a/test/useGet.test.ts +++ b/test/useGet.test.ts @@ -12,6 +12,7 @@ import TestModel from '$/__helpers__/TestModel'; const testModel: TestModel = { _id: '111', mood: '😀', action: '🧘', category: 'enjoy' }; const additionalTestModel: TestModel = { _id: 'aaa', mood: '🤩', action: '🏄', category: 'sport' }; const changedTestModel: TestModel = { ...testModel, mood: '😅', action: '🏋️', category: 'sport' }; +const partialChangedTestModel: Partial = { _id: '111', action: '🏋️', category: 'sport' }; describe('Get composition', () => { beforeEach(() => { @@ -504,6 +505,38 @@ describe('Get composition', () => { expect(getComposition && getComposition.data.value).toStrictEqual(testModel); }); + it('should handle "patch" events with partial responses properly', async () => { + expect.assertions(3); + + // given + const emitter = eventHelper(); + const feathersMock = { + service: () => ({ + get: vi.fn(() => testModel), + on: emitter.on, + off: vi.fn(), + }), + on: vi.fn(), + off: vi.fn(), + } as unknown as Application; + const useGet = useGetOriginal(feathersMock); + let getComposition = null as UseGet | null; + mountComposition(() => { + getComposition = useGet('testModels', ref(testModel._id)); + }); + + // before then to ensure previous state + await nextTick(); + expect(getComposition && getComposition.data.value).toStrictEqual(testModel); + + // when + emitter.emit('patched', partialChangedTestModel); + + // then + expect(getComposition).toBeTruthy(); + expect(getComposition && getComposition.data.value).toStrictEqual({ ...testModel, ...partialChangedTestModel }); + }); + it('should listen to "remove" events', async () => { expect.assertions(3); From 858a47c03638323eaae8240c4b985837e9f723f6 Mon Sep 17 00:00:00 2001 From: mariusheine Date: Tue, 18 Jul 2023 06:00:26 +0000 Subject: [PATCH 2/3] added gitpod config --- .gitpod.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 .gitpod.yml diff --git a/.gitpod.yml b/.gitpod.yml new file mode 100644 index 0000000..c70e78a --- /dev/null +++ b/.gitpod.yml @@ -0,0 +1,12 @@ +# This configuration file was automatically generated by Gitpod. +# Please adjust to your needs (see https://www.gitpod.io/docs/introduction/learn-gitpod/gitpod-yaml) +# and commit this file to your remote git repository to share the goodness with others. + +# Learn more from ready-to-use templates: https://www.gitpod.io/docs/introduction/getting-started/quickstart + +tasks: + - before: npm install -g pnpm@7 + init: pnpm install + command: pnpm run start + + From a308f95973bc947b106c9f0433a10d745d6948fa Mon Sep 17 00:00:00 2001 From: mariusheine Date: Tue, 18 Jul 2023 06:29:12 +0000 Subject: [PATCH 3/3] fix formatting --- .gitpod.yml | 2 -- test/useFind.test.ts | 5 ++++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.gitpod.yml b/.gitpod.yml index c70e78a..ff11682 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -8,5 +8,3 @@ tasks: - before: npm install -g pnpm@7 init: pnpm install command: pnpm run start - - diff --git a/test/useFind.test.ts b/test/useFind.test.ts index 891846d..014c244 100644 --- a/test/useFind.test.ts +++ b/test/useFind.test.ts @@ -870,7 +870,10 @@ describe('Find composition', () => { // then expect(findComposition).toBeTruthy(); - expect(findComposition && findComposition.data.value).toContainEqual({ ...testModel, ...partialChangedTestModel }); + expect(findComposition && findComposition.data.value).toContainEqual({ + ...testModel, + ...partialChangedTestModel, + }); }); it('should listen to "remove" events', async () => {