diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index f048fd8..172da2f 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -19,7 +19,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v4 with: - node-version: '18' + node-version-file: '.nvmrc' cache: 'yarn' - name: Install dependencies diff --git a/.github/workflows/type-check.yml b/.github/workflows/type-check.yml index 8dbde80..3f3816a 100644 --- a/.github/workflows/type-check.yml +++ b/.github/workflows/type-check.yml @@ -19,7 +19,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v4 with: - node-version: '18' + node-version-file: '.nvmrc' cache: 'yarn' - name: Install dependencies diff --git a/src/store/actions.test.ts b/src/store/actions.test.ts index 1a06c69..17601b9 100644 --- a/src/store/actions.test.ts +++ b/src/store/actions.test.ts @@ -320,7 +320,7 @@ describe('store actions', () => { type: ActionType.UPLOADING_WCIF, uploading: true, }); - expect(patchWcifMock).toHaveBeenCalledWith('Comp1', { events: wcif.events }); + expect(patchWcifMock).toHaveBeenCalledWith('Comp1', { events: wcif.events, formatVersion: wcif.formatVersion }); expect(dispatch.mock.calls[1][0]).toEqual({ type: ActionType.UPLOADING_WCIF, uploading: false, diff --git a/src/store/reducers/_tests_/roundActivities.test.ts b/src/store/reducers/_tests_/roundActivities.test.ts index 5249327..564aa7f 100644 --- a/src/store/reducers/_tests_/roundActivities.test.ts +++ b/src/store/reducers/_tests_/roundActivities.test.ts @@ -23,7 +23,23 @@ describe('roundActivities reducers', () => { expect(nextState.needToSave).toBe(true); expect(nextState.changedKeys.has('schedule')).toBe(true); expect(nextActivities[0]).toBe(activityOne); - expect(nextActivities[1]).toBe(updatedActivityTwo); + // The updated activity is returned as a new object (extraneous props are stripped), so use toEqual + expect(nextActivities[1]).not.toBe(updatedActivityTwo); + expect(nextActivities[1]).toEqual(updatedActivityTwo); + }); + + it('updateRoundActivities strips extraneous properties (e.g. room) from stored activities', () => { + const activityOne = buildActivity({ id: 1, name: 'Round 1', activityCode: '333-r1' }); + const room = { id: 10, name: 'Room A', color: '#000', extensions: [], activities: [activityOne] }; + // Simulate ActivityWithRoom: an activity with an extra `room` reference attached internally + const activityWithRoom = { ...activityOne, name: 'Round 1 Updated', room }; + const state = buildState(buildWcif([activityOne])); + + const nextState = updateRoundActivities(state, { activities: [activityWithRoom] }); + + const nextActivity = nextState.wcif?.schedule.venues[0].rooms[0].activities[0]; + expect(nextActivity).not.toHaveProperty('room'); + expect(nextActivity).toEqual(expect.objectContaining({ id: 1, name: 'Round 1 Updated' })); }); it('updateRoundChildActivities updates child activities and keeps other assignments intact', () => { diff --git a/src/store/reducers/roundActivities.ts b/src/store/reducers/roundActivities.ts index 3fc011d..b3eb363 100644 --- a/src/store/reducers/roundActivities.ts +++ b/src/store/reducers/roundActivities.ts @@ -1,7 +1,7 @@ import { mapIn } from '../../lib/utils'; import type { UpdateRoundActivitiesPayload, UpdateRoundChildActivitiesPayload } from '../actions'; import type { AppState } from '../initialState'; -import type { Assignment, Person } from '@wca/helpers'; +import type { Activity, Assignment, Person } from '@wca/helpers'; /** * Updates the child activities of a round activity and also updates the assignments of the persons accordingly @@ -83,7 +83,13 @@ export const updateRoundActivities = ( ...room, activities: room.activities.map((activity) => { const updatedActivity = action.activities.find((a) => a.id === activity.id); - return updatedActivity || activity; + if (!updatedActivity) return activity; + // Strip extraneous properties (e.g. `room`) that may be present from internal use + // but are not valid WCIF schema properties + const { room: _room, ...wcifActivity } = updatedActivity as Activity & { + room?: unknown; + }; + return wcifActivity as Activity; }), })), })),