Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incoming data partially not normalized when matching a fuzzy possibleType and selected on a fragment when nullable field is null #11521

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Changes from all 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
165 changes: 164 additions & 1 deletion src/cache/inmemory/__tests__/policies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -661,7 +661,7 @@ describe("type policies", function () {
).toBe('DeathAdder:{"tagId":"LethalAbacus666"}');
});

it("typePolicies can be inherited from supertypes with fuzzy possibleTypes", () => {
it.only("typePolicies can be inherited from supertypes with fuzzy possibleTypes", () => {
const cache = new InMemoryCache({
possibleTypes: {
EntitySupertype: [".*Entity"],
Expand Down Expand Up @@ -837,6 +837,169 @@ describe("type policies", function () {
});
});

it.only("typePolicies can be inherited from supertypes with fuzzy possibleTypes, with null returned for a nullable field on a fragment", () => {
const cache = new InMemoryCache({
possibleTypes: {
EntitySupertype: [".*Entity"],
},
typePolicies: {
Query: {
fields: {
coworkers: {
merge(existing, incoming) {
return existing ? existing.concat(incoming) : incoming;
},
},
},
},

// The point of this test is to ensure keyFields: ["uid"] can be
// registered for all __typename strings matching the RegExp /.*Entity/,
// without manually enumerating all of them.
EntitySupertype: {
keyFields: ["uid"],
},
},
});

type WorkerEntity = {
uid: string;
name: string;
};

type Coworker = CoworkerEntity | ManagerEntity;

type CoworkerEntity = {
__typename: "CoworkerEntity";
foo: {
bar: string;
} | null;
} & WorkerEntity;

type ManagerEntity = {
__typename: "ManagerEntity";
foo: {
bar: string;
} | null;
} & WorkerEntity;

const query: TypedDocumentNode<{
coworkers: Coworker[];
}> = gql`
query {
coworkers {
uid
name
...ManagerFields
...CoworkerFields
# comment out fragment spreads and uncomment the following 3 lines
# to see the test passing
# foo {
# bar
# }
}
}
fragment ManagerFields on ManagerEntity {
foo {
bar
}
}
fragment CoworkerFields on CoworkerEntity {
foo {
bar
}
}
`;

// whether a `ManagerEntity` or `CoworkerEntity` appears first
// in coworkers array changes the result of the test
cache.writeQuery({
query,
data: {
coworkers: [
{
__typename: "CoworkerEntity",
uid: "qwer",
name: "Alessia",
foo: null,
},
{
__typename: "CoworkerEntity",
uid: "asdf",
name: "Jerel",
foo: null,
},
{
__typename: "CoworkerEntity",
uid: "zxcv",
name: "Lenz",
foo: null,
},
{
__typename: "ManagerEntity",
uid: "uiop",
name: "Jeff",
foo: null,
},
],
},
});

// this assertion passes
expect(cache.readQuery({ query })).toEqual({
coworkers: [
{
__typename: "CoworkerEntity",
uid: "qwer",
name: "Alessia",
foo: null,
},
{ __typename: "CoworkerEntity", uid: "asdf", name: "Jerel", foo: null },
{ __typename: "CoworkerEntity", uid: "zxcv", name: "Lenz", foo: null },
{ __typename: "ManagerEntity", uid: "uiop", name: "Jeff", foo: null },
],
});

// this assertion fails: the ManagerEntity can no longer be normalized:
// the data appears inside of the coworkers array but the normalized object
// and reference are missing
expect(cache.extract()).toEqual({
ROOT_QUERY: {
__typename: "Query",
coworkers: [
{ __ref: 'CoworkerEntity:{"uid":"qwer"}' },
{ __ref: 'CoworkerEntity:{"uid":"asdf"}' },
{ __ref: 'CoworkerEntity:{"uid":"zxcv"}' },
{ __ref: 'ManagerEntity:{"uid":"uiop"}' },
],
},
'CoworkerEntity:{"uid":"qwer"}': {
__typename: "CoworkerEntity",
uid: "qwer",
name: "Alessia",
foo: null,
},
'CoworkerEntity:{"uid":"asdf"}': {
__typename: "CoworkerEntity",
uid: "asdf",
name: "Jerel",
foo: null,
},
'CoworkerEntity:{"uid":"zxcv"}': {
__typename: "CoworkerEntity",
uid: "zxcv",
name: "Lenz",
foo: null,
},
'ManagerEntity:{"uid":"uiop"}': {
__typename: "ManagerEntity",
uid: "uiop",
name: "Jeff",
foo: null,
},
});
});

describe("field policies", function () {
it(`can filter arguments using keyArgs`, function () {
const cache = new InMemoryCache({
Expand Down
Loading