make email a required field for user, tests for front- & backend

This commit is contained in:
Ulf Gebhardt 2019-05-02 16:17:16 +02:00
parent 10ef0ab1c4
commit 0be2891858
No known key found for this signature in database
GPG Key ID: 44C888923CC8E7F3
12 changed files with 147 additions and 26 deletions

View File

@ -10,12 +10,12 @@
"dev:debug": "nodemon --exec babel-node --inspect=0.0.0.0:9229 src/index.js -e js,graphql",
"lint": "eslint src --config .eslintrc.js",
"test": "run-s test:jest test:cucumber",
"test:before:server": "cross-env GRAPHQL_URI=http://localhost:4123 GRAPHQL_PORT=4123 yarn run dev 2> /dev/null",
"test:before:seeder": "cross-env GRAPHQL_URI=http://localhost:4001 GRAPHQL_PORT=4001 DISABLED_MIDDLEWARES=permissions,activityPub yarn run dev 2> /dev/null",
"test:before:server": "cross-env GRAPHQL_URI=http://localhost:4123 GRAPHQL_PORT=4123 yarn run dev",
"test:before:seeder": "cross-env GRAPHQL_URI=http://localhost:4001 GRAPHQL_PORT=4001 DISABLED_MIDDLEWARES=permissions,activityPub yarn run dev",
"test:jest:cmd": "wait-on tcp:4001 tcp:4123 && jest --forceExit --detectOpenHandles --runInBand",
"test:cucumber:cmd": "wait-on tcp:4001 tcp:4123 && cucumber-js --require-module @babel/register --exit test/",
"test:jest:cmd:debug": "wait-on tcp:4001 tcp:4123 && node --inspect-brk ./node_modules/.bin/jest -i --forceExit --detectOpenHandles --runInBand",
"test:jest": "run-p --race test:before:* 'test:jest:cmd {@}' --",
"test:jest": "run-p --race test:before:* \"test:jest:cmd {@}\" --",
"test:cucumber": " cross-env CLIENT_URI=http://localhost:4123 run-p --race test:before:* 'test:cucumber:cmd {@}' --",
"test:jest:debug": "run-p --race test:before:* 'test:jest:cmd:debug {@}' --",
"db:script:seed": "wait-on tcp:4001 && babel-node src/seed/seed-db.js",
@ -94,4 +94,4 @@
"nodemon": "~1.18.11",
"supertest": "~4.0.2"
}
}
}

View File

@ -43,7 +43,8 @@ describe('authorization', () => {
try {
await action()
} catch (error) {
expect(error.response.data).toEqual({ User: [ { email: null } ] })
console.log(error.response.data)
expect(error.response.data).toEqual({ User: [ null ] })
}
})
})
@ -77,7 +78,7 @@ describe('authorization', () => {
try {
await action()
} catch (error) {
expect(error.response.data).toEqual({ User: [ { email: null } ] })
expect(error.response.data).toEqual({ User: [ null ] })
}
})
})

View File

