зеркало из https://github.com/mozilla/fxa.git
respect metrics opt-out flag
This commit is contained in:
Родитель
3da291f829
Коммит
d0f7bcd26c
|
@ -23,11 +23,18 @@ import { MockStatsDProvider } from '@fxa/shared/metrics/statsd';
|
|||
import { PriceManager } from '@fxa/payments/customer';
|
||||
import { MockFirestoreProvider } from '@fxa/shared/db/firestore';
|
||||
import { MockPaymentsGleanFactory } from './glean.provider';
|
||||
import {
|
||||
AccountFactory,
|
||||
MockAccountDatabaseNestFactory,
|
||||
} from '@fxa/shared/db/mysql/account';
|
||||
import { AccountManager } from '@fxa/shared/account/account';
|
||||
import { faker } from '@faker-js/faker';
|
||||
|
||||
describe('PaymentsGleanService', () => {
|
||||
let paymentsGleanService: PaymentsGleanService;
|
||||
let paymentsGleanManager: PaymentsGleanManager;
|
||||
let productConfigurationManager: ProductConfigurationManager;
|
||||
let accountsManager: AccountManager;
|
||||
|
||||
beforeEach(async () => {
|
||||
const moduleRef = await Test.createTestingModule({
|
||||
|
@ -35,6 +42,7 @@ describe('PaymentsGleanService', () => {
|
|||
MockPaymentsGleanFactory,
|
||||
MockStrapiClientConfigProvider,
|
||||
MockStripeConfigProvider,
|
||||
MockAccountDatabaseNestFactory,
|
||||
MockFirestoreProvider,
|
||||
MockStatsDProvider,
|
||||
StrapiClient,
|
||||
|
@ -43,18 +51,21 @@ describe('PaymentsGleanService', () => {
|
|||
PaymentsGleanManager,
|
||||
ProductConfigurationManager,
|
||||
PaymentsGleanService,
|
||||
AccountManager,
|
||||
],
|
||||
}).compile();
|
||||
|
||||
paymentsGleanService = moduleRef.get(PaymentsGleanService);
|
||||
paymentsGleanManager = moduleRef.get(PaymentsGleanManager);
|
||||
productConfigurationManager = moduleRef.get(ProductConfigurationManager);
|
||||
accountsManager = moduleRef.get(AccountManager);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(paymentsGleanService).toBeDefined();
|
||||
expect(paymentsGleanManager).toBeDefined();
|
||||
expect(productConfigurationManager).toBeDefined();
|
||||
expect(accountsManager).toBeDefined();
|
||||
});
|
||||
|
||||
describe('handleEventFxaPaySetupView', () => {
|
||||
|
@ -106,5 +117,27 @@ describe('PaymentsGleanService', () => {
|
|||
{ priceId: '', productId: '' }
|
||||
);
|
||||
});
|
||||
|
||||
it('should not call recordFxaPaySetupView if opted out', async () => {
|
||||
const uid = Buffer.from(
|
||||
faker.string.hexadecimal({
|
||||
length: 32,
|
||||
prefix: '',
|
||||
casing: 'lower',
|
||||
}),
|
||||
'hex'
|
||||
);
|
||||
const mockUser = AccountFactory({
|
||||
uid,
|
||||
metricsOptOutAt: new Date().valueOf(),
|
||||
});
|
||||
jest.spyOn(accountsManager, 'getAccounts').mockResolvedValue([mockUser]);
|
||||
|
||||
await paymentsGleanService.handleEventFxaPaySetupView({
|
||||
...mockMetricsData,
|
||||
uid: uid.toString('hex'),
|
||||
});
|
||||
expect(paymentsGleanManager.recordFxaPaySetupView).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -7,6 +7,7 @@ import { ProductConfigurationManager } from '@fxa/shared/cms';
|
|||
import { Injectable } from '@nestjs/common';
|
||||
import { mapParams } from './utils/mapParams';
|
||||
import { PaymentsGleanManager } from './glean.manager';
|
||||
import { AccountManager } from '@fxa/shared/account/account';
|
||||
import { SubplatInterval } from '@fxa/payments/customer';
|
||||
|
||||
@Injectable()
|
||||
|
@ -15,7 +16,8 @@ export class PaymentsGleanService {
|
|||
|
||||
constructor(
|
||||
private productConfigurationManager: ProductConfigurationManager,
|
||||
private paymentsGleanManager: PaymentsGleanManager
|
||||
private paymentsGleanManager: PaymentsGleanManager,
|
||||
private accountManager: AccountManager
|
||||
) {
|
||||
this.emitter = new Emittery<GleanEvents>();
|
||||
this.emitter.on(
|
||||
|
@ -30,9 +32,17 @@ export class PaymentsGleanService {
|
|||
|
||||
async handleEventFxaPaySetupView(metricsData: FxaPaySetupViewMetrics) {
|
||||
const { offeringId, interval } = mapParams(metricsData.params);
|
||||
const cmsData = await this.retrieveCMSData(offeringId, interval);
|
||||
const [cmsData, optedOut] = await Promise.all([
|
||||
this.retrieveCMSData(offeringId, interval),
|
||||
this.retrieveOptOut(metricsData.uid),
|
||||
]);
|
||||
|
||||
await this.paymentsGleanManager.recordFxaPaySetupView(metricsData, cmsData);
|
||||
if (!optedOut) {
|
||||
await this.paymentsGleanManager.recordFxaPaySetupView(
|
||||
metricsData,
|
||||
cmsData
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private async retrieveCMSData(offeringId: string, interval: SubplatInterval) {
|
||||
|
@ -53,4 +63,10 @@ export class PaymentsGleanService {
|
|||
};
|
||||
}
|
||||
}
|
||||
|
||||
private async retrieveOptOut(uid?: string): Promise<boolean> {
|
||||
if (!uid) return false;
|
||||
const accounts = await this.accountManager.getAccounts([uid]);
|
||||
return accounts[0].metricsOptOutAt !== null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ export * from './lib/associated-types';
|
|||
export * from './lib/kysely-types';
|
||||
export {
|
||||
CartFactory,
|
||||
AccountFactory,
|
||||
AccountCustomerFactory,
|
||||
PaypalCustomerFactory,
|
||||
} from './lib/factories';
|
||||
|
|
|
@ -4,7 +4,12 @@
|
|||
|
||||
import { faker } from '@faker-js/faker';
|
||||
|
||||
import { AccountCustomer, NewCart, PaypalCustomer } from './associated-types';
|
||||
import {
|
||||
Account,
|
||||
AccountCustomer,
|
||||
NewCart,
|
||||
PaypalCustomer,
|
||||
} from './associated-types';
|
||||
import { CartEligibilityStatus, CartState } from './kysely-types';
|
||||
|
||||
export const CartFactory = (override?: Partial<NewCart>): NewCart => ({
|
||||
|
@ -39,6 +44,51 @@ export const CartFactory = (override?: Partial<NewCart>): NewCart => ({
|
|||
...override,
|
||||
});
|
||||
|
||||
const getHexBuffer = (length: number, prefix = ''): Buffer => {
|
||||
return Buffer.from(
|
||||
faker.string.hexadecimal({
|
||||
length,
|
||||
prefix,
|
||||
casing: 'lower',
|
||||
}),
|
||||
'hex'
|
||||
);
|
||||
};
|
||||
|
||||
export const AccountFactory = (override?: Partial<Account>): Account => ({
|
||||
uid: getHexBuffer(32),
|
||||
createdAt: faker.date.recent().getTime(),
|
||||
email: faker.internet.email(),
|
||||
normalizedEmail: faker.internet.email().toLocaleLowerCase(),
|
||||
emailCode: getHexBuffer(16),
|
||||
emailVerified: 1,
|
||||
verifierVersion: 1,
|
||||
kA: getHexBuffer(32),
|
||||
wrapWrapKb: Buffer.from(
|
||||
faker.string.hexadecimal({
|
||||
length: 32,
|
||||
prefix: '',
|
||||
casing: 'lower',
|
||||
}),
|
||||
'hex'
|
||||
),
|
||||
wrapWrapKbVersion2: getHexBuffer(32),
|
||||
authSalt: getHexBuffer(32),
|
||||
verifyHash: getHexBuffer(32),
|
||||
verifierSetAt: faker.date.recent().getTime(),
|
||||
verifyHashVersion2: getHexBuffer(32),
|
||||
locale: 'en-US',
|
||||
lockedAt: null,
|
||||
profileChangedAt: null,
|
||||
keysChangedAt: null,
|
||||
ecosystemAnonId: faker.string.numeric(),
|
||||
disabledAt: null,
|
||||
metricsOptOutAt: null,
|
||||
clientSalt: null,
|
||||
atLeast18AtReg: 1,
|
||||
...override,
|
||||
});
|
||||
|
||||
export const AccountCustomerFactory = (
|
||||
override?: Partial<AccountCustomer>
|
||||
): AccountCustomer => ({
|
||||
|
|
Загрузка…
Ссылка в новой задаче