🍰 Refactor THX Page – 1. Step
This commit is contained in:
Wolfgang Huß 2022-05-05 16:06:28 +02:00 committed by GitHub
commit 851a16e183
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 396 additions and 145 deletions

View File

@ -0,0 +1,63 @@
import { mount } from '@vue/test-utils'
import Message from './Message'
const localVue = global.localVue
const propsData = {
headline: 'site.thx.title',
subtitle: 'site.thx.email',
buttonText: 'login',
linkTo: '/login',
}
const mocks = {
$t: jest.fn((t) => t),
}
describe('Message', () => {
let wrapper
const Wrapper = () => {
return mount(Message, { localVue, mocks, propsData })
}
describe('mount', () => {
beforeEach(() => {
wrapper = Wrapper()
})
it('renders the component', () => {
expect(wrapper.find('div.header').exists()).toBe(true)
})
describe('with button', () => {
it('renders title, subtitle, and button text', () => {
expect(wrapper.find('.test-message-headline').text()).toBe('site.thx.title')
expect(wrapper.find('.test-message-subtitle').text()).toBe('site.thx.email')
expect(wrapper.find('.test-message-button').text()).toBe('login')
})
it('button link redirects to /login', () => {
expect(wrapper.find('a.btn').attributes('href')).toBe('/login')
})
})
describe('without button', () => {
beforeEach(() => {
wrapper.setProps({
buttonText: null,
linkTo: null,
})
})
it('renders title, subtitle, and button text', () => {
expect(wrapper.find('.test-message-headline').text()).toBe('site.thx.title')
expect(wrapper.find('.test-message-subtitle').text()).toBe('site.thx.email')
})
it('button is not shown', () => {
expect(wrapper.find('.test-message-button').exists()).toBe(false)
})
})
})
})

View File

@ -0,0 +1,36 @@
<template>
<div>
<div class="header py-lg-6">
<b-container class="w-50">
<div class="header-body text-center mb-7">
<p class="h1 test-message-headline">{{ headline }}</p>
<p class="h4 test-message-subtitle">{{ subtitle }}</p>
<hr />
<b-button v-if="showButton" class="test-message-button" :to="buttonLinkTo">
{{ buttonText }}
</b-button>
</div>
</b-container>
</div>
</div>
</template>
<script>
export default {
name: 'Message',
props: {
headline: { type: String, required: true },
subtitle: { type: String, required: true },
buttonText: { type: String, required: false, default: null },
linkTo: { type: String, required: false, default: null },
},
computed: {
showButton() {
return this.buttonText && this.linkTo
},
buttonLinkTo() {
return this.linkTo ? this.linkTo : null
},
},
}
</script>

View File

@ -33,9 +33,12 @@
"email-already-sent": "Wir haben dir bereits eine E-Mail vor weniger als 10 Minuten geschickt.", "email-already-sent": "Wir haben dir bereits eine E-Mail vor weniger als 10 Minuten geschickt.",
"empty-transactionlist": "Es gab einen Fehler mit der Übermittlung der Anzahl deiner Transaktionen.", "empty-transactionlist": "Es gab einen Fehler mit der Übermittlung der Anzahl deiner Transaktionen.",
"error": "Fehler!", "error": "Fehler!",
"no-account": "Leider konnten wir keinen Account mit diesen Daten finden.", "no-account": "Leider konnten wir keinen (aktivierten) Account mit diesen Daten finden.",
"no-transactionlist": "Es gab leider einen Fehler. Es wurden keine Transaktionen vom Server übermittelt", "no-transactionlist": "Es gab leider einen Fehler. Es wurden keine Transaktionen vom Server übermittelt.",
"session-expired": "Die Sitzung wurde aus Sicherheitsgründen beendet." "no-user": "Kein Benutzer mit diesen Anmeldedaten.",
"session-expired": "Die Sitzung wurde aus Sicherheitsgründen beendet.",
"unknown-error": "Unbekanter Fehler: ",
"user-already-exists": "Ein Benutzer mit diesen Daten existiert bereits."
}, },
"footer": { "footer": {
"app_version": "App version {version}", "app_version": "App version {version}",
@ -234,7 +237,8 @@
"register": "Du bist jetzt registriert, bitte überprüfe deine Emails und klicke auf den Aktivierungslink.", "register": "Du bist jetzt registriert, bitte überprüfe deine Emails und klicke auf den Aktivierungslink.",
"reset": "Dein Passwort wurde geändert.", "reset": "Dein Passwort wurde geändert.",
"resetPassword": "Den Code den Du genutzt hast ist zu alt bitte fordere ein neuen über die Passwort Reset Seite an.", "resetPassword": "Den Code den Du genutzt hast ist zu alt bitte fordere ein neuen über die Passwort Reset Seite an.",
"title": "Danke!" "title": "Danke!",
"unsetPassword": "Dein Passwort wurde noch nicht gesetzt. Bitte setze es neu."
} }
}, },
"success": "Erfolg", "success": "Erfolg",

