diff --git a/webapp/components/Registration/RegistrationSlider.vue b/webapp/components/Registration/RegistrationSlider.vue index 6bd704b32..25cbe648a 100644 --- a/webapp/components/Registration/RegistrationSlider.vue +++ b/webapp/components/Registration/RegistrationSlider.vue @@ -30,7 +30,7 @@ @@ -163,6 +163,10 @@ export default { } return { + loginLink: { + name: 'login', + query: this.$route.query, + }, links, metadata, sliderData: { diff --git a/webapp/pages/login.spec.js b/webapp/pages/login.spec.js index 31ff2b489..6f54b2693 100644 --- a/webapp/pages/login.spec.js +++ b/webapp/pages/login.spec.js @@ -1,14 +1,20 @@ import Vuex from 'vuex' import { mount } from '@vue/test-utils' import login from './login.vue' +import LoginForm from '~/components/LoginForm/LoginForm.vue' const localVue = global.localVue const stubs = { 'client-only': true, 'nuxt-link': true, + 'router-link': true, } +const routerPushMock = jest.fn() +const routerReplaceMock = jest.fn() +const i18nSetMock = jest.fn() + describe('Login.vue', () => { let store let mocks @@ -22,6 +28,14 @@ describe('Login.vue', () => { $t: jest.fn(), $i18n: { locale: () => 'en', + set: i18nSetMock, + }, + $route: { + query: {}, + }, + $router: { + replace: routerReplaceMock, + push: routerPushMock, }, } asyncData = false @@ -73,5 +87,51 @@ describe('Login.vue', () => { wrapper = await Wrapper() expect(redirect).toHaveBeenCalledWith('/') }) + + describe('handle succcess', () => { + beforeEach(async () => { + asyncData = true + tosVersion = '0.0.4' + }) + + describe('with route query to invite code', () => { + beforeEach(async () => { + mocks.$route.query = { + inviteCode: 'ABCDEF', + } + wrapper = await Wrapper() + wrapper.findComponent(LoginForm).vm.$emit('success') + }) + + it('calls i18n.set', () => { + expect(i18nSetMock).toBeCalledWith('en') + }) + + it('call router push to registration page', () => { + expect(routerPushMock).toBeCalledWith({ + name: 'registration', + query: { + inviteCode: 'ABCDEF', + }, + }) + }) + }) + + describe('without route query to invite code', () => { + beforeEach(async () => { + mocks.$route.query = {} + wrapper = await Wrapper() + wrapper.findComponent(LoginForm).vm.$emit('success') + }) + + it('calls i18n.set', () => { + expect(i18nSetMock).toBeCalledWith('en') + }) + + it('call router push to registration page', () => { + expect(routerReplaceMock).toBeCalledWith('/') + }) + }) + }) }) }) diff --git a/webapp/pages/login.vue b/webapp/pages/login.vue index 799957bea..883626112 100644 --- a/webapp/pages/login.vue +++ b/webapp/pages/login.vue @@ -32,7 +32,14 @@ export default { this.$i18n.set(this.user.locale || 'en') try { - await this.$router.replace(this.$route.query.path || '/') + if (this.$route.query.inviteCode) { + this.$router.push({ + name: 'registration', + query: this.$route.query, + }) + } else { + await this.$router.replace(this.$route.query.path || '/') + } } catch (err) { // throw new Error(`Problem handling something: ${err}.`); // TODO this is causing trouble - most likely due to double redirect on terms&conditions diff --git a/webapp/pages/registration.spec.js b/webapp/pages/registration.spec.js index 9bc6f150b..578808ed9 100644 --- a/webapp/pages/registration.spec.js +++ b/webapp/pages/registration.spec.js @@ -20,7 +20,7 @@ const app = { apolloProvider: { defaultClient: { query: queryMock, - mutation: mutationMock, + mutate: mutationMock, }, }, } @@ -387,8 +387,7 @@ describe('Registration', () => { }) }) - // no idea why this is not working - describe.skip('route contains group invite code to public group', () => { + describe('route contains group invite code to public group', () => { beforeEach(async () => { jest.clearAllMocks() queryMock.mockResolvedValue({ @@ -433,6 +432,96 @@ describe('Registration', () => { }) }) }) + + describe('route contains group invite code to closed group', () => { + beforeEach(async () => { + jest.clearAllMocks() + queryMock.mockResolvedValue({ + data: { + validateInviteCode: { + invitedTo: { + id: 'closed-group', + slug: 'closed-group', + groupType: 'closed', + }, + }, + }, + }) + mutationMock.mockResolvedValue({ + data: { + redeemInviteCode: true, + }, + }) + route.query.inviteCode = 'ABCDEF' + wrapper = await Wrapper() + }) + + it('calls validate invite code', () => { + expect(queryMock).toHaveBeenCalledWith({ + query: validateInviteCodeQuery, + variables: { + code: 'ABCDEF', + }, + }) + }) + + it('redirects to index', () => { + expect(redirect).toHaveBeenCalledWith('/') + }) + + it('redeems the code', () => { + expect(mutationMock).toBeCalledWith({ + mutation: redeemInviteCodeMutation, + variables: { + code: 'ABCDEF', + }, + }) + }) + }) + + describe('route contains group invite code to public group, but redeem throws', () => { + beforeEach(async () => { + jest.clearAllMocks() + queryMock.mockResolvedValue({ + data: { + validateInviteCode: { + invitedTo: { + id: 'public-group', + slug: 'public-group', + groupType: 'public', + }, + }, + }, + }) + mutationMock.mockRejectedValue({ + error: 'Aua!', + }) + route.query.inviteCode = 'ABCDEF' + wrapper = await Wrapper() + }) + + it('calls validate invite code', () => { + expect(queryMock).toHaveBeenCalledWith({ + query: validateInviteCodeQuery, + variables: { + code: 'ABCDEF', + }, + }) + }) + + it('redirects to index', () => { + expect(redirect).toHaveBeenCalledWith('/') + }) + + it('redeems the code', () => { + expect(mutationMock).toBeCalledWith({ + mutation: redeemInviteCodeMutation, + variables: { + code: 'ABCDEF', + }, + }) + }) + }) }) // copied from webapp/components/Registration/Signup.spec.js as testing template diff --git a/webapp/pages/registration.vue b/webapp/pages/registration.vue index ec8d94adc..af0eb30e7 100644 --- a/webapp/pages/registration.vue +++ b/webapp/pages/registration.vue @@ -36,7 +36,7 @@ export default { } }, async asyncData({ store, route, app, redirect }) { - // http://localhost:3000/registration?method=invite-code&inviteCode=T9TWMJ + // http://localhost:3000/registration?method=invite-code&inviteCode=PEY8FN if (store.getters['auth/isLoggedIn']) { const { query: { inviteCode: code }, @@ -62,18 +62,15 @@ export default { }) if (mutationResult.data.redeemInviteCode && group.groupType === 'public') { redirect(`/groups/${group.id}/${group.slug}`) - } else { - redirect('/') + return } - } else { - redirect('/') } } catch (_err) { redirect('/') + return } - } else { - redirect('/') } + redirect('/') } }, computed: {