mirror of
https://github.com/IT4Change/Ocelot-Social.git
synced 2025-12-13 07:45:56 +00:00
Merge branch 'master' into add-styleguide-dev-mode
This commit is contained in:
commit
d6a44edb7c
@ -1,2 +1 @@
|
||||
JWT_SECRET="b/&&7b78BF&fv/Vd"
|
||||
MAPBOX_TOKEN="pk.eyJ1IjoiaHVtYW4tY29ubmVjdGlvbiIsImEiOiJjajl0cnBubGoweTVlM3VwZ2lzNTNud3ZtIn0.KZ8KK9l70omjXbEkkbHGsQ"
|
||||
|
||||
@ -2,7 +2,6 @@ import { When, Then } from 'cypress-cucumber-preprocessor/steps'
|
||||
|
||||
/* global cy */
|
||||
|
||||
|
||||
When('I navigate to the administration dashboard', () => {
|
||||
cy.get('.avatar-menu').click()
|
||||
cy.get('.avatar-menu-popover')
|
||||
@ -14,11 +13,15 @@ Then('I can see a list of categories ordered by post count:', table => {
|
||||
cy.get('thead')
|
||||
.find('tr th')
|
||||
.should('have.length', 3)
|
||||
table.hashes().forEach(({Name, Posts}, index) => {
|
||||
cy.get(`tbody > :nth-child(${index + 1}) > :nth-child(2)`)
|
||||
.should('contain', Name)
|
||||
cy.get(`tbody > :nth-child(${index + 1}) > :nth-child(3)`)
|
||||
.should('contain', Posts)
|
||||
table.hashes().forEach(({ Name, Posts }, index) => {
|
||||
cy.get(`tbody > :nth-child(${index + 1}) > :nth-child(2)`).should(
|
||||
'contain',
|
||||
Name
|
||||
)
|
||||
cy.get(`tbody > :nth-child(${index + 1}) > :nth-child(3)`).should(
|
||||
'contain',
|
||||
Posts
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
@ -26,12 +29,18 @@ Then('I can see a list of tags ordered by user count:', table => {
|
||||
cy.get('thead')
|
||||
.find('tr th')
|
||||
.should('have.length', 4)
|
||||
table.hashes().forEach(({Name, Users, Posts}, index) => {
|
||||
cy.get(`tbody > :nth-child(${index + 1}) > :nth-child(2)`)
|
||||
.should('contain', Name)
|
||||
cy.get(`tbody > :nth-child(${index + 1}) > :nth-child(3)`)
|
||||
.should('contain', Users)
|
||||
cy.get(`tbody > :nth-child(${index + 1}) > :nth-child(4)`)
|
||||
.should('contain', Posts)
|
||||
table.hashes().forEach(({ Name, Users, Posts }, index) => {
|
||||
cy.get(`tbody > :nth-child(${index + 1}) > :nth-child(2)`).should(
|
||||
'contain',
|
||||
Name
|
||||
)
|
||||
cy.get(`tbody > :nth-child(${index + 1}) > :nth-child(3)`).should(
|
||||
'contain',
|
||||
Users
|
||||
)
|
||||
cy.get(`tbody > :nth-child(${index + 1}) > :nth-child(4)`).should(
|
||||
'contain',
|
||||
Posts
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
@ -111,7 +111,7 @@ Then(`I can't see the moderation menu item`, () => {
|
||||
.should('not.exist')
|
||||
})
|
||||
|
||||
When(/^I confirm the reporting dialog .*:$/, (message) => {
|
||||
When(/^I confirm the reporting dialog .*:$/, message => {
|
||||
cy.contains(message) // wait for element to become visible
|
||||
cy.get('.ds-modal').within(() => {
|
||||
cy.get('button')
|
||||
|
||||
@ -15,7 +15,7 @@ beforeEach(async () => {
|
||||
})
|
||||
|
||||
Cypress.Commands.add('factory', () => {
|
||||
return Factory({seedServerHost})
|
||||
return Factory({ seedServerHost })
|
||||
})
|
||||
|
||||
Cypress.Commands.add(
|
||||
|
||||
@ -14,7 +14,6 @@ services:
|
||||
environment:
|
||||
- HOST=0.0.0.0
|
||||
- BACKEND_URL=http://backend:4000
|
||||
- JWT_SECRET=b/&&7b78BF&fv/Vd
|
||||
- MAPBOX_TOKEN="pk.eyJ1IjoiaHVtYW4tY29ubmVjdGlvbiIsImEiOiJjajl0cnBubGoweTVlM3VwZ2lzNTNud3ZtIn0.bZ8KK9l70omjXbEkkbHGsQ"
|
||||
|
||||
networks:
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
"nonGlobalStepDefinitions": true
|
||||
},
|
||||
"jest": {
|
||||
"verbose": true,
|
||||
"moduleFileExtensions": [
|
||||
"js",
|
||||
"json",
|
||||
|
||||
@ -48,101 +48,90 @@
|
||||
<script>
|
||||
import gql from 'graphql-tag'
|
||||
|
||||
import { mapGetters } from 'vuex'
|
||||
import { mapGetters, mapMutations } from 'vuex'
|
||||
import { CancelToken } from 'axios'
|
||||
import find from 'lodash/find'
|
||||
|
||||
let timeout
|
||||
const mapboxToken = process.env.MAPBOX_TOKEN
|
||||
|
||||
const query = gql`
|
||||
query getUser($id: ID) {
|
||||
User(id: $id) {
|
||||
id
|
||||
name
|
||||
locationName
|
||||
about
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
const mutation = gql`
|
||||
mutation($id: ID!, $name: String, $locationName: String, $about: String) {
|
||||
UpdateUser(
|
||||
id: $id
|
||||
name: $name
|
||||
locationName: $locationName
|
||||
about: $about
|
||||
) {
|
||||
id
|
||||
name
|
||||
locationName
|
||||
about
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
axiosSource: null,
|
||||
cities: [],
|
||||
sending: false,
|
||||
form: {
|
||||
name: null,
|
||||
locationName: null,
|
||||
about: null
|
||||
}
|
||||
formData: {}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
user: 'auth/user'
|
||||
})
|
||||
},
|
||||
watch: {
|
||||
user: {
|
||||
immediate: true,
|
||||
handler: function(user) {
|
||||
this.form = {
|
||||
name: user.name,
|
||||
locationName: user.locationName,
|
||||
about: user.about
|
||||
}
|
||||
currentUser: 'auth/user'
|
||||
}),
|
||||
form: {
|
||||
get: function() {
|
||||
const { name, locationName, about } = this.currentUser
|
||||
return { name, locationName, about }
|
||||
},
|
||||
set: function(formData) {
|
||||
this.formData = formData
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapMutations({
|
||||
setCurrentUser: 'auth/SET_USER'
|
||||
}),
|
||||
submit() {
|
||||
this.sending = true
|
||||
const { name, about } = this.formData
|
||||
let { locationName } = this.formData
|
||||
locationName = locationName && (locationName['label'] || locationName)
|
||||
this.$apollo
|
||||
.mutate({
|
||||
mutation: gql`
|
||||
mutation(
|
||||
$id: ID!
|
||||
$name: String
|
||||
$locationName: String
|
||||
$about: String
|
||||
) {
|
||||
UpdateUser(
|
||||
id: $id
|
||||
name: $name
|
||||
locationName: $locationName
|
||||
about: $about
|
||||
) {
|
||||
id
|
||||
name
|
||||
locationName
|
||||
about
|
||||
}
|
||||
}
|
||||
`,
|
||||
// Parameters
|
||||
mutation,
|
||||
variables: {
|
||||
id: this.user.id,
|
||||
name: this.form.name,
|
||||
locationName: this.form.locationName
|
||||
? this.form.locationName['label'] || this.form.locationName
|
||||
: null,
|
||||
about: this.form.about
|
||||
id: this.currentUser.id,
|
||||
name,
|
||||
locationName,
|
||||
about
|
||||
},
|
||||
// Update the cache with the result
|
||||
// The query will be updated with the optimistic response
|
||||
// and then with the real result of the mutation
|
||||
update: (store, { data: { UpdateUser } }) => {
|
||||
this.$store.dispatch('auth/fetchCurrentUser')
|
||||
|
||||
// Read the data from our cache for this query.
|
||||
// const data = store.readQuery({ query: TAGS_QUERY })
|
||||
// Add our tag from the mutation to the end
|
||||
// data.tags.push(addTag)
|
||||
// Write our data back to the cache.
|
||||
// store.writeQuery({ query: TAGS_QUERY, data })
|
||||
const { name, locationName, about } = UpdateUser
|
||||
this.setCurrentUser({
|
||||
...this.currentUser,
|
||||
name,
|
||||
locationName,
|
||||
about
|
||||
})
|
||||
}
|
||||
// Optimistic UI
|
||||
// Will be treated as a 'fake' result as soon as the request is made
|
||||
// so that the UI can react quickly and the user be happy
|
||||
/* optimisticResponse: {
|
||||
__typename: 'Mutation',
|
||||
addTag: {
|
||||
__typename: 'Tag',
|
||||
id: -1,
|
||||
label: newTag
|
||||
}
|
||||
} */
|
||||
})
|
||||
.then(data => {
|
||||
this.$toast.success('Updated user')
|
||||
|
||||
@ -57,90 +57,70 @@ export const actions = {
|
||||
if (!token) {
|
||||
return
|
||||
}
|
||||
|
||||
const payload = await jwt.verify(token, process.env.JWT_SECRET)
|
||||
if (!payload.id) {
|
||||
return
|
||||
}
|
||||
commit('SET_TOKEN', token)
|
||||
commit('SET_USER', {
|
||||
id: payload.id
|
||||
})
|
||||
await dispatch('fetchCurrentUser')
|
||||
},
|
||||
|
||||
async check({ commit, dispatch, getters }) {
|
||||
if (!this.app.$apolloHelpers.getToken()) {
|
||||
await dispatch('logout')
|
||||
}
|
||||
return getters.isLoggedIn
|
||||
},
|
||||
async fetchCurrentUser({ commit, getters }) {
|
||||
await this.app.apolloProvider.defaultClient
|
||||
.query({
|
||||
query: gql(`
|
||||
query User($id: ID!) {
|
||||
User(id: $id) {
|
||||
id
|
||||
name
|
||||
slug
|
||||
email
|
||||
avatar
|
||||
role
|
||||
locationName
|
||||
about
|
||||
}
|
||||
|
||||
async fetchCurrentUser({ commit, dispatch }) {
|
||||
const client = this.app.apolloProvider.defaultClient
|
||||
const {
|
||||
data: { currentUser }
|
||||
} = await client.query({
|
||||
query: gql(`{
|
||||
currentUser {
|
||||
id
|
||||
name
|
||||
slug
|
||||
email
|
||||
avatar
|
||||
role
|
||||
about
|
||||
locationName
|
||||
}
|
||||
`),
|
||||
variables: { id: getters.user.id }
|
||||
})
|
||||
.then(({ data }) => {
|
||||
const user = data.User.pop()
|
||||
if (user.id && user.email) {
|
||||
commit('SET_USER', user)
|
||||
}
|
||||
})
|
||||
return getters.user
|
||||
}`)
|
||||
})
|
||||
if (!currentUser) return dispatch('logout')
|
||||
commit('SET_USER', currentUser)
|
||||
return currentUser
|
||||
},
|
||||
async login({ commit }, { email, password }) {
|
||||
|
||||
async login({ commit, dispatch }, { email, password }) {
|
||||
commit('SET_PENDING', true)
|
||||
try {
|
||||
const res = await this.app.apolloProvider.defaultClient
|
||||
.mutate({
|
||||
mutation: gql(`
|
||||
const client = this.app.apolloProvider.defaultClient
|
||||
const {
|
||||
data: { login }
|
||||
} = await client.mutate({
|
||||
mutation: gql(`
|
||||
mutation($email: String!, $password: String!) {
|
||||
login(email: $email, password: $password) {
|
||||
id
|
||||
name
|
||||
slug
|
||||
email
|
||||
avatar
|
||||
role
|
||||
locationName
|
||||
about
|
||||
token
|
||||
}
|
||||
login(email: $email, password: $password)
|
||||
}
|
||||
`),
|
||||
variables: { email, password }
|
||||
})
|
||||
.then(({ data }) => data && data.login)
|
||||
|
||||
await this.app.$apolloHelpers.onLogin(res.token)
|
||||
commit('SET_TOKEN', res.token)
|
||||
const userData = Object.assign({}, res)
|
||||
delete userData.token
|
||||
commit('SET_USER', userData)
|
||||
variables: { email, password }
|
||||
})
|
||||
await this.app.$apolloHelpers.onLogin(login)
|
||||
commit('SET_TOKEN', login)
|
||||
await dispatch('fetchCurrentUser')
|
||||
} catch (err) {
|
||||
throw new Error(err)
|
||||
} finally {
|
||||
commit('SET_PENDING', false)
|
||||
}
|
||||
},
|
||||
|
||||
async logout({ commit }) {
|
||||
commit('SET_USER', null)
|
||||
commit('SET_TOKEN', null)
|
||||
return this.app.$apolloHelpers.onLogout()
|
||||
},
|
||||
|
||||
register(
|
||||
{ dispatch, commit },
|
||||
{ email, password, inviteCode, invitedByUserId }
|
||||
|
||||
@ -2,23 +2,21 @@ import { getters, mutations, actions } from './auth.js'
|
||||
|
||||
let state
|
||||
let commit
|
||||
let dispatch
|
||||
|
||||
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 currentUser = {
|
||||
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'
|
||||
}
|
||||
const successfulLoginResponse = { data: { login: token } }
|
||||
const successfulCurrentUserResponse = { data: { currentUser } }
|
||||
|
||||
const incorrectPasswordResponse = {
|
||||
data: {
|
||||
login: null
|
||||
@ -39,6 +37,7 @@ const incorrectPasswordResponse = {
|
||||
|
||||
beforeEach(() => {
|
||||
commit = jest.fn()
|
||||
dispatch = jest.fn(() => Promise.resolve())
|
||||
})
|
||||
|
||||
describe('getters', () => {
|
||||
@ -55,34 +54,67 @@ describe('getters', () => {
|
||||
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 }
|
||||
describe('init', () => {
|
||||
const theAction = () => {
|
||||
const module = {
|
||||
app: {
|
||||
$apolloHelpers: {
|
||||
getToken: () => token
|
||||
}
|
||||
}
|
||||
action = actions.login.bind(module)
|
||||
await action(
|
||||
{ commit },
|
||||
{ email: 'user@example.org', password: '1234' }
|
||||
)
|
||||
}
|
||||
action = actions.init.bind(module)
|
||||
return action({ commit, dispatch })
|
||||
}
|
||||
|
||||
describe('client-side', () => {
|
||||
beforeEach(() => {
|
||||
process.server = false
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
action = null
|
||||
it('returns', async () => {
|
||||
await theAction()
|
||||
expect(dispatch.mock.calls).toEqual([])
|
||||
expect(commit.mock.calls).toEqual([])
|
||||
})
|
||||
})
|
||||
|
||||
describe('server-side', () => {
|
||||
beforeEach(() => {
|
||||
process.server = true
|
||||
})
|
||||
|
||||
it('saves the JWT Bearer token', () => {
|
||||
it('fetches the current user', async () => {
|
||||
await theAction()
|
||||
expect(dispatch.mock.calls).toEqual([['fetchCurrentUser']])
|
||||
})
|
||||
|
||||
it('saves the JWT Bearer token', async () => {
|
||||
await theAction()
|
||||
expect(commit.mock.calls).toEqual(
|
||||
expect.arrayContaining([['SET_TOKEN', token]])
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('fetchCurrentUser', () => {
|
||||
describe('given a successful response', () => {
|
||||
beforeEach(async () => {
|
||||
const module = {
|
||||
app: {
|
||||
apolloProvider: {
|
||||
defaultClient: {
|
||||
query: jest.fn(() =>
|
||||
Promise.resolve(successfulCurrentUserResponse)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
action = actions.fetchCurrentUser.bind(module)
|
||||
await action({ commit })
|
||||
})
|
||||
|
||||
it('saves user data without token', () => {
|
||||
expect(commit.mock.calls).toEqual(
|
||||
@ -102,6 +134,44 @@ describe('actions', () => {
|
||||
])
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('login', () => {
|
||||
describe('given valid credentials and a successful response', () => {
|
||||
beforeEach(async () => {
|
||||
const module = {
|
||||
app: {
|
||||
apolloProvider: {
|
||||
defaultClient: {
|
||||
mutate: jest.fn(() => Promise.resolve(successfulLoginResponse))
|
||||
}
|
||||
},
|
||||
$apolloHelpers: {
|
||||
onLogin: jest.fn(() => Promise.resolve())
|
||||
}
|
||||
}
|
||||
}
|
||||
action = actions.login.bind(module)
|
||||
await action(
|
||||
{ commit, dispatch },
|
||||
{ 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('fetches the user', () => {
|
||||
expect(dispatch.mock.calls).toEqual([['fetchCurrentUser']])
|
||||
})
|
||||
|
||||
it('saves pending flags in order', () => {
|
||||
expect(commit.mock.calls).toEqual(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user