diff --git a/src/app/imex/sync/is-valid-app-data.util.spec.ts b/src/app/imex/sync/is-valid-app-data.util.spec.ts index 5d6527f179..619bbb8239 100644 --- a/src/app/imex/sync/is-valid-app-data.util.spec.ts +++ b/src/app/imex/sync/is-valid-app-data.util.spec.ts @@ -3,10 +3,10 @@ import { AppDataComplete } from './sync.model'; import { EntityState } from '@ngrx/entity'; import { isValidAppData } from './is-valid-app-data.util'; import { MODEL_VERSION_KEY } from '../../app.constants'; -import { DEFAULT_TASK } from '../../features/tasks/task.model'; +import { DEFAULT_TASK, Task } from '../../features/tasks/task.model'; import { fakeEntityStateFromArray } from '../../util/fake-entity-state-from-array'; -import { DEFAULT_PROJECT } from '../../features/project/project.const'; -import { DEFAULT_TAG } from '../../features/tag/tag.const'; +import { Project } from '../../features/project/project.model'; +import { Tag } from '../../features/tag/tag.model'; const EMPTY_ENTITY_MOCK = (): EntityState => ({ ids: [], @@ -101,51 +101,76 @@ describe('isValidAppData()', () => { }); it('inconsistent task state', () => { - const prop = 'task'; expect(() => isValidAppData({ ...mock, task: { - ...mock[prop], + ...mock.task, entities: {'A asdds': DEFAULT_TASK}, ids: ['asasdasd'] }, - })).toThrowError(`Inconsistent entity state "${prop}"`); + })).toThrowError(`Inconsistent entity state "task"`); }); - xit('orphaned today entries for projects', () => { + it('missing today task data for projects', () => { expect(() => isValidAppData({ ...mock, // NOTE: it's empty task: mock.task, - project: fakeEntityStateFromArray([{ - ...DEFAULT_PROJECT, - taskIds: ['gone'] - }]) - })).toThrowError(`NOT DEFINED YET`); + project: { + ...fakeEntityStateFromArray([{ + title: 'TEST_T', + id: 'TEST_ID', + taskIds: ['gone'], + }] as Partial []), + [MODEL_VERSION_KEY]: 5 + }, + })).toThrowError(`Inconsistent Task State: Missing task id gone for Project/Tag TEST_T`); }); - xit('orphaned backlog entries for projects', () => { + it('missing backlog task data for projects', () => { expect(() => isValidAppData({ ...mock, // NOTE: it's empty task: mock.task, - project: fakeEntityStateFromArray([{ - ...DEFAULT_PROJECT, - backlogIds: ['gone'] - }]) - })).toThrowError(`NOT DEFINED YET`); + project: { + ...fakeEntityStateFromArray([{ + title: 'TEST_T', + id: 'TEST_ID', + taskIds: [], + backlogTaskIds: ['goneBL'], + }] as Partial []), + [MODEL_VERSION_KEY]: 5 + }, + })).toThrowError(`Inconsistent Task State: Missing task id goneBL for Project/Tag TEST_T`); }); - xit('orphaned today entries for tags', () => { + it('missing today task data for tags', () => { expect(() => isValidAppData({ ...mock, // NOTE: it's empty task: mock.task, - tag: fakeEntityStateFromArray([{ - ...DEFAULT_TAG, - taskIds: ['gone'] - }]) - })).toThrowError(`NOT DEFINED YET`); + tag: { + ...fakeEntityStateFromArray([{ + title: 'TEST_TAG', + id: 'TEST_ID_TAG', + taskIds: ['goneTag'], + }] as Partial []), + [MODEL_VERSION_KEY]: 5 + }, + })).toThrowError(`Inconsistent Task State: Missing task id goneTag for Project/Tag TEST_TAG`); + }); + + xit('missing tag for task', () => { + expect(() => isValidAppData({ + ...mock, + task: { + ...mock.task, + ...fakeEntityStateFromArray([{ + ...DEFAULT_TASK, + tagIds: ['Non existent'] + }]) + } as any, + })).toThrowError(`No tagX`); }); }); }); diff --git a/src/app/imex/sync/is-valid-app-data.util.ts b/src/app/imex/sync/is-valid-app-data.util.ts index 6c8e6d60e5..1cbca0838b 100644 --- a/src/app/imex/sync/is-valid-app-data.util.ts +++ b/src/app/imex/sync/is-valid-app-data.util.ts @@ -5,7 +5,6 @@ import { devError } from '../../util/dev-error'; import { Tag } from '../../features/tag/tag.model'; import { Project } from '../../features/project/project.model'; -// TODO unit test this export const isValidAppData = (d: AppDataComplete, isSkipInconsistentTaskStateError = false): boolean => { const dAny: any = d; // TODO remove this later on @@ -32,7 +31,7 @@ export const isValidAppData = (d: AppDataComplete, isSkipInconsistentTaskStateEr && typeof dAny.project === 'object' && dAny.project !== null && Array.isArray(d.reminders) && _isEntityStatesConsistent(d) - && _isTaskIdsConsistent(d, isSkipInconsistentTaskStateError) + && (isSkipInconsistentTaskStateError || _isAllTasksAvailable(d)) : typeof dAny === 'object' ; @@ -41,7 +40,7 @@ export const isValidAppData = (d: AppDataComplete, isSkipInconsistentTaskStateEr return isValid; }; -const _isTaskIdsConsistent = (data: AppDataComplete, isSkipInconsistentTaskStateError = false): boolean => { +const _isAllTasksAvailable = (data: AppDataComplete): boolean => { let allIds: string [] = []; (data.tag.ids as string[]) @@ -68,8 +67,7 @@ const _isTaskIdsConsistent = (data: AppDataComplete, isSkipInconsistentTaskState ); const notFound = allIds.find(id => !(data.task.ids.includes(id))); - - if (notFound && !isSkipInconsistentTaskStateError) { + if (notFound) { const tag = (data.tag.ids as string[]) .map(id => data.tag.entities[id]) .find(tagI => (tagI as Tag).taskIds.includes(notFound));