From dee24c8a8c984a1e63d73240fe8851f8bc1b46e1 Mon Sep 17 00:00:00 2001
From: Katrina Nguyen <71999631+katrinan029@users.noreply.github.com>
Date: Tue, 5 Mar 2024 13:27:43 -0800
Subject: [PATCH 1/2] feat: update prequery experiment logic for variant group
(#988)
feat: update prequery experiment logic for variant group
---
package-lock.json | 36 +++++++++----------
package.json | 8 ++---
src/components/search/Search.jsx | 26 ++++++++++----
.../search/tests/SearchSections.test.jsx | 27 +++++++++++---
src/utils/optimizely.js | 1 +
5 files changed, 66 insertions(+), 32 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 116d96096d..58b5271315 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -11,10 +11,10 @@
"dependencies": {
"@edx/brand": "npm:@openedx/brand-openedx@1.2.2",
"@edx/frontend-component-footer": "13.0.2",
- "@edx/frontend-enterprise-catalog-search": "7.0.0",
- "@edx/frontend-enterprise-hotjar": "4.0.0",
- "@edx/frontend-enterprise-logistration": "6.0.0",
- "@edx/frontend-enterprise-utils": "6.0.0",
+ "@edx/frontend-enterprise-catalog-search": "8.0.0",
+ "@edx/frontend-enterprise-hotjar": "5.0.0",
+ "@edx/frontend-enterprise-logistration": "7.0.0",
+ "@edx/frontend-enterprise-utils": "7.0.0",
"@edx/frontend-platform": "7.1.0",
"@loadable/component": "5.16.3",
"@openedx/paragon": "^21.5.7",
@@ -2323,11 +2323,11 @@
}
},
"node_modules/@edx/frontend-enterprise-catalog-search": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/@edx/frontend-enterprise-catalog-search/-/frontend-enterprise-catalog-search-7.0.0.tgz",
- "integrity": "sha512-w0DMJBz8cong8I/vyoX3T4cfAyeBaV4W5pWh0rkTQIBh2bathJdD9cP4MNZeWRp7gG1z2iw9/WhWMY5jcTpraw==",
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@edx/frontend-enterprise-catalog-search/-/frontend-enterprise-catalog-search-8.0.0.tgz",
+ "integrity": "sha512-hl46gWVhH09AcepKP+X+Ug9ZXYO/8N19W5Dr/9tsX8+KB18rXVRy+0wZGhVtN9doq8hBbqKi5D0WkpC1NdMIxw==",
"dependencies": {
- "@edx/frontend-enterprise-utils": "^6.0.0",
+ "@edx/frontend-enterprise-utils": "^7.0.0",
"classnames": "2.2.5",
"lodash.debounce": "4.0.8",
"prop-types": "15.7.2"
@@ -2347,9 +2347,9 @@
"integrity": "sha512-DTt3GhOUDKhh4ONwIJW4lmhyotQmV2LjNlGK/J2hkwUcqcbKkCLAdJPtxQnxnlc7SR3f1CEXCyMmc7WLUsWbNA=="
},
"node_modules/@edx/frontend-enterprise-hotjar": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/@edx/frontend-enterprise-hotjar/-/frontend-enterprise-hotjar-4.0.0.tgz",
- "integrity": "sha512-FCXjJJ8gdluxasywt07irIgxV6uRTzjDuOCdb5QF9mlj8I3sbURxXBWeYb5wg/Dj1usBq0vhSnWNNny5iwJK8w==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/@edx/frontend-enterprise-hotjar/-/frontend-enterprise-hotjar-5.0.0.tgz",
+ "integrity": "sha512-zCV09oi9AyJE2K/4lvmnOuHmOltOHnKr2/AqHky5NuXJVSHgFx+nA9qd8LrcEGFLyM0vi8sDozgY+STNNUYAdg==",
"peerDependencies": {
"react": "^16.12.0 || ^17.0.0",
"react-dom": "^16.12.0 || ^17.0.0",
@@ -2357,11 +2357,11 @@
}
},
"node_modules/@edx/frontend-enterprise-logistration": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/@edx/frontend-enterprise-logistration/-/frontend-enterprise-logistration-6.0.0.tgz",
- "integrity": "sha512-HLJ7YF6SicgEj1tcjNJ6iHl6lxC+EvEGIuxzfZNg/WsDW411lq43N1eQquGFfcF3uDPyKeI8e6tyWsKqyvdFyA==",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/@edx/frontend-enterprise-logistration/-/frontend-enterprise-logistration-7.0.0.tgz",
+ "integrity": "sha512-uqnsXtMqRPM9dXA457SwdMnfrO3yjXOnr25sCCdJvuyZCZOYbMFh69S/iWHMad8LwZlDuI4GJC1/lknAbB+0qg==",
"dependencies": {
- "@edx/frontend-enterprise-utils": "^6.0.0",
+ "@edx/frontend-enterprise-utils": "^7.0.0",
"prop-types": "15.7.2"
},
"peerDependencies": {
@@ -2372,9 +2372,9 @@
}
},
"node_modules/@edx/frontend-enterprise-utils": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/@edx/frontend-enterprise-utils/-/frontend-enterprise-utils-6.0.0.tgz",
- "integrity": "sha512-DgNvCg7Q9Z2102pZgkV4b1EYRfgJIELHcYHC/9kss87Y0aY9k9BThwqkFC46f/3NluYWzVxBRKnYW5MLGls5Lg==",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/@edx/frontend-enterprise-utils/-/frontend-enterprise-utils-7.0.0.tgz",
+ "integrity": "sha512-6w5wnA7WSl9qVRexUdUXBCGr9XYelT8sJUO6DWY2pV1nvntcp5Ff1POX1dW75C/827m8zMxqcDyqZsTyz9Srsw==",
"dependencies": {
"@testing-library/react": "12.1.4",
"history": "4.10.1"
diff --git a/package.json b/package.json
index c8604df23a..0a32f8a729 100644
--- a/package.json
+++ b/package.json
@@ -9,10 +9,10 @@
"dependencies": {
"@edx/brand": "npm:@openedx/brand-openedx@1.2.2",
"@edx/frontend-component-footer": "13.0.2",
- "@edx/frontend-enterprise-catalog-search": "7.0.0",
- "@edx/frontend-enterprise-hotjar": "4.0.0",
- "@edx/frontend-enterprise-logistration": "6.0.0",
- "@edx/frontend-enterprise-utils": "6.0.0",
+ "@edx/frontend-enterprise-catalog-search": "8.0.0",
+ "@edx/frontend-enterprise-hotjar": "5.0.0",
+ "@edx/frontend-enterprise-logistration": "7.0.0",
+ "@edx/frontend-enterprise-utils": "7.0.0",
"@edx/frontend-platform": "7.1.0",
"@loadable/component": "5.16.3",
"@openedx/paragon": "^21.5.7",
diff --git a/src/components/search/Search.jsx b/src/components/search/Search.jsx
index 856a85a808..ca4b533151 100644
--- a/src/components/search/Search.jsx
+++ b/src/components/search/Search.jsx
@@ -42,6 +42,14 @@ import AuthenticatedPageContext from '../app/AuthenticatedPageContext';
import { determineLearnerHasContentAssignmentsOnly } from '../enterprise-user-subsidy/data/utils';
import { EVENTS, isExperimentVariant, pushEvent } from '../../utils/optimizely';
+export const sendPushEvent = (isPreQueryEnabled, courseKeyMetadata) => {
+ if (isPreQueryEnabled) {
+ pushEvent(EVENTS.PREQUERY_SUGGESTION_CLICK, { courseKeyMetadata });
+ } else {
+ pushEvent(EVENTS.SEARCH_SUGGESTION_CLICK, { courseKeyMetadata });
+ }
+};
+
const Search = () => {
const config = getConfig();
const { pathwayUUID } = useParams();
@@ -154,12 +162,17 @@ const Search = () => {
const shouldDisplayBalanceAlert = hasNoEnterpriseOffersBalance || hasLowEnterpriseOffersBalance;
const { content_type: contentType } = refinements;
- const hasRefinements = Object.keys(refinements).filter(refinement => refinement !== 'showAll').length > 0 && (contentType !== undefined ? contentType.length > 0 : true);
+ const hasRefinements = Object.keys(refinements).filter(refinement => refinement !== 'showAll').length > 0
+ && (contentType !== undefined ? contentType.length > 0 : true);
- const optimizelyPrequerySuggestionClickHandler = (courseKey) => {
- if (isExperimentVariation) {
- pushEvent(EVENTS.PREQUERY_SUGGESTION_CLICK, { courseKey });
- }
+ const isPreQueryEnabled = enterpriseConfig.enterpriseFeatures?.featurePrequerySearchSuggestions
+ && isExperimentVariation;
+
+ const optimizelySuggestionClickHandler = (courseKey) => {
+ // Programs pass in a list of keys. Optimizely does not accept array values
+ // so we are joining the items in the array.
+ const courseKeyMetadata = Array.isArray(courseKey) ? courseKey.join(', ') : courseKey;
+ sendPushEvent(isPreQueryEnabled, courseKeyMetadata);
};
return (
@@ -185,7 +198,8 @@ const Search = () => {
index={courseIndex}
filters={filters}
enterpriseConfig={enterpriseConfig}
- optimizelyPrequerySuggestionClickHandler={optimizelyPrequerySuggestionClickHandler}
+ optimizelySuggestionClickHandler={optimizelySuggestionClickHandler}
+ isPreQueryEnabled={isPreQueryEnabled}
/>
)}
diff --git a/src/components/search/tests/SearchSections.test.jsx b/src/components/search/tests/SearchSections.test.jsx
index d37e1d0007..3ef5299910 100644
--- a/src/components/search/tests/SearchSections.test.jsx
+++ b/src/components/search/tests/SearchSections.test.jsx
@@ -9,10 +9,11 @@ import { renderWithRouter } from '../../../utils/tests';
import '@testing-library/jest-dom';
import SearchProgram from '../SearchProgram';
import SearchPathway from '../SearchPathway';
-import Search from '../Search';
+import Search, { sendPushEvent } from '../Search';
import AuthenticatedPageContext from '../../app/AuthenticatedPageContext';
import { UserSubsidyContext } from '../../enterprise-user-subsidy';
import { SUBSIDY_TYPE, SubsidyRequestsContext } from '../../enterprise-subsidy-requests';
+import { EVENTS, pushEvent } from '../../../utils/optimizely';
const APP_CONFIG = {
ALGOLIA_INDEX_NAME: 'test-index-name',
@@ -23,6 +24,11 @@ jest.mock('@edx/frontend-platform/config', () => ({
getConfig: jest.fn(() => APP_CONFIG),
}));
+jest.mock('../../../utils/optimizely', () => ({
+ ...jest.requireActual('../../../utils/optimizely'),
+ pushEvent: jest.fn(),
+}));
+
const searchContext1 = {
refinements: { showAll: 1, content_type: ['course'] },
dispatch: () => null,
@@ -41,6 +47,9 @@ const initialAppState = {
name: 'BearsRUs',
slug: 'test-enterprise-slug',
showIntegrationWarning: false,
+ enterpriseFeatures: {
+ featurePrequerySearchSuggestions: true,
+ },
},
authenticatedUser: { userId: 'test-user-id' },
algolia: {
@@ -85,7 +94,7 @@ describe('', () => {
renderWithRouter(
-
+
@@ -97,7 +106,7 @@ describe('', () => {
renderWithRouter(
-
+
@@ -110,7 +119,7 @@ describe('', () => {
renderWithRouter(
-
+
@@ -172,4 +181,14 @@ describe('', () => {
);
expect(screen.getByText('Pathways (2 results)')).toBeInTheDocument();
});
+
+ describe('pushEvent', () => {
+ test.each([
+ [true, 'test-course-101', EVENTS.PREQUERY_SUGGESTION_CLICK],
+ [false, 'test-course-102', EVENTS.SEARCH_SUGGESTION_CLICK],
+ ])('if isPrequeryEnabled is %p with course metadata %p, submit event %p', (isPrequeryEnabled, courseKeyMetadata, event) => {
+ sendPushEvent(isPrequeryEnabled, courseKeyMetadata);
+ expect(pushEvent).toHaveBeenCalledWith(event, { courseKeyMetadata });
+ });
+ });
});
diff --git a/src/utils/optimizely.js b/src/utils/optimizely.js
index 0b7a0cb37d..60605a83d6 100644
--- a/src/utils/optimizely.js
+++ b/src/utils/optimizely.js
@@ -2,6 +2,7 @@ export const EVENTS = {
ENROLLMENT_CLICK: 'enterprise_learner_portal_enrollment_click',
FIRST_ENROLLMENT_CLICK: 'enterprise_learner_portal_first_enrollment_click',
PREQUERY_SUGGESTION_CLICK: 'enterprise_learner_portal_prequery_suggestions_click',
+ SEARCH_SUGGESTION_CLICK: 'enterprise_learner_portal_search_suggestions_click',
};
export const getActiveExperiments = () => {
From 471e5cda8a87deecedd072333db319f012555245 Mon Sep 17 00:00:00 2001
From: Katrina Nguyen <71999631+katrinan029@users.noreply.github.com>
Date: Tue, 5 Mar 2024 13:38:53 -0800
Subject: [PATCH 2/2] feat: add support for optimizely experiments on stage
(#985)
feat: add support for optimizely experiments on stage
---
public/index.html | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/public/index.html b/public/index.html
index f9bf23e122..e1cb9886ca 100644
--- a/public/index.html
+++ b/public/index.html
@@ -15,11 +15,12 @@
<% }); %>
- <% if (htmlWebpackPlugin.options.NODE_ENV === 'production' && htmlWebpackPlugin.options.OPTIMIZELY_PROJECT_ID) { %>
+ <% if (htmlWebpackPlugin.options.NODE_ENV==='production' && htmlWebpackPlugin.options.OPTIMIZELY_PROJECT_ID &&
+ htmlWebpackPlugin.options.DEPLOYMENT_ENV==='production') { %>
<% } %>
- <% if (htmlWebpackPlugin.options.NODE_ENV !== 'production' && htmlWebpackPlugin.options.OPTIMIZELY_PROJECT_ID) { %>
+ <% if (htmlWebpackPlugin.options.OPTIMIZELY_PROJECT_ID) { %>
<% } %>