apollographql / apollo-ios

📱  A strongly-typed, caching GraphQL client for iOS, written in Swift.
https://www.apollographql.com/docs/ios/
MIT License
3.89k stars 728 forks source link

Directives (`@include`, `@skip` etc) not working with Mocks #3449

Closed asaadreh-meister closed 1 month ago

asaadreh-meister commented 1 month ago

Summary

I use several includes and skips in my queries. They are working fine in the app. However, while writing tests for the code, I noticed that any field or fragment marked with include is always omitted. I tested it with skip and it was the same. If i leave out the include, the correct object is returned.

Is this issue known? Is there a workaround? (without having to remove the directives)

Version

1.15.1

Steps to reproduce the behavior

My query looks like this:

query GetTaskQuery(
    $taskId: Int!,
    $token : String!,
    $loadWithId : Boolean = false,
    $loadWithToken : Boolean = false
) {
    find_task(id: $taskId) @include(if: $loadWithId) {
        ...TaskItemView
    }

    find_task_by_token(token: $token) @include(if: $loadWithToken) {
        ...TaskItemView
    }
}

A very basic test is:

class TestIncludeQuery: _SyncEngineOperationTestCase {
    func testIncludeQuery() async throws {

        let client = MockGraphQLClient(query: givenQueryMock())
        let res = try await client.fetch(
            query: MTApolloClient.GetTaskQuery(
                taskId: 1,
                token: "abc",
                loadWithId: true,
                loadWithToken: false,
                attachmentCursor: nil,
                checklistsCursor: nil,
                customFieldsCursor: nil,
                targetRelationshipsCursor: nil,
                ownerRelationshipsCursor: nil,
                taskLabelsCursor: nil,
                taskSubscriptionCursor: nil,
                workIntervalsCursor: nil,
                customFieldTypesCursor: nil,
                projectRightsCursor: nil,
                activeSectionsCursor: nil
            ),
            cachePolicy: .fetchIgnoringCacheCompletely,
            contextIdentifier: nil
        )
        XCTAssertEqual(res.findTask?.id, 1)
    }

    private func givenQueryMock() -> Mock<MeisterTaskQuery> {
        Mock<MeisterTaskQuery>(
            find_task: Mock<Task>(
                id: 1,
                name: "Mock Task",
                token: "abc"
            ),
            find_task_by_token: Mock<Task>(
                id: 1,
                name: "Mock Task",
                token: "abc"
            )
        )
    }
}

Any field or fragment that has include in it is returned as nil in the mocks. In the actual app it works fine.

Logs

No response

Anything else?

No response

BobaFetters commented 1 month ago

@asaadreh-meister To get the variables properly mapped onto your selection set you should be able to use the from(_ mock: withVariables:) method on your selection set and pass in the variables being used for your include/skip conditions.

A very basic usage of this is shown in this test.

BobaFetters commented 1 month ago

Going to go ahead and close this since the above comment should resolve the issue, feel free to comment if this is still an issue and we can reopen and investigate.

github-actions[bot] commented 1 month ago

Do you have any feedback for the maintainers? Please tell us by taking a one-minute survey. Your responses will help us understand Apollo iOS usage and allow us to serve you better.