diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index dcfee4b92..985887035 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -70,7 +70,7 @@ jobs: SCRATCH_ENV: ${{ vars.SCRATCH_ENV }} SORTING_HAT_HOST: ${{ vars.SORTING_HAT_HOST }} USER_GUIDING_ID: ${{ secrets.USER_GUIDING_ID }} - ONBOARDING_TESTING_TOGGLED: ${{ secrets.ONBOARDING_TESTING_TOGGLED }} + ONBOARDING_TEST_ACTIVE: ${{ secrets.ONBOARDING_TEST_ACTIVE }} ONBOARDING_TESTING_STARTING_DATE: ${{ secrets.ONBOARDING_TESTING_STARTING_DATE }} ONBOARDING_TESTING_ENDING_DATE: ${{ secrets.ONBOARDING_TESTING_ENDING_DATE }} diff --git a/src/lib/onboarding.js b/src/lib/onboarding.js index 8131d4f8a..41f378ec4 100644 --- a/src/lib/onboarding.js +++ b/src/lib/onboarding.js @@ -7,43 +7,36 @@ const isAdmin = permissions => permissions.admin; const isMuted = permissions => !!Object.keys(permissions.mute_status).length; -const isDateInRange = (date, startingDate, endingDate) => { +const isDateInOnboardingRange = date => { const dateToCompare = Date.parse(date); - const startDate = Date.parse(startingDate); - const endDate = Date.parse(endingDate); + const startDate = Date.parse(process.env.ONBOARDING_TESTING_STARTING_DATE); + const endDate = Date.parse(process.env.ONBOARDING_TESTING_ENDING_DATE); - if (dateToCompare >= startDate && dateToCompare <= endDate) { - return true; - } - return false; + return dateToCompare >= startDate && dateToCompare <= endDate; }; const isRegisteredInRange = user => { const dateOfJoin = user.dateJoined.split('T')[0]; - return isDateInRange( - dateOfJoin, - process.env.ONBOARDING_TESTING_STARTING_DATE, - process.env.ONBOARDING_TESTING_ENDING_DATE - ); + return isDateInOnboardingRange(dateOfJoin); }; const isCurrentDayInRange = () => { const currentDate = new Date().toJSON() .split('T')[0]; - return isDateInRange( - currentDate, - process.env.ONBOARDING_TESTING_STARTING_DATE, - process.env.ONBOARDING_TESTING_ENDING_DATE - ); + return isDateInOnboardingRange(currentDate); }; -const isOnboardingTestingToggledOn = () => - JSON.parse(process.env.ONBOARDING_TESTING_TOGGLED); - -const isUserEligible = user => - user.id % 2 === 0 && isRegisteredInRange(user) && isCurrentDayInRange(); +const isUserEligible = (user, permissions) => + Object.keys(user).length !== 0 && + Object.keys(permissions).length !== 0 && + JSON.parse(process.env.ONBOARDING_TEST_ACTIVE) && + isRegisteredInRange(user) && + isCurrentDayInRange() && + !isAdmin(permissions) && + !isMuted(permissions) && + !isBanned(user); const calculateAgeGroup = (birthYear, birthMonth) => { const today = new Date(); @@ -66,14 +59,8 @@ const onboardingTestGroup = user => ONBOARDING_TESTING_GROUP_A_NAME : ONBOARDING_TESTING_GROUP_B_NAME); -export const onboardingEligibilityCheck = (user, permissions) => - Object.keys(user).length !== 0 && - Object.keys(permissions).length !== 0 && - isOnboardingTestingToggledOn() && - isUserEligible(user) && - !isAdmin(permissions) && - !isMuted(permissions) && - !isBanned(user); +export const shouldDisplayOnboarding = (user, permissions) => + user.id % 2 === 0 && isUserEligible(user, permissions); export const triggerAnalyticsEvent = eventVaribles => { window.dataLayer = window.dataLayer || []; @@ -83,12 +70,8 @@ export const triggerAnalyticsEvent = eventVaribles => { }); }; -export const sendUserProperties = user => { - if ( - !isOnboardingTestingToggledOn() || - !isRegisteredInRange(user) || - !isCurrentDayInRange() - ) { +export const sendUserProperties = (user, permissions) => { + if (!isUserEligible(user, permissions)) { window.dataLayer.push({ testGroup: null, ageGroup: null, diff --git a/src/views/preview/presentation.jsx b/src/views/preview/presentation.jsx index eeac5c040..f3cd24b16 100644 --- a/src/views/preview/presentation.jsx +++ b/src/views/preview/presentation.jsx @@ -43,7 +43,7 @@ require('./preview.scss'); const frameless = require('../../lib/frameless'); const {useState, useCallback, useEffect} = require('react'); const ProjectJourney = require('../../components/journeys/project-journey/project-journey.jsx'); -const {triggerAnalyticsEvent, onboardingEligibilityCheck} = require('../../lib/onboarding.js'); +const {triggerAnalyticsEvent, shouldDisplayOnboarding} = require('../../lib/onboarding.js'); // disable enter key submission on formsy input fields; otherwise formsy thinks // we meant to trigger the "See inside" button. Instead, treat these keypresses @@ -157,7 +157,7 @@ const PreviewPresentation = ({ setCanViewProjectJourney( queryString.parse(location.search, {parseBooleans: true}).showJourney && !userOwnsProject && - onboardingEligibilityCheck(user, permissions) + shouldDisplayOnboarding(user, permissions) ); }, [userOwnsProject, user, permissions]); const shareDate = ((projectInfo.history && projectInfo.history.shared)) ? projectInfo.history.shared : ''; diff --git a/src/views/preview/project-view.jsx b/src/views/preview/project-view.jsx index d9b8f544a..9f967c812 100644 --- a/src/views/preview/project-view.jsx +++ b/src/views/preview/project-view.jsx @@ -47,7 +47,7 @@ const {useEffect, useState} = require('react'); const EditorJourney = require('../../components/journeys/editor-journey/editor-journey.jsx'); const {usePrevious} = require('react-use'); const TutorialsHighlight = require('../../components/journeys/tutorials-highlight/tutorials-highlight.jsx'); -const {triggerAnalyticsEvent, sendUserProperties, onboardingEligibilityCheck} = require('../../lib/onboarding.js'); +const {triggerAnalyticsEvent, sendUserProperties, shouldDisplayOnboarding} = require('../../lib/onboarding.js'); const IntlGUIWithProjectHandler = ({...props}) => { const [showJourney, setShowJourney] = useState(false); @@ -62,7 +62,7 @@ const IntlGUIWithProjectHandler = ({...props}) => { props.projectId && props.projectId !== '0' && !isTutorialOpen && - onboardingEligibilityCheck(props.user, props.permissions) + shouldDisplayOnboarding(props.user, props.permissions) ) { setShowJourney(true); } @@ -258,8 +258,8 @@ class Preview extends React.Component { ); } - if (!prevProps.user.id && this.props.user.id) { - sendUserProperties(this.props.user); + if (!prevProps.user.id && this.props.user.id && this.props.permissions) { + sendUserProperties(this.props.user, this.props.permissions); } } componentWillUnmount () { @@ -548,7 +548,7 @@ class Preview extends React.Component { } const showJourney = queryString.parse(location.search, {parseBooleans: true}).showJourney; - if (showJourney && onboardingEligibilityCheck(this.props.user, this.props.permissions)) { + if (showJourney && shouldDisplayOnboarding(this.props.user, this.props.permissions)) { triggerAnalyticsEvent({ event: 'tutorial-played', playedProject: this.props.projectInfo.title @@ -667,7 +667,7 @@ class Preview extends React.Component { } handleRemix () { const showJourney = queryString.parse(location.search, {parseBooleans: true}).showJourney; - if (showJourney && onboardingEligibilityCheck(this.props.user, this.props.permissions)) { + if (showJourney && shouldDisplayOnboarding(this.props.user, this.props.permissions)) { triggerAnalyticsEvent({ event: 'tutorial-remixed', remixedProject: this.props.projectInfo.title diff --git a/test/unit/lib/onboarding.test.js b/test/unit/lib/onboarding.test.js index 6da1b174f..7864c3be8 100644 --- a/test/unit/lib/onboarding.test.js +++ b/test/unit/lib/onboarding.test.js @@ -1,4 +1,4 @@ -import {onboardingEligibilityCheck} from '../../../src/lib/onboarding'; +import {shouldDisplayOnboarding} from '../../../src/lib/onboarding'; describe('unit test lib/onboarding.js', () => { const startDate = new Date(); @@ -9,7 +9,7 @@ describe('unit test lib/onboarding.js', () => { let permissions; beforeEach(() => { - process.env.ONBOARDING_TESTING_TOGGLED = true; + process.env.ONBOARDING_TEST_ACTIVE = 'true'; process.env.ONBOARDING_TESTING_STARTING_DATE = startDate.toJSON().split('T')[0]; process.env.ONBOARDING_TESTING_ENDING_DATE = endDate.toJSON().split('T')[0]; @@ -17,95 +17,71 @@ describe('unit test lib/onboarding.js', () => { permissions = {admin: false, mute_status: {}, new_scratcher: true}; }); - describe('#onboardingEligibilityCheck', () => { + describe('#shouldDisplayOnboarding', () => { describe('when user is eligible to view onboarding journeys', () => { describe('when there is time frame for A/B testing', () => { test('returns true', () => { - expect(onboardingEligibilityCheck(user, permissions)).toBeTruthy(); + expect(shouldDisplayOnboarding(user, permissions)).toBeTruthy(); }); }); }); describe('when user is not eligible to view onboarding journeys', () => { describe('when feature flag is toggled off', () => { - beforeEach(() => { - process.env.ONBOARDING_TESTING_TOGGLED = false; - }); - test('returns false', () => { - expect(onboardingEligibilityCheck(user, permissions)).toBeFalsy(); + process.env.ONBOARDING_TEST_ACTIVE = 'false'; + expect(shouldDisplayOnboarding(user, permissions)).toBeFalsy(); }); }); describe('when user is in other testing group', () => { - beforeEach(() => { - user.id = 1; - }); - test('returns false', () => { - expect(onboardingEligibilityCheck(user, permissions)).toBeFalsy(); + user.id = 1; + expect(shouldDisplayOnboarding(user, permissions)).toBeFalsy(); }); }); describe('when user is registered outside of time frame', () => { - beforeEach(() => { + test('returns false', () => { const currentDate = new Date(); currentDate.setDate(currentDate.getDate() - 1); user.dateJoined = currentDate.toJSON(); - }); - - test('returns false', () => { - expect(onboardingEligibilityCheck(user, permissions)).toBeFalsy(); + expect(shouldDisplayOnboarding(user, permissions)).toBeFalsy(); }); }); describe('when user is admin', () => { - beforeEach(() => { - permissions.admin = true; - }); - test('returns false', () => { - expect(onboardingEligibilityCheck(user, permissions)).toBeFalsy(); + permissions.admin = true; + expect(shouldDisplayOnboarding(user, permissions)).toBeFalsy(); }); }); describe('when user is muted', () => { - beforeEach(() => { - permissions.mute_status = {showWarning: true}; - }); - test('returns false', () => { - expect(onboardingEligibilityCheck(user, permissions)).toBeFalsy(); + permissions.mute_status = {showWarning: true}; + expect(shouldDisplayOnboarding(user, permissions)).toBeFalsy(); }); }); describe('when user is banned', () => { - beforeEach(() => { - user.banned = true; - }); - test('returns false', () => { - expect(onboardingEligibilityCheck(user, permissions)).toBeFalsy(); + user.banned = true; + expect(shouldDisplayOnboarding(user, permissions)).toBeFalsy(); }); }); describe('when user is empty', () => { - beforeEach(() => { - user = {}; - }); - test('returns false', () => { - expect(onboardingEligibilityCheck(user, permissions)).toBeFalsy(); + user = {}; + expect(shouldDisplayOnboarding(user, permissions)).toBeFalsy(); }); }); describe('when permissions is empty', () => { - beforeEach(() => { - permissions = {}; - }); - test('returns false', () => { - expect(onboardingEligibilityCheck(user, permissions)).toBeFalsy(); + permissions = {}; + expect(shouldDisplayOnboarding(user, permissions)).toBeFalsy(); }); }); }); diff --git a/webpack.config.js b/webpack.config.js index 7aea1447c..827f92413 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -287,8 +287,8 @@ module.exports = { 'process.env.GTM_ID': process.env.GTM_ID ? `"${process.env.GTM_ID}"` : null, 'process.env.USER_GUIDING_ID': `"${process.env.USER_GUIDING_ID || ''}"`, 'process.env.SORTING_HAT_HOST': `"${process.env.SORTING_HAT_HOST || ''}"`, - 'process.env.ONBOARDING_TESTING_TOGGLED': `"${ - process.env.ONBOARDING_TESTING_TOGGLED || true + 'process.env.ONBOARDING_TEST_ACTIVE': `"${ + process.env.ONBOARDING_TEST_ACTIVE || true }"`, 'process.env.ONBOARDING_TESTING_STARTING_DATE': `"${ process.env.ONBOARDING_TESTING_STARTING_DATE || '2024-01-20'