Skip to content

Commit

Permalink
Implemented unit tests for public link view
Browse files Browse the repository at this point in the history
  • Loading branch information
kiranparajuli589 committed Nov 8, 2021
1 parent 9dcce09 commit f3966eb
Show file tree
Hide file tree
Showing 3 changed files with 242 additions and 17 deletions.
4 changes: 2 additions & 2 deletions packages/web-app-files/src/views/PublicLink.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@
<oc-spinner :aria-hidden="true" />
</template>
<template v-else-if="errorMessage">
<h2 class="oc-login-card-title">
<h2 class="oc-login-card-title" data-testid="public-link-error-message">
<translate>An error occurred while loading the public link</translate>
</h2>
<p class="oc-text-lead">{{ errorMessage }}</p>
</template>
<template v-else-if="passwordRequired">
<form @submit.prevent="resolvePublicLink">
<form data-testid="public-link-password-required" @submit.prevent="resolvePublicLink">
<h2 class="oc-login-card-title">
<translate>This resource is password-protected.</translate>
</h2>
Expand Down
185 changes: 170 additions & 15 deletions packages/web-app-files/tests/unit/views/PublicLink.spec.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,189 @@
import PublicLink from '@files/src/views/PublicLink.vue'
import { getStore, localVue } from './views.setup.js'
import { shallowMount, mount } from '@vue/test-utils'

const theme = {
general: { slogan: 'some-slogan' },
logo: 'some-logo',
loginPage: { backgroundImg: 'some-image' }
}

const stubs = {
'oc-spinner': true,
translate: true
}

const route = { meta: { title: 'some page title' }, params: { token: 'some-token' } }

const component = { ...PublicLink, mounted: jest.fn(), created: jest.fn() }

const selectors = {
loginLogo: '.oc-login-logo',
loginCardFooter: '.oc-login-card-footer',
loginCardBody: '.oc-login-card-body',
submitButton: '.oc-login-authorize-button',
errorMessage: '[data-testid="public-link-error-message"]',
publicLinkPasswordRequired: '[data-testid="public-link-password-required"]'
}

const spinnerStub = 'oc-spinner-stub'
const textInputStub = 'oc-text-input-stub'

describe('PublicLink', () => {
describe('theming options', () => {
test.todo('should have the background image set')
test.todo('should display the page title')
test.todo('should display the logo image inside login card')
test.todo('should display the configuration theme general slogan as the login card footer')
const wrapper = getWrapper()

it('should have the background image and page-title set', () => {
expect(wrapper).toMatchSnapshot()
})
it('should display the logo image inside login card', () => {
const logo = wrapper.find(selectors.loginLogo)

expect(logo).toMatchSnapshot()
})
it('should display the configuration theme general slogan as the login card footer', () => {
const slogan = wrapper.find(selectors.loginCardFooter)

expect(slogan).toMatchSnapshot()
})
})

describe('when the view is still loading', () => {
test.todo('should display the loading text with the spinner')
test.todo('should not display the error message')
test.todo('should not display the password required form')
const wrapper = getWrapper({ loading: true })
it('should display the loading text with the spinner', () => {
const loading = wrapper.find(selectors.loginCardBody)

expect(wrapper.find(spinnerStub).exists()).toBeTruthy()
expect(loading).toMatchSnapshot()
})
it('should not display the error message', () => {
expect(wrapper.find(selectors.errorMessage).exists()).toBeFalsy()
})
it('should not display the password required form', () => {
expect(wrapper.find(selectors.publicLinkPasswordRequired).exists()).toBeFalsy()
})
})

describe('when the view is not loading anymore', () => {
test.todo('should not display the loading text and the spinner')
test.todo('should display the error message if "errorMessage" is not empty')
it('should not display the loading text and the spinner', () => {
const wrapper = getWrapper({ loading: false })
const loading = wrapper.find(selectors.loginCardBody)

expect(loading).toMatchSnapshot()
})
it('should display the error message if "errorMessage" is not empty', async () => {
const wrapper = getWrapper({ loading: false })
await wrapper.setData({ errorMessage: 'some-error-message' })

expect(wrapper.find(selectors.errorMessage).exists()).toBeTruthy()
expect(wrapper.find(selectors.errorMessage)).toMatchSnapshot()
})

describe('when "passwordRequired" is set as true', () => {
test.todo('should display the password required form')
let passwordRequiredForm
const wrapper = getWrapper({ loading: false })

beforeEach(async () => {
await wrapper.setData({ passwordRequired: true })
passwordRequiredForm = wrapper.find('form')
})

it('should display the password required form', () => {
expect(passwordRequiredForm.exists()).toBeTruthy()
expect(passwordRequiredForm).toMatchSnapshot()
})

describe('password input', () => {
test.todo('should have a computed label')
test.todo('should display the error message if "inputErrorMessage" is not empty')
test.todo('should not display the error message if "inputErrorMessage" is falsy')
it('should have a computed label', () => {
const passwordInput = passwordRequiredForm.find(textInputStub)

expect(passwordInput).toMatchSnapshot()
})
it('should not display the error message if "inputErrorMessage" is falsy', () => {
const passwordInput = passwordRequiredForm.find(textInputStub)

expect(passwordInput.attributes().errormessage).toBeUndefined()
})
it('should display the error message if "inputErrorMessage" is not empty', async () => {
await wrapper.setData({ inputErrorMessage: 'some input error message' })
const passwordInput = passwordRequiredForm.find(textInputStub)

expect(passwordInput).toMatchSnapshot()
})
})

describe('submit button', () => {
test.todo('should be set as disabled if "password" is empty')
test.todo('should be set as enabled if "password" is not empty')
it('should be set as disabled if "password" is empty', () => {
expect(wrapper.vm.password).toBeNull()

const submitButton = wrapper.find(selectors.submitButton)
expect(submitButton.exists()).toBeTruthy()
expect(submitButton).toMatchSnapshot()
})
it('should be set as enabled if "password" is not empty', async () => {
await wrapper.setData({ password: 'some-value' })
expect(wrapper.vm.password).toBe('some-value')

const submitButton = wrapper.find(selectors.submitButton)
expect(submitButton.exists()).toBeTruthy()
expect(submitButton.attributes().disabled).toBeUndefined()
})
})

it('should call "resolvePublicLink" method on form submit', async () => {
const spyResolvePublicLink = jest.spyOn(PublicLink.methods, 'resolvePublicLink')
const wrapper = getMountedWrapper({ loading: false })

await wrapper.setData({ passwordRequired: true, password: 'some-pass' })

const submitButton = wrapper.find(selectors.submitButton)

await submitButton.trigger('click')

expect(spyResolvePublicLink).toHaveBeenCalledTimes(1)
wrapper.destroy()
})
})
})
})