View File

@ -33,9 +33,12 @@
"email-already-sent": "We already sent you an email less than 10 minutes ago.", "email-already-sent": "We already sent you an email less than 10 minutes ago.",
"empty-transactionlist": "There was an error with the transmission of the number of your transactions.", "empty-transactionlist": "There was an error with the transmission of the number of your transactions.",
"error": "Error!", "error": "Error!",
"no-account": "Unfortunately we could not find an account to the given data!", "no-account": "Unfortunately we could not find an (activated) account to the given data.",
"no-transactionlist": "Unfortunately, there was an error. No transactions have been sent from the server.", "no-transactionlist": "Unfortunately, there was an error. No transactions have been sent from the server.",
"session-expired": "The session was closed for security reasons." "no-user": "No user with this credentials.",
"session-expired": "The session was closed for security reasons.",
"unknown-error": "Unknown error: ",
"user-already-exists": "A user with this data already exists."
}, },
"footer": { "footer": {
"app_version": "App version {version}", "app_version": "App version {version}",
@ -226,7 +229,7 @@
"uppercase": "One uppercase letter required." "uppercase": "One uppercase letter required."
}, },
"thx": { "thx": {
"activateEmail": "Your account has not been activated yet, please check your emails and click the activation link or order a new activation link over the password reset page.", "activateEmail": "Your account has not been activated yet. Please check your emails and click the activation link or order a new activation link over the password reset page.",
"checkEmail": "Your email has been successfully verified. You can sign in now.", "checkEmail": "Your email has been successfully verified. You can sign in now.",
"email": "We have sent you an email.", "email": "We have sent you an email.",
"emailActivated": "Thank you your email has been activated.", "emailActivated": "Thank you your email has been activated.",
@ -234,7 +237,8 @@
"register": "You are registered now, please check your emails and click the activation link.", "register": "You are registered now, please check your emails and click the activation link.",
"reset": "Your password has been changed.", "reset": "Your password has been changed.",
"resetPassword": "The code you used was to old please order a new on over the password reset page.", "resetPassword": "The code you used was to old please order a new on over the password reset page.",
"title": "Thank you!" "title": "Thank you!",
"unsetPassword": "Your password has not been set yet. Please set it again."
} }
}, },
"success": "Success", "success": "Success",

View File

