Skip to content

Commit

Permalink
add addRecords and add test on data GET_MANY_REFERENCE and GET_MANY a…
Browse files Browse the repository at this point in the history
…ction
  • Loading branch information
ThieryMichel committed Jan 7, 2020
1 parent d4ed9cd commit 3727948
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 5 deletions.
58 changes: 57 additions & 1 deletion packages/ra-core/src/reducer/admin/resource/data.spec.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
import assert from 'assert';

import { DELETE, DELETE_MANY, UPDATE } from '../../../core';
import {
DELETE,
DELETE_MANY,
UPDATE,
GET_MANY,
GET_MANY_REFERENCE,
} from '../../../core';
import getFetchedAt from '../../../util/getFetchedAt';
import dataReducer, { replaceRecords, addOneRecord } from './data';
import { FETCH_END } from '../../../actions';

jest.mock('../../../util/getFetchedAt');

Expand Down Expand Up @@ -253,4 +260,53 @@ describe('Resources data reducer', () => {
assert.notDeepEqual(newState.fetchedAt.record2, before);
});
});

describe.each([GET_MANY_REFERENCE, GET_MANY])('%s', actionType => {
it('should add new records to the old one', () => {
const before = new Date(0);
const now = new Date();

// @ts-ignore
getFetchedAt.mockImplementationOnce(() => ({
new_record: now,
record2: now,
}));

const state = {
record1: { id: 'record1', prop: 'value' },
record2: { id: 'record2', prop: 'value' },
record3: { id: 'record3', prop: 'value' },
fetchedAt: {
record1: before,
record2: before,
record3: before,
},
};

const newState = dataReducer(state, {
type: actionType,
payload: {
data: [
{ id: 'record2', prop: 'updated value' },
{ id: 'new_record', prop: 'new value' },
],
},
meta: {
fetchResponse: actionType,
fetchStatus: FETCH_END,
},
});
assert.deepEqual(newState, {
record1: { id: 'record1', prop: 'value' },
record2: { id: 'record2', prop: 'updated value' },
record3: { id: 'record3', prop: 'value' },
new_record: { id: 'new_record', prop: 'new value' },
});
assert.deepEqual(newState.fetchedAt.record1, before);
assert.deepEqual(newState.fetchedAt.record3, before);

assert.notDeepEqual(newState.fetchedAt.record2, before);
assert.notDeepEqual(newState.fetchedAt.new_record, before);
});
});
});
33 changes: 29 additions & 4 deletions packages/ra-core/src/reducer/admin/resource/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,34 @@ export const replaceRecords = (

return hideFetchedAt(records);
};

/**
* Add new records to the pool, without touching the other ones.
*/
export const addRecords = (
newRecords: Record[] = [],
oldRecords: RecordSetWithDate
): RecordSetWithDate => {
const newRecordsById = { ...oldRecords };
newRecords.forEach(record => {
newRecordsById[record.id] = isEqual(record, oldRecords[record.id])
? (oldRecords[record.id] as Record)
: record;
});

const updatedFetchedAt = getFetchedAt(
newRecords.map(({ id }) => id),
oldRecords.fetchedAt
);

Object.defineProperty(newRecordsById, 'fetchedAt', {
value: { ...oldRecords.fetchedAt, ...updatedFetchedAt },
enumerable: false,
});

return newRecordsById;
};

export const addOneRecord = (
newRecord: Record,
oldRecords: RecordSetWithDate,
Expand Down Expand Up @@ -160,10 +188,7 @@ const dataReducer: Reducer<RecordSetWithDate> = (
return replaceRecords(payload.data, previousState);
case GET_MANY:
case GET_MANY_REFERENCE:
return replaceRecords(
Object.values(previousState).concat(payload.data) as Record[],
previousState
);
return addRecords(payload.data, previousState);
case UPDATE:
case CREATE:
case GET_ONE:
Expand Down

0 comments on commit 3727948

Please sign in to comment.