diff --git a/admin/src/components/CommunityStatistic.spec.js b/admin/src/components/CommunityStatistic.spec.js deleted file mode 100644 index dbcca5fed..000000000 --- a/admin/src/components/CommunityStatistic.spec.js +++ /dev/null @@ -1,39 +0,0 @@ -import { mount } from '@vue/test-utils' -import CommunityStatistic from './CommunityStatistic' - -const localVue = global.localVue - -const mocks = { - $t: jest.fn((t) => t), - $n: jest.fn((n) => n), -} - -const propsData = { - value: { - totalUsers: '123', - activeUsers: '100', - deletedUsers: '5', - totalGradidoCreated: '2500', - totalGradidoDecayed: '200', - totalGradidoAvailable: '500', - totalGradidoUnbookedDecayed: '111', - }, -} - -describe('CommunityStatistic', () => { - let wrapper - - const Wrapper = () => { - return mount(CommunityStatistic, { localVue, mocks, propsData }) - } - - describe('mount', () => { - beforeEach(() => { - wrapper = Wrapper() - }) - - it('renders the Div Element ".community-statistic"', () => { - expect(wrapper.find('div.community-statistic').exists()).toBe(true) - }) - }) -}) diff --git a/admin/src/components/CommunityStatistic.vue b/admin/src/components/CommunityStatistic.vue deleted file mode 100644 index c19f8deec..000000000 --- a/admin/src/components/CommunityStatistic.vue +++ /dev/null @@ -1,59 +0,0 @@ - - diff --git a/admin/src/components/NavBar.spec.js b/admin/src/components/NavBar.spec.js index 8956564bd..139172c30 100644 --- a/admin/src/components/NavBar.spec.js +++ b/admin/src/components/NavBar.spec.js @@ -49,28 +49,36 @@ describe('NavBar', () => { it('has a link to overview', () => { expect(wrapper.findAll('.nav-item').at(0).find('a').attributes('href')).toBe('/') }) + it('has a link to /user', () => { expect(wrapper.findAll('.nav-item').at(1).find('a').attributes('href')).toBe('/user') }) + it('has a link to /creation', () => { expect(wrapper.findAll('.nav-item').at(2).find('a').attributes('href')).toBe('/creation') }) + it('has a link to /creation-confirm', () => { expect(wrapper.findAll('.nav-item').at(3).find('a').attributes('href')).toBe( '/creation-confirm', ) }) + it('has a link to /contribution-links', () => { expect(wrapper.findAll('.nav-item').at(4).find('a').attributes('href')).toBe( '/contribution-links', ) }) + + it('has a link to /statistic', () => { + expect(wrapper.findAll('.nav-item').at(5).find('a').attributes('href')).toBe('/statistic') + }) }) describe('wallet', () => { const assignLocationSpy = jest.fn() beforeEach(async () => { - await wrapper.findAll('.nav-item').at(5).find('a').trigger('click') + await wrapper.findAll('.nav-item').at(6).find('a').trigger('click') }) it.skip('changes window location to wallet', () => { @@ -89,7 +97,7 @@ describe('NavBar', () => { window.location = { assign: windowLocationMock, } - await wrapper.findAll('.nav-item').at(6).find('a').trigger('click') + await wrapper.findAll('.nav-item').at(7).find('a').trigger('click') }) it('redirects to /logout', () => { diff --git a/admin/src/components/NavBar.vue b/admin/src/components/NavBar.vue index f8dd008d1..6bed8e6e4 100644 --- a/admin/src/components/NavBar.vue +++ b/admin/src/components/NavBar.vue @@ -22,6 +22,7 @@ {{ $t('navbar.automaticContributions') }} + {{ $t('navbar.statistic') }} {{ $t('navbar.my-account') }} {{ $t('navbar.logout') }} diff --git a/admin/src/components/Tables/StatisticTable.spec.js b/admin/src/components/Tables/StatisticTable.spec.js new file mode 100644 index 000000000..876728aff --- /dev/null +++ b/admin/src/components/Tables/StatisticTable.spec.js @@ -0,0 +1,50 @@ +import { mount } from '@vue/test-utils' +import StatisticTable from './StatisticTable.vue' + +const localVue = global.localVue + +const propsData = { + value: { + totalUsers: 3113, + activeUsers: 1057, + deletedUsers: 35, + totalGradidoCreated: '4083774.05000000000000000000', + totalGradidoDecayed: '-1062639.13634129622923372197', + totalGradidoAvailable: '2513565.869444365732411569', + totalGradidoUnbookedDecayed: '-500474.6738366222166261272', + }, +} + +const mocks = { + $t: jest.fn((t) => t), + $n: jest.fn((n) => n), + $d: jest.fn((d) => d), +} + +describe('StatisticTable', () => { + let wrapper + + const Wrapper = () => { + return mount(StatisticTable, { localVue, mocks, propsData }) + } + + describe('mount', () => { + beforeEach(() => { + wrapper = Wrapper() + }) + + it('has a DIV element with the class .statistic-table', () => { + expect(wrapper.find('div.statistic-table').exists()).toBe(true) + }) + + describe('renders the table', () => { + it('with three colunms', () => { + expect(wrapper.findAll('thead > tr > th')).toHaveLength(3) + }) + + it('with seven rows', () => { + expect(wrapper.findAll('tbody > tr')).toHaveLength(7) + }) + }) + }) +}) diff --git a/admin/src/components/Tables/StatisticTable.vue b/admin/src/components/Tables/StatisticTable.vue new file mode 100644 index 000000000..a72e007a3 --- /dev/null +++ b/admin/src/components/Tables/StatisticTable.vue @@ -0,0 +1,84 @@ + + + diff --git a/admin/src/locales/de.json b/admin/src/locales/de.json index 456290ca7..ad7a668e2 100644 --- a/admin/src/locales/de.json +++ b/admin/src/locales/de.json @@ -85,7 +85,6 @@ "hide_details": "Details verbergen", "lastname": "Nachname", "math": { - "colon": ":", "equals": "=", "exclaim": "!", "pipe": "|", @@ -104,6 +103,7 @@ "my-account": "Mein Konto", "open_creation": "Offene Schöpfungen", "overview": "Übersicht", + "statistic": "Statistik", "user_search": "Nutzersuche" }, "not_open_creations": "Keine offenen Schöpfungen", @@ -125,8 +125,9 @@ "save": "Speichern", "statistic": { "activeUsers": "Aktive Mitglieder", + "count": "Menge", "deletedUsers": "Gelöschte Mitglieder", - "name": "Statistik", + "details": "Details", "totalGradidoAvailable": "GDD insgesamt im Umlauf", "totalGradidoCreated": "GDD insgesamt geschöpft", "totalGradidoDecayed": "GDD insgesamt verfallen", diff --git a/admin/src/locales/en.json b/admin/src/locales/en.json index 9bff733c5..3f8751fa1 100644 --- a/admin/src/locales/en.json +++ b/admin/src/locales/en.json @@ -85,7 +85,6 @@ "hide_details": "Hide details", "lastname": "Lastname", "math": { - "colon": ":", "equals": "=", "exclaim": "!", "pipe": "|", @@ -104,6 +103,7 @@ "my-account": "My Account", "open_creation": "Open creations", "overview": "Overview", + "statistic": "Statistic", "user_search": "User search" }, "not_open_creations": "No open creations", @@ -125,8 +125,9 @@ "save": "Speichern", "statistic": { "activeUsers": "Active members", + "count": "Count", "deletedUsers": "Deleted members", - "name": "Statistic", + "details": "Details", "totalGradidoAvailable": "Total GDD in circulation", "totalGradidoCreated": "Total created GDD", "totalGradidoDecayed": "Total GDD decay", diff --git a/admin/src/pages/CommunityStatistic.spec.js b/admin/src/pages/CommunityStatistic.spec.js new file mode 100644 index 000000000..50e04d11f --- /dev/null +++ b/admin/src/pages/CommunityStatistic.spec.js @@ -0,0 +1,98 @@ +import { mount } from '@vue/test-utils' +import CommunityStatistic from './CommunityStatistic.vue' +import { communityStatistics } from '@/graphql/communityStatistics.js' +import { toastErrorSpy } from '../../test/testSetup' +import VueApollo from 'vue-apollo' +import { createMockClient } from 'mock-apollo-client' + +const mockClient = createMockClient() +const apolloProvider = new VueApollo({ + defaultClient: mockClient, +}) + +const localVue = global.localVue +localVue.use(VueApollo) + +const defaultData = () => { + return { + communityStatistics: { + totalUsers: 3113, + activeUsers: 1057, + deletedUsers: 35, + totalGradidoCreated: '4083774.05000000000000000000', + totalGradidoDecayed: '-1062639.13634129622923372197', + totalGradidoAvailable: '2513565.869444365732411569', + totalGradidoUnbookedDecayed: '-500474.6738366222166261272', + }, + } +} + +const mocks = { + $t: jest.fn((t) => t), + $n: jest.fn((n) => n), +} + +describe('CommunityStatistic', () => { + let wrapper + + const communityStatisticsMock = jest.fn() + + mockClient.setRequestHandler( + communityStatistics, + communityStatisticsMock + .mockRejectedValueOnce({ message: 'Ouch!' }) + .mockResolvedValue({ data: defaultData() }), + ) + + const Wrapper = () => { + return mount(CommunityStatistic, { localVue, mocks, apolloProvider }) + } + + describe('mount', () => { + beforeEach(() => { + wrapper = Wrapper() + }) + + it('renders the Div Element ".community-statistic"', () => { + expect(wrapper.find('div.community-statistic').exists()).toBe(true) + }) + + describe('server response for get statistics is an error', () => { + it('toast an error message', () => { + expect(toastErrorSpy).toBeCalledWith('Ouch!') + }) + }) + + describe('server response for getting statistics is success', () => { + it('renders the data correctly', () => { + expect(wrapper.findAll('tr').at(1).findAll('td').at(1).text()).toEqual('3113') + expect(wrapper.findAll('tr').at(2).findAll('td').at(1).text()).toEqual('1057') + expect(wrapper.findAll('tr').at(3).findAll('td').at(1).text()).toEqual('35') + expect(wrapper.findAll('tr').at(4).findAll('td').at(1).text()).toEqual( + '4083774.05000000000000000000 GDD', + ) + expect(wrapper.findAll('tr').at(4).findAll('td').at(2).text()).toEqual( + '4083774.05000000000000000000', + ) + expect(wrapper.findAll('tr').at(5).findAll('td').at(1).text()).toEqual( + '-1062639.13634129622923372197 GDD', + ) + expect(wrapper.findAll('tr').at(5).findAll('td').at(2).text()).toEqual( + '-1062639.13634129622923372197', + ) + expect(wrapper.findAll('tr').at(6).findAll('td').at(1).text()).toEqual( + '2513565.869444365732411569 GDD', + ) + expect(wrapper.findAll('tr').at(6).findAll('td').at(2).text()).toEqual( + '2513565.869444365732411569', + ) + expect(wrapper.findAll('tr').at(7).findAll('td').at(1).text()).toEqual( + '-500474.6738366222166261272 GDD', + ) + expect(wrapper.findAll('tr').at(7).findAll('td').at(2).text()).toEqual( + '-500474.6738366222166261272', + ) + }) + }) + }) +}) diff --git a/admin/src/pages/CommunityStatistic.vue b/admin/src/pages/CommunityStatistic.vue new file mode 100644 index 000000000..3b4865ee3 --- /dev/null +++ b/admin/src/pages/CommunityStatistic.vue @@ -0,0 +1,42 @@ + + diff --git a/admin/src/pages/Overview.spec.js b/admin/src/pages/Overview.spec.js index affd018a7..8c714853f 100644 --- a/admin/src/pages/Overview.spec.js +++ b/admin/src/pages/Overview.spec.js @@ -1,6 +1,5 @@ import { mount } from '@vue/test-utils' import Overview from './Overview.vue' -import { communityStatistics } from '@/graphql/communityStatistics.js' import { listUnconfirmedContributions } from '@/graphql/listUnconfirmedContributions.js' const localVue = global.localVue @@ -22,19 +21,6 @@ const apolloQueryMock = jest ], }, }) - .mockResolvedValueOnce({ - data: { - communityStatistics: { - totalUsers: 3113, - activeUsers: 1057, - deletedUsers: 35, - totalGradidoCreated: '4083774.05000000000000000000', - totalGradidoDecayed: '-1062639.13634129622923372197', - totalGradidoAvailable: '2513565.869444365732411569', - totalGradidoUnbookedDecayed: '-500474.6738366222166261272', - }, - }, - }) .mockResolvedValue({ data: { listUnconfirmedContributions: [ @@ -88,14 +74,6 @@ describe('Overview', () => { ) }) - it('calls communityStatistics', () => { - expect(apolloQueryMock).toBeCalledWith( - expect.objectContaining({ - query: communityStatistics, - }), - ) - }) - it('commits three pending creations to store', () => { expect(storeCommitMock).toBeCalledWith('setOpenCreations', 3) }) diff --git a/admin/src/pages/Overview.vue b/admin/src/pages/Overview.vue index 57bf7ff8c..115fffb72 100644 --- a/admin/src/pages/Overview.vue +++ b/admin/src/pages/Overview.vue @@ -28,32 +28,13 @@ - diff --git a/admin/src/router/router.test.js b/admin/src/router/router.test.js index 22273c15b..fdc4b0b83 100644 --- a/admin/src/router/router.test.js +++ b/admin/src/router/router.test.js @@ -44,8 +44,8 @@ describe('router', () => { }) describe('routes', () => { - it('has seven routes defined', () => { - expect(routes).toHaveLength(8) + it('has nine routes defined', () => { + expect(routes).toHaveLength(9) }) it('has "/overview" as default', async () => { @@ -82,12 +82,19 @@ describe('router', () => { }) describe('contribution-links', () => { - it('loads the "ContributionLinks" component', async () => { + it('loads the "ContributionLinks" page', async () => { const component = await routes.find((r) => r.path === '/contribution-links').component() expect(component.default.name).toBe('ContributionLinks') }) }) + describe('statistics', () => { + it('loads the "CommunityStatistic" page', async () => { + const component = await routes.find((r) => r.path === '/statistic').component() + expect(component.default.name).toBe('CommunityStatistic') + }) + }) + describe('not found page', () => { it('renders the "NotFound" component', async () => { const component = await routes.find((r) => r.path === '*').component() diff --git a/admin/src/router/routes.js b/admin/src/router/routes.js index ee82f128e..e365a6e40 100644 --- a/admin/src/router/routes.js +++ b/admin/src/router/routes.js @@ -6,6 +6,10 @@ const routes = [ path: '/', component: () => import('@/pages/Overview.vue'), }, + { + path: '/statistic', + component: () => import('@/pages/CommunityStatistic.vue'), + }, { // TODO: Implement a "You are logged out"-Page path: '/logout',