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 Aug 31, 2021
1 parent 250ecf5 commit c7104bd
Show file tree
Hide file tree
Showing 4 changed files with 246 additions and 22 deletions.
8 changes: 4 additions & 4 deletions packages/web-app-files/src/views/PublicLink.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,23 @@
uk-height-viewport
:style="{ backgroundImage: 'url(' + backgroundImg + ')' }"
>
<h1 class="oc-invisible-sr">{{ pageTitle }}</h1>
<h1 class="oc-invisible-sr" data-testid="public-link-page-title">{{ pageTitle }}</h1>
<div class="oc-login-card uk-position-center">
<img class="oc-login-logo" :src="logoImg" alt="" :aria-hidden="true" />
<div class="oc-login-card-body">
<template v-if="loading">
<h2 class="oc-login-card-title">
<h2 class="oc-login-card-title" data-testid="public-link-loading-text">
<translate>Loading public link…</translate>
</h2>
<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">
<template v-else-if="passwordRequired" data-testid="public-link-password-required">
<form @submit.prevent="resolvePublicLink">
<h2 class="oc-login-card-title">
<translate>This resource is password-protected.</translate>
Expand Down
192 changes: 177 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,196 @@
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 = {
pageTitle: '[data-testid="public-link-page-title"]',
loginLogo: '.oc-login-logo',
loginCardFooter: '.oc-login-card-footer',
loginCardBody: '.oc-login-card-body',
errorMessage: '[data-testid="public-link-error-message"]',
publicLinkPasswordRequired: '[data-testid="public-link-password-required"]',
loadingText: '[data-testid="public-link-loading-text"]',
publicLinkErrorMessage: '[data-testid="public-link-error-message"]',
submitButton: '.oc-login-authorize-button'
}

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 set', () => {
expect(wrapper).toMatchSnapshot()
})
it('should display the page title', () => {
const pageTitle = wrapper.find(selectors.pageTitle)

expect(pageTitle).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.find(selectors.loadingText).exists()).toBeFalsy()
expect(loading.find(spinnerStub).exists()).toBeFalsy()
})
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.publicLinkErrorMessage).exists()).toBeTruthy()
expect(wrapper.find(selectors.publicLinkErrorMessage)).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.find(textInputStub).exists()).toBeTruthy()
expect(passwordRequiredForm.find('.oc-login-authorize-button').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.attributes().errormessage).toBe('some input error message')
})
})

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.attributes().disabled).toBeTruthy()
})
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({
theme: theme
}),
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,58 @@
// 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 alt="" aria-hidden="true" class="oc-login-logo">`;
exports[`PublicLink theming options should display the page title 1`] = `<h1 data-testid="public-link-page-title" class="oc-invisible-sr">some page title</h1>`;
exports[`PublicLink theming options should have the background image set 1`] = `
<div uk-height-viewport="" class="oc-login" style="background-image: url(some-image);">
<h1 data-testid="public-link-page-title" class="oc-invisible-sr">some page title</h1>
<div class="oc-login-card uk-position-center"><img 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 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>
<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 still loading should display the loading text with the spinner 1`] = `
<div class="oc-login-card-body">
<h2 data-testid="public-link-loading-text" 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>
`;
10 changes: 7 additions & 3 deletions packages/web-app-files/tests/unit/views/views.setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ export const getStore = function({
inProgress = [null],
totalFilesCount = null,
selectedFiles = [],
totalFilesSize = null
totalFilesSize = null,
publicLinkPassword = null,
theme = null
} = {}) {
return createStore(Vuex.Store, {
state: {
Expand All @@ -50,7 +52,8 @@ export const getStore = function({
configuration: () => ({
options: {
disablePreviews: disablePreviews
}
},
theme: theme
}),
getToken: () => '',
isOcis: () => true,
Expand All @@ -72,7 +75,8 @@ export const getStore = function({
inProgress: () => inProgress,
highlightedFile: () => highlightedFile,
pages: () => pages,
currentFolder: () => currentFolder
currentFolder: () => currentFolder,
publicLinkPassword: () => publicLinkPassword
},
mutations: {
UPDATE_RESOURCE: (state, resource) => {
Expand Down

0 comments on commit c7104bd

Please sign in to comment.