function getMountOptions({
$route = route,
store = getStore({
slogan: theme.general.slogan,
loginLogo: theme.logo,
loginBackgroundImg: theme.loginPage.backgroundImg
}),
loading = false
} = {}) {
return {
localVue,
store,
stubs,
mocks: {
$route
},
data: () => ({
loading: loading
})
}
}

function getWrapper({ loading, store } = {}) {
return shallowMount(component, getMountOptions({ store, loading }))
}

function getMountedWrapper({ loading, store } = {}) {
// https://stackoverflow.com/questions/53382235/trigger-form-submit-on-button-click-in-vue-unit-test
// Vue Test Utils does not attach DOM nodes to the document by default.
// This is to avoid enforcing cleanup.
// You can solve this by setting attachTo to an HTML element when you mount the component
const div = document.createElement('div')
div.id = 'root'
document.body.appendChild(div)
return mount(component, {
...getMountOptions({ store, loading }),
attachTo: '#root',
stubs: {}
})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`PublicLink theming options should display the configuration theme general slogan as the login card footer 1`] = `
<div class="oc-login-card-footer">
<p>
some-slogan
</p>
</div>
`;

exports[`PublicLink theming options should display the logo image inside login card 1`] = `<img src="some-logo" alt="" aria-hidden="true" class="oc-login-logo">`;
exports[`PublicLink theming options should have the background image and page-title set 1`] = `
<div uk-height-viewport="" class="oc-login" style="background-image: url(some-image);">
<h1 class="oc-invisible-sr">some page title</h1>
<div class="oc-login-card uk-position-center"><img src="some-logo" alt="" aria-hidden="true" class="oc-login-logo">
<div class="oc-login-card-body">
<!---->
</div>
<div class="oc-login-card-footer">
<p>
some-slogan
</p>
</div>
</div>
</div>
`;
exports[`PublicLink when the view is not loading anymore should display the error message if "errorMessage" is not empty 1`] = `
<h2 data-testid="public-link-error-message" class="oc-login-card-title">
<translate-stub tag="span">An error occurred while loading the public link</translate-stub>
</h2>
`;
exports[`PublicLink when the view is not loading anymore should not display the loading text and the spinner 1`] = `
<div class="oc-login-card-body">
<!---->
</div>
`;
exports[`PublicLink when the view is not loading anymore when "passwordRequired" is set as true password input should display the error message if "inputErrorMessage" is not empty 1`] = `<oc-text-input-stub id="oc-textinput-3" type="password" clearbuttonaccessiblelabel="" label="Enter password for public link" class="oc-mb-s" errormessage="some input error message"></oc-text-input-stub>`;
exports[`PublicLink when the view is not loading anymore when "passwordRequired" is set as true password input should have a computed label 1`] = `<oc-text-input-stub id="oc-textinput-3" type="password" clearbuttonaccessiblelabel="" label="Enter password for public link" class="oc-mb-s"></oc-text-input-stub>`;
exports[`PublicLink when the view is not loading anymore when "passwordRequired" is set as true should display the password required form 1`] = `
<form data-testid="public-link-password-required">
<h2 class="oc-login-card-title">
<translate-stub tag="span">This resource is password-protected.</translate-stub>
</h2>
<oc-text-input-stub id="oc-textinput-3" type="password" clearbuttonaccessiblelabel="" label="Enter password for public link" class="oc-mb-s"></oc-text-input-stub>
<oc-button-stub type="button" disabled="true" size="medium" variation="primary" appearance="filled" justifycontent="center" gapsize="medium" class="oc-login-authorize-button">
<translate-stub tag="span">Continue</translate-stub>
</oc-button-stub>
</form>
`;
exports[`PublicLink when the view is not loading anymore when "passwordRequired" is set as true submit button should be set as disabled if "password" is empty 1`] = `
<oc-button-stub type="button" disabled="true" size="medium" variation="primary" appearance="filled" justifycontent="center" gapsize="medium" class="oc-login-authorize-button">
<translate-stub tag="span">Continue</translate-stub>
</oc-button-stub>
`;
exports[`PublicLink when the view is still loading should display the loading text with the spinner 1`] = `
<div class="oc-login-card-body">
<h2 class="oc-login-card-title">
<translate-stub tag="span">Loading public link…</translate-stub>
</h2>
<oc-spinner-stub arialabel="" size="medium" aria-hidden="true"></oc-spinner-stub>
</div>
`;

0 comments on commit f3966eb

Please sign in to comment.