mirror of
https://github.com/IT4Change/Ocelot-Social.git
synced 2025-12-13 07:45:56 +00:00
Merge pull request #100 from Human-Connection/refactor_login_method_and_setup_unit_tests
Refactor login method and setup unit tests
This commit is contained in:
commit
241a14f09c
@ -44,6 +44,19 @@ const logout = () => {
|
|||||||
cy.location('pathname').should('contain', '/login') // we're out
|
cy.location('pathname').should('contain', '/login') // we're out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const lastColumnIsSortedInDescendingOrder = () => {
|
||||||
|
cy.get('tbody')
|
||||||
|
.find('tr td:last-child')
|
||||||
|
.then(last_column => {
|
||||||
|
cy.wrap(last_column)
|
||||||
|
const values = last_column
|
||||||
|
.map((i, td) => parseInt(td.textContent))
|
||||||
|
.toArray()
|
||||||
|
const ordered_descending = values.slice(0).sort((a, b) => b - a)
|
||||||
|
return cy.wrap(values).should('deep.eq', ordered_descending)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
Given('I am logged in', () => {
|
Given('I am logged in', () => {
|
||||||
login('admin@example.org', 1234)
|
login('admin@example.org', 1234)
|
||||||
})
|
})
|
||||||
@ -52,11 +65,11 @@ Given('we have a selection of tags and categories as well as posts', () => {
|
|||||||
// TODO: use db factories instead of seed data
|
// TODO: use db factories instead of seed data
|
||||||
})
|
})
|
||||||
|
|
||||||
Given('my account has the following details:', (table) => {
|
Given('my account has the following details:', table => {
|
||||||
// TODO: use db factories instead of seed data
|
// TODO: use db factories instead of seed data
|
||||||
})
|
})
|
||||||
|
|
||||||
Given('my user account has the role {string}', (role) => {
|
Given('my user account has the role {string}', role => {
|
||||||
// TODO: use db factories instead of seed data
|
// TODO: use db factories instead of seed data
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -127,28 +140,22 @@ When('I navigate to the administration dashboard', () => {
|
|||||||
.click()
|
.click()
|
||||||
})
|
})
|
||||||
|
|
||||||
When('I click on {string}', linkOrButton => {
|
When(`I click on {string}`, linkOrButton => {
|
||||||
cy.contains(linkOrButton).click()
|
cy.contains(linkOrButton).click()
|
||||||
})
|
})
|
||||||
|
|
||||||
Then('I can see a list of categories ordered by post count:', table => {
|
Then('I can see a list of categories ordered by post count:', table => {
|
||||||
// TODO: match the table in the feature with the html table
|
// TODO: match the table in the feature with the html table
|
||||||
cy.get('thead').find('tr th').should('have.length', 3)
|
cy.get('thead')
|
||||||
const last_column = cy.get('tbody').find('tr td:last-child').then((last_column) => {
|
.find('tr th')
|
||||||
cy.wrap(last_column)
|
.should('have.length', 3)
|
||||||
const values = last_column.map((i, td) => parseInt(td.textContent)).toArray()
|
lastColumnIsSortedInDescendingOrder()
|
||||||
const ordered_descending = values.slice(0).sort((a,b) => b - a)
|
|
||||||
return cy.wrap(values).should('deep.eq', ordered_descending)
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
Then('I can see a list of tags ordered by user and post count:', table => {
|
Then('I can see a list of tags ordered by user and post count:', table => {
|
||||||
// TODO: match the table in the feature with the html table
|
// TODO: match the table in the feature with the html table
|
||||||
cy.get('thead').find('tr th').should('have.length', 4)
|
cy.get('thead')
|
||||||
const last_column = cy.get('tbody').find('tr td:last-child').then((last_column) => {
|
.find('tr th')
|
||||||
cy.wrap(last_column)
|
.should('have.length', 4)
|
||||||
const values = last_column.map((i, td) => parseInt(td.textContent)).toArray()
|
lastColumnIsSortedInDescendingOrder()
|
||||||
const ordered_descending = values.slice(0).sort((a,b) => b - a)
|
|
||||||
return cy.wrap(values).should('deep.eq', ordered_descending)
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|||||||
@ -13,11 +13,6 @@ export const mutations = {
|
|||||||
SET_USER(state, user) {
|
SET_USER(state, user) {
|
||||||
state.user = user || null
|
state.user = user || null
|
||||||
},
|
},
|
||||||
SET_USER_SETTINGS(state, userSettings) {
|
|
||||||
// state.user = Object.assign(state.user, {
|
|
||||||
// userSettings: Object.assign(this.getters['auth/userSettings'], userSettings)
|
|
||||||
// })
|
|
||||||
},
|
|
||||||
SET_TOKEN(state, token) {
|
SET_TOKEN(state, token) {
|
||||||
state.token = token || null
|
state.token = token || null
|
||||||
},
|
},
|
||||||
@ -27,15 +22,15 @@ export const mutations = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const getters = {
|
export const getters = {
|
||||||
|
isAuthenticated(state) {
|
||||||
|
return !!state.token
|
||||||
|
},
|
||||||
isLoggedIn(state) {
|
isLoggedIn(state) {
|
||||||
return !!(state.user && state.token)
|
return !!(state.user && state.token)
|
||||||
},
|
},
|
||||||
pending(state) {
|
pending(state) {
|
||||||
return !!state.pending
|
return !!state.pending
|
||||||
},
|
},
|
||||||
isVerified(state) {
|
|
||||||
return !!state.user && state.user.isVerified && !!state.user.name
|
|
||||||
},
|
|
||||||
isAdmin(state) {
|
isAdmin(state) {
|
||||||
return !!state.user && state.user.role === 'admin'
|
return !!state.user && state.user.role === 'admin'
|
||||||
},
|
},
|
||||||
@ -51,20 +46,6 @@ export const getters = {
|
|||||||
token(state) {
|
token(state) {
|
||||||
return state.token
|
return state.token
|
||||||
}
|
}
|
||||||
// userSettings(state, getters, rootState, rootGetters) {
|
|
||||||
// const userSettings = (state.user && state.user.userSettings) ? state.user.userSettings : {}
|
|
||||||
//
|
|
||||||
// const defaultLanguage = (state.user && state.user.language) ? state.user.language : rootGetters['i18n/locale']
|
|
||||||
// let contentLanguages = !isEmpty(userSettings.contentLanguages) ? userSettings.contentLanguages : []
|
|
||||||
// if (isEmpty(contentLanguages)) {
|
|
||||||
// contentLanguages = userSettings.uiLanguage ? [userSettings.uiLanguage] : [defaultLanguage]
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// return Object.assign({
|
|
||||||
// uiLanguage: defaultLanguage,
|
|
||||||
// contentLanguages: contentLanguages
|
|
||||||
// }, userSettings)
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const actions = {
|
export const actions = {
|
||||||
@ -97,10 +78,8 @@ export const actions = {
|
|||||||
return getters.isLoggedIn
|
return getters.isLoggedIn
|
||||||
},
|
},
|
||||||
async login({ commit }, { email, password }) {
|
async login({ commit }, { email, password }) {
|
||||||
|
commit('SET_PENDING', true)
|
||||||
try {
|
try {
|
||||||
commit('SET_PENDING', true)
|
|
||||||
commit('SET_USER', null)
|
|
||||||
commit('SET_TOKEN', null)
|
|
||||||
const res = await this.app.apolloProvider.defaultClient
|
const res = await this.app.apolloProvider.defaultClient
|
||||||
.mutate({
|
.mutate({
|
||||||
mutation: gql(`
|
mutation: gql(`
|
||||||
@ -120,22 +99,15 @@ export const actions = {
|
|||||||
})
|
})
|
||||||
.then(({ data }) => data && data.login)
|
.then(({ data }) => data && data.login)
|
||||||
|
|
||||||
if (res && res.token) {
|
await this.app.$apolloHelpers.onLogin(res.token)
|
||||||
await this.app.$apolloHelpers.onLogin(res.token)
|
commit('SET_TOKEN', res.token)
|
||||||
commit('SET_TOKEN', res.token)
|
const userData = Object.assign({}, res)
|
||||||
delete res.token
|
delete userData.token
|
||||||
commit('SET_USER', res)
|
commit('SET_USER', userData)
|
||||||
commit('SET_PENDING', false)
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
commit('SET_PENDING', false)
|
|
||||||
throw new Error('THERE IS AN ERROR')
|
|
||||||
}
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
commit('SET_USER', null)
|
|
||||||
commit('SET_TOKEN', null)
|
|
||||||
commit('SET_PENDING', false)
|
|
||||||
throw new Error(err)
|
throw new Error(err)
|
||||||
|
} finally {
|
||||||
|
commit('SET_PENDING', false)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async logout({ commit }) {
|
async logout({ commit }) {
|
||||||
|
|||||||
160
store/auth.test.js
Normal file
160
store/auth.test.js
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
import { getters, mutations, actions } from './auth.js'
|
||||||
|
|
||||||
|
let state
|
||||||
|
let commit
|
||||||
|
|
||||||
|
const token =
|
||||||
|
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6InUzIiwic2x1ZyI6Implbm55LXJvc3RvY2siLCJuYW1lIjoiSmVubnkgUm9zdG9jayIsImF2YXRhciI6Imh0dHBzOi8vczMuYW1hem9uYXdzLmNvbS91aWZhY2VzL2ZhY2VzL3R3aXR0ZXIvbXV0dV9rcmlzaC8xMjguanBnIiwiZW1haWwiOiJ1c2VyQGV4YW1wbGUub3JnIiwicm9sZSI6InVzZXIiLCJpYXQiOjE1NDUxNDQ2ODgsImV4cCI6MTYzMTU0NDY4OCwiYXVkIjoiaHR0cDovL2xvY2FsaG9zdDozMDAwIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo0MDAwIiwic3ViIjoidTMifQ.s5_JeQN9TaUPfymAXPOpbMAwhmTIg9cnOvNEcj4z75k'
|
||||||
|
const successfulLoginResponse = {
|
||||||
|
data: {
|
||||||
|
login: {
|
||||||
|
id: 'u3',
|
||||||
|
name: 'Jenny Rostock',
|
||||||
|
slug: 'jenny-rostock',
|
||||||
|
email: 'user@example.org',
|
||||||
|
avatar:
|
||||||
|
'https://s3.amazonaws.com/uifaces/faces/twitter/mutu_krish/128.jpg',
|
||||||
|
role: 'user',
|
||||||
|
token
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const incorrectPasswordResponse = {
|
||||||
|
data: {
|
||||||
|
login: null
|
||||||
|
},
|
||||||
|
errors: [
|
||||||
|
{
|
||||||
|
message: 'Incorrect password.',
|
||||||
|
locations: [
|
||||||
|
{
|
||||||
|
line: 2,
|
||||||
|
column: 3
|
||||||
|
}
|
||||||
|
],
|
||||||
|
path: ['login']
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
commit = jest.fn()
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('getters', () => {
|
||||||
|
describe('isAuthenticated', () => {
|
||||||
|
describe('given JWT Bearer token', () => {
|
||||||
|
test('true', () => {
|
||||||
|
state = { token }
|
||||||
|
expect(getters.isAuthenticated(state)).toBe(true)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('actions', () => {
|
||||||
|
let action
|
||||||
|
|
||||||
|
describe('login', () => {
|
||||||
|
describe('given valid credentials and a successful response', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
const response = Object.assign({}, successfulLoginResponse)
|
||||||
|
const mutate = jest.fn(() => Promise.resolve(response))
|
||||||
|
const onLogin = jest.fn(() => Promise.resolve())
|
||||||
|
const module = {
|
||||||
|
app: {
|
||||||
|
apolloProvider: { defaultClient: { mutate } },
|
||||||
|
$apolloHelpers: { onLogin }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
action = actions.login.bind(module)
|
||||||
|
await action(
|
||||||
|
{ commit },
|
||||||
|
{ email: 'user@example.org', password: '1234' }
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
action = null
|
||||||
|
})
|
||||||
|
|
||||||
|
it('saves the JWT Bearer token', () => {
|
||||||
|
expect(commit.mock.calls).toEqual(
|
||||||
|
expect.arrayContaining([['SET_TOKEN', token]])
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('saves user data without token', () => {
|
||||||
|
expect(commit.mock.calls).toEqual(
|
||||||
|
expect.arrayContaining([
|
||||||
|
[
|
||||||
|
'SET_USER',
|
||||||
|
{
|
||||||
|
id: 'u3',
|
||||||
|
name: 'Jenny Rostock',
|
||||||
|
slug: 'jenny-rostock',
|
||||||
|
email: 'user@example.org',
|
||||||
|
avatar:
|
||||||
|
'https://s3.amazonaws.com/uifaces/faces/twitter/mutu_krish/128.jpg',
|
||||||
|
role: 'user'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
])
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('saves pending flags in order', () => {
|
||||||
|
expect(commit.mock.calls).toEqual(
|
||||||
|
expect.arrayContaining([
|
||||||
|
['SET_PENDING', true],
|
||||||
|
['SET_PENDING', false]
|
||||||
|
])
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('given invalid credentials and incorrect password response', () => {
|
||||||
|
let onLogin
|
||||||
|
let mutate
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
mutate = jest.fn(() => Promise.reject('This error is expected.'))
|
||||||
|
onLogin = jest.fn(() => Promise.resolve())
|
||||||
|
const module = {
|
||||||
|
app: {
|
||||||
|
apolloProvider: { defaultClient: { mutate } },
|
||||||
|
$apolloHelpers: { onLogin }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
action = actions.login.bind(module)
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
action = null
|
||||||
|
})
|
||||||
|
|
||||||
|
it('populates error messages', async () => {
|
||||||
|
expect(
|
||||||
|
action({ commit }, { email: 'user@example.org', password: 'wrong' })
|
||||||
|
).rejects.toThrowError('This error is expected.')
|
||||||
|
expect(mutate).toHaveBeenCalled()
|
||||||
|
expect(onLogin).not.toHaveBeenCalled()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('saves pending flags in order', async () => {
|
||||||
|
try {
|
||||||
|
await action(
|
||||||
|
{ commit },
|
||||||
|
{ email: 'user@example.org', password: 'wrong' }
|
||||||
|
)
|
||||||
|
} catch (err) {} // ignore
|
||||||
|
expect(commit.mock.calls).toEqual(
|
||||||
|
expect.arrayContaining([
|
||||||
|
['SET_PENDING', true],
|
||||||
|
['SET_PENDING', false]
|
||||||
|
])
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
Loading…
x
Reference in New Issue
Block a user