From d9f1704d572ec8aaab6220504bd8b2dfa5891386 Mon Sep 17 00:00:00 2001 From: griest024 Date: Wed, 7 Feb 2024 18:26:55 -0500 Subject: [PATCH] feat(driver): store and set Magento cache ID header (#2743) --- .../cache-header-apollo-link.spec.ts | 90 +++++++++++++++++++ .../cache-header/cache-header-apollo-link.ts | 40 +++++++++ libs/driver/magento/src/graphql/public_api.ts | 1 + 3 files changed, 131 insertions(+) create mode 100644 libs/driver/magento/src/graphql/cache-header/cache-header-apollo-link.spec.ts create mode 100644 libs/driver/magento/src/graphql/cache-header/cache-header-apollo-link.ts diff --git a/libs/driver/magento/src/graphql/cache-header/cache-header-apollo-link.spec.ts b/libs/driver/magento/src/graphql/cache-header/cache-header-apollo-link.spec.ts new file mode 100644 index 0000000000..7038663443 --- /dev/null +++ b/libs/driver/magento/src/graphql/cache-header/cache-header-apollo-link.spec.ts @@ -0,0 +1,90 @@ +import { TestBed } from '@angular/core/testing'; +import { + ApolloLink, + gql, + NextLink, + Observable, + Operation, +} from '@apollo/client/core'; +import { Apollo } from 'apollo-angular'; +import { + ApolloTestingController, + ApolloTestingModule, +} from 'apollo-angular/testing'; + +import { + DaffMagentoCacheHeaderApolloLinkGenerator, + MAGENTO_CUSTOMER_CACHE_ID_HEADER, +} from './cache-header-apollo-link'; + +describe('@daffodil/driver/magento | DaffMagentoCacheHeaderApolloLinkGenerator', () => { + let service: DaffMagentoCacheHeaderApolloLinkGenerator; + let operation: Operation; + let apollo: Apollo; + let controller: ApolloTestingController; + let link: ApolloLink; + let linkSpy: jasmine.Spy; + let cacheId: string; + const query = gql`{ Operation(test: string) { name }}`; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [ + ApolloTestingModule, + ], + }); + + controller = TestBed.inject(ApolloTestingController); + apollo = TestBed.inject(Apollo); + service = TestBed.inject(DaffMagentoCacheHeaderApolloLinkGenerator); + + link = service.getLink(); + linkSpy = jasmine.createSpy(); + linkSpy.and.returnValue(Observable.of()); + cacheId = 'cacheId'; + }); + + describe('getLink', () => { + it('should not set the cache header when it was not included with a previous response', () => { + apollo.query({ query }).subscribe(); + operation = controller.expectOne(query).operation; + link.request(operation, linkSpy); + + expect(operation.getContext().headers?.[MAGENTO_CUSTOMER_CACHE_ID_HEADER]).toBeFalsy(); + }); + + it('should set the cache header when it was included with a previous response', () => { + apollo.query({ query }).subscribe(); + operation = controller.expectOne(query).operation; + operation.setContext({ + headers: { + [MAGENTO_CUSTOMER_CACHE_ID_HEADER]: cacheId, + }, + }); + link.request(operation, linkSpy); + + expect(operation.getContext().headers?.[MAGENTO_CUSTOMER_CACHE_ID_HEADER]).toEqual(cacheId); + }); + + it('should set the cache header to the new value when the cache ID changes', () => { + const newCacheId = 'newCacheId'; + apollo.query({ query }).subscribe(); + operation = controller.expectOne(query).operation; + operation.setContext({ + headers: { + [MAGENTO_CUSTOMER_CACHE_ID_HEADER]: cacheId, + }, + }); + link.request(operation, linkSpy); + + operation.setContext({ + headers: { + [MAGENTO_CUSTOMER_CACHE_ID_HEADER]: newCacheId, + }, + }); + link.request(operation, linkSpy); + + expect(operation.getContext().headers?.[MAGENTO_CUSTOMER_CACHE_ID_HEADER]).toEqual(newCacheId); + }); + }); +}); diff --git a/libs/driver/magento/src/graphql/cache-header/cache-header-apollo-link.ts b/libs/driver/magento/src/graphql/cache-header/cache-header-apollo-link.ts new file mode 100644 index 0000000000..12bd8e1a5b --- /dev/null +++ b/libs/driver/magento/src/graphql/cache-header/cache-header-apollo-link.ts @@ -0,0 +1,40 @@ +import { Injectable } from '@angular/core'; +import { ApolloLink } from '@apollo/client/core'; + +import { DaffApolloLinkGenerator } from '@daffodil/core/graphql'; + +export const MAGENTO_CUSTOMER_CACHE_ID_HEADER = 'X-Magento-Cache-Id'; + +/** + * Stores and sets the Magento cache ID header. + * This will set the `X-Magento-Cache-Id` header from the most recent value encountered + * on a response, if there was a response with that header set. + * + * @inheritdoc + */ +@Injectable({ + providedIn: 'root', +}) +export class DaffMagentoCacheHeaderApolloLinkGenerator implements DaffApolloLinkGenerator { + private _cacheHeader?: string; + + getLink(): ApolloLink { + return new ApolloLink((operation, forward) => { + if (this._cacheHeader) { + operation.setContext({ + headers: { + ...operation.getContext().headers, + [MAGENTO_CUSTOMER_CACHE_ID_HEADER]: this._cacheHeader, + }, + }); + } + return forward(operation).map((response) => { + const { headers } = operation.getContext().response; + if (headers.get(MAGENTO_CUSTOMER_CACHE_ID_HEADER)) { + this._cacheHeader = headers.get(MAGENTO_CUSTOMER_CACHE_ID_HEADER); + } + return response; + }); + }); + } +} diff --git a/libs/driver/magento/src/graphql/public_api.ts b/libs/driver/magento/src/graphql/public_api.ts index 8707e15b52..8cf7a58898 100644 --- a/libs/driver/magento/src/graphql/public_api.ts +++ b/libs/driver/magento/src/graphql/public_api.ts @@ -2,3 +2,4 @@ export { DaffMagentoApolloCacheableOperationsLinkGenerator } from './cacheable-o export * from './cacheable-operations/cacheable-operations-token'; export * from './type-policies'; export * from './cache.service'; +export * from './cache-header/cache-header-apollo-link';