diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index e3a140658..9029afb8e 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -448,7 +448,7 @@ jobs:
report_name: Coverage Admin Interface
type: lcov
result_path: ./coverage/lcov.info
- min_coverage: 78
+ min_coverage: 81
token: ${{ github.token }}
##############################################################################
diff --git a/admin/package.json b/admin/package.json
index e38d21af8..11ca864c9 100644
--- a/admin/package.json
+++ b/admin/package.json
@@ -12,7 +12,7 @@
"dev": "yarn run serve",
"build": "vue-cli-service build",
"lint": "eslint --ext .js,.vue .",
- "test": "jest --coverage",
+ "test": "TZ=UTC jest --coverage",
"locales": "scripts/missing-keys.sh && scripts/sort.sh"
},
"dependencies": {
@@ -36,14 +36,12 @@
"graphql": "^15.6.1",
"identity-obj-proxy": "^3.0.0",
"jest": "26.6.3",
- "moment": "^2.29.1",
"regenerator-runtime": "^0.13.9",
"stats-webpack-plugin": "^0.7.0",
"vue": "^2.6.11",
"vue-apollo": "^3.0.8",
"vue-i18n": "^8.26.5",
"vue-jest": "^3.0.7",
- "vue-moment": "^4.1.0",
"vue-router": "^3.5.3",
"vue-toasted": "^1.1.28",
"vuex": "^3.6.2",
diff --git a/admin/src/components/CreationFormular.spec.js b/admin/src/components/CreationFormular.spec.js
index b3807b16f..cfc23fa26 100644
--- a/admin/src/components/CreationFormular.spec.js
+++ b/admin/src/components/CreationFormular.spec.js
@@ -5,14 +5,6 @@ import { createPendingCreations } from '../graphql/createPendingCreations'
const localVue = global.localVue
-const apolloMock = jest.fn().mockResolvedValue({
- data: {
- verifyLogin: {
- name: 'success',
- id: 0,
- },
- },
-})
const apolloMutateMock = jest.fn().mockResolvedValue({
data: {
createPendingCreation: [0, 0, 0],
@@ -23,19 +15,12 @@ const toastedErrorMock = jest.fn()
const toastedSuccessMock = jest.fn()
const mocks = {
- $t: jest.fn((t) => t),
- $moment: jest.fn(() => {
- return {
- format: jest.fn((m) => m),
- subtract: jest.fn(() => {
- return {
- format: jest.fn((m) => m),
- }
- }),
- }
+ $t: jest.fn((t, options) => (options ? [t, options] : t)),
+ $d: jest.fn((d) => {
+ const date = new Date(d)
+ return date.toISOString().split('T')[0]
}),
$apollo: {
- query: apolloMock,
mutate: apolloMutateMock,
},
$store: {
@@ -56,7 +41,12 @@ const mocks = {
const propsData = {
type: '',
creation: [],
- itemsMassCreation: {},
+}
+
+const now = new Date(Date.now())
+const getCreationDate = (sub) => {
+ const date = sub === 0 ? now : new Date(now.getFullYear(), now.getMonth() - sub, 1, 0)
+ return date.toISOString().split('T')[0]
}
describe('CreationFormular', () => {
@@ -75,21 +65,24 @@ describe('CreationFormular', () => {
expect(wrapper.find('.component-creation-formular').exists()).toBeTruthy()
})
- describe('server sends back moderator data', () => {
- it('called store commit with mocked data', () => {
- expect(stateCommitMock).toBeCalledWith('moderator', { name: 'success', id: 0 })
- })
- })
-
- describe('server throws error for moderator data call', () => {
- beforeEach(() => {
- jest.clearAllMocks()
- apolloMock.mockRejectedValueOnce({ message: 'Ouch!' })
- wrapper = Wrapper()
+ describe('text and value form props', () => {
+ beforeEach(async () => {
+ wrapper = mount(CreationFormular, {
+ localVue,
+ mocks,
+ propsData: {
+ creationUserData: { memo: 'Memo from property', amount: 42 },
+ ...propsData,
+ },
+ })
})
- it('has called store commit with fake data', () => {
- expect(stateCommitMock).toBeCalledWith('moderator', { id: 0, name: 'Test Moderator' })
+ it('has text taken from props', () => {
+ expect(wrapper.vm.text).toBe('Memo from property')
+ })
+
+ it('has value taken from props', () => {
+ expect(wrapper.vm.value).toBe(42)
})
})
@@ -98,52 +91,6 @@ describe('CreationFormular', () => {
expect(wrapper.findAll('input[type="radio"]').length).toBe(3)
})
- describe('with mass creation', () => {
- beforeEach(async () => {
- jest.clearAllMocks()
- await wrapper.setProps({ type: 'massCreation', creation: [200, 400, 600] })
- await wrapper.setData({ rangeMin: 180 })
- await wrapper.setData({ text: 'Test create coins' })
- await wrapper.setData({ value: 90 })
- })
-
- describe('first radio button', () => {
- beforeEach(async () => {
- await wrapper.findAll('input[type="radio"]').at(0).setChecked()
- })
-
- it('emits update-radio-selected with index 0', () => {
- expect(wrapper.emitted()['update-radio-selected']).toEqual([
- [expect.arrayContaining([0])],
- ])
- })
- })
-
- describe('second radio button', () => {
- beforeEach(async () => {
- await wrapper.findAll('input[type="radio"]').at(1).setChecked()
- })
-
- it('emits update-radio-selected with index 1', () => {
- expect(wrapper.emitted()['update-radio-selected']).toEqual([
- [expect.arrayContaining([1])],
- ])
- })
- })
-
- describe('third radio button', () => {
- beforeEach(async () => {
- await wrapper.findAll('input[type="radio"]').at(2).setChecked()
- })
-
- it('emits update-radio-selected with index 2', () => {
- expect(wrapper.emitted()['update-radio-selected']).toEqual([
- [expect.arrayContaining([2])],
- ])
- })
- })
- })
-
describe('with single creation', () => {
beforeEach(async () => {
jest.clearAllMocks()
@@ -153,17 +100,17 @@ describe('CreationFormular', () => {
item: { email: 'benjamin@bluemchen.de' },
})
await wrapper.findAll('input[type="radio"]').at(1).setChecked()
- await wrapper.find('textarea').setValue('Test create coins')
await wrapper.find('input[type="number"]').setValue(90)
})
describe('first radio button', () => {
beforeEach(async () => {
await wrapper.findAll('input[type="radio"]').at(0).setChecked()
+ await wrapper.find('textarea').setValue('Test create coins')
})
it('sets rangeMax to 200', () => {
- expect(wrapper.vm.rangeMax).toBe(400)
+ expect(wrapper.vm.rangeMax).toBe(200)
})
describe('sendForm', () => {
@@ -177,7 +124,7 @@ describe('CreationFormular', () => {
mutation: createPendingCreation,
variables: {
email: 'benjamin@bluemchen.de',
- creationDate: 'YYYY-MM-01',
+ creationDate: getCreationDate(2),
amount: 90,
memo: 'Test create coins',
moderator: 0,
@@ -185,9 +132,30 @@ describe('CreationFormular', () => {
}),
)
})
+
+ it('emits update-user-data', () => {
+ expect(wrapper.emitted('update-user-data')).toEqual([
+ [{ email: 'benjamin@bluemchen.de' }, [0, 0, 0]],
+ ])
+ })
+
+ it('toasts a success message', () => {
+ expect(toastedSuccessMock).toBeCalledWith([
+ 'creation_form.toasted',
+ { email: 'benjamin@bluemchen.de', value: '90' },
+ ])
+ })
+
+ it('updates open creations in store', () => {
+ expect(stateCommitMock).toBeCalledWith('openCreationsPlus', 1)
+ })
+
+ it('resets the form data', () => {
+ expect(wrapper.vm.value).toBe(0)
+ })
})
- describe('sendForm', () => {
+ describe('sendForm with server error', () => {
beforeEach(async () => {
apolloMutateMock.mockRejectedValueOnce({ message: 'Ouch!' })
await wrapper.find('.test-submit').trigger('click')
@@ -373,9 +341,18 @@ describe('CreationFormular', () => {
})
})
- describe('with mass creation', () => {
+ describe('mass creation with success', () => {
beforeEach(async () => {
jest.clearAllMocks()
+ apolloMutateMock.mockResolvedValue({
+ data: {
+ createPendingCreations: {
+ success: true,
+ successfulCreation: ['bob@baumeister.de', 'bibi@bloxberg.de'],
+ failedCreation: [],
+ },
+ },
+ })
await wrapper.setProps({
type: 'massCreation',
creation: [200, 400, 600],
@@ -395,14 +372,14 @@ describe('CreationFormular', () => {
pendingCreations: [
{
email: 'bob@baumeister.de',
- creationDate: 'YYYY-MM-01',
+ creationDate: getCreationDate(1),
amount: 200,
memo: 'Test mass create coins',
moderator: 0,
},
{
email: 'bibi@bloxberg.de',
- creationDate: 'YYYY-MM-01',
+ creationDate: getCreationDate(1),
amount: 200,
memo: 'Test mass create coins',
moderator: 0,
@@ -412,6 +389,73 @@ describe('CreationFormular', () => {
}),
)
})
+
+ it('updates open creations in store', () => {
+ expect(stateCommitMock).toBeCalledWith('openCreationsPlus', 2)
+ })
+
+ it('emits remove-all-bookmark', () => {
+ expect(wrapper.emitted('remove-all-bookmark')).toBeTruthy()
+ })
+ })
+
+ describe('mass creation with success but all failed', () => {
+ beforeEach(async () => {
+ jest.clearAllMocks()
+ apolloMutateMock.mockResolvedValue({
+ data: {
+ createPendingCreations: {
+ success: true,
+ successfulCreation: [],
+ failedCreation: ['bob@baumeister.de', 'bibi@bloxberg.de'],
+ },
+ },
+ })
+ await wrapper.setProps({
+ type: 'massCreation',
+ creation: [200, 400, 600],
+ items: [{ email: 'bob@baumeister.de' }, { email: 'bibi@bloxberg.de' }],
+ })
+ await wrapper.findAll('input[type="radio"]').at(1).setChecked()
+ await wrapper.find('textarea').setValue('Test mass create coins')
+ await wrapper.find('input[type="number"]').setValue(200)
+ await wrapper.find('.test-submit').trigger('click')
+ })
+
+ it('updates open creations in store', () => {
+ expect(stateCommitMock).toBeCalledWith('openCreationsPlus', 0)
+ })
+
+ it('toasts two errors', () => {
+ expect(toastedErrorMock).toBeCalledWith(
+ 'Could not created PendingCreation for bob@baumeister.de',
+ )
+ expect(toastedErrorMock).toBeCalledWith(
+ 'Could not created PendingCreation for bibi@bloxberg.de',
+ )
+ })
+ })
+
+ describe('mass creation with error', () => {
+ beforeEach(async () => {
+ jest.clearAllMocks()
+ apolloMutateMock.mockRejectedValue({
+ message: 'Oh no!',
+ })
+ await wrapper.setProps({
+ type: 'massCreation',
+ creation: [200, 400, 600],
+ items: [{ email: 'bob@baumeister.de' }, { email: 'bibi@bloxberg.de' }],
+ })
+ await wrapper.findAll('input[type="radio"]').at(1).setChecked()
+ await wrapper.find('textarea').setValue('Test mass create coins')
+ await wrapper.find('input[type="number"]').setValue(200)
+ await wrapper.find('.test-submit').trigger('click')
+ })
+
+ it('toasts an error message', () => {
+ expect(toastedErrorMock).toBeCalledWith('Oh no!')
+ })
})
})
})
diff --git a/admin/src/components/CreationFormular.vue b/admin/src/components/CreationFormular.vue
index 3c8c914e2..34df13e11 100644
--- a/admin/src/components/CreationFormular.vue
+++ b/admin/src/components/CreationFormular.vue
@@ -7,51 +7,15 @@