diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index acff97d0e..7e07cc8d3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -399,7 +399,7 @@ jobs: report_name: Coverage Frontend type: lcov result_path: ./coverage/lcov.info - min_coverage: 86 + min_coverage: 87 token: ${{ github.token }} ############################################################################## @@ -441,7 +441,7 @@ jobs: report_name: Coverage Admin Interface type: lcov result_path: ./coverage/lcov.info - min_coverage: 50 + min_coverage: 60 token: ${{ github.token }} ############################################################################## @@ -657,4 +657,4 @@ jobs: - name: database | up run: docker-compose -f docker-compose.yml run -T database yarn up - name: database | reset - run: docker-compose -f docker-compose.yml run -T database yarn reset \ No newline at end of file + run: docker-compose -f docker-compose.yml run -T database yarn reset diff --git a/README.md b/README.md index ead54701c..ce8e84df0 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,22 @@ We are currently restructuring the service to reduce dependencies and unify busi Once you have `docker-compose` up and running, you can open [http://localhost/vue](http://localhost/vue) and create yourself a new wallet account. +## How to release + +A release is tagged on Github by its version number and published as github release. This is done automatically when a new version is defined in the [package.json](./package.json) and merged into master - furthermore we set all our sub-package-versions to the same version as the main package.json version to make version management as simple as possible. +Each release is accompanied with release notes automatically generated from the git log which is available as [CHANGELOG.md](./CHANGELOG.md). + +To generate the Changelog and set a new Version you should use the following commands in the main folder +```bash +git fetch --all +yarn release +``` + +The first command `git fetch --all` will make sure you have all tags previously defined which is required to generate a correct changelog. The second command `yarn release` will execute the changelog tool and set version numbers in the main package and sub-packages. It is required to do `yarn install` before you can use this command. +After generating a new version you should commit the changes. This will be the CHANGELOG.md and several package.json files. This commit will be omitted in the changelog. + +Note: The Changelog will be regenerated with all tags on release on the external builder tool, but will not be checked in there. The Changelog on the github release will therefore always be correct, on the repo it might be incorrect due to missing tags when executing the `yarn release` command. + ## Troubleshooting | Problem | Issue | Solution | Description | diff --git a/admin/public/img/brand/gradido_logo_w.png b/admin/public/img/brand/gradido_logo_w.png new file mode 100644 index 000000000..b6a8f5c27 Binary files /dev/null and b/admin/public/img/brand/gradido_logo_w.png differ diff --git a/admin/src/components/CreationFormular.spec.js b/admin/src/components/CreationFormular.spec.js index e1bbff1cc..f6bd1a924 100644 --- a/admin/src/components/CreationFormular.spec.js +++ b/admin/src/components/CreationFormular.spec.js @@ -11,7 +11,14 @@ const apolloMock = jest.fn().mockResolvedValue({ }, }, }) +const apolloMutateMock = jest.fn().mockResolvedValue({ + data: { + createPendingCreation: [0, 0, 0], + }, +}) const stateCommitMock = jest.fn() +const toastedErrorMock = jest.fn() +const toastedSuccessMock = jest.fn() const mocks = { $moment: jest.fn(() => { @@ -26,15 +33,25 @@ const mocks = { }), $apollo: { query: apolloMock, + mutate: apolloMutateMock, }, $store: { commit: stateCommitMock, + state: { + moderator: { + id: 0, + name: 'test moderator', + }, + }, + }, + $toasted: { + error: toastedErrorMock, + success: toastedSuccessMock, }, } const propsData = { type: '', - item: {}, creation: [], itemsMassCreation: {}, } @@ -64,9 +81,10 @@ describe('CreationFormular', () => { describe('server throws error for moderator data call', () => { beforeEach(() => { jest.clearAllMocks() - apolloMock.mockRejectedValue({ message: 'Ouch!' }) + apolloMock.mockRejectedValueOnce({ message: 'Ouch!' }) wrapper = Wrapper() }) + it('has called store commit with fake data', () => { expect(stateCommitMock).toBeCalledWith('moderator', { id: 0, name: 'Test Moderator' }) }) @@ -125,6 +143,8 @@ describe('CreationFormular', () => { jest.clearAllMocks() await wrapper.setProps({ type: 'singleCreation', 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', () => { @@ -139,6 +159,66 @@ describe('CreationFormular', () => { it('sets rangeMax to 200', () => { expect(wrapper.vm.rangeMax).toBe(200) }) + + describe('sendForm', () => { + beforeEach(async () => { + await wrapper.find('.test-submit').trigger('click') + }) + + it('sends ... to apollo', () => { + expect(apolloMutateMock).toBeCalled() + }) + }) + + describe('sendForm', () => { + beforeEach(async () => { + apolloMutateMock.mockRejectedValueOnce({ message: 'Ouch!' }) + await wrapper.find('.test-submit').trigger('click') + }) + + it('sends ... to apollo', () => { + expect(toastedErrorMock).toBeCalled() + }) + }) + + describe('Negativ value', () => { + beforeEach(async () => { + jest.clearAllMocks() + await wrapper.setProps({ type: 'singleCreation', creation: [200, 400, 600] }) + await wrapper.setData({ rangeMin: 180 }) + await wrapper.setData({ value: -20 }) + }) + + it('has no submit button', async () => { + expect(await wrapper.find('.test-submit').attributes('disabled')).toBe('disabled') + }) + }) + + describe('Empty text', () => { + beforeEach(async () => { + jest.clearAllMocks() + await wrapper.setProps({ type: 'singleCreation', creation: [200, 400, 600] }) + await wrapper.setData({ rangeMin: 180 }) + await wrapper.setData({ text: '' }) + }) + + it('has no submit button', async () => { + expect(await wrapper.find('.test-submit').attributes('disabled')).toBe('disabled') + }) + }) + + describe('Text length less than 10', () => { + beforeEach(async () => { + jest.clearAllMocks() + await wrapper.setProps({ type: 'singleCreation', creation: [200, 400, 600] }) + await wrapper.setData({ rangeMin: 180 }) + await wrapper.setData({ text: 'Try this' }) + }) + + it('has no submit button', async () => { + expect(await wrapper.find('.test-submit').attributes('disabled')).toBe('disabled') + }) + }) }) describe('second radio button', () => { @@ -153,6 +233,55 @@ describe('CreationFormular', () => { it('sets rangeMax to 400', () => { expect(wrapper.vm.rangeMax).toBe(400) }) + + describe('sendForm', () => { + beforeEach(async () => { + await wrapper.find('.test-submit').trigger('click') + }) + + it('sends ... to apollo', () => { + expect(apolloMutateMock).toBeCalled() + }) + }) + + describe('Negativ value', () => { + beforeEach(async () => { + jest.clearAllMocks() + await wrapper.setProps({ type: 'singleCreation', creation: [200, 400, 600] }) + await wrapper.setData({ rangeMin: 180 }) + await wrapper.setData({ value: -20 }) + }) + + it('has no submit button', async () => { + expect(await wrapper.find('.test-submit').attributes('disabled')).toBe('disabled') + }) + }) + + describe('Empty text', () => { + beforeEach(async () => { + jest.clearAllMocks() + await wrapper.setProps({ type: 'singleCreation', creation: [200, 400, 600] }) + await wrapper.setData({ rangeMin: 180 }) + await wrapper.setData({ text: '' }) + }) + + it('has no submit button', async () => { + expect(await wrapper.find('.test-submit').attributes('disabled')).toBe('disabled') + }) + }) + + describe('Text length less than 10', () => { + beforeEach(async () => { + jest.clearAllMocks() + await wrapper.setProps({ type: 'singleCreation', creation: [200, 400, 600] }) + await wrapper.setData({ rangeMin: 180 }) + await wrapper.setData({ text: 'Try this' }) + }) + + it('has no submit button', async () => { + expect(await wrapper.find('.test-submit').attributes('disabled')).toBe('disabled') + }) + }) }) describe('third radio button', () => { @@ -167,6 +296,63 @@ describe('CreationFormular', () => { it('sets rangeMax to 400', () => { expect(wrapper.vm.rangeMax).toBe(600) }) + + describe('sendForm', () => { + beforeEach(async () => { + await wrapper.find('.test-submit').trigger('click') + }) + + it('sends mutation to apollo', () => { + expect(apolloMutateMock).toBeCalled() + }) + + it('toast success message', () => { + expect(toastedSuccessMock).toBeCalled() + }) + + it('store commit openCreationPlus', () => { + expect(stateCommitMock).toBeCalledWith('openCreationsPlus', 1) + }) + }) + + describe('Negativ value', () => { + beforeEach(async () => { + jest.clearAllMocks() + await wrapper.setProps({ type: 'singleCreation', creation: [200, 400, 600] }) + await wrapper.setData({ rangeMin: 180 }) + await wrapper.setData({ value: -20 }) + }) + + it('has no submit button', async () => { + expect(await wrapper.find('.test-submit').attributes('disabled')).toBe('disabled') + }) + }) + + describe('Empty text', () => { + beforeEach(async () => { + jest.clearAllMocks() + await wrapper.setProps({ type: 'singleCreation', creation: [200, 400, 600] }) + await wrapper.setData({ rangeMin: 180 }) + await wrapper.setData({ text: '' }) + }) + + it('has no submit button', async () => { + expect(await wrapper.find('.test-submit').attributes('disabled')).toBe('disabled') + }) + }) + + describe('Text length less than 10', () => { + beforeEach(async () => { + jest.clearAllMocks() + await wrapper.setProps({ type: 'singleCreation', creation: [200, 400, 600] }) + await wrapper.setData({ rangeMin: 180 }) + await wrapper.setData({ text: 'Try this' }) + }) + + it('has no submit button', async () => { + expect(await wrapper.find('.test-submit').attributes('disabled')).toBe('disabled') + }) + }) }) }) }) diff --git a/admin/src/components/CreationFormular.vue b/admin/src/components/CreationFormular.vue index b6a12433e..d73ea3c81 100644 --- a/admin/src/components/CreationFormular.vue +++ b/admin/src/components/CreationFormular.vue @@ -1,60 +1,54 @@