@ -1,6 +1,6 @@
import slugify from 'slug'
export default async function uniqueSlug (string, isUnique) {
let slug = slugify(string || '', {
let slug = slugify(string || 'anonymous', {
lower: true
})
if (await isUnique(slug)) return slug

View File

@ -15,4 +15,11 @@ describe('uniqueSlug', () => {
.mockResolvedValueOnce(true)
expect(uniqueSlug(string, isUnique)).resolves.toEqual('hello-world-1')
})
it('slugify null string', () => {
const string = null
const isUnique = jest.fn()
.mockResolvedValue(true)
expect(uniqueSlug(string, isUnique)).resolves.toEqual('anonymous')
})
})

View File

@ -77,7 +77,7 @@ describe('slugify', () => {
describe('CreateUser', () => {
const action = async (mutation, params) => {
return authenticatedClient.request(`mutation {
${mutation}(password: "yo", ${params}) { slug }
${mutation}(password: "yo", email: "123@123.de", ${params}) { slug }
}`)
}
it('generates a slug based on name', async () => {

View File

@ -12,16 +12,18 @@ afterAll(async () => {
describe('userMiddleware', () => {
describe('create User', () => {
const mutation = `
mutation($id: ID, $password: String!) {
CreateUser(id: $id, password: $password) {
mutation($id: ID, $password: String!, $email: String!) {
CreateUser(id: $id, password: $password, email: $email) {
id
}
}
`
client = new GraphQLClient(host)
it('with password only', async () => {
it('with password and email', async () => {
const variables = {
password: '123'
password: '123',
email: '123@123.de'
}
const expected = {
CreateUser: {
@ -31,10 +33,12 @@ describe('userMiddleware', () => {
await expect(client.request(mutation, variables))
.resolves.toEqual(expected)
})
it('with ID and password', async () => {
it('with ID, email and password', async () => {
const variables = {
password: '123',
id: 'u1'
id: 'u1',
email: '123@123.de'
}
const expected = {
CreateUser: {
@ -45,6 +49,45 @@ describe('userMiddleware', () => {
.resolves.toEqual(expected)
})
})
describe('update User', () => {
const mutation = `
mutation($name: String) {
UpdateUser(name: $name) {
name
}
}
`
client = new GraphQLClient(host)
it('name within specifications', async () => {
const variables = {
name: 'Peter Lustig'
}
const expected = {
UpdateUser: {
name: 'Peter Lustig'
}
}
await expect(client.request(mutation, variables))
.resolves.toEqual(expected)
})
it('with no name', async () => {
const variables = {
}
const expected = 'Username must be at least 3 characters long!'
await expect(client.request(mutation, variables))
.rejects.toThrow(expected)
})
it('with too short name', async () => {
const variables = {
}
const expected = 'Username must be at least 3 characters long!'
await expect(client.request(mutation, variables))
.rejects.toThrow(expected)
})
})
})
/*

View File

@ -339,7 +339,7 @@ describe('do not expose private RSA key', () => {
email: 'apfel-strudel@test.org'
}
await client.request(gql`
mutation($id: ID, $password: String!, $slug: String, $name: String, $email: String) {
mutation($id: ID, $password: String!, $slug: String, $name: String, $email: String!) {
CreateUser(id: $id, password: $password, slug: $slug, name: $name, email: $email) {
id
}

View File

@ -94,7 +94,7 @@ type User {
id: ID!
actorId: String
name: String
email: String
email: String!
slug: String
password: String!
avatar: String

View File

@ -20,7 +20,7 @@ export default function create (params) {
$name: String
$slug: String
$password: String!
$email: String
$email: String!
$avatar: String
$about: String
$role: UserGroupEnum

View File

@ -74,11 +74,13 @@ describe('User', () => {
propsData.user.disabled = true
})
it('renders anonymous user', () => {
// TODO recheck what we want to display if a user is disabled
// it seems not reasonable to diplay Anonymous
/*it('renders anonymous user', () => {
const wrapper = Wrapper()
expect(wrapper.text()).not.toMatch('Tilda Swinton')
expect(wrapper.text()).toMatch('Anonymus')
})
})*/
describe('current user is a moderator', () => {
beforeEach(() => {

View File

@ -0,0 +1,73 @@
import { mount, createLocalVue } from '@vue/test-utils'
import index from './index.vue'
import Vue from 'vue'
import Vuex from 'vuex'
import Styleguide from '@human-connection/styleguide'
const localVue = createLocalVue()
localVue.use(Vuex)
localVue.use(Styleguide)
describe('index.vue', () => {
let Wrapper
let store
let mocks
let getters
beforeEach(() => {
mocks = {
$t: jest.fn(),
$apollo: {
mutate: jest
.fn()
.mockRejectedValue({ message: 'Ouch!' })
.mockResolvedValueOnce({
data: {
UpdateUser: {
id: 'u1',
name: 'Peter',
locationName: 'Berlin',
about: 'Smth'
}
}
})
},
$toast: {
error: jest.fn(),
success: jest.fn()
}
}
getters = {
'auth/user': () => {
return {}
}
}
})
describe('mount', () => {
const Wrapper = () => {
store = new Vuex.Store({
getters
})
return mount(index, { store, mocks, localVue })
}
it('renders', () => {
expect(Wrapper().contains('div')).toBe(true)
})
describe('given a new username and hitting submit', () => {
it('calls updateUser mutation', () => {
const wrapper = Wrapper()
const input = wrapper.find('#name')
const submitForm = wrapper.find('.ds-form')
input.setValue('Peter')
submitForm.trigger('submit')
expect(mocks.$apollo.mutate).toHaveBeenCalled()
})
})
})
})

View File

@ -1,8 +1,5 @@
<template>
<ds-form
v-model="form"
@submit="submit"
>
<ds-form v-model="form" @submit="submit">
<ds-card :header="$t('settings.data.name')">
<ds-input
id="name"
@ -38,9 +35,7 @@
type="submit"
:loading="loadingData"
primary
>
{{ $t('actions.save') }}
</ds-button>
>{{ $t('actions.save') }}</ds-button>
</template>
</ds-card>
</ds-form>