@ -1,8 +1,7 @@
import { mount, RouterLinkStub } from '@vue/test-utils' import { mount, RouterLinkStub } from '@vue/test-utils'
import flushPromises from 'flush-promises' import flushPromises from 'flush-promises'
import ForgotPassword from './ForgotPassword'
import { toastErrorSpy } from '@test/testSetup' import { toastErrorSpy } from '@test/testSetup'
import ForgotPassword from './ForgotPassword'
const mockAPIcall = jest.fn() const mockAPIcall = jest.fn()
@ -48,7 +47,7 @@ describe('ForgotPassword', () => {
}) })
it('renders the component', () => { it('renders the component', () => {
expect(wrapper.find('div.forgot-password').exists()).toBeTruthy() expect(wrapper.find('div.forgot-password').exists()).toBe(true)
}) })
it('has a title', () => { it('has a title', () => {
@ -85,7 +84,7 @@ describe('ForgotPassword', () => {
}) })
it('has a submit button', () => { it('has a submit button', () => {
expect(form.find('button[type="submit"]').exists()).toBeTruthy() expect(form.find('button[type="submit"]').exists()).toBe(true)
}) })
describe('invalid Email', () => { describe('invalid Email', () => {
@ -118,19 +117,25 @@ describe('ForgotPassword', () => {
await flushPromises() await flushPromises()
}) })
it('toasts a standard error message', () => { it('shows error title, subtitle, login button', () => {
expect(toastErrorSpy).toBeCalledWith('error.email-already-sent') expect(wrapper.vm.showPageMessage).toBe(true)
expect(wrapper.find('.test-message-headline').text()).toBe('site.thx.errorTitle')
expect(wrapper.find('.test-message-subtitle').text()).toBe('error.email-already-sent')
expect(wrapper.find('.test-message-button').text()).toBe('login')
}) })
it('pushes to "/thx/forgotPassword"', () => { it('button link directs to "/login"', () => {
expect(mockAPIcall).toBeCalledWith( expect(wrapper.find('.test-message-button').attributes('href')).toBe('/login')
expect.objectContaining({ })
variables: {
email: 'user@example.org', it.skip('click redirects to "/login"', async () => {
}, // wrapper.find('.test-message-button').trigger('click')
}), // await wrapper.vm.$nextTick()
) expect(mockRouterPush).toBeCalledWith('/login')
expect(mockRouterPush).toHaveBeenCalledWith('/thx/forgotPassword') })
it('toasts a standard error message', () => {
expect(toastErrorSpy).toBeCalledWith('error.email-already-sent')
}) })
}) })
@ -147,15 +152,19 @@ describe('ForgotPassword', () => {
await flushPromises() await flushPromises()
}) })
it('pushes to "/thx/forgotPassword"', () => { it('shows success title, subtitle, login button', () => {
expect(mockAPIcall).toBeCalledWith( expect(wrapper.vm.showPageMessage).toBe(true)
expect.objectContaining({ expect(wrapper.find('.test-message-headline').text()).toBe('site.thx.title')
variables: { expect(wrapper.find('.test-message-subtitle').text()).toBe('site.thx.email')
email: 'user@example.org', expect(wrapper.find('.test-message-button').text()).toBe('login')
}, })
}),
) it('button link redirects to "/login"', () => {
expect(mockRouterPush).toHaveBeenCalledWith('/thx/forgotPassword') expect(wrapper.find('.test-message-button').attributes('href')).toBe('/login')
})
it.skip('click redirects to "/login"', () => {
// expect(mockRouterPush).toBeCalledWith('/login')
}) })
}) })
}) })

View File

@ -13,7 +13,7 @@
</div> </div>
</b-container> </b-container>
</div> </div>
<b-container class="mt--8 p-1"> <b-container v-if="enterData" class="mt--8 p-1">
<b-row class="justify-content-center"> <b-row class="justify-content-center">
<b-col lg="6" md="8"> <b-col lg="6" md="8">
<b-card no-body class="border-0 gradido-custom-background"> <b-card no-body class="border-0 gradido-custom-background">
@ -36,24 +36,48 @@
<router-link to="/login" class="mt-3">{{ $t('back') }}</router-link> <router-link to="/login" class="mt-3">{{ $t('back') }}</router-link>
</div> </div>
</b-container> </b-container>
<b-container v-else class="mt--8 p-1">
<message
v-if="success"
:headline="$t('site.thx.title')"
:subtitle="$t('site.thx.email')"
:buttonText="$t('login')"
linkTo="/login"
/>
<message
v-else
:headline="$t('site.thx.errorTitle')"
:subtitle="$t('error.email-already-sent')"
:buttonText="$t('login')"
linkTo="/login"
/>
</b-container>
</div> </div>
</template> </template>
<script> <script>
import { forgotPassword } from '@/graphql/mutations' import { forgotPassword } from '@/graphql/mutations'
import InputEmail from '@/components/Inputs/InputEmail' import InputEmail from '@/components/Inputs/InputEmail'
import Message from '@/components/Message/Message'
export default { export default {
name: 'ForgotPassword', name: 'ForgotPassword',
components: { components: {
InputEmail, InputEmail,
Message,
}, },
data() { data() {
return { return {
disable: 'disabled',
form: { form: {
email: '', email: '',
}, },
subtitle: 'settings.password.subtitle', subtitle: 'settings.password.subtitle',
showPageMessage: false,
success: null,
}
},
created() {
if (this.$route.params.comingFrom) {
this.subtitle = 'settings.password.resend_subtitle'
} }
}, },
methods: { methods: {
@ -66,18 +90,20 @@ export default {
}, },
}) })
.then(() => { .then(() => {
this.$router.push('/thx/forgotPassword') this.showPageMessage = true
this.success = true
}) })
.catch(() => { .catch(() => {
this.showPageMessage = true
this.success = false
this.toastError(this.$t('error.email-already-sent')) this.toastError(this.$t('error.email-already-sent'))
this.$router.push('/thx/forgotPassword')
}) })
}, },
}, },
created() { computed: {
if (this.$route.params.comingFrom) { enterData() {
this.subtitle = 'settings.password.resend_subtitle' return !this.showPageMessage
} },
}, },
} }
</script> </script>

