it('changes clientApp when different site link clicked', () => { const dispatchSpy = sinon.spy(_store, 'dispatch'); const fakeEvent = createFakeEvent({ currentTarget: { getAttribute: (attribute) => { if (attribute === 'data-clientapp') { return CLIENT_APP_ANDROID; } if (attribute === 'href') { return `/en-US/${CLIENT_APP_ANDROID}/`; } return undefined; }, }, }); const getAttributeSpy = sinon.spy(fakeEvent.currentTarget, 'getAttribute'); const fakeHistory = createFakeHistory(); _store.dispatch(setClientApp(CLIENT_APP_FIREFOX)); const root = render({ history: fakeHistory }); root.find(`.SectionLinks-clientApp-android`).simulate('click', fakeEvent); sinon.assert.called(fakeEvent.preventDefault); sinon.assert.calledWith(getAttributeSpy, 'data-clientapp'); sinon.assert.calledWith(getAttributeSpy, 'href'); sinon.assert.calledWith(dispatchSpy, setClientApp(CLIENT_APP_ANDROID)); sinon.assert.calledWith(fakeHistory.push, `/en-US/${CLIENT_APP_ANDROID}/`); });
function renderUserProfileEdit({ history = createFakeHistory(), i18n = fakeI18n(), params = { userId: 100 }, store = null, userProps, ...props } = {}) { if (!store) { // eslint-disable-next-line no-param-reassign store = dispatchSignInActions({ userId: params.userId, userProps: defaultUserProps(userProps), }).store; } return shallowUntilTarget( <UserProfileEdit _window={{}} history={history} i18n={i18n} match={{ params }} store={store} {...props} />, UserProfileEditBase, ); }
it('lets you create a new collection by navigating to the collection page', () => { const clientApp = CLIENT_APP_FIREFOX; const lang = 'fr'; const id = 234; const addon = createInternalAddon({ ...fakeAddon, id }); signInAndDispatchCollections({ clientApp, lang, }); const historySpy = createFakeHistory(); const root = render({ addon, history: historySpy }); const select = root.find('.AddAddonToCollection-select'); const createOption = findOption({ root, text: 'Create new collection', }); select.simulate( 'change', createFakeEvent({ target: { value: createOption.prop('value') }, }), ); sinon.assert.calledWith( historySpy.push, `/${lang}/${clientApp}/collections/add/?include_addon_id=${id}`, ); });
it('dispatches deleteUserAccount and logOutUser when current logged-in user confirms account deletion', () => { const clientApp = CLIENT_APP_FIREFOX; const lang = 'fr-FR'; const userId = 456; const params = { userId }; const { store } = dispatchSignInActions({ clientApp, lang, userProps: defaultUserProps({ id: userId }), }); const dispatchSpy = sinon.spy(store, 'dispatch'); const preventDefaultSpy = sinon.spy(); const errorHandler = createStubErrorHandler(); const history = createFakeHistory(); const root = renderUserProfileEdit({ errorHandler, history, params, store, }); dispatchSpy.resetHistory(); // User opens the modal. root .find('.UserProfileEdit-delete-button') .simulate('click', createFakeEvent()); sinon.assert.notCalled(dispatchSpy); sinon.assert.notCalled(preventDefaultSpy); // User confirms account deletion. root .find('.UserProfileEdit-confirm-button') .simulate( 'click', createFakeEvent({ preventDefault: preventDefaultSpy }), ); sinon.assert.callCount(dispatchSpy, 2); sinon.assert.calledWith( dispatchSpy, deleteUserAccount({ errorHandlerId: errorHandler.id, userId, }), ); sinon.assert.calledWith(dispatchSpy, logOutUser()); sinon.assert.calledWith(history.push, `/${lang}/${clientApp}`); sinon.assert.calledOnce(preventDefaultSpy); });
const getProps = (customProps = {}) => { return { addon: createInternalAddon(fakeAddon), i18n: fakeI18n(), history: createFakeHistory(), store, ...customProps, }; };
beforeEach(() => { fakeHistory = createFakeHistory(); store = dispatchClientMetadata().store; dispatchSignInActions({ lang, store, userId: signedInUserId, userProps: { username: signedInUsername }, }); });
it("does not update the page when removeAddon is called and the current page isn't the last page", () => { const authorUserId = 11; const { store } = dispatchSignInActions({ userId: authorUserId }); const addons = createFakeCollectionAddons(); const addonId = addons[0].addon.id; const detail = createFakeCollectionDetail({ authorId: authorUserId, // This will simulate 1 item on the 3nd page. count: DEFAULT_API_PAGE_SIZE * 2 + 1, }); const errorHandler = createStubErrorHandler(); const fakeDispatch = sinon.spy(store, 'dispatch'); const page = '1'; const sort = COLLECTION_SORT_NAME; const location = createFakeLocation({ query: { page, collection_sort: sort }, }); const history = createFakeHistory({ location }); store.dispatch( loadCurrentCollection({ addons, detail, pageSize: DEFAULT_API_PAGE_SIZE, }), ); const root = renderComponent({ editing: true, errorHandler, history, location, store, }); fakeDispatch.resetHistory(); // This simulates the user clicking the "Remove" button on the // EditableCollectionAddon component. root.instance().removeAddon(addonId); sinon.assert.calledWith( fakeDispatch, removeAddonFromCollection({ addonId, errorHandlerId: errorHandler.id, filters: { page, collectionSort: sort }, slug: detail.slug, username: detail.author.username, }), ); sinon.assert.callCount(fakeDispatch, 1); sinon.assert.notCalled(history.push); });
it('adds a query object to history.location', () => { const history = createFakeHistory({ location: createFakeLocation({ query: null }), }); expect(history).toHaveProperty('location.query', null); const historyWithQueryParams = addQueryParamsToHistory({ history }); expect(historyWithQueryParams).toHaveProperty('location.query', {}); });
it('parses the query string to build the query object', () => { const history = createFakeHistory({ location: createFakeLocation({ query: null, search: 'foo=123' }), }); expect(history).toHaveProperty('location.query', null); const historyWithQueryParams = addQueryParamsToHistory({ history }); expect(historyWithQueryParams).toHaveProperty('location.query', { foo: '123', }); });
const getProps = ({ ...otherProps } = {}) => ({ dispatch: sinon.stub(), errorHandler: createStubErrorHandler(), i18n: fakeI18n(), location: createFakeLocation(), match: { params: { username: defaultUser, slug: defaultSlug, }, }, history: createFakeHistory(), store: dispatchClientMetadata().store, ...otherProps, });
it('redirects to user profile page when user profile has been updated', () => { const userId = 123; const clientApp = CLIENT_APP_FIREFOX; const lang = 'en-US'; const { store } = dispatchSignInActions({ clientApp, lang, userId, userProps: defaultUserProps({ userId }), }); const user = getCurrentUser(store.getState().users); const history = createFakeHistory(); const params = { userId }; const occupation = 'new occupation'; _updateUserAccount({ store, userFields: { occupation, }, userId: user.id, }); const root = renderUserProfileEdit({ history, params, store }); expect(root.find(Notice)).toHaveLength(0); expect(root.find('.UserProfileEdit-submit-button')).toHaveProp( 'disabled', true, ); // The user profile has been updated. store.dispatch(finishUpdateUserAccount()); const { isUpdating } = store.getState().users; root.setProps({ isUpdating }); expect(root.find('.UserProfileEdit-submit-button')).toHaveProp( 'disabled', false, ); sinon.assert.calledWith( history.push, `/${lang}/${clientApp}/user/${userId}/`, ); });
it('creates a collection with an add-on on submit', () => { const id = 123; const dispatchSpy = sinon.spy(store, 'dispatch'); const root = render({ collection: null, creating: true, history: createFakeHistory({ location: createFakeLocation({ query: { include_addon_id: id } }), }), }); // Fill in the form with values. const name = 'A collection name'; const description = 'A collection description'; const slug = 'collection-slug'; typeInput({ root, name: 'name', text: name }); typeInput({ root, name: 'description', text: description }); typeInput({ root, name: 'slug', text: slug }); simulateSubmit(root); sinon.assert.calledWith( dispatchSpy, createCollection({ defaultLocale: lang, description: { [lang]: description }, errorHandlerId: root.instance().props.errorHandler.id, includeAddonId: id, name: { [lang]: name }, slug, username: signedInUsername, }), ); });
beforeEach(() => { fakeHistory = createFakeHistory(); });