From 6c03aff18954b1efd21a403adea5c1ad950bc030 Mon Sep 17 00:00:00 2001 From: Paulo Sobrinho Ferreira <110847590+pauloSF0@users.noreply.github.com> Date: Fri, 9 Aug 2024 11:32:03 -0300 Subject: [PATCH] [UXE-4356] feat: add secrets segment variables in the workflows (#1597) --- .github/workflows/deploy-production.yml | 1 + .github/workflows/deploy-stage.yml | 1 + src/plugins/AnalyticsTrackerAdapterPlugin.js | 11 +++--- .../analytics/AnalyticsTrackerAdapter.js | 13 +++++-- .../factories/analytics-tracking-factory.js | 27 +------------- .../segment-handler-token-factory.js | 13 +++++++ .../analytics/AnalyticsTrackerAdapter.test.js | 1 - .../analytics-tracking-factory.test.js | 16 +-------- .../segment-handler-token-factory.test.js | 36 +++++++++++++++++++ 9 files changed, 70 insertions(+), 49 deletions(-) create mode 100644 src/plugins/factories/segment-handler-token-factory.js create mode 100644 src/tests/plugins/factories/segment-handler-token-factory.test.js diff --git a/.github/workflows/deploy-production.yml b/.github/workflows/deploy-production.yml index 67ae71c09..a3dcbd07d 100644 --- a/.github/workflows/deploy-production.yml +++ b/.github/workflows/deploy-production.yml @@ -35,5 +35,6 @@ jobs: env: VITE_STRIPE_TOKEN_PROD: ${{ secrets.PROD_STRIPE_TOKEN }} VITE_RECAPTCHA_SITE_KEY: ${{ secrets.PROD_RECAPTCHA_SITE_KEY }} + VITE_SEGMENT_TOKEN: ${{ secrets.PROD_SEGMENT_TOKEN }} NODE_ENV: production VITE_ENVIRONMENT: production \ No newline at end of file diff --git a/.github/workflows/deploy-stage.yml b/.github/workflows/deploy-stage.yml index cf2f836c8..7e576926f 100644 --- a/.github/workflows/deploy-stage.yml +++ b/.github/workflows/deploy-stage.yml @@ -35,5 +35,6 @@ jobs: env: VITE_STRIPE_TOKEN_STAGE: ${{ secrets.STAGE_STRIPE_TOKEN }} VITE_RECAPTCHA_SITE_KEY: ${{ secrets.STAGE_RECAPTCHA_SITE_KEY }} + VITE_SEGMENT_TOKEN: ${{ secrets.STAGE_SEGMENT_TOKEN }} NODE_ENV: stage VITE_ENVIRONMENT: stage diff --git a/src/plugins/AnalyticsTrackerAdapterPlugin.js b/src/plugins/AnalyticsTrackerAdapterPlugin.js index c7ab80f19..eaf0a1f0c 100644 --- a/src/plugins/AnalyticsTrackerAdapterPlugin.js +++ b/src/plugins/AnalyticsTrackerAdapterPlugin.js @@ -1,14 +1,17 @@ -import { getEnvironment } from '@/helpers' import { makeAnalyticsClient } from './factories/analytics-tracking-factory' import { AnalyticsTrackerAdapter } from './analytics/AnalyticsTrackerAdapter' - +import { makeSegmentToken } from './factories/segment-handler-token-factory' /**@type {import('vue').Plugin} */ export default { // eslint-disable-next-line no-unused-vars install: (Vue, options) => { - const environment = getEnvironment() + const segmentToken = makeSegmentToken() + + let analyticsClient = undefined - const analyticsClient = makeAnalyticsClient(environment) + if (segmentToken) { + analyticsClient = makeAnalyticsClient(segmentToken) + } const app = Vue const trackerInstance = new AnalyticsTrackerAdapter(analyticsClient) diff --git a/src/plugins/analytics/AnalyticsTrackerAdapter.js b/src/plugins/analytics/AnalyticsTrackerAdapter.js index 6ca05cfbe..b74292c96 100644 --- a/src/plugins/analytics/AnalyticsTrackerAdapter.js +++ b/src/plugins/analytics/AnalyticsTrackerAdapter.js @@ -15,6 +15,8 @@ export class AnalyticsTrackerAdapter { #events = [] /** @type {import('analytics').AnalyticsInstance} */ #analyticsClient = null + /** @type {Boolean} */ + #hasAnalyticsClient = false #traits = {} /** @type {SignUpTracker} */ @@ -31,6 +33,7 @@ export class AnalyticsTrackerAdapter { * @param {import('analytics').AnalyticsInstance} analyticsClient - The client for tracking. */ constructor(analyticsClient) { + this.#hasAnalyticsClient = !!analyticsClient this.#analyticsClient = analyticsClient this.#signUpTracker = new SignUpTracker(this) @@ -48,10 +51,14 @@ export class AnalyticsTrackerAdapter { this.#events.push(event) } + #hasAnalytics() { + return this.#hasAnalyticsClient + } /** * call this method to run each stored tracker event */ async track() { + if (!this.#hasAnalytics()) return this.#events.forEach(async (action) => { const { eventName, props } = action props.application = 'console-kit' @@ -68,9 +75,8 @@ export class AnalyticsTrackerAdapter { * @return {Promise} */ async identify(id) { - if (!id) { - return - } + if (!id || !this.#hasAnalytics()) return + await this.#analyticsClient.identify(id, this.#traits) } @@ -79,6 +85,7 @@ export class AnalyticsTrackerAdapter { * @param {Object} traitsToAssign - traits that should be sended with all tracking calls */ assignGroupTraits(traitsToAssign) { + if (!this.#hasAnalytics()) return if (!traitsToAssign) { throw new Error('Invalid traits provided') } diff --git a/src/plugins/factories/analytics-tracking-factory.js b/src/plugins/factories/analytics-tracking-factory.js index 7eb5f9b96..3a3387057 100644 --- a/src/plugins/factories/analytics-tracking-factory.js +++ b/src/plugins/factories/analytics-tracking-factory.js @@ -1,37 +1,12 @@ import { Analytics } from 'analytics' import segmentPlugin from '@analytics/segment' -const environment = { - development: { - segmentToken: 'EeKBQaSXEBAkaOYc0Z9XrPALzdt5rLpI' - }, - stage: { - segmentToken: 'EeKBQaSXEBAkaOYc0Z9XrPALzdt5rLpI' - }, - production: { - segmentToken: 'MFfoMuZo6JPehBpfh21zXEjlwOs2zDeP' - } -} - -function getSegmentToken(env) { - return environment[env].segmentToken -} /** * Initialize analytics module. * @param {string} environment * @returns {import('analytics').AnalyticsInstance} */ -export function makeAnalyticsClient(environment) { - if (!environment) { - throw Error('Provide an environment to select correct tracking token') - } - const isInvalidEnvironment = !['development', 'stage', 'production'].includes(environment) - if (isInvalidEnvironment) { - throw Error('Provide an valid environment to select correct tracking token') - } - - const segmentToken = getSegmentToken(environment) - +export function makeAnalyticsClient(segmentToken) { const plugins = [segmentPlugin({ writeKey: segmentToken })] return new Analytics({ plugins }) diff --git a/src/plugins/factories/segment-handler-token-factory.js b/src/plugins/factories/segment-handler-token-factory.js new file mode 100644 index 000000000..7839d2704 --- /dev/null +++ b/src/plugins/factories/segment-handler-token-factory.js @@ -0,0 +1,13 @@ +function makeSegmentToken() { + const segmentToken = import.meta.env['VITE_SEGMENT_TOKEN'] + + if (!segmentToken) { + // eslint-disable-next-line no-console + console.warn('Segment token is missing') + return + } + + return segmentToken +} + +export { makeSegmentToken } diff --git a/src/tests/plugins/analytics/AnalyticsTrackerAdapter.test.js b/src/tests/plugins/analytics/AnalyticsTrackerAdapter.test.js index bec7b6bb2..bb08d98f0 100644 --- a/src/tests/plugins/analytics/AnalyticsTrackerAdapter.test.js +++ b/src/tests/plugins/analytics/AnalyticsTrackerAdapter.test.js @@ -10,7 +10,6 @@ const makeSut = () => { track: vi.fn(), identify: vi.fn() } - const sut = new AnalyticsTrackerAdapter(analyticsClientSpy) return { diff --git a/src/tests/plugins/factories/analytics-tracking-factory.test.js b/src/tests/plugins/factories/analytics-tracking-factory.test.js index e4532b6c4..e40884894 100644 --- a/src/tests/plugins/factories/analytics-tracking-factory.test.js +++ b/src/tests/plugins/factories/analytics-tracking-factory.test.js @@ -8,24 +8,10 @@ const makeSut = () => { } describe('AnalyticsTrackingFactory', () => { - it('should return an error whe no environment is provided', () => { - const { sut } = makeSut() - - expect(() => sut(null)).toThrowError('Provide an environment to select correct tracking token') - }) - - it('should return an error on invalid environment provided', () => { - const { sut } = makeSut() - - expect(() => sut('invalid-environment-stub')).toThrowError( - 'Provide an valid environment to select correct tracking token' - ) - }) - it('should create analytics with correct configuration', () => { const { sut } = makeSut() - const analyticsClient = sut('development') + const analyticsClient = sut('token_segment') expect(analyticsClient).toBeTruthy() }) diff --git a/src/tests/plugins/factories/segment-handler-token-factory.test.js b/src/tests/plugins/factories/segment-handler-token-factory.test.js new file mode 100644 index 000000000..3079ab0e1 --- /dev/null +++ b/src/tests/plugins/factories/segment-handler-token-factory.test.js @@ -0,0 +1,36 @@ +import { describe, it, expect, vi, afterEach } from 'vitest' +import { makeSegmentToken } from '@/plugins/factories/segment-handler-token-factory' + +afterEach(() => { + vi.unstubAllEnvs() + vi.unstubAllGlobals() +}) + +describe('makeSegmentToken', () => { + it('should return the production token if environment is production', () => { + vi.stubEnv('VITE_SEGMENT_TOKEN', 'prod_token_value') + const result = makeSegmentToken() + + expect(result).toBe('prod_token_value') + }) + + it('should return the stage token if environment is not production', () => { + vi.stubEnv('VITE_SEGMENT_TOKEN', 'stage_token_value') + + const result = makeSegmentToken() + + expect(result).toBe('stage_token_value') + }) + + it('should warn and return an empty string if the token is missing', () => { + const warnMock = vi.spyOn(console, 'warn').mockImplementation(() => {}) + vi.stubEnv('VITE_SEGMENT_TOKEN', '') + + const result = makeSegmentToken() + + expect(warnMock).toHaveBeenCalledWith('Segment token is missing') + expect(result).toBeUndefined() + + warnMock.mockRestore() + }) +})