Skip to content

Commit

Permalink
Tolerate surprise Reference arguments in EntityStore#merge.
Browse files Browse the repository at this point in the history
  • Loading branch information
benjamn committed Jul 16, 2021
1 parent 97a1d74 commit 4832e87
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 1 deletion.
75 changes: 74 additions & 1 deletion src/cache/inmemory/__tests__/entityStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { DocumentNode } from 'graphql';
import { StoreObject } from '../types';
import { ApolloCache } from '../../core/cache';
import { Cache } from '../../core/types/Cache';
import { Reference, makeReference, isReference } from '../../../utilities/graphql/storeUtils';
import { Reference, makeReference, isReference, StoreValue } from '../../../utilities/graphql/storeUtils';
import { MissingFieldError } from '../..';
import { TypedDocumentNode } from '@graphql-typed-document-node/core';

Expand Down Expand Up @@ -2593,4 +2593,77 @@ describe('EntityStore', () => {
"1449373321",
]);
});

it("Refuses to merge { __ref } objects as StoreObjects", () => {
const cache = new InMemoryCache({
typePolicies: {
Query: {
fields: {
book: {
keyArgs: ["isbn"],
},
},
},

Book: {
keyFields: ["isbn"],
},
},
});

const store = cache["data"];

const query = gql`
query Book($isbn: string) {
book(isbn: $isbn) {
title
}
}
`;

const data = {
book: {
__typename: "Book",
isbn: "1449373321",
title: "Designing Data-Intensive Applications",
},
};

cache.writeQuery({
query,
data,
variables: {
isbn: data.book.isbn,
},
});

const bookId = cache.identify(data.book)!;

store.merge(
bookId,
makeReference(bookId) as StoreValue as StoreObject,
);

const snapshot = cache.extract();
expect(snapshot).toEqual({
ROOT_QUERY: {
__typename: "Query",
'book:{"isbn":"1449373321"}': {
__ref: 'Book:{"isbn":"1449373321"}',
},
},
'Book:{"isbn":"1449373321"}': {
__typename: "Book",
isbn: "1449373321",
title: "Designing Data-Intensive Applications",
},
});

store.merge(
makeReference(bookId) as StoreValue as StoreObject,
bookId,
);

expect(cache.extract()).toEqual(snapshot);
});
});
4 changes: 4 additions & 0 deletions src/cache/inmemory/entityStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ export abstract class EntityStore implements NormalizedCache {
): void {
let dataId: string | undefined;

// Convert unexpected references to ID strings.
if (isReference(older)) older = older.__ref;
if (isReference(newer)) newer = newer.__ref;

const existing: StoreObject | undefined =
typeof older === "string"
? this.lookup(dataId = older)
Expand Down

0 comments on commit 4832e87

Please sign in to comment.