Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions packages/toolkit/src/entities/sorted_state_adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,12 +160,12 @@ export function createSortedStateAdapter<T, Id extends EntityId>(
state,
)

if (updated.length) {
updateManyMutably(updated, state)
}
if (added.length) {
addManyMutably(added, state, existingIdsArray)
}
if (updated.length) {
updateManyMutably(updated, state)
}
}

function areArraysEqual(a: readonly unknown[], b: readonly unknown[]) {
Expand Down
2 changes: 1 addition & 1 deletion packages/toolkit/src/entities/unsorted_state_adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,8 @@ export function createUnsortedStateAdapter<T, Id extends EntityId>(
state,
)

updateManyMutably(updated, state)
addManyMutably(added, state)
updateManyMutably(updated, state)
}

return {
Expand Down
4 changes: 3 additions & 1 deletion packages/toolkit/src/entities/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,15 @@ export function splitAddedUpdatedEntities<T, Id extends EntityId>(
const existingIds = new Set<Id>(existingIdsArray)

const added: T[] = []
const addedIds = new Set<Id>([])
const updated: Update<T, Id>[] = []

for (const entity of newEntities) {
const id = selectIdValue(entity, selectId)
if (existingIds.has(id)) {
if (existingIds.has(id) || addedIds.has(id)) {
updated.push({ id, changes: entity })
} else {
addedIds.add(id)
added.push(entity)
}
}
Expand Down
53 changes: 53 additions & 0 deletions packages/toolkit/src/tests/createEntityAdapter.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { createAction, createEntityAdapter, type EntityId } from '@reduxjs/toolkit'

describe('createEntityAdapter', () => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tests for createEntityAdapter are in packages/toolkit/src/entities/tests

describe('CRUD operations', () => {
describe('upsertMany', () => {
type Entity = {
id: EntityId
value?: string
value2?: number
}

const entity1 = { id: 1 }
const entity2 = { id: 2 }
const update1 = { id: 1, value: 'hello' }
const update2 = { id: 1, value: 'world' }
const update3 = { id: 1, value2: 42 }
const adapter = createEntityAdapter<Entity>()
const anyAction = createAction<Entity[]>('anyAction')
const { selectAll } = adapter.getSelectors()

describe('when adding new entities', () => {
const initialState = adapter.setOne(adapter.getInitialState({}), entity1)
const upsertAction = anyAction([entity2])

it('should add a new entity to the state', () => {
expect(selectAll(adapter.upsertMany(initialState, upsertAction))).toEqual([entity1, entity2])
})
})

describe('when updating existing entities', () => {
const initialState = adapter.setOne(adapter.getInitialState({}), entity1)
const upsertAction = anyAction([update1, update2, update3])

it('should update existing entity with multiple updates', () => {
expect(selectAll(adapter.upsertMany(initialState, upsertAction))).toEqual([
Object.assign({}, entity1, update1, update2, update3),
])
})
})

describe('when applying updates to non-existing entities', () => {
const initialState = adapter.getInitialState({})
const upsertAction = anyAction([update1, update2, update3])

it('should add the new entity and apply related updates', () => {
expect(selectAll(adapter.upsertMany(initialState, upsertAction))).toEqual([
Object.assign({}, update1, update2, update3),
])
})
})
})
})
})