View File

@ -1,8 +1,7 @@
import { RouterLinkStub, mount } from '@vue/test-utils' import { RouterLinkStub, mount } from '@vue/test-utils'
import flushPromises from 'flush-promises' import flushPromises from 'flush-promises'
import Login from './Login'
import { toastErrorSpy } from '@test/testSetup' import { toastErrorSpy } from '@test/testSetup'
import Login from './Login'
const localVue = global.localVue const localVue = global.localVue
@ -60,7 +59,7 @@ describe('Login', () => {
}) })
it('renders the Login form', () => { it('renders the Login form', () => {
expect(wrapper.find('div.login-form').exists()).toBeTruthy() expect(wrapper.find('div.login-form').exists()).toBe(true)
}) })
describe('Login header', () => { describe('Login header', () => {
@ -103,19 +102,19 @@ describe('Login', () => {
describe('Login form', () => { describe('Login form', () => {
it('has a login form', () => { it('has a login form', () => {
expect(wrapper.find('form').exists()).toBeTruthy() expect(wrapper.find('form').exists()).toBe(true)
}) })
it('has an Email input field', () => { it('has an Email input field', () => {
expect(wrapper.find('input[placeholder="Email"]').exists()).toBeTruthy() expect(wrapper.find('input[placeholder="Email"]').exists()).toBe(true)
}) })
it('has an Password input field', () => { it('has an Password input field', () => {
expect(wrapper.find('input[placeholder="form.password"]').exists()).toBeTruthy() expect(wrapper.find('input[placeholder="form.password"]').exists()).toBe(true)
}) })
it('has a Submit button', () => { it('has a Submit button', () => {
expect(wrapper.find('button[type="submit"]').exists()).toBeTruthy() expect(wrapper.find('button[type="submit"]').exists()).toBe(true)
}) })
}) })
@ -205,61 +204,111 @@ describe('Login', () => {
}) })
describe('login fails', () => { describe('login fails', () => {
beforeEach(async () => { const createError = async (errorMessage) => {
apolloQueryMock.mockRejectedValue({
message: errorMessage,
})
wrapper = Wrapper()
jest.clearAllMocks() jest.clearAllMocks()
await wrapper.find('input[placeholder="Email"]').setValue('user@example.org') await wrapper.find('input[placeholder="Email"]').setValue('user@example.org')
await wrapper.find('input[placeholder="form.password"]').setValue('1234') await wrapper.find('input[placeholder="form.password"]').setValue('1234')
await flushPromises() await flushPromises()
apolloQueryMock.mockRejectedValue({
message: '..No user with this credentials',
})
await wrapper.find('form').trigger('submit') await wrapper.find('form').trigger('submit')
await flushPromises() await flushPromises()
}
describe('login fails with "User email not validated"', () => {
beforeEach(async () => {
await createError('GraphQL error: User email not validated.')
}) })
it('hides the spinner', () => { it('hides the spinner', () => {
expect(spinnerHideMock).toBeCalled() expect(spinnerHideMock).toBeCalled()
}) })
it('toasts an error message', () => { it('shows error title, subtitle, login button', () => {
expect(wrapper.vm.showPageMessage).toBe(true)
expect(wrapper.find('.test-message-headline').text()).toBe('site.thx.errorTitle')
expect(wrapper.find('.test-message-subtitle').text()).toBe('site.thx.activateEmail')
expect(wrapper.find('.test-message-button').text()).toBe('settings.password.reset')
})
it('button link directs to "/forgot-password"', () => {
expect(wrapper.find('.test-message-button').attributes('href')).toBe('/forgot-password')
})
it.skip('click redirects to "/forgot-password"', async () => {
// wrapper.find('.test-message-button').trigger('click')
// await flushPromises()
// await wrapper.vm.$nextTick()
// expect(mockRouterPush).toBeCalledWith('/forgot-password')
})
it('toasts the error message', () => {
expect(toastErrorSpy).toBeCalledWith('error.no-account') expect(toastErrorSpy).toBeCalledWith('error.no-account')
}) })
describe('login fails with "User email not validated"', () => {
beforeEach(async () => {
apolloQueryMock.mockRejectedValue({
message: 'User email not validated',
})
wrapper = Wrapper()
jest.clearAllMocks()
await wrapper.find('input[placeholder="Email"]').setValue('user@example.org')
await wrapper.find('input[placeholder="form.password"]').setValue('1234')
await flushPromises()
await wrapper.find('form').trigger('submit')
await flushPromises()
})
it('redirects to /thx/login', () => {
expect(mockRouterPush).toBeCalledWith('/thx/login')
})
}) })
describe('login fails with "User has no password set yet"', () => { describe('login fails with "User has no password set yet"', () => {
beforeEach(async () => { beforeEach(async () => {
apolloQueryMock.mockRejectedValue({ await createError('GraphQL error: User has no password set yet.')
message: 'User has no password set yet',
})
wrapper = Wrapper()
jest.clearAllMocks()
await wrapper.find('input[placeholder="Email"]').setValue('user@example.org')
await wrapper.find('input[placeholder="form.password"]').setValue('1234')
await flushPromises()
await wrapper.find('form').trigger('submit')
await flushPromises()
}) })
it('redirects to /reset-password/login', () => { it('shows error title, subtitle, login button', () => {
expect(mockRouterPush).toBeCalledWith('/reset-password/login') expect(wrapper.vm.showPageMessage).toBe(true)
expect(wrapper.find('.test-message-headline').text()).toBe('site.thx.errorTitle')
expect(wrapper.find('.test-message-subtitle').text()).toBe('site.thx.unsetPassword')
expect(wrapper.find('.test-message-button').text()).toBe('settings.password.reset')
})
it('button link directs to "/reset-password/login"', () => {
expect(wrapper.find('.test-message-button').attributes('href')).toBe(
'/reset-password/login',
)
})
it.skip('click redirects to "/reset-password/login"', () => {
// expect(mockRouterPush).toBeCalledWith('/reset-password/login')
})
it('toasts the error message', () => {
expect(toastErrorSpy).toBeCalledWith('error.no-account')
})
})
describe('login fails with "No user with this credentials"', () => {
beforeEach(async () => {
await createError('GraphQL error: No user with this credentials.')
})
it('shows no error message on the page', () => {
// don't show any error on the page! against boots
expect(wrapper.vm.showPageMessage).toBe(false)
expect(wrapper.find('.test-message-headline').exists()).toBe(false)
expect(wrapper.find('.test-message-subtitle').exists()).toBe(false)
expect(wrapper.find('.test-message-button').exists()).toBe(false)
})
it('toasts the error message', () => {
expect(toastErrorSpy).toBeCalledWith('error.no-user')
})
})
describe('login fails with an unknow error', () => {
beforeEach(async () => {
await createError(' Unknow error')
})
it('shows no error message on the page', () => {
// don't show any error on the page! against boots
expect(wrapper.vm.showPageMessage).toBe(false)
expect(wrapper.find('.test-message-headline').exists()).toBe(false)
expect(wrapper.find('.test-message-subtitle').exists()).toBe(false)
expect(wrapper.find('.test-message-button').exists()).toBe(false)
})
it('toasts the error message', () => {
expect(toastErrorSpy).toBeCalledWith('error.unknown-error Unknow error')
}) })
}) })
}) })

View File

@ -13,7 +13,7 @@
</div> </div>
</b-container> </b-container>
</div> </div>
<b-container class="mt--8"> <b-container v-if="enterData" class="mt--8 p-1">
<b-row class="justify-content-center"> <b-row class="justify-content-center">
<b-col lg="5" md="7"> <b-col lg="5" md="7">
<b-card no-body class="border-0 mb-0 gradido-custom-background"> <b-card no-body class="border-0 mb-0 gradido-custom-background">
@ -57,11 +57,21 @@
</b-col> </b-col>
</b-row> </b-row>
</b-container> </b-container>
<b-container v-else class="mt--8 p-1">
<message
:headline="$t('site.thx.errorTitle')"
:subtitle="errorSubtitle"
:buttonText="$t('settings.password.reset')"
:linkTo="errorLinkTo"
/>
</b-container>
</div> </div>
</template> </template>
<script> <script>
import InputPassword from '@/components/Inputs/InputPassword' import InputPassword from '@/components/Inputs/InputPassword'
import InputEmail from '@/components/Inputs/InputEmail' import InputEmail from '@/components/Inputs/InputEmail'
import Message from '@/components/Message/Message'
import { login } from '@/graphql/queries' import { login } from '@/graphql/queries'
import CONFIG from '@/config' import CONFIG from '@/config'
@ -70,6 +80,7 @@ export default {
components: { components: {
InputPassword, InputPassword,
InputEmail, InputEmail,
Message,
}, },
data() { data() {
return { return {
@ -78,6 +89,10 @@ export default {
password: '', password: '',
}, },
passwordVisible: false, passwordVisible: false,
showPageMessage: false,
errorReason: null,
errorSubtitle: '',
errorLinkTo: '',
CONFIG, CONFIG,
} }
}, },
@ -109,15 +124,31 @@ export default {
} }
}) })
.catch((error) => { .catch((error) => {
this.toastError(this.$t('error.no-account'))
if (error.message.includes('User email not validated')) { if (error.message.includes('User email not validated')) {
this.$router.push('/thx/login') this.showPageMessage = true
this.errorSubtitle = this.$t('site.thx.activateEmail')
this.errorLinkTo = '/forgot-password'
this.toastError(this.$t('error.no-account'))
} else if (error.message.includes('User has no password set yet')) { } else if (error.message.includes('User has no password set yet')) {
this.$router.push('/reset-password/login') this.showPageMessage = true
this.errorSubtitle = this.$t('site.thx.unsetPassword')
this.errorLinkTo = '/reset-password/login'
this.toastError(this.$t('error.no-account'))
} else if (error.message.includes('No user with this credentials')) {
// don't show any error on the page! against boots
this.toastError(this.$t('error.no-user'))
} else {
// don't show any error on the page! against boots
this.toastError(this.$t('error.unknown-error') + error.message)
} }
loader.hide() loader.hide()
}) })
}, },
}, },
computed: {
enterData() {
return !this.showPageMessage
},
},
} }
</script> </script>

