Skip to content

Commit

Permalink
TFAC-789: Setting up Growthbook SDK
Browse files Browse the repository at this point in the history
  • Loading branch information
Jed Tan authored and jedtan committed Feb 24, 2022
1 parent b4849e0 commit bd11fd7
Show file tree
Hide file tree
Showing 12 changed files with 136 additions and 8 deletions.
6 changes: 5 additions & 1 deletion .env.development
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,8 @@ NEXT_PUBLIC_URLS_BASE_PATH=/newtab
NEXT_PUBLIC_URLS_USE_TRAILING_SLASH=true

# Media Endpoint
NEXT_PUBLIC_MEDIA_ENDPOINT=https://dev-tab2017-media.gladly.io
NEXT_PUBLIC_MEDIA_ENDPOINT=https://dev-tab2017-media.gladly.io

########## Growthbook ##########

NEXT_PUBLIC_GROWTHBOOK_ENV=dev
2 changes: 2 additions & 0 deletions .env.local.info
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,5 @@
##########################################
# As needed, override .env.development
# values here.

NEXT_PUBLIC_GROWTHBOOK_ENV=local
3 changes: 3 additions & 0 deletions .env.preview.info
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,6 @@ COOKIE_SECURE_SAME_SITE_NONE=true
NEXT_PUBLIC_URLS_BASE_PATH=/newtab
NEXT_PUBLIC_URLS_USE_TRAILING_SLASH=true

########## Growthbook ##########

NEXT_PUBLIC_GROWTHBOOK_ENV=qa
4 changes: 4 additions & 0 deletions .env.production.info
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,7 @@ NEXT_PUBLIC_URLS_BASE_PATH=/newtab
NEXT_PUBLIC_URLS_USE_TRAILING_SLASH=true
# Media Endpoint
NEXT_PUBLIC_MEDIA_ENDPOINT=https://prod-tab2017-media.gladly.io

########## Growthbook ##########

NEXT_PUBLIC_GROWTHBOOK_ENV=production
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
},
"dependencies": {
"@fontsource/poppins": "^4.5.0",
"@growthbook/growthbook-react": "^0.7.0",
"@material-ui/core": "^4.11.2",
"@material-ui/icons": "^4.11.2",
"@material-ui/lab": "^4.11.3-deprecations.1",
Expand Down
17 changes: 17 additions & 0 deletions src/__mocks__/@growthbook/growthbook-react.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import features from 'src/features/features.json'

const { GrowthBook, GrowthBookProvider } = jest.requireActual(
'@growthbook/growthbook-react'
)
const mockGrowthBook = jest.createMockFromModule('@growthbook/growthbook-react')

mockGrowthBook.useGrowthBook = jest.fn(() => {
const growthbook = new GrowthBook()
growthbook.setFeatures(features)
return growthbook
})

mockGrowthBook.GrowthBook = jest.fn(() => new GrowthBook())
mockGrowthBook.GrowthBookProvider = GrowthBookProvider

module.exports = mockGrowthBook
16 changes: 16 additions & 0 deletions src/__tests__/pages/_app.moduleLoad.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -268,3 +268,19 @@ describe('_app: router overrides', () => {
})
})
})

describe('_app: GrowthBook', () => {
it('initializes app with Growthbook and calls it with features', () => {
expect.assertions(1)
const { GrowthBook } = require('@growthbook/growthbook-react')
const features = require('src/features/features.json')
const mockGrowthbook = {
setFeatures: jest.fn(),
}
GrowthBook.mockImplementation(() => mockGrowthbook)

// eslint-disable-next-line no-unused-expressions
require('src/pages/_app').default
expect(mockGrowthbook.setFeatures).toHaveBeenCalledWith(features)
})
})
24 changes: 24 additions & 0 deletions src/__tests__/pages/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
showMockAchievements,
showBackgroundImages,
showDevelopmentOnlyMissionsFeature,
showInternalOnly,
} from 'src/utils/featureFlags'
import flushAllPromises from 'src/utils/testHelpers/flushAllPromises'
import Achievement from 'src/components/Achievement'
Expand All @@ -31,6 +32,7 @@ import InviteFriendsIconContainer from 'src/components/InviteFriendsIconContaine
import SquadCounter from 'src/components/SquadCounter'
import UserImpactContainer from 'src/components/UserImpactContainer'
import useCustomTheming from 'src/utils/hooks/useCustomTheming'
import { useGrowthBook } from '@growthbook/growthbook-react'

