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

MockPayloadGenerator: __typename mocking depends on generated request ordering #3744

Open
Tracked by #3749
tomgasson opened this issue Jan 12, 2022 · 2 comments
Open
Tracked by #3749
Labels
bug rust Related to the compiler written in Rust

Comments

@tomgasson
Copy link
Contributor

tomgasson commented Jan 12, 2022

We have a regression between v12 and v13 in example queries using MockPayloadGenerator.

This is caused by a bug in MockPayloadGenerator, but appears as a regression when upgrading.

It has to do with the feature where the __typename is correctly provided in the mock payload if you don't provide a __typename value in the mock data.

Assume we have these 2 selections generated by the compiler(s):

const generalSelection = {
  kind: 'InlineFragment',
  selections: [
    {
      kind: 'ScalarField',
      name: 'id',
    },
  ],
  type: 'TypeB',
};

const typenameSelection = {
  kind: 'ScalarField',
  name: '__typename',
};

For a query that looks like this

query testQuery {
    a {
        b {
            ... on TypeB {
                id
            }
            __typename
        }
    }
}

These 2 selections are going to be in a request under a linked field

const dummyOperationDescriptor = (items) => ({
    request: {
      node: { // <-- the generated ConcreteRequest
        operation: {
          name: 'testQuery',
          selections: [
            {
              concreteType: 'TypeA',
              kind: 'LinkedField',
              name: 'a',
              selections: [
                {
                  concreteType: null,
                  kind: 'LinkedField',
                  name: 'b',
                  plural: false,
                  selections: items, // <-- here's the order-dependent list
                },
              ],
            },
          ],
        },
        params: {
          metadata: {},
        },
      },
      variables: {},
      cacheConfig: {},
    },
  });

The JS compiler always output the __typename field first in this list of selections

const working = RelayMockPayloadGenerator.generate(dummyOperationDescriptor([
  typenameSelection,
  generalSelection
 ]));

Which leads to this (correct) output

{
    "data": {
        "a": {
            "b": {
                "__typename": "TypeB",
                "id": "<TypeB-mock-id-1>"
            }
        }
    }
}

The rust compiler changed the output ordering of fields, and __typename is no longer first.

const failing = RelayMockPayloadGenerator.generate(dummyOperationDescriptor([
  generalSelection,
  typenameSelection
]));

Now this gives us incorrect output

{
    "data": {
        "a": {
            "b": {
                "__typename": "__MockObject",
                "id": "<TypeB-mock-id-1>"
            }
        }
    }
}

This means that queries that we're previously mocked fine no longer work

@alunyov
Copy link
Contributor

alunyov commented Jan 12, 2022

Oh, interesting. I wonder how we didn't got this internally.

I'm not sure what is the right fix could be here... Can you try adding a __typename field explicitly to your queries?

@alunyov alunyov added bug rust Related to the compiler written in Rust labels Jan 12, 2022
@tomgasson
Copy link
Contributor Author

Yeah there's a few workarounds here, that all work:

  • Manually provide the __typename in the mock
  • Make sure the inline fragment also selects __typename
  • Re-order the fragment to put __typename above everything else

Mostly just reporting for visibility in case someone else hits this too. A simple fix to MockPayloadGenerator might just sort the selections to shift a __typename up to the top before generating?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug rust Related to the compiler written in Rust
Projects
None yet
Development

No branches or pull requests

2 participants