import Vuex from 'vuex' import { mount } from '@vue/test-utils' import Registration from './registration.vue' import Vue from 'vue' import { validateInviteCodeQuery, redeemInviteCodeMutation } from '~/graphql/inviteCodes' const localVue = global.localVue const stubs = { 'client-only': true, 'router-link': true, 'nuxt-link': true, 'infinite-loading': true, } const queryMock = jest.fn() const mutationMock = jest.fn() const app = { apolloProvider: { defaultClient: { query: queryMock, mutate: mutationMock, }, }, } describe('Registration', () => { let wrapper let Wrapper let mocks let asyncData let store let redirect let isLoggedIn let route beforeEach(() => { mocks = { $t: (key) => key, $i18n: { locale: () => 'de', }, $route: { query: {}, }, $env: {}, $toast: { error: jest.fn(), success: jest.fn(), }, } asyncData = false isLoggedIn = false redirect = jest.fn() route = { query: {}, } }) describe('mount', () => { Wrapper = async () => { if (asyncData) { store = new Vuex.Store({ getters: { 'auth/isLoggedIn': () => isLoggedIn, }, }) const data = { method: mocks, overwriteSliderData: { collectedInputData: { inviteCode: null, email: null, emailSend: !!null, nonce: null, }, }, publicRegistration: false, inviteRegistration: false, } const aData = await Registration.asyncData({ store, redirect, route, app, }) Registration.data = function () { return { ...data, ...aData } } } else { Registration.data = Registration.backupData ? Registration.backupData : Registration.data } return mount(Registration, { mocks, localVue, stubs, }) } describe('no "PUBLIC_REGISTRATION" and no "INVITE_REGISTRATION"', () => { beforeEach(() => { mocks.$env = { PUBLIC_REGISTRATION: false, INVITE_REGISTRATION: false, } }) it('no "method" query in URI show "RegistrationSlideNoPublic"', async () => { mocks.$route.query = {} wrapper = await Wrapper() expect(wrapper.find('.hc-empty').exists()).toBe(true) expect(wrapper.find('.enter-invite').exists()).toBe(false) expect(wrapper.find('.enter-email').exists()).toBe(false) }) describe('"method=invite-mail" in URI show "RegistrationSlideNonce"', () => { it('no "email" query in URI', async () => { mocks.$route.query = { method: 'invite-mail' } wrapper = await Wrapper() expect(wrapper.find('.enter-nonce').exists()).toBe(true) }) describe('"email=user%40example.org" query in URI', () => { it('have email displayed', async () => { mocks.$route.query = { method: 'invite-mail', email: 'user@example.org' } wrapper = await Wrapper() expect(wrapper.find('.enter-nonce').text()).toContain('user@example.org') }) it('"nonce=64835" query in URI have nonce in input', async () => { mocks.$route.query = { method: 'invite-mail', email: 'user@example.org', nonce: '64835', } wrapper = await Wrapper() await Vue.nextTick() const form = wrapper.find('.enter-nonce') expect(form.vm.formData.nonce).toEqual('64835') }) }) }) describe('"method=invite-code" in URI show "RegistrationSlideNoPublic"', () => { it('no "inviteCode" query in URI', async () => { mocks.$route.query = { method: 'invite-code' } wrapper = await Wrapper() expect(wrapper.find('.hc-empty').exists()).toBe(true) }) it('"inviteCode=ABCDEF" query in URI', async () => { mocks.$route.query = { method: 'invite-code', inviteCode: 'ABCDEF' } wrapper = await Wrapper() expect(wrapper.find('.hc-empty').exists()).toBe(true) }) }) }) describe('no "PUBLIC_REGISTRATION" but "INVITE_REGISTRATION"', () => { beforeEach(() => { mocks.$env = { PUBLIC_REGISTRATION: false, INVITE_REGISTRATION: true, } }) it('no "method" query in URI show "RegistrationSlideInvite"', async () => { mocks.$route.query = {} wrapper = await Wrapper() expect(wrapper.find('.enter-invite').exists()).toBe(true) expect(wrapper.find('.enter-email').exists()).toBe(false) }) describe('"method=invite-mail" in URI show "RegistrationSlideNonce"', () => { it('no "inviteCode" query in URI', async () => { mocks.$route.query = { method: 'invite-mail' } wrapper = await Wrapper() expect(wrapper.find('.enter-nonce').exists()).toBe(true) }) describe('"email=user%40example.org" query in URI', () => { it('have email displayed', async () => { mocks.$route.query = { method: 'invite-mail', email: 'user@example.org' } wrapper = await Wrapper() expect(wrapper.find('.enter-nonce').text()).toContain('user@example.org') }) it('"nonce=64835" query in URI have nonce in input', async () => { mocks.$route.query = { method: 'invite-mail', email: 'user@example.org', nonce: '64835', } wrapper = await Wrapper() await Vue.nextTick() const form = wrapper.find('.enter-nonce') expect(form.vm.formData.nonce).toEqual('64835') }) }) }) describe('"method=invite-code" in URI show "RegistrationSlideInvite"', () => { it('no "inviteCode" query in URI', async () => { mocks.$route.query = { method: 'invite-code' } wrapper = await Wrapper() expect(wrapper.find('.enter-invite').exists()).toBe(true) }) it('"inviteCode=ABCDEF" query in URI have invite code in input', async () => { mocks.$route.query = { method: 'invite-code', inviteCode: 'ABCDEF' } wrapper = await Wrapper() await Vue.nextTick() const form = wrapper.find('.enter-invite') expect(form.vm.formData.inviteCode).toEqual('ABCDEF') }) }) }) describe('"PUBLIC_REGISTRATION" but no "INVITE_REGISTRATION"', () => { beforeEach(() => { mocks.$env = { PUBLIC_REGISTRATION: true, INVITE_REGISTRATION: false, } }) it('no "method" query in URI show "RegistrationSlideEmail"', async () => { mocks.$route.query = {} wrapper = await Wrapper() expect(wrapper.find('.enter-email').exists()).toBe(true) expect(wrapper.find('.enter-invite').exists()).toBe(false) }) describe('"method=invite-mail" in URI show "RegistrationSlideNonce"', () => { it('no "inviteCode" query in URI', async () => { mocks.$route.query = { method: 'invite-mail' } wrapper = await Wrapper() expect(wrapper.find('.enter-nonce').exists()).toBe(true) }) describe('"email=user%40example.org" query in URI', () => { it('have email displayed', async () => { mocks.$route.query = { method: 'invite-mail', email: 'user@example.org' } wrapper = await Wrapper() expect(wrapper.find('.enter-nonce').text()).toContain('user@example.org') }) it('"nonce=64835" query in URI have nonce in input', async () => { mocks.$route.query = { method: 'invite-mail', email: 'user@example.org', nonce: '64835', } wrapper = await Wrapper() await Vue.nextTick() const form = wrapper.find('.enter-nonce') expect(form.vm.formData.nonce).toEqual('64835') }) }) }) describe('"method=invite-code" in URI show "RegistrationSlideEmail"', () => { it('no "inviteCode" query in URI', async () => { mocks.$route.query = { method: 'invite-code' } wrapper = await Wrapper() expect(wrapper.find('.enter-email').exists()).toBe(true) expect(wrapper.find('.enter-invite').exists()).toBe(false) }) }) }) describe('"PUBLIC_REGISTRATION" and "INVITE_REGISTRATION"', () => { beforeEach(() => { mocks.$env = { PUBLIC_REGISTRATION: true, INVITE_REGISTRATION: true, } }) it('no "method" query in URI show "RegistrationSlideEmail"', async () => { mocks.$route.query = {} wrapper = await Wrapper() expect(wrapper.find('.enter-email').exists()).toBe(true) expect(wrapper.find('.enter-invite').exists()).toBe(false) }) describe('"method=invite-mail" in URI show "RegistrationSlideNonce"', () => { it('no "inviteCode" query in URI', async () => { mocks.$route.query = { method: 'invite-mail' } wrapper = await Wrapper() expect(wrapper.find('.enter-nonce').exists()).toBe(true) }) describe('"email=user%40example.org" query in URI', () => { it('have email displayed', async () => { mocks.$route.query = { method: 'invite-mail', email: 'user@example.org' } wrapper = await Wrapper() expect(wrapper.find('.enter-nonce').text()).toContain('user@example.org') }) it('"nonce=64835" query in URI have nonce in input', async () => { mocks.$route.query = { method: 'invite-mail', email: 'user@example.org', nonce: '64835', } wrapper = await Wrapper() await Vue.nextTick() const form = wrapper.find('.enter-nonce') expect(form.vm.formData.nonce).toEqual('64835') }) }) }) describe('"method=invite-code" in URI show "RegistrationSlideInvite"', () => { it('no "inviteCode" query in URI', async () => { mocks.$route.query = { method: 'invite-code' } wrapper = await Wrapper() expect(wrapper.find('.enter-invite').exists()).toBe(true) }) it('"inviteCode=ABCDEF" query in URI have invite code in input', async () => { mocks.$route.query = { method: 'invite-code', inviteCode: 'ABCDEF' } wrapper = await Wrapper() await Vue.nextTick() const form = wrapper.find('.enter-invite') expect(form.vm.formData.inviteCode).toEqual('ABCDEF') }) }) }) it('renders', async () => { wrapper = await Wrapper() expect(wrapper.find('.registration-slider')).toBeTruthy() }) // The asyncTests must go last it('renders with asyncData and not loggedIn', async () => { asyncData = true wrapper = await Wrapper() expect(redirect).not.toHaveBeenCalled() }) it('renders with asyncData and loggedIn', async () => { asyncData = true isLoggedIn = true wrapper = await Wrapper() 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() }) }) describe('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', }, }) }) }) 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 // describe('with invitation code', () => { // let action // beforeEach(() => { // propsData.token = '12345' // action = async () => { // wrapper = Wrapper() // wrapper.find('input#email').setValue('mail@example.org') // await wrapper.find('form').trigger('submit') // await wrapper.html() // } // }) // describe('submit', () => { // it('delivers invitation code to backend', async () => { // await action() // const expected = expect.objectContaining({ // mutation: SignupMutation, // variables: { email: 'mail@example.org', inviteCode: '12345' }, // }) // expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expected) // }) // describe('in case a user account with the email already exists', () => { // beforeEach(() => { // mocks.$apollo.mutate = jest // .fn() // .mockRejectedValue( // new Error('UserInputError: A user account with this email already exists.'), // ) // }) // it('explains the error', async () => { // await action() // expect(mocks.$t).toHaveBeenCalledWith( // 'components.registration.signup.form.errors.email-exists', // ) // }) // }) // }) // }) }) }) // template from deleted webapp/components/Registration/CreateUserAccount.spec.js // import { config, mount } from '@vue/test-utils' // import Vue from 'vue' // import { VERSION } from '~/constants/terms-and-conditions-version.js' // import CreateUserAccount from './CreateUserAccount' // import { SignupVerificationMutation } from '~/graphql/Registration.js' // const localVue = global.localVue // config.stubs['sweetalert-icon'] = '' // config.stubs['client-only'] = '' // config.stubs['nuxt-link'] = '' // describe('CreateUserAccount', () => { // let wrapper, Wrapper, mocks, propsData, stubs // beforeEach(() => { // mocks = { // $toast: { // success: jest.fn(), // error: jest.fn(), // }, // $t: jest.fn(), // $apollo: { // loading: false, // mutate: jest.fn(), // }, // $i18n: { // locale: () => 'en', // }, // } // propsData = {} // stubs = { // LocaleSwitch: "
", // } // }) // describe('mount', () => { // Wrapper = () => { // return mount(CreateUserAccount, { // mocks, // propsData, // localVue, // stubs, // }) // } // describe('given email and nonce', () => { // beforeEach(() => { // propsData.nonce = '666777' // propsData.email = 'sixseven@example.org' // }) // it('renders a form to create a new user', () => { // wrapper = Wrapper() // expect(wrapper.find('.create-user-account').exists()).toBe(true) // }) // describe('submit', () => { // let action // beforeEach(() => { // action = async () => { // wrapper = Wrapper() // wrapper.find('input#name').setValue('John Doe') // wrapper.find('input#password').setValue('hellopassword') // wrapper.find('textarea#about').setValue('Hello I am the `about` attribute') // wrapper.find('input#passwordConfirmation').setValue('hellopassword') // wrapper.find('input#checkbox0').setChecked() // wrapper.find('input#checkbox1').setChecked() // wrapper.find('input#checkbox2').setChecked() // wrapper.find('input#checkbox3').setChecked() // wrapper.find('input#checkbox4').setChecked() // await wrapper.find('form').trigger('submit') // await wrapper.html() // } // }) // it('delivers data to backend', async () => { // await action() // const expected = expect.objectContaining({ // variables: { // about: 'Hello I am the `about` attribute', // name: 'John Doe', // email: 'sixseven@example.org', // nonce: '666777', // password: 'hellopassword', // termsAndConditionsAgreedVersion: VERSION, // locale: 'en', // }, // }) // expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expected) // }) // it('calls CreateUserAccount graphql mutation', async () => { // await action() // const expected = expect.objectContaining({ mutation: SignupVerificationMutation }) // expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expected) // }) // describe('in case mutation resolves', () => { // beforeEach(() => { // mocks.$apollo.mutate = jest.fn().mockResolvedValue({ // data: { // SignupVerification: { // id: 'u1', // name: 'John Doe', // slug: 'john-doe', // }, // }, // }) // }) // it('displays success', async () => { // await action() // await Vue.nextTick() // expect(mocks.$t).toHaveBeenCalledWith( // 'components.registration.create-user-account.success', // ) // }) // describe('after timeout', () => { // beforeEach(jest.useFakeTimers) // it('emits `userCreated` with { password, email }', async () => { // await action() // jest.runAllTimers() // expect(wrapper.emitted('userCreated')).toEqual([ // [ // { // email: 'sixseven@example.org', // password: 'hellopassword', // }, // ], // ]) // }) // }) // }) // describe('in case mutation rejects', () => { // beforeEach(() => { // mocks.$apollo.mutate = jest.fn().mockRejectedValue(new Error('Invalid nonce')) // }) // it('displays form errors', async () => { // await action() // await Vue.nextTick() // expect(mocks.$t).toHaveBeenCalledWith( // 'components.registration.create-user-account.error', // ) // }) // }) // }) // }) // }) // })