View File

@ -1,5 +1,6 @@
import { mount, RouterLinkStub } from '@vue/test-utils' import { mount, RouterLinkStub } from '@vue/test-utils'
import flushPromises from 'flush-promises' import flushPromises from 'flush-promises'
import { toastErrorSpy } from '@test/testSetup'
import Register from './Register' import Register from './Register'
const localVue = global.localVue const localVue = global.localVue
@ -49,7 +50,7 @@ describe('Register', () => {
}) })
it('renders the Register form', () => { it('renders the Register form', () => {
expect(wrapper.find('div#registerform').exists()).toBeTruthy() expect(wrapper.find('div#registerform').exists()).toBe(true)
}) })
describe('Register header', () => { describe('Register header', () => {
@ -93,22 +94,22 @@ describe('Register', () => {
describe('Register form', () => { describe('Register form', () => {
it('has a register form', () => { it('has a register form', () => {
expect(wrapper.find('form').exists()).toBeTruthy() expect(wrapper.find('form').exists()).toBe(true)
}) })
it('has firstname input fields', () => { it('has firstname input fields', () => {
expect(wrapper.find('#registerFirstname').exists()).toBeTruthy() expect(wrapper.find('#registerFirstname').exists()).toBe(true)
}) })
it('has lastname input fields', () => { it('has lastname input fields', () => {
expect(wrapper.find('#registerLastname').exists()).toBeTruthy() expect(wrapper.find('#registerLastname').exists()).toBe(true)
}) })
it('has email input fields', () => { it('has email input fields', () => {
expect(wrapper.find('#Email-input-field').exists()).toBeTruthy() expect(wrapper.find('#Email-input-field').exists()).toBe(true)
}) })
it('has Language selected field', () => { it('has Language selected field', () => {
expect(wrapper.find('.selectedLanguage').exists()).toBeTruthy() expect(wrapper.find('.selectedLanguage').exists()).toBe(true)
}) })
it('selects Language value en', async () => { it('selects Language value en', async () => {
@ -117,7 +118,7 @@ describe('Register', () => {
}) })
it('has 1 checkbox input fields', () => { it('has 1 checkbox input fields', () => {
expect(wrapper.find('#registerCheckbox').exists()).toBeTruthy() expect(wrapper.find('#registerCheckbox').exists()).toBe(true)
}) })
it('has PublisherId input fields', () => { it('has PublisherId input fields', () => {
@ -220,42 +221,63 @@ describe('Register', () => {
}) })
describe('server sends back error', () => { describe('server sends back error', () => {
beforeEach(async () => { const createError = async (errorMessage) => {
registerUserMutationMock.mockRejectedValue({ message: 'Ouch!' }) registerUserMutationMock.mockRejectedValue({
message: errorMessage,
})
await wrapper.find('form').trigger('submit') await wrapper.find('form').trigger('submit')
await flushPromises() await flushPromises()
}
describe('server sends back error "User already exists."', () => {
beforeEach(async () => {
await createError('GraphQL error: User already exists.')
}) })
it('shows error message', () => { it('shows no error message on the page', () => {
expect(wrapper.find('span.alert-text').exists()).toBeTruthy() // don't show any error on the page! against boots
expect(wrapper.find('span.alert-text').text().length !== 0).toBeTruthy() expect(wrapper.vm.showPageMessage).toBe(false)
expect(wrapper.find('span.alert-text').text()).toContain('error.error') expect(wrapper.find('.test-message-headline').exists()).toBe(false)
expect(wrapper.find('span.alert-text').text()).toContain('Ouch!') expect(wrapper.find('.test-message-subtitle').exists()).toBe(false)
expect(wrapper.find('.test-message-button').exists()).toBe(false)
}) })
it('button to dismisses error message is present', () => { it('toasts the error message', () => {
expect(wrapper.find('button.close').exists()).toBeTruthy() expect(toastErrorSpy).toBeCalledWith('error.user-already-exists')
})
}) })
it('dismisses error message', async () => { describe('server sends back error "Unknown error"', () => {
await wrapper.find('button.close').trigger('click') beforeEach(async () => {
await flushPromises() await createError(' Unknown error.')
expect(wrapper.find('span.alert-text').exists()).not.toBeTruthy() })
it('shows no error message on the page', () => {
// don't show any error on the page! against boots
expect(wrapper.vm.showPageMessage).toBe(false)
expect(wrapper.find('.test-message-headline').exists()).toBe(false)
expect(wrapper.find('.test-message-subtitle').exists()).toBe(false)
expect(wrapper.find('.test-message-button').exists()).toBe(false)
})
it('toasts the error message', () => {
expect(toastErrorSpy).toBeCalledWith('error.unknown-error Unknown error.')
})
}) })
}) })
describe('server sends back success', () => { describe('server sends back success', () => {
beforeEach(() => { beforeEach(async () => {
registerUserMutationMock.mockResolvedValue({ registerUserMutationMock.mockResolvedValue({
data: { data: {
create: 'success', create: 'success',
}, },
}) })
})
it('routes to "/thx/register"', async () => {
await wrapper.find('form').trigger('submit') await wrapper.find('form').trigger('submit')
await flushPromises() await flushPromises()
})
it('submit sends apollo mutate', () => {
expect(registerUserMutationMock).toBeCalledWith( expect(registerUserMutationMock).toBeCalledWith(
expect.objectContaining({ expect.objectContaining({
variables: { variables: {
@ -267,7 +289,16 @@ describe('Register', () => {
}, },
}), }),
) )
expect(routerPushMock).toHaveBeenCalledWith('/thx/register') })
it('shows success title, subtitle', () => {
expect(wrapper.vm.showPageMessage).toBe(true)
expect(wrapper.find('.test-message-headline').text()).toBe('site.thx.title')
expect(wrapper.find('.test-message-subtitle').text()).toBe('site.thx.register')
})
it('button is not present', () => {
expect(wrapper.find('.test-message-button').exists()).toBe(false)
}) })
}) })
}) })

View File

@ -15,7 +15,7 @@
</div> </div>
<!-- Page content --> <!-- Page content -->
<b-container class="mt--8 p-1"> <b-container v-if="enterData" class="mt--8 p-1">
<!-- Table --> <!-- Table -->
<b-row class="justify-content-center"> <b-row class="justify-content-center">
@ -105,19 +105,6 @@
</b-form-checkbox> </b-form-checkbox>
</b-col> </b-col>
</b-row> </b-row>
<b-alert
v-if="showError"
show
dismissible
variant="danger"
@dismissed="closeAlert"
>
<span class="alert-icon"><i class="ni ni-point"></i></span>
<span class="alert-text">
<strong>{{ $t('error.error') }}</strong>
{{ messageError }}
</span>
</b-alert>
<b-row v-b-toggle:my-collapse class="text-muted shadow-sm p-3 publisherCollaps"> <b-row v-b-toggle:my-collapse class="text-muted shadow-sm p-3 publisherCollaps">
<b-col>{{ $t('publisher.publisherId') }} {{ $store.state.publisherId }}</b-col> <b-col>{{ $t('publisher.publisherId') }} {{ $store.state.publisherId }}</b-col>
@ -177,6 +164,9 @@
</b-col> </b-col>
</b-row> </b-row>
</b-container> </b-container>
<b-container v-else class="mt--8 p-1">
<message :headline="$t('site.thx.title')" :subtitle="$t('site.thx.register')" />
</b-container>
<!-- <!--
<div class="text-center pt-4"> <div class="text-center pt-4">
<router-link class="test-button-another-community" to="/select-community"> <router-link class="test-button-another-community" to="/select-community">
@ -189,13 +179,18 @@
</div> </div>
</template> </template>
<script> <script>
import InputEmail from '@/components/Inputs/InputEmail.vue'
import LanguageSwitchSelect from '@/components/LanguageSwitchSelect.vue'
import { createUser } from '@/graphql/mutations' import { createUser } from '@/graphql/mutations'
import CONFIG from '@/config' import CONFIG from '@/config'
import InputEmail from '@/components/Inputs/InputEmail.vue'
import LanguageSwitchSelect from '@/components/LanguageSwitchSelect.vue'
import Message from '@/components/Message/Message'
export default { export default {
components: { InputEmail, LanguageSwitchSelect }, components: {
InputEmail,
LanguageSwitchSelect,
Message,
},
name: 'Register', name: 'Register',
data() { data() {
return { return {
@ -206,10 +201,8 @@ export default {
agree: false, agree: false,
}, },
language: '', language: '',
showPageMessage: false,
submitted: false, submitted: false,
showError: false,
messageError: '',
register: true,
publisherId: this.$store.state.publisherId, publisherId: this.$store.state.publisherId,
redeemCode: this.$route.params.code, redeemCode: this.$route.params.code,
CONFIG, CONFIG,
@ -240,20 +233,22 @@ export default {
}, },
}) })
.then(() => { .then(() => {
this.$router.push('/thx/register') this.showPageMessage = true
}) })
.catch((error) => { .catch((error) => {
this.showError = true // don't show any error on the page! against boots
this.messageError = error.message let errorMessage
switch (error.message) {
case 'GraphQL error: User already exists.':
errorMessage = this.$t('error.user-already-exists')
break
default:
errorMessage = this.$t('error.unknown-error') + error.message
break
}
this.toastError(errorMessage)
}) })
}, },
closeAlert() {
this.showError = false
this.messageError = ''
this.form.email = ''
this.form.firstname = ''
this.form.lastname = ''
},
}, },
computed: { computed: {
namesFilled() { namesFilled() {
@ -270,6 +265,9 @@ export default {
disabled() { disabled() {
return !(this.namesFilled && this.emailFilled && this.form.agree && !!this.language) return !(this.namesFilled && this.emailFilled && this.form.agree && !!this.language)
}, },
enterData() {
return !this.showPageMessage
},
}, },
} }
</script> </script>