jest.mock('uuid')
uuid.mockReturnValue('some-uuid')
Expand Down Expand Up @@ -74,6 +76,7 @@ jest.mock('src/components/SquadCounter')
jest.mock('src/components/UserImpactContainer')
jest.mock('src/utils/pageWrappers/CustomThemeHOC')
jest.mock('src/utils/hooks/useCustomTheming')
jest.mock('@growthbook/growthbook-react')

const setUpAds = () => {
isClientSide.mockReturnValue(true)
Expand Down Expand Up @@ -852,4 +855,25 @@ describe('index.js', () => {
'testSetMe'
)
})

it('calls setFeatures on growthbook with correct values', async () => {
expect.assertions(1)
const IndexPage = require('src/pages/index').default
const mockProps = getMockProps()
const mockGrowthbook = {
feature: jest.fn().mockReturnValue({ value: true }),
setAttributes: jest.fn(),
}
useGrowthBook.mockReturnValue(mockGrowthbook)
mount(<IndexPage {...mockProps} />)

expect(mockGrowthbook.setAttributes).toHaveBeenCalledWith({
userId: mockProps.data.user.id,
env: process.env.NEXT_PUBLIC_GROWTHBOOK_ENV,
causeId: mockProps.data.user.cause.causeId,
v4BetaEnabled: true,
joined: mockProps.data.user.joined,
isTabTeamMember: showInternalOnly(mockProps.data.user.email),
})
})
})
14 changes: 14 additions & 0 deletions src/features/features.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"test-feature": {
"defaultValue": false,
"rules": [
{
"condition": {
"isTabTeamMember": true,
"env": "local"
},
"force": true
}
]
}
}
24 changes: 18 additions & 6 deletions src/pages/_app.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import 'src/utils/styles/globalStyles.css'
import '@fontsource/poppins/300.css'
import '@fontsource/poppins/400.css'
import '@fontsource/poppins/500.css'
import { GrowthBook, GrowthBookProvider } from '@growthbook/growthbook-react'
import features from 'src/features/features.json'

initAuth()

Expand Down Expand Up @@ -83,6 +85,14 @@ if (isClientSide()) {
// The MUI theme prior to any user-level customization.
const standardTheme = createTheme(defaultTheme)

// Context for designing GrowthBook features: https://docs.google.com/document/d/1ru-oO7-OWVM3ByYZseJBQ-Mu8_1LwcLUMNlHdpQ2JN4/edit#heading=h.5qxtlklvlhrs
// When adding a new experiment, design it so that the weights of the experiment should be constant.
// For example to design an experiment and modify experiment, we can:
// - Run an experiment over x% of traffic (e.g. a 50/50 exp over 10% of traffic)
// - Adjust the percentage of traffic the experiment is run over. This allows us to scale the total amount of traffic going to a particular bucket.
const growthbook = new GrowthBook()
growthbook.setFeatures(features)

const MyApp = (props) => {
const { Component, pageProps } = props

Expand Down Expand Up @@ -121,12 +131,14 @@ const MyApp = (props) => {
content="minimum-scale=1, initial-scale=1, width=device-width"
/>
</Head>
<ThemeProvider theme={standardTheme}>
<CssBaseline />
<ErrorBoundary>
<Component {...pageProps} />
</ErrorBoundary>
</ThemeProvider>
<GrowthBookProvider growthbook={growthbook}>
<ThemeProvider theme={standardTheme}>
<CssBaseline />
<ErrorBoundary>
<Component {...pageProps} />
</ErrorBoundary>
</ThemeProvider>
</GrowthBookProvider>
</>
)
}
Expand Down
21 changes: 20 additions & 1 deletion src/pages/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
withAuthUserTokenSSR,
AuthAction,
} from 'next-firebase-auth'
import { useGrowthBook } from '@growthbook/growthbook-react'

