Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/gladly-team/tab-web into …
Browse files Browse the repository at this point in the history
…spicer/momentum-test

# Conflicts:
#	src/pages/index.js
  • Loading branch information
Spicer Matthews committed Nov 27, 2023
2 parents 0de2c49 + 0a5196d commit 7e8898d
Show file tree
Hide file tree
Showing 95 changed files with 5,049 additions and 305 deletions.
2 changes: 1 addition & 1 deletion .env.development
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,4 @@ NEXT_PUBLIC_GROWTHBOOK_ENV=dev

########## Estimated Money Per Tab ##########

EST_MONEY_RAISED_PER_TAB=0.000765
NEXT_PUBLIC_EST_MONEY_RAISED_PER_TAB=0.000765
2 changes: 1 addition & 1 deletion .env.local.info
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,4 @@ NEXT_PUBLIC_GROWTHBOOK_ENV=local

########## Estimated Money Per Tab ##########

EST_MONEY_RAISED_PER_TAB=0.000765
NEXT_PUBLIC_EST_MONEY_RAISED_PER_TAB=0.000765
4 changes: 4 additions & 0 deletions .env.preview.info
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,7 @@ NEXT_PUBLIC_MEDIA_ENDPOINT=https://prod-tab2017-media.gladly.io
########## Growthbook ##########

NEXT_PUBLIC_GROWTHBOOK_ENV=dev

########## Estimated Money Per Tab ##########

NEXT_PUBLIC_EST_MONEY_RAISED_PER_TAB=0.000765
2 changes: 1 addition & 1 deletion .env.production.info
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,4 @@ NEXT_PUBLIC_GROWTHBOOK_ENV=production

########## Estimated Money Per Tab ##########

EST_MONEY_RAISED_PER_TAB=0.000765
NEXT_PUBLIC_EST_MONEY_RAISED_PER_TAB=0.000765
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"next-transpile-modules": "^8.0.0",
"prop-types": "^15.7.2",
"react": "^17.0.2",
"react-color": "^2.19.3",
"react-dom": "^17.0.2",
"react-firebaseui": "^5.0.2",
"react-relay": "^12.0.0",
Expand All @@ -68,7 +69,7 @@
"remark-parse": "^9.0.0",
"remark-rehype": "^8.0.0",
"swr": "^1.0.1",
"tab-ads": "^1.1.10",
"tab-ads": "^1.1.23",
"tab-cmp": "^0.15.0-alpha.0",
"unified": "^9.0.0",
"uuid": "^8.3.2"
Expand Down
61 changes: 61 additions & 0 deletions src/__tests__/pages/account.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import localStorageFeaturesManager from 'src/utils/localStorageFeaturesManager'
import Switch from '@material-ui/core/Switch'
import localStorageMgr from 'src/utils/localstorage-mgr'
import { STORAGE_NEW_USER_IS_TAB_V4_BETA } from 'src/utils/constants'
import UpdateWidgetEnabledMutation from 'src/utils/mutations/UpdateWidgetEnabledMutation'

jest.mock('next-offline/runtime')
jest.mock('tab-cmp')
Expand All @@ -49,6 +50,7 @@ jest.mock('src/utils/localStorageFeaturesManager', () => ({
getFeatureValue: jest.fn(),
}))
jest.mock('src/utils/localstorage-mgr', () => ({ removeItem: jest.fn() }))
jest.mock('src/utils/mutations/UpdateWidgetEnabledMutation')

