From 914440bd7e8fabb6cec22b125579e076db1f9128 Mon Sep 17 00:00:00 2001 From: Reino Muhl <10620585+StaberindeZA@users.noreply.github.com> Date: Tue, 29 Oct 2024 13:12:05 -0400 Subject: [PATCH] feat(payments-metrics): add glean enabled env var Because: - Need to be able to enable or disable glean recording of events. This commit: - Adds enabled value to payments metrics glean config - Updates payments metrics glean manager to respect enabled config value Closes #FXA-10564 --- apps/payments/next/.env.development | 3 +- apps/payments/next/.env.production | 3 +- .../metrics/src/lib/glean/glean.config.ts | 20 ++++- .../src/lib/glean/glean.manager.spec.ts | 76 ++++++++++++++++++- .../metrics/src/lib/glean/glean.manager.ts | 51 ++++++++----- .../src/lib/emitter/emitter.service.spec.ts | 2 + 6 files changed, 133 insertions(+), 22 deletions(-) diff --git a/apps/payments/next/.env.development b/apps/payments/next/.env.development index e498c98bba..a156068fd7 100644 --- a/apps/payments/next/.env.development +++ b/apps/payments/next/.env.development @@ -37,7 +37,7 @@ STRIPE_CONFIG__TAX_IDS={} STRIPE_PUBLIC_API_KEY=pk_test_VNpCidC0a2TJJB3wqXq7drhN00sF8r9mhs # PayPal Config -PAYPAL_CLIENT_CONFIG__SANDBOX=false +PAYPAL_CLIENT_CONFIG__SANDBOX=true PAYPAL_CLIENT_CONFIG__USER=ASDF PAYPAL_CLIENT_CONFIG__PWD=ASDF PAYPAL_CLIENT_CONFIG__SIGNATURE=ASDF @@ -80,6 +80,7 @@ STATS_D_CONFIG__PORT= STATS_D_CONFIG__PREFIX= # Glean Config +GLEAN_CONFIG__ENABLED=true GLEAN_CONFIG__APPLICATION_ID= # GLEAN_CONFIG__VERSION= # Set in next.config.js GLEAN_CONFIG__CHANNEL='development' diff --git a/apps/payments/next/.env.production b/apps/payments/next/.env.production index 4192a18fbf..dc41a995c3 100644 --- a/apps/payments/next/.env.production +++ b/apps/payments/next/.env.production @@ -33,7 +33,7 @@ STRIPE_CONFIG__TAX_IDS={} STRIPE_PUBLIC_API_KEY= # PayPal Config -PAYPAL_CLIENT_CONFIG__SANDBOX=false +PAYPAL_CLIENT_CONFIG__SANDBOX= PAYPAL_CLIENT_CONFIG__USER=ASDF PAYPAL_CLIENT_CONFIG__PWD=ASDF PAYPAL_CLIENT_CONFIG__SIGNATURE=ASDF @@ -76,6 +76,7 @@ STATS_D_CONFIG__PORT= STATS_D_CONFIG__PREFIX= # Glean Config +GLEAN_CONFIG__ENABLED= GLEAN_CONFIG__APPLICATION_ID= # GLEAN_CONFIG__VERSION= # Set in next.config.js GLEAN_CONFIG__CHANNEL='production' diff --git a/libs/payments/metrics/src/lib/glean/glean.config.ts b/libs/payments/metrics/src/lib/glean/glean.config.ts index f3972b0de3..0ea9fd9949 100644 --- a/libs/payments/metrics/src/lib/glean/glean.config.ts +++ b/libs/payments/metrics/src/lib/glean/glean.config.ts @@ -1,7 +1,9 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import { IsEnum, IsString } from 'class-validator'; +import { faker } from '@faker-js/faker'; +import { Provider } from '@nestjs/common'; +import { IsBoolean, IsEnum, IsString } from 'class-validator'; enum GleanChannel { Development = 'development', @@ -10,6 +12,9 @@ enum GleanChannel { } export class PaymentsGleanConfig { + @IsBoolean() + enabled!: boolean; + @IsString() applicationId!: string; @@ -22,3 +27,16 @@ export class PaymentsGleanConfig { @IsString() loggerAppName!: string; } + +export const MockPaymentsGleanConfig = { + enabled: true, + applicationId: faker.string.uuid(), + version: '0.0.1', + channel: GleanChannel.Development, + loggerAppName: 'payments-next-test', +} satisfies PaymentsGleanConfig; + +export const MockPaymentsGleanConfigProvider = { + provide: PaymentsGleanConfig, + useValue: MockPaymentsGleanConfig, +} satisfies Provider; diff --git a/libs/payments/metrics/src/lib/glean/glean.manager.spec.ts b/libs/payments/metrics/src/lib/glean/glean.manager.spec.ts index a2709836f3..9d0c82b92e 100644 --- a/libs/payments/metrics/src/lib/glean/glean.manager.spec.ts +++ b/libs/payments/metrics/src/lib/glean/glean.manager.spec.ts @@ -10,6 +10,10 @@ import { } from './glean.factory'; import { PaymentsGleanProvider } from './glean.types'; import { MockPaymentsGleanFactory } from './glean.test-provider'; +import { + MockPaymentsGleanConfigProvider, + PaymentsGleanConfig, +} from './glean.config'; const mockCommonMetricsData = { commonMetricsData: CommonMetricsFactory(), @@ -26,7 +30,11 @@ describe('PaymentsGleanManager', () => { beforeEach(async () => { const moduleRef = await Test.createTestingModule({ - providers: [MockPaymentsGleanFactory, PaymentsGleanManager], + providers: [ + MockPaymentsGleanFactory, + PaymentsGleanManager, + MockPaymentsGleanConfigProvider, + ], }).compile(); paymentsGleanManager = moduleRef.get(PaymentsGleanManager); @@ -156,4 +164,70 @@ describe('PaymentsGleanManager', () => { }); }); }); + + describe('enabled is false', () => { + { + let paymentsGleanManager: PaymentsGleanManager; + let paymentsGleanServerEventsLogger: any; + + beforeAll(async () => { + const moduleRef = await Test.createTestingModule({ + providers: [ + MockPaymentsGleanFactory, + PaymentsGleanManager, + MockPaymentsGleanConfigProvider, + { + provide: PaymentsGleanConfig, + useValue: { + enabled: false, + }, + }, + ], + }).compile(); + + paymentsGleanManager = moduleRef.get(PaymentsGleanManager); + paymentsGleanServerEventsLogger = moduleRef.get(PaymentsGleanProvider); + jest.spyOn(paymentsGleanServerEventsLogger, 'recordPaySetupView'); + jest.spyOn(paymentsGleanServerEventsLogger, 'recordPaySetupEngage'); + jest.spyOn(paymentsGleanServerEventsLogger, 'recordPaySetupSubmit'); + jest.spyOn(paymentsGleanServerEventsLogger, 'recordPaySetupSuccess'); + jest.spyOn(paymentsGleanServerEventsLogger, 'recordPaySetupFail'); + }); + + it('recordFxaPaySetupView', () => { + paymentsGleanManager.recordFxaPaySetupView(mockCommonMetricsData); + expect( + paymentsGleanServerEventsLogger.recordPaySetupView + ).not.toHaveBeenCalled(); + }); + + it('recordFxaPaySetupEngage', () => { + paymentsGleanManager.recordFxaPaySetupEngage(mockCommonMetricsData); + expect( + paymentsGleanServerEventsLogger.recordPaySetupEngage + ).not.toHaveBeenCalled(); + }); + + it('recordFxaPaySetupSubmit', () => { + paymentsGleanManager.recordFxaPaySetupSubmit(mockCommonMetricsData); + expect( + paymentsGleanServerEventsLogger.recordPaySetupSubmit + ).not.toHaveBeenCalled(); + }); + + it('recordFxaPaySetupSuccess', () => { + paymentsGleanManager.recordFxaPaySetupSuccess(mockCommonMetricsData); + expect( + paymentsGleanServerEventsLogger.recordPaySetupSuccess + ).not.toHaveBeenCalled(); + }); + + it('recordFxaPaySetupFail', () => { + paymentsGleanManager.recordFxaPaySetupFail(mockCommonMetricsData); + expect( + paymentsGleanServerEventsLogger.recordPaySetupFail + ).not.toHaveBeenCalled(); + }); + } + }); }); diff --git a/libs/payments/metrics/src/lib/glean/glean.manager.ts b/libs/payments/metrics/src/lib/glean/glean.manager.ts index 1212abf38e..9d60d3a115 100644 --- a/libs/payments/metrics/src/lib/glean/glean.manager.ts +++ b/libs/payments/metrics/src/lib/glean/glean.manager.ts @@ -15,10 +15,12 @@ import { mapUtm } from './utils/mapUtm'; import { mapSubscription } from './utils/mapSubscription'; import { mapRelyingParty } from './utils/mapRelyingParty'; import { normalizeGleanFalsyValues } from './utils/normalizeGleanFalsyValues'; +import { PaymentsGleanConfig } from './glean.config'; @Injectable() export class PaymentsGleanManager { constructor( + private paymentsGleanConfig: PaymentsGleanConfig, @Inject(PaymentsGleanProvider) private paymentsGleanServerEventsLogger: PaymentsGleanServerEventsLogger ) {} @@ -28,9 +30,11 @@ export class PaymentsGleanManager { cartMetricsData: CartMetrics; cmsMetricsData: CmsMetricsData; }) { - this.paymentsGleanServerEventsLogger.recordPaySetupView( - this.populateCommonMetrics(metrics) - ); + if (this.paymentsGleanConfig.enabled) { + this.paymentsGleanServerEventsLogger.recordPaySetupView( + this.populateCommonMetrics(metrics) + ); + } } recordFxaPaySetupEngage(metrics: { @@ -38,9 +42,11 @@ export class PaymentsGleanManager { cartMetricsData: CartMetrics; cmsMetricsData: CmsMetricsData; }) { - this.paymentsGleanServerEventsLogger.recordPaySetupEngage( - this.populateCommonMetrics(metrics) - ); + if (this.paymentsGleanConfig.enabled) { + this.paymentsGleanServerEventsLogger.recordPaySetupEngage( + this.populateCommonMetrics(metrics) + ); + } } recordFxaPaySetupSubmit( @@ -51,10 +57,13 @@ export class PaymentsGleanManager { }, paymentProvider?: PaymentProvidersType ) { - this.paymentsGleanServerEventsLogger.recordPaySetupSubmit({ - ...this.populateCommonMetrics(metrics), - subscription_payment_provider: normalizeGleanFalsyValues(paymentProvider), - }); + if (this.paymentsGleanConfig.enabled) { + this.paymentsGleanServerEventsLogger.recordPaySetupSubmit({ + ...this.populateCommonMetrics(metrics), + subscription_payment_provider: + normalizeGleanFalsyValues(paymentProvider), + }); + } } recordFxaPaySetupSuccess( @@ -67,10 +76,13 @@ export class PaymentsGleanManager { ) { const commonMetrics = this.populateCommonMetrics(metrics); - this.paymentsGleanServerEventsLogger.recordPaySetupSuccess({ - ...commonMetrics, - subscription_payment_provider: normalizeGleanFalsyValues(paymentProvider), - }); + if (this.paymentsGleanConfig.enabled) { + this.paymentsGleanServerEventsLogger.recordPaySetupSuccess({ + ...commonMetrics, + subscription_payment_provider: + normalizeGleanFalsyValues(paymentProvider), + }); + } } recordFxaPaySetupFail( @@ -83,10 +95,13 @@ export class PaymentsGleanManager { ) { const commonMetrics = this.populateCommonMetrics(metrics); - this.paymentsGleanServerEventsLogger.recordPaySetupFail({ - ...commonMetrics, - subscription_payment_provider: normalizeGleanFalsyValues(paymentProvider), - }); + if (this.paymentsGleanConfig.enabled) { + this.paymentsGleanServerEventsLogger.recordPaySetupFail({ + ...commonMetrics, + subscription_payment_provider: + normalizeGleanFalsyValues(paymentProvider), + }); + } } private populateCommonMetrics(metrics: { diff --git a/libs/payments/ui/src/lib/emitter/emitter.service.spec.ts b/libs/payments/ui/src/lib/emitter/emitter.service.spec.ts index 3a5635f36a..8896eadc11 100644 --- a/libs/payments/ui/src/lib/emitter/emitter.service.spec.ts +++ b/libs/payments/ui/src/lib/emitter/emitter.service.spec.ts @@ -14,6 +14,7 @@ import { MockFirestoreProvider } from '@fxa/shared/db/firestore'; import { CheckoutParamsFactory, CommonMetricsFactory, + MockPaymentsGleanConfigProvider, MockPaymentsGleanFactory, PaymentProvidersType, PaymentsGleanManager, @@ -48,6 +49,7 @@ describe('PaymentsEmitterService', () => { beforeEach(async () => { const moduleRef = await Test.createTestingModule({ providers: [ + MockPaymentsGleanConfigProvider, MockAccountDatabaseNestFactory, MockPaymentsGleanFactory, MockStrapiClientConfigProvider,