From acaa1467c0a29968ae82816fb6901c479c523d15 Mon Sep 17 00:00:00 2001 From: Shadaj Laddad Date: Thu, 13 Jul 2017 12:22:24 -0700 Subject: [PATCH] Cleanup and add unit test for new flag --- src/ApolloClient.ts | 8 +++--- src/core/QueryManager.ts | 3 +- src/mutations/store.ts | 20 ++++++++------ src/queries/store.ts | 59 ++++++++++++++++++++++++--------------- test/client.ts | 60 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 114 insertions(+), 36 deletions(-) diff --git a/src/ApolloClient.ts b/src/ApolloClient.ts index 1f9e5b98982..643f539ad14 100644 --- a/src/ApolloClient.ts +++ b/src/ApolloClient.ts @@ -446,8 +446,8 @@ export default class ApolloClient implements DataProxy { this.devToolsHookCb({ action, state: { - queries: this.queryManager.queryStore._store, - mutations: this.queryManager.mutationStore._store, + queries: this.queryManager.queryStore.getStore(), + mutations: this.queryManager.mutationStore.getStore(), }, dataWithOptimisticResults: this.queryManager.getDataWithOptimisticResults(), }); @@ -488,8 +488,8 @@ export default class ApolloClient implements DataProxy { this.devToolsHookCb({ action, state: { - queries: this.queryManager.queryStore._store, - mutations: this.queryManager.mutationStore._store, + queries: this.queryManager.queryStore.getStore(), + mutations: this.queryManager.mutationStore.getStore(), }, dataWithOptimisticResults: this.queryManager.getDataWithOptimisticResults(), }); diff --git a/src/core/QueryManager.ts b/src/core/QueryManager.ts index 37954a9c398..59de87c651e 100644 --- a/src/core/QueryManager.ts +++ b/src/core/QueryManager.ts @@ -460,7 +460,8 @@ export class QueryManager { variables, isPoll: fetchType === FetchType.poll, isRefetch: fetchType === FetchType.refetch, - metadata, fetchMoreForQueryId, + metadata, + fetchMoreForQueryId, }); this.broadcastQueries(); diff --git a/src/mutations/store.ts b/src/mutations/store.ts index 6fad646c514..7e29df28918 100644 --- a/src/mutations/store.ts +++ b/src/mutations/store.ts @@ -1,12 +1,16 @@ export class MutationStore { - public _store: {[mutationId: string]: MutationStoreValue} = {}; + private store: {[mutationId: string]: MutationStoreValue} = {}; + + public getStore(): {[mutationId: string]: MutationStoreValue} { + return this.store; + } public get(mutationId: string): MutationStoreValue { - return this._store[mutationId]; + return this.store[mutationId]; } public initMutation(mutationId: string, mutationString: string, variables: Object | undefined) { - this._store[mutationId] = { + this.store[mutationId] = { mutationString: mutationString, variables: variables || {}, loading: true, @@ -15,17 +19,17 @@ export class MutationStore { } public markMutationError(mutationId: string, error: Error) { - this._store[mutationId].loading = false; - this._store[mutationId].error = error; + this.store[mutationId].loading = false; + this.store[mutationId].error = error; } public markMutationResult(mutationId: string) { - this._store[mutationId].loading = false; - this._store[mutationId].error = null; + this.store[mutationId].loading = false; + this.store[mutationId].error = null; } public reset() { - this._store = {}; + this.store = {}; } } diff --git a/src/queries/store.ts b/src/queries/store.ts index dcd5a2fddc9..022df9e4786 100644 --- a/src/queries/store.ts +++ b/src/queries/store.ts @@ -20,15 +20,28 @@ export type QueryStoreValue = { }; export class QueryStore { - public _store: {[queryId: string]: QueryStoreValue} = {}; + private store: {[queryId: string]: QueryStoreValue} = {}; + + public getStore(): {[queryId: string]: QueryStoreValue} { + return this.store; + } public get(queryId: string): QueryStoreValue { - return this._store[queryId]; + return this.store[queryId]; } - public initQuery(query: {queryId: string, queryString: string, document: DocumentNode, storePreviousVariables: boolean, - variables: Object, isPoll: boolean, isRefetch: boolean, metadata: any, fetchMoreForQueryId: string | undefined}) { - const previousQuery = this._store[query.queryId]; + public initQuery(query: { + queryId: string, + queryString: string, + document: DocumentNode, + storePreviousVariables: boolean, + variables: Object, + isPoll: boolean, + isRefetch: boolean, + metadata: any, + fetchMoreForQueryId: string | undefined, + }) { + const previousQuery = this.store[query.queryId]; if (previousQuery && previousQuery.queryString !== query.queryString) { // XXX we're throwing an error here to catch bugs where a query gets overwritten by a new one. @@ -68,7 +81,7 @@ export class QueryStore { // XXX right now if QUERY_INIT is fired twice, like in a refetch situation, we just overwrite // the store. We probably want a refetch action instead, because I suspect that if you refetch // before the initial fetch is done, you'll get an error. - this._store[query.queryId] = { + this.store[query.queryId] = { queryString: query.queryString, document: query.document, variables: query.variables, @@ -87,35 +100,35 @@ export class QueryStore { // This is because the implementation of `fetchMore` *always* sets // `fetchPolicy` to `network-only` so we would never have a client result. if (typeof query.fetchMoreForQueryId === 'string') { - this._store[query.fetchMoreForQueryId].networkStatus = NetworkStatus.fetchMore; + this.store[query.fetchMoreForQueryId].networkStatus = NetworkStatus.fetchMore; } } public markQueryResult(queryId: string, result: ExecutionResult, fetchMoreForQueryId: string | undefined) { - if (!this._store[queryId]) { + if (!this.store[queryId]) { return; } - this._store[queryId].networkError = null; - this._store[queryId].graphQLErrors = (result.errors && result.errors.length) ? result.errors : []; - this._store[queryId].previousVariables = null; - this._store[queryId].networkStatus = NetworkStatus.ready; + this.store[queryId].networkError = null; + this.store[queryId].graphQLErrors = (result.errors && result.errors.length) ? result.errors : []; + this.store[queryId].previousVariables = null; + this.store[queryId].networkStatus = NetworkStatus.ready; // If we have a `fetchMoreForQueryId` then we need to update the network // status for that query. See the branch for query initialization for more // explanation about this process. if (typeof fetchMoreForQueryId === 'string') { - this._store[fetchMoreForQueryId].networkStatus = NetworkStatus.ready; + this.store[fetchMoreForQueryId].networkStatus = NetworkStatus.ready; } } public markQueryError(queryId: string, error: Error, fetchMoreForQueryId: string | undefined) { - if (!this._store[queryId]) { + if (!this.store[queryId]) { return; } - this._store[queryId].networkError = error; - this._store[queryId].networkStatus = NetworkStatus.error; + this.store[queryId].networkError = error; + this.store[queryId].networkStatus = NetworkStatus.error; // If we have a `fetchMoreForQueryId` then we need to update the network // status for that query. See the branch for query initialization for more @@ -126,27 +139,27 @@ export class QueryStore { } public markQueryResultClient(queryId: string, complete: boolean) { - if (!this._store[queryId]) { + if (!this.store[queryId]) { return; } - this._store[queryId].networkError = null; - this._store[queryId].previousVariables = null; - this._store[queryId].networkStatus = complete ? NetworkStatus.ready : NetworkStatus.loading; + this.store[queryId].networkError = null; + this.store[queryId].previousVariables = null; + this.store[queryId].networkStatus = complete ? NetworkStatus.ready : NetworkStatus.loading; } public stopQuery(queryId: string) { - delete this._store[queryId]; + delete this.store[queryId]; } public reset(observableQueryIds: string[]) { // keep only the queries with query ids that are associated with observables - this._store = Object.keys(this._store).filter((queryId) => { + this.store = Object.keys(this.store).filter((queryId) => { return (observableQueryIds.indexOf(queryId) > -1); }).reduce((res, key) => { // XXX set loading to true so listeners don't trigger unless they want results with partial data res[key] = { - ...this._store[key], + ...this.store[key], networkStatus: NetworkStatus.loading, }; diff --git a/test/client.ts b/test/client.ts index 6e9c0218e4e..29fc8b64628 100644 --- a/test/client.ts +++ b/test/client.ts @@ -1521,6 +1521,66 @@ describe('client', () => { }); }); + it('emits Redux actions when the flag is enabled', () => { + QueryManager.EMIT_REDUX_ACTIONS = true; + + const query = gql` + query people { + allPeople(first: 1) { + people { + name + __typename + } + __typename + } + } + `; + + const data = { + allPeople: { + people: [ + { + name: 'Luke Skywalker', + __typename: 'Person', + }, + ], + __typename: 'People', + }, + }; + + const networkInterface = mockNetworkInterface({ + request: { query: cloneDeep(query) }, + result: { data }, + }); + + const client = new ApolloClient({ + networkInterface, + }); + + client.initStore(); + + const orig = client.store.dispatch; + let actionEmitted = false; + + client.store.dispatch = (action) => { + if (action.type === 'APOLLO_QUERY_INIT') { + actionEmitted = true; + } + + orig(action); + }; + + const queryPromise = client.query({ query }).then((result) => { + assert.deepEqual(result.data, data); + }); + + QueryManager.EMIT_REDUX_ACTIONS = false; + + return queryPromise.then(() => { + assert(actionEmitted, 'An action was not emitted'); + }); + }); + describe('deprecated options', () => { const query = gql` query people {