const getMockDataResponse = () => ({
user: {
Expand All @@ -62,6 +64,17 @@ const getMockDataResponse = () => ({
},
name: 'Cats',
},
widgets: {
edges: [
{
node: {
id: 'fake-widget-id-bookmarks',
type: 'bookmarks',
enabled: false,
},
},
],
},
},
app: {
causes: {
Expand Down Expand Up @@ -321,6 +334,54 @@ describe('account.js', () => {
const content = wrapper.find(Switch)
expect(content.length).toEqual(1)
})

it('updates Bookmarks widget data and calls mutation if applicable user', async () => {
expect.assertions(3)
const AccountPage = require('src/pages/account').default
const mockProps = getMockProps()
const defaultMockData = getMockDataResponse()
useData.mockReturnValue({ data: defaultMockData })
localStorageFeaturesManager.getFeatureValue.mockReturnValue('true')
const wrapper = mount(<AccountPage {...mockProps} />)

expect(wrapper.find(Switch).first().prop('checked')).toEqual(false)

await act(async () => {
wrapper.find(Switch).first().prop('onChange')({
target: { checked: true },
})
await flushAllPromises()
wrapper.update()
})

expect(UpdateWidgetEnabledMutation).toHaveBeenCalledWith(
defaultMockData.user,
{
id: 'fake-widget-id-bookmarks',
type: 'bookmarks',
enabled: false,
},
true
)

await act(async () => {
wrapper.find(Switch).first().prop('onChange')({
target: { checked: true },
})
await flushAllPromises()
wrapper.update()
})

expect(UpdateWidgetEnabledMutation).toHaveBeenCalledWith(
defaultMockData.user,
{
id: 'fake-widget-id-bookmarks',
type: 'bookmarks',
enabled: false,
},
false
)
})
})

const getRevertAccountItem = (wrapper) =>
Expand Down
47 changes: 46 additions & 1 deletion src/__tests__/pages/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
STORAGE_NEW_USER_CAUSE_ID,
HAS_SEEN_SEARCH_V2_TOOLTIP,
CAUSE_IMPACT_TYPES,
WIDGET_TYPE_BOOKMARKS,
} from 'src/utils/constants'
import {
showMockAchievements,
Expand Down Expand Up @@ -59,6 +60,8 @@ import { isSearchActivityComponentSupported } from 'src/utils/browserSupport'
import localStorageFeaturesManager from 'src/utils/localStorageFeaturesManager'
import moment from 'moment'
import GroupImpactContainer from 'src/components/groupImpactComponents/GroupImpactContainer'
import AddShortcutPageContainer from 'src/components/AddShortcutPageContainer'
import FrontpageShortcutListContainer from 'src/components/FrontpageShortcutListContainer'

jest.mock('uuid')
uuid.mockReturnValue('some-uuid')
Expand Down Expand Up @@ -165,6 +168,20 @@ const getMockProps = () => ({
notifications: [],
searches: 10,
showSfacIcon: false,
widgets: {
edges: [
{
node: {
enabled: true,
id: 'abcde',
type: WIDGET_TYPE_BOOKMARKS,
data: JSON.stringify({
bookmarks: [],
}),
},
},
],
},
},
userImpact: {
userId: 'asdf',
Expand Down Expand Up @@ -195,6 +212,7 @@ beforeEach(() => {
useDoesBrowserSupportSearchExtension.mockReturnValue(true)
useBrowserName.mockReturnValue('chrome')
MockDate.set(moment(mockNow))
localStorageFeaturesManager.getFeatureValue.mockReturnValue('false')
})

afterEach(() => {
Expand Down Expand Up @@ -1544,6 +1562,33 @@ describe('index.js', () => {
})
})

it('does display shortcut components if applicable', async () => {
localStorageFeaturesManager.getFeatureValue.mockReturnValue('true')
const IndexPage = require('src/pages/index').default
const defaultMockProps = getMockProps()
useData.mockReturnValue({ data: defaultMockProps.data })
const wrapper = mount(<IndexPage {...defaultMockProps} />)

expect(wrapper.find(FrontpageShortcutListContainer).exists()).toBe(true)

wrapper
.find(FrontpageShortcutListContainer)
.find(IconButton)
.simulate('click')

expect(wrapper.find(AddShortcutPageContainer).exists()).toBe(true)
})

it('does not shortcut components if applicable', async () => {
const IndexPage = require('src/pages/index').default
const defaultMockProps = getMockProps()
useData.mockReturnValue({ data: defaultMockProps.data })
const wrapper = mount(<IndexPage {...defaultMockProps} />)

expect(wrapper.find(FrontpageShortcutListContainer).exists()).toBe(false)
expect(wrapper.find(AddShortcutPageContainer).exists()).toBe(false)
})

/* END: core tests */

/* START: notification tests */
Expand All @@ -1556,7 +1601,7 @@ describe('index.js: hardcoded notifications', () => {
const IndexPage = require('src/pages/index').default
const mockProps = getMockProps()
useData.mockReturnValue({ data: mockProps.data, isDataFresh: true })
const wrapper = mount(<IndexPage {...mockProps} />)
const wrapper = shallow(<IndexPage {...mockProps} />)
const notification = wrapper.find(Notification)
expect(notification.exists()).not.toBe(true)
})
Expand Down
Binary file added src/assets/images/shortcut.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/promos/allexpress.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/promos/bookshop.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/promos/glossier.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/promos/horse.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/promos/kiwico.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/promos/lego.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/promos/lowes.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/promos/macys.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/promos/microsoft.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/promos/oldnavy.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/promos/samsung.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/promos/sephora.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/promos/sonos.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/promos/thriftbooks.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/promos/ultra-beauty.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/promos/walmart.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/promos/zulily.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
89 changes: 75 additions & 14 deletions src/components/AddShortcut.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import React, { useState } from 'react'
import React, { useEffect, useState } from 'react'
import { makeStyles } from '@material-ui/core/styles'
import Button from '@material-ui/core/Button'
import PropTypes from 'prop-types'
import { Typography } from '@material-ui/core'
import TextField from '@material-ui/core/TextField'
import { addProtocolToURLIfNeeded } from 'src/utils/urls'
import Notification from './Notification'

const useStyles = makeStyles((theme) => ({
Expand Down Expand Up @@ -34,32 +35,80 @@ const useStyles = makeStyles((theme) => ({
marginBottom: theme.spacing(2),
},
}))
const AddShortcut = ({ onCancel, onSave }) => {
const [open, setOpen] = useState(true)
const [name, setName] = useState('')
const [url, setUrl] = useState('')

const isValidUrl = (urlString) => {
try {
return Boolean(new URL(urlString))
} catch (e) {
return false
}
}

const AddShortcut = ({
onCancel,
onSave,
existingName,
existingUrl,
existingId,
}) => {
const [name, setName] = useState(existingName)
const [url, setUrl] = useState(existingUrl)
const [nameError, setNameError] = useState(null)
const [urlError, setUrlError] = useState(null)
useEffect(() => setName(existingName), [existingName])
useEffect(() => setUrl(existingUrl), [existingUrl])
const classes = useStyles()
const onCancelClick = () => {
setName('')
setUrl('')
setName(existingName)
setUrl(existingUrl)
onCancel()
setOpen(false)
}
const validateName = (newName) => {
let newNameError
if (newName.length === 0) {
newNameError = 'Shortcut name cannot be empty.'
} else {
newNameError = null
}
setNameError(newNameError)
return newNameError
}
const validateUrl = (newUrl) => {
let newUrlError
if (newUrl.length === 0) {
newUrlError = 'URL cannot be empty.'
} else if (!isValidUrl(addProtocolToURLIfNeeded(newUrl))) {
newUrlError = 'URL is not valid.'
} else {
newUrlError = null
}
setUrlError(newUrlError)
return newUrlError
}
const validateForm = () => {
const newNameError = validateName(name)
const newUrlError = validateUrl(url)
return newNameError || newUrlError
}
const onSaveClick = () => {
onSave(name, url)
setName('')
setUrl('')
setOpen(false)
const newUrl = addProtocolToURLIfNeeded(url)
if (validateForm()) {
return
}
onSave(existingId, name, newUrl)
setName(name)
setUrl(newUrl)
}
const changeName = (e) => {
setName(e.target.value)
validateName(e.target.value)
}
const changeUrl = (e) => {
setUrl(e.target.value)
validateUrl(e.target.value)
}
return (
<Notification
open={open}
text={
<span className={classes.text}>
<Typography
Expand All @@ -68,7 +117,8 @@ const AddShortcut = ({ onCancel, onSave }) => {
gutterBottom
color="primary"
>
Add Shortcut
{existingName === '' && existingUrl === '' ? 'Add' : 'Edit'}{' '}
Shortcut
</Typography>
<hr />
<div className={classes.urlFields}>
Expand All @@ -78,6 +128,8 @@ const AddShortcut = ({ onCancel, onSave }) => {
label="Name"
value={name}
onChange={changeName}
error={!!nameError}
helperText={nameError}
className={classes.textField}
/>
<TextField
Expand All @@ -86,6 +138,8 @@ const AddShortcut = ({ onCancel, onSave }) => {
label="URL"
value={url}
onChange={changeUrl}
error={!!urlError}
helperText={urlError}
className={classes.textField}
/>
</div>
Expand All @@ -105,6 +159,7 @@ const AddShortcut = ({ onCancel, onSave }) => {
className={classes.yesButton}
variant="contained"
disableElevation
disabled={!!(nameError || urlError)}
>
Save
</Button>
Expand All @@ -117,11 +172,17 @@ const AddShortcut = ({ onCancel, onSave }) => {
AddShortcut.propTypes = {
onCancel: PropTypes.func,
onSave: PropTypes.func,
existingName: PropTypes.string,
existingUrl: PropTypes.string,
existingId: PropTypes.string,
}

AddShortcut.defaultProps = {
onCancel: () => {},
onSave: () => {},
existingName: '',
existingUrl: '',
existingId: null,
}

export default AddShortcut
6 changes: 6 additions & 0 deletions src/components/AddShortcut.stories.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,9 @@ const Template = (args) => {

export const basic = Template.bind({})
basic.args = {}

export const existingValues = Template.bind({})
existingValues.args = {
existingName: 'Google',
existingUrl: 'http://www.google.com',
}
Loading

0 comments on commit 7e8898d

Please sign in to comment.