// custom components
import Achievement from 'src/components/Achievement'
Expand Down Expand Up @@ -61,6 +62,7 @@ import {
showMockAchievements,
showBackgroundImages,
showDevelopmentOnlyMissionsFeature,
showInternalOnly,
} from 'src/utils/featureFlags'
import logger from 'src/utils/logger'
import FullPageLoader from 'src/components/FullPageLoader'
Expand Down Expand Up @@ -272,6 +274,7 @@ const getRelayQuery = async ({ AuthUser }) => {
hasViewedIntroFlow
tabs
vcCurrent
joined
cause {
causeId
individualImpactEnabled
Expand Down Expand Up @@ -340,10 +343,23 @@ const Index = ({ data: fallbackData }) => {
}
}, [])
const { app, user, userImpact } = data || {}
const { currentMission, email, cause } = user || {}
const { id: userId, currentMission, email, cause, joined } = user || {}
const { theme, onboarding, causeId, individualImpactEnabled } = cause || {}
const { primaryColor, secondaryColor } = theme || {}

const growthbook = useGrowthBook()

useEffect(() => {
growthbook.setAttributes({
userId,
env: process.env.NEXT_PUBLIC_GROWTHBOOK_ENV,
causeId,
v4BetaEnabled: true,
joined,
isTabTeamMember: showInternalOnly(email),
})
}, [causeId, email, growthbook, joined, userId])

// Set the theme based on cause.
const setTheme = useCustomTheming()
useEffect(
Expand Down Expand Up @@ -548,6 +564,9 @@ const Index = ({ data: fallbackData }) => {
variant="h5"
className={clsx(classes.userMenuItem)}
>
{growthbook.feature('test-feature').value ? (
<p>Welcome to our site!</p>
) : null}
<MoneyRaisedContainer app={app} />
</Typography>
</div>
Expand Down
12 changes: 12 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1652,6 +1652,18 @@
stream-events "^1.0.1"
xdg-basedir "^4.0.0"

"@growthbook/growthbook-react@^0.7.0":
version "0.7.0"
resolved "https://registry.yarnpkg.com/@growthbook/growthbook-react/-/growthbook-react-0.7.0.tgz#8a94a47dec60cc5ad25ea78dd97760d8f50cb401"
integrity sha512-3+aBMBO3PTfvxaNNiAE8nwej1fhtWwVuPZIwg2hyM4Jsrq3TjP+UPlbJNtT3VndLv5+cuzfVxMcl0Kr5ORlnww==
dependencies:
"@growthbook/growthbook" "^0.16.0"

"@growthbook/growthbook@^0.16.0":
version "0.16.2"
resolved "https://registry.yarnpkg.com/@growthbook/growthbook/-/growthbook-0.16.2.tgz#e5e5041992be66c684bc058832d925f5c579a96e"
integrity sha512-mEPqDLDSO6n76gp9TLoyvgjkBaFKrH9BJyQNb0PwF4oXXzjbgG2qsIuNL/DKJvvkYFqOK80mbDR6C5xw9HGHyA==

"@grpc/grpc-js@^1.3.2":
version "1.4.1"
resolved "https://registry.yarnpkg.com/@grpc/grpc-js/-/grpc-js-1.4.1.tgz#799063a4ff7395987d4fceb2aab133629b003840"
Expand Down

0 comments on commit bd11fd7

Please sign in to comment.