func testOwnerCreatedDataCanBeReadByOtherUsersForReadableModel()

in AmplifyPlugins/DataStore/AWSDataStoreCategoryPluginAuthIntegrationTests/DefaultAuthCognito/AWSDataStoreCategoryPluginAuthIntegrationTests.swift [92:205]


    func testOwnerCreatedDataCanBeReadByOtherUsersForReadableModel() throws {
        setup(withModels: ModelsRegistration(), testType: .defaultAuthCognito)

        signIn(user: user1)

        let id = UUID().uuidString
        let localTodo = TodoExplicitOwnerField(id: id, content: "owner created content", owner: nil)
        let localTodoSaveInvoked = expectation(description: "local note was saved")

        let syncReceivedInvoked = expectation(description: "received SyncReceived event")
        var remoteTodoOptional: TodoExplicitOwnerField?
        let syncReceivedListener = Amplify.Hub.listen(to: .dataStore, eventName: syncReceived) { payload in
            guard let mutationEvent = payload.data as? MutationEvent,
                let todo = try? mutationEvent.decodeModel() as? TodoExplicitOwnerField else {
                    XCTFail("Can't cast payload as mutation event")
                    return
            }
            if todo.id == localTodo.id, remoteTodoOptional == nil {
                remoteTodoOptional = todo
                syncReceivedInvoked.fulfill()
            }
        }
        guard try HubListenerTestUtilities.waitForListener(with: syncReceivedListener, timeout: 5.0) else {
            XCTFail("syncReceivedListener registered for hub")
            return
        }

        Amplify.DataStore.save(localTodo) { result in
            switch result {
            case .success(let note):
                localTodoSaveInvoked.fulfill()
            case .failure(let error):
                XCTFail("Failed to save note \(error)")
            }
        }
        wait(for: [localTodoSaveInvoked], timeout: TestCommonConstants.networkTimeout)
        wait(for: [syncReceivedInvoked], timeout: TestCommonConstants.networkTimeout)
        guard let remoteTodo = remoteTodoOptional else {
            XCTFail("Should have received a SyncReceived event with the remote note reconciled to local store")
            return
        }
        guard let owner = remoteTodo.owner else {
            XCTFail("Could not retrieve owner value from remote note")
            return
        }

        signOut()

        let clearCompletedInvoked = expectation(description: "clear completed")
        Amplify.DataStore.clear { result in
            switch result {
            case .success:
                clearCompletedInvoked.fulfill()
            case .failure(let error):
                XCTFail("Failed to clear \(error)")
            }
        }

        wait(for: [clearCompletedInvoked], timeout: TestCommonConstants.networkTimeout)

        let modelSyncedInvoked = expectation(description: "Model fully synced")
        Amplify
            .Hub
            .publisher(for: .dataStore)
            .filter { $0.eventName == HubPayload.EventName.DataStore.ready }
            .sink { _ in
                modelSyncedInvoked.fulfill()
            }.store(in: &requests)

        let localNoteOptional = queryModel(TodoExplicitOwnerField.self, byId: id)
        XCTAssertNil(localNoteOptional)

        let syncStartedInvoked2 = expectation(description: "Sync started after other sign in")
        let syncStartedListener2 = Amplify.Hub.listen(to: .dataStore, eventName: syncStarted) { _ in
            syncStartedInvoked2.fulfill()
        }
        guard try HubListenerTestUtilities.waitForListener(with: syncStartedListener2, timeout: 5.0) else {
            XCTFail("syncStartedListener2 not registered")
            return
        }

        let syncReceivedInvoked2 = expectation(description: "received SyncReceived event for owner")
        var remoteNoteOptional2: TodoExplicitOwnerField?
        let syncReceivedListener2 = Amplify.Hub.listen(to: .dataStore, eventName: syncReceived) { payload in
            guard let mutationEvent = payload.data as? MutationEvent,
                let note = try? mutationEvent.decodeModel() as? TodoExplicitOwnerField else {
                    XCTFail("Can't cast payload as mutation event")
                    return
            }
            if note.id == localTodo.id {
                remoteNoteOptional2 = note
                syncReceivedInvoked2.fulfill()
            }
        }
        guard try HubListenerTestUtilities.waitForListener(with: syncReceivedListener2, timeout: 5.0) else {
            XCTFail("syncReceivedListener2 registered for hub")
            return
        }
        signIn(user: user2)
        guard let currentUser = Amplify.Auth.getCurrentUser() else {
            XCTFail("Could not retrieve current user")
            return
        }
        XCTAssertNotEqual(currentUser.username, owner)
        wait(for: [syncStartedInvoked2], timeout: TestCommonConstants.networkTimeout)
        wait(for: [syncReceivedInvoked2], timeout: TestCommonConstants.networkTimeout)
        guard let ownerRemoteNote = remoteNoteOptional2, let remoteNoteOwner = ownerRemoteNote.owner else {
            XCTFail("Should have received a SyncReceived event with the remote note reconciled to local store")
            return
        }

        XCTAssertEqual(owner, remoteNoteOwner)
        wait(for: [modelSyncedInvoked], timeout: TestCommonConstants.networkTimeout)
    }