State not updating after dispatching createBlockSession async thunk

37 Views Asked by At

Title: Redux Toolkit - State not updating after dispatching createBlockSession async thunk

I'm working on a Redux Toolkit project where I have an async thunk createBlockSession that is supposed to update the state with a new block session. However, the state is not being updated as expected.

Here's the relevant code:

block-session.slice.ts:

import { createSlice } from '@reduxjs/toolkit'
import { createBlockSession } from './usecases/create-block-session.usecase.ts'
import { BlockSession } from './block.session.ts'

type BlockSessionState = {
  blockSessions: BlockSession[]
}
export const blockSessionSlice = createSlice({
  name: 'blockSession',
  initialState: { blockSessions: [] } as BlockSessionState,
  reducers: {},
  extraReducers(builder) {
    builder.addCase(createBlockSession.fulfilled, (state, action) => {
      console.log(action.payload)
      state.blockSessions.push(action.payload)
    })
  },
})

create-block-session.usecase.ts:

import { createAppAsyncThunk } from '../../create-app-thunk.ts'
import { BlockSession } from '../block.session.ts'

export const createBlockSession = createAppAsyncThunk(
  'blockSession/createBlockSession',
  async (payload: BlockSession, { extra: { blockSessionRepository } }) => {
    return blockSessionRepository.createSession(payload)
  },
)

create-block-session.usecase.spec.ts:

describe('Feature: Creating a block session', () => {
  let fixture: ReturnType<typeof createBlockSessionFixture>

  beforeEach(() => {
    fixture = createBlockSessionFixture()
  })

  it('should create a block session', () => {
    const blockSessionPayload: BlockSession = {
      id: 'block-session-id',
      name: 'block-session-name',
      blocklists: [
        { id: 'blocklist-id', name: 'Distraction', totalBlocks: 10 },
      ],
      devices: [
        {
          id: 'device-id',
          type: 'ios',
          name: 'Huawei P30',
        },
      ],
      start: '2021-01-01T00:00:00Z',
      end: '2021-01-01T00:00:00Z',
    }

    fixture.when.creatingBlockSession(blockSessionPayload)

    fixture.then.blockSessionsShouldBe([
      {
        id: 'block-session-id',
        name: 'block-session-name',
        blocklists: [
          { id: 'blocklist-id', name: 'blocklist-name', totalBlocks: 10 },
        ],
        devices: [
          {
            id: 'device-id',
            type: 'ios',
            name: 'Huawei P30',
          },
        ],
        start: '2021-01-01T00:00:00Z',
        end: '2021-01-01T00:00:00Z',
      },
    ])
  })
})

create-block-session.fixture.ts:

export function createBlockSessionFixture() {
  const store: AppStore = createStore({
    blockSessionRepository: new FakeDataBlockSessionRepository(),
  })

  return {
    when: {
      creatingBlockSession: async (payload: BlockSession) => {
        await store.dispatch(createBlockSession(payload))
      },
    },
    then: {
      blockSessionsShouldBe: (expectedBlockSessions: BlockSession[]) => {
        const retrievedBlockSessions =
          store.getState().blockSession.blockSessions
        expect(retrievedBlockSessions).toStrictEqual(expectedBlockSessions)
      },
    },
  }
}

Here is the error message of the failing test:

{
  id: 'block-session-id',
  name: 'block-session-name',
  blocklists: [ { id: 'blocklist-id', name: 'Distraction', totalBlocks: 10 } ],
  devices: [ { id: 'device-id', type: 'ios', name: 'Huawei P30' } ],
  start: '2021-01-01T00:00:00Z',
  end: '2021-01-01T00:00:00Z'
}

AssertionError: expected [] to strictly equal [ { id: 'block-session-id', …(5) } ]
<Click to see difference>

    at Object.blockSessionsShouldBe (/Users/arthurmehmetoglu/Development/TiedSiren/src/core/block-session/usecases/create-block-session.fixture.ts:22:40)
    at /Users/arthurmehmetoglu/Development/TiedSiren/src/core/block-session/usecases/create-block-session.usecase.spec.ts:32:18
    at file:///Users/arthurmehmetoglu/Development/TiedSiren/node_modules/@vitest/runner/dist/index.js:128:14
    at file:///Users/arthurmehmetoglu/Development/TiedSiren/node_modules/@vitest/runner/dist/index.js:59:26
    at runTest (file:///Users/arthurmehmetoglu/Development/TiedSiren/node_modules/@vitest/runner/dist/index.js:675:17)
    at runSuite (file:///Users/arthurmehmetoglu/Development/TiedSiren/node_modules/@vitest/runner/dist/index.js:793:15)
    at runSuite (file:///Users/arthurmehmetoglu/Development/TiedSiren/node_modules/@vitest/runner/dist/index.js:793:15)
    at runFiles (file:///Users/arthurmehmetoglu/Development/TiedSiren/node_modules/@vitest/runner/dist/index.js:842:5)
    at startTests (file:///Users/arthurmehmetoglu/Development/TiedSiren/node_modules/@vitest/runner/dist/index.js:851:3)
    at file:///Users/arthurmehmetoglu/Development/TiedSiren/node_modules/vitest/dist/chunks/runtime-runBaseTests.QReNMrJA.js:114:7

I've checked the following:

  1. The createBlockSession async thunk is being dispatched correctly.
  2. The payload of the createBlockSession.fulfilled action is as expected.
  3. The blockSessions array in the state is being mutated correctly.
  4. The blockSessions array in the state is being accessed correctly when it's being retrieved.

Despite all these checks, the state is not being updated as expected. Any ideas on what could be going wrong?

The Github repository can be accessed here : https://github.com/amehmeto/TiedSiren

1

There are 1 best solutions below

0
A Mehmeto On

Ok I found my issue. I need to make my testFixture async so that the state could take effect: await fixture.when.creatingBlockSession(blockSessionPayload)