Update failing test, fix linting

- moved passwordStrength to watch since there was a "unexpected side effect in computed property vue" in lint
- found this SO post https://stackoverflow.com/questions/53757107/handling-unexpected-side-effect-in-computed-properties-vuejs
This commit is contained in:
Matt Rider 2019-05-08 21:20:58 -03:00
parent 5058a0c778
commit b8465c914c
5 changed files with 48 additions and 28 deletions

View File

@ -1,5 +1,5 @@
import { mount, createLocalVue } from '@vue/test-utils' import { mount, createLocalVue } from '@vue/test-utils'
import ChangePassword from './ChangePassword.vue' import ChangePassword from './Change.vue'
import Vue from 'vue' import Vue from 'vue'
import Styleguide from '@human-connection/styleguide' import Styleguide from '@human-connection/styleguide'
@ -10,6 +10,7 @@ localVue.use(Styleguide)
describe('ChangePassword.vue', () => { describe('ChangePassword.vue', () => {
let mocks let mocks
let wrapper let wrapper
let data
beforeEach(() => { beforeEach(() => {
mocks = { mocks = {
@ -34,7 +35,7 @@ describe('ChangePassword.vue', () => {
describe('mount', () => { describe('mount', () => {
let wrapper let wrapper
const Wrapper = () => { const Wrapper = () => {
return mount(ChangePassword, { mocks, localVue }) return mount(ChangePassword, { mocks, localVue, data })
} }
beforeEach(() => { beforeEach(() => {
@ -97,8 +98,8 @@ describe('ChangePassword.vue', () => {
}) })
describe('submit form', () => { describe('submit form', () => {
beforeEach(() => { beforeEach(async () => {
wrapper.find('form').trigger('submit') await wrapper.find('form').trigger('submit')
}) })
it('calls changePassword mutation', () => { it('calls changePassword mutation', () => {
@ -119,18 +120,19 @@ describe('ChangePassword.vue', () => {
describe('mutation resolves', () => { describe('mutation resolves', () => {
beforeEach(() => { beforeEach(() => {
mocks.$apollo.mutate = jest.fn().mockResolvedValue() wrapper.find('form').trigger('submit')
wrapper = Wrapper() // mocks.$apollo.mutate = jest.fn().mockResolvedValue()
// wrapper = Wrapper()
}) })
it('calls auth/SET_TOKEN with response', () => { it('calls auth/SET_TOKEN with response', async () => {
expect(mocks.$store.commit).toHaveBeenCalledWith( expect(mocks.$store.commit).toHaveBeenCalledWith(
'auth/SET_TOKEN', 'auth/SET_TOKEN',
'NEWTOKEN' 'NEWTOKEN'
) )
}) })
it('displays success message', () => { it('displays success message', async () => {
expect(mocks.$t).toHaveBeenCalledWith( expect(mocks.$t).toHaveBeenCalledWith(
'settings.security.change-password.success' 'settings.security.change-password.success'
) )
@ -140,11 +142,16 @@ describe('ChangePassword.vue', () => {
describe('mutation rejects', () => { describe('mutation rejects', () => {
beforeEach(() => { beforeEach(() => {
// second call will reject wrapper.find('input#oldPassword').setValue('supersecret')
wrapper.find('form').trigger('submit') wrapper.find('input#newPassword').setValue('supersecret')
wrapper.find('input#confirmPassword').setValue('supersecret')
}) })
it('displays error message', () => { it('displays error message', async () => {
await wrapper.find('form').trigger('submit')
await wrapper.find('form').trigger('submit')
await mocks.$apollo.mutate
expect(mocks.$toast.error).toHaveBeenCalledWith('Ouch!') expect(mocks.$toast.error).toHaveBeenCalledWith('Ouch!')
}) })
}) })

View File

@ -25,13 +25,15 @@
type="password" type="password"
:label="$t('settings.security.change-password.label-new-password-confirm')" :label="$t('settings.security.change-password.label-new-password-confirm')"
/> />
<password-strength :password="formData.newPassword"/> <password-strength :password="formData.newPassword" />
<ds-space margin-top="base"> <ds-space margin-top="base">
<ds-button <ds-button
:loading="loading" :loading="loading"
:disabled="disabled" :disabled="disabled"
primary primary
>{{ $t('settings.security.change-password.button') }}</ds-button> >
{{ $t('settings.security.change-password.button') }}
</ds-button>
</ds-space> </ds-space>
</template> </template>
</ds-form> </ds-form>

View File

@ -1,10 +1,16 @@
<template> <template>
<div class="field"> <div class="field">
<div class="password-strength-meter"> <div class="password-strength-meter">
<div class="password-strength-meter-inner" :class="strengthClass"></div> <div
class="password-strength-meter-inner"
:class="strengthClass"
/>
</div> </div>
<p class="help"> <p class="help">
<span v-if="this.pass" :class="{ insecure: (passwordStrength < 3) }"> <span
v-if="pass"
:class="{ insecure: (passwordStrength < 3) }"
>
{{ $t('settings.security.change-password.passwordSecurity') }}: {{ $t('settings.security.change-password.passwordSecurity') }}:
<strong>{{ $t(`settings.security.change-password.passwordStrength${passwordStrength}`) }}</strong> <strong>{{ $t(`settings.security.change-password.passwordStrength${passwordStrength}`) }}</strong>
</span> </span>
@ -18,26 +24,25 @@ import zxcvbn from 'zxcvbn'
import { isEmpty } from 'lodash' import { isEmpty } from 'lodash'
export default { export default {
name: 'PasswordMeter',
props: { props: {
password: { password: {
type: String, type: String,
required: true required: true
} }
}, },
name: 'password-meter',
data() { data() {
return { return {
lastScore: 0, lastScore: 0,
pass: this.password || null pass: this.password || null
} }
}, },
watch: { computed: {
password(pass) { strengthClass() {
// update password when prop is changing return `strength-${this.passwordStrength}`
this.pass = pass || null
} }
}, },
computed: { watch: {
/** /**
* passwordStrength is the score calculated by zxcvbn * passwordStrength is the score calculated by zxcvbn
* @return {Number} Password Strength Score * @return {Number} Password Strength Score
@ -53,8 +58,9 @@ export default {
} }
return score return score
}, },
strengthClass() { password(pass) {
return `strength-${this.passwordStrength}` // update password when prop is changing
this.pass = pass || null
} }
} }
} }

View File

@ -1,6 +1,6 @@
<template> <template>
<ds-card :header="$t('settings.security.name')"> <ds-card :header="$t('settings.security.name')">
<change-password/> <change-password />
</ds-card> </ds-card>
</template> </template>

View File

@ -763,10 +763,10 @@
resolved "https://registry.yarnpkg.com/@csstools/convert-colors/-/convert-colors-1.4.0.tgz#ad495dc41b12e75d588c6db8b9834f08fa131eb7" resolved "https://registry.yarnpkg.com/@csstools/convert-colors/-/convert-colors-1.4.0.tgz#ad495dc41b12e75d588c6db8b9834f08fa131eb7"
integrity sha512-5a6wqoJV/xEdbRNKVo6I4hO3VjyDq//8q2f9I6PBAvMesJHFauXDorcNCsr9RzvsZnaWi5NYCcfyqP1QeFHFbw== integrity sha512-5a6wqoJV/xEdbRNKVo6I4hO3VjyDq//8q2f9I6PBAvMesJHFauXDorcNCsr9RzvsZnaWi5NYCcfyqP1QeFHFbw==
"@human-connection/styleguide@0.5.15": "@human-connection/styleguide@0.5.17":
version "0.5.15" version "0.5.17"
resolved "https://registry.yarnpkg.com/@human-connection/styleguide/-/styleguide-0.5.15.tgz#87142957b1ae03749e99db287adb6eafc5e2980a" resolved "https://registry.yarnpkg.com/@human-connection/styleguide/-/styleguide-0.5.17.tgz#99816579616c8d5be6c66ee86c39cb6c4e694878"
integrity sha512-BsYwXhPZutRVxyyvCWYkSsw8rEoUTimFeH4GdA9u9gohfS+opVl56KjiBPpepHsaVjbnuL8932BD/47QdM5cZg== integrity sha512-Qlo29eOi97lHls40Ms1hbGC29Aoz/W6BLoX/no5TQgHlP4qm+OK7Ra75g0sbj3a2x1Q4mZthUDWcqtjTYf6brw==
dependencies: dependencies:
vue "^2.6.6" vue "^2.6.6"
@ -11494,3 +11494,8 @@ zen-observable@^0.8.0:
version "0.8.13" version "0.8.13"
resolved "https://registry.yarnpkg.com/zen-observable/-/zen-observable-0.8.13.tgz#a9f1b9dbdfd2d60a08761ceac6a861427d44ae2e" resolved "https://registry.yarnpkg.com/zen-observable/-/zen-observable-0.8.13.tgz#a9f1b9dbdfd2d60a08761ceac6a861427d44ae2e"
integrity sha512-fa+6aDUVvavYsefZw0zaZ/v3ckEtMgCFi30sn91SEZea4y/6jQp05E3omjkX91zV6RVdn15fqnFZ6RKjRGbp2g== integrity sha512-fa+6aDUVvavYsefZw0zaZ/v3ckEtMgCFi30sn91SEZea4y/6jQp05E3omjkX91zV6RVdn15fqnFZ6RKjRGbp2g==
zxcvbn@^4.4.2:
version "4.4.2"
resolved "https://registry.yarnpkg.com/zxcvbn/-/zxcvbn-4.4.2.tgz#28ec17cf09743edcab056ddd8b1b06262cc73c30"
integrity sha1-KOwXzwl0PtyrBW3dixsGJizHPDA=