mirror of
https://github.com/IT4Change/Ocelot-Social.git
synced 2025-12-13 07:45:56 +00:00
feat(webapp): redirect on registration for invite links (#8517)
* feat(webapp): redirect on registration for invite links
This commit is contained in:
parent
ff366a4075
commit
9300fbd5fc
19
webapp/graphql/inviteCodes.js
Normal file
19
webapp/graphql/inviteCodes.js
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import gql from 'graphql-tag'
|
||||||
|
|
||||||
|
export const validateInviteCodeQuery = gql`
|
||||||
|
query ($code: String!) {
|
||||||
|
validateInviteCode(code: $code) {
|
||||||
|
invitedTo {
|
||||||
|
id
|
||||||
|
slug
|
||||||
|
groupType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
export const redeemInviteCodeMutation = gql`
|
||||||
|
mutation ($code: String!) {
|
||||||
|
redeemInviteCode(code: $code)
|
||||||
|
}
|
||||||
|
`
|
||||||
@ -2,6 +2,7 @@ import Vuex from 'vuex'
|
|||||||
import { mount } from '@vue/test-utils'
|
import { mount } from '@vue/test-utils'
|
||||||
import Registration from './registration.vue'
|
import Registration from './registration.vue'
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
|
import { validateInviteCodeQuery, redeemInviteCodeMutation } from '~/graphql/inviteCodes'
|
||||||
|
|
||||||
const localVue = global.localVue
|
const localVue = global.localVue
|
||||||
|
|
||||||
@ -12,6 +13,18 @@ const stubs = {
|
|||||||
'infinite-loading': true,
|
'infinite-loading': true,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const queryMock = jest.fn()
|
||||||
|
const mutationMock = jest.fn()
|
||||||
|
|
||||||
|
const app = {
|
||||||
|
apolloProvider: {
|
||||||
|
defaultClient: {
|
||||||
|
query: queryMock,
|
||||||
|
mutation: mutationMock,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
describe('Registration', () => {
|
describe('Registration', () => {
|
||||||
let wrapper
|
let wrapper
|
||||||
let Wrapper
|
let Wrapper
|
||||||
@ -20,6 +33,7 @@ describe('Registration', () => {
|
|||||||
let store
|
let store
|
||||||
let redirect
|
let redirect
|
||||||
let isLoggedIn
|
let isLoggedIn
|
||||||
|
let route
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
mocks = {
|
mocks = {
|
||||||
@ -39,6 +53,9 @@ describe('Registration', () => {
|
|||||||
asyncData = false
|
asyncData = false
|
||||||
isLoggedIn = false
|
isLoggedIn = false
|
||||||
redirect = jest.fn()
|
redirect = jest.fn()
|
||||||
|
route = {
|
||||||
|
query: {},
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('mount', () => {
|
describe('mount', () => {
|
||||||
@ -65,6 +82,8 @@ describe('Registration', () => {
|
|||||||
const aData = await Registration.asyncData({
|
const aData = await Registration.asyncData({
|
||||||
store,
|
store,
|
||||||
redirect,
|
redirect,
|
||||||
|
route,
|
||||||
|
app,
|
||||||
})
|
})
|
||||||
Registration.data = function () {
|
Registration.data = function () {
|
||||||
return { ...data, ...aData }
|
return { ...data, ...aData }
|
||||||
@ -330,6 +349,92 @@ describe('Registration', () => {
|
|||||||
expect(redirect).toHaveBeenCalledWith('/')
|
expect(redirect).toHaveBeenCalledWith('/')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('already logged in', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
asyncData = true
|
||||||
|
isLoggedIn = true
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('route contains personal invite code', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
jest.clearAllMocks()
|
||||||
|
queryMock.mockResolvedValue({
|
||||||
|
data: {
|
||||||
|
validateInviteCode: {
|
||||||
|
invitedTo: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
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('does not redeem the link', () => {
|
||||||
|
expect(mutationMock).not.toBeCalled()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
// no idea why this is not working
|
||||||
|
describe.skip('route contains group invite code to public group', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
jest.clearAllMocks()
|
||||||
|
queryMock.mockResolvedValue({
|
||||||
|
data: {
|
||||||
|
validateInviteCode: {
|
||||||
|
invitedTo: {
|
||||||
|
id: 'public-group',
|
||||||
|
slug: 'public-group',
|
||||||
|
groupType: 'public',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
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 group', () => {
|
||||||
|
expect(redirect).toHaveBeenCalledWith('/groups/public-group/public-group')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('redeems the code', () => {
|
||||||
|
expect(mutationMock).toBeCalledWith({
|
||||||
|
mutation: redeemInviteCodeMutation,
|
||||||
|
variables: {
|
||||||
|
code: 'ABCDEF',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
// copied from webapp/components/Registration/Signup.spec.js as testing template
|
// copied from webapp/components/Registration/Signup.spec.js as testing template
|
||||||
// describe('with invitation code', () => {
|
// describe('with invitation code', () => {
|
||||||
// let action
|
// let action
|
||||||
|
|||||||
@ -11,6 +11,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import registrationConstants from '~/constants/registrationBranded.js'
|
import registrationConstants from '~/constants/registrationBranded.js'
|
||||||
import RegistrationSlider from '~/components/Registration/RegistrationSlider'
|
import RegistrationSlider from '~/components/Registration/RegistrationSlider'
|
||||||
|
import { validateInviteCodeQuery, redeemInviteCodeMutation } from '~/graphql/inviteCodes'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
layout: registrationConstants.LAYOUT,
|
layout: registrationConstants.LAYOUT,
|
||||||
@ -34,10 +35,46 @@ export default {
|
|||||||
inviteRegistration: this.$env.INVITE_REGISTRATION === true, // for 'false' in .env INVITE_REGISTRATION is of type undefined and not(!) boolean false, because of internal handling
|
inviteRegistration: this.$env.INVITE_REGISTRATION === true, // for 'false' in .env INVITE_REGISTRATION is of type undefined and not(!) boolean false, because of internal handling
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
asyncData({ store, redirect }) {
|
async asyncData({ store, route, app, redirect }) {
|
||||||
|
// http://localhost:3000/registration?method=invite-code&inviteCode=T9TWMJ
|
||||||
if (store.getters['auth/isLoggedIn']) {
|
if (store.getters['auth/isLoggedIn']) {
|
||||||
|
const {
|
||||||
|
query: { inviteCode: code },
|
||||||
|
} = route
|
||||||
|
if (code) {
|
||||||
|
const {
|
||||||
|
apolloProvider: { defaultClient: client },
|
||||||
|
} = app
|
||||||
|
try {
|
||||||
|
const result = await client.query({
|
||||||
|
query: validateInviteCodeQuery,
|
||||||
|
variables: { code },
|
||||||
|
})
|
||||||
|
const {
|
||||||
|
data: {
|
||||||
|
validateInviteCode: { invitedTo: group },
|
||||||
|
},
|
||||||
|
} = result
|
||||||
|
if (group) {
|
||||||
|
const mutationResult = await client.mutate({
|
||||||
|
mutation: redeemInviteCodeMutation,
|
||||||
|
variables: { code },
|
||||||
|
})
|
||||||
|
if (mutationResult.data.redeemInviteCode && group.groupType === 'public') {
|
||||||
|
redirect(`/groups/${group.id}/${group.slug}`)
|
||||||
|
} else {
|
||||||
redirect('/')
|
redirect('/')
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
redirect('/')
|
||||||
|
}
|
||||||
|
} catch (_err) {
|
||||||
|
redirect('/')
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
redirect('/')
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
registrationType() {
|
registrationType() {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user