From c4fcd54ef5f996efb83d6de442623e533c782988 Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Wed, 20 Apr 2022 03:33:38 +0200 Subject: [PATCH 01/47] Create LICENSE --- LICENSE | 201 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..261eeb9e9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. From 29745204b21a55c10d45cb23750b95354c23d381 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Wed, 20 Apr 2022 09:47:03 +0200 Subject: [PATCH 02/47] Create Message component --- .../src/components/Message/Message.spec.js | 101 ++++++++++++++++++ frontend/src/components/Message/Message.vue | 72 +++++++++++++ frontend/src/pages/ForgotPassword.vue | 5 + 3 files changed, 178 insertions(+) create mode 100644 frontend/src/components/Message/Message.spec.js create mode 100644 frontend/src/components/Message/Message.vue diff --git a/frontend/src/components/Message/Message.spec.js b/frontend/src/components/Message/Message.spec.js new file mode 100644 index 000000000..9d65e792c --- /dev/null +++ b/frontend/src/components/Message/Message.spec.js @@ -0,0 +1,101 @@ +import { mount } from '@vue/test-utils' +import Thx from './Message' + +const localVue = global.localVue + +const createMockObject = (comingFrom) => { + return { + $t: jest.fn((t) => t), + $route: { + params: { + comingFrom, + }, + }, + } +} + +describe('Message', () => { + let wrapper + + const Wrapper = (mocks) => { + return mount(Thx, { localVue, mocks }) + } + + describe('mount', () => { + beforeEach(() => { + wrapper = Wrapper(createMockObject('forgotPassword')) + }) + + it('renders the thx page', () => { + expect(wrapper.find('div.header').exists()).toBeTruthy() + }) + + it('renders the title', () => { + expect(wrapper.find('p.h1').text()).toBe('site.thx.title') + }) + }) + + describe('coming from /forgot-password', () => { + beforeEach(() => { + wrapper = Wrapper(createMockObject('forgotPassword')) + }) + + it('renders the thanks text', () => { + expect(wrapper.find('p.h4').text()).toBe('site.thx.email') + }) + + it('renders the thanks redirect button', () => { + expect(wrapper.find('a.btn').text()).toBe('login') + }) + + it('links the redirect button to /login', () => { + expect(wrapper.find('a.btn').attributes('href')).toBe('/login') + }) + }) + + describe('coming from /reset-password', () => { + beforeEach(() => { + wrapper = Wrapper(createMockObject('resetPassword')) + }) + + it('renders the thanks text', () => { + expect(wrapper.find('p.h4').text()).toBe('site.thx.reset') + }) + + it('renders the thanks redirect button', () => { + expect(wrapper.find('a.btn').text()).toBe('login') + }) + + it('links the redirect button to /login', () => { + expect(wrapper.find('a.btn').attributes('href')).toBe('/login') + }) + }) + + describe('coming from /register', () => { + beforeEach(() => { + wrapper = Wrapper(createMockObject('register')) + }) + + it('renders the thanks text', () => { + expect(wrapper.find('p.h4').text()).toBe('site.thx.register') + }) + }) + + describe('coming from /login', () => { + beforeEach(() => { + wrapper = Wrapper(createMockObject('login')) + }) + + it('renders the thanks text', () => { + expect(wrapper.find('p.h4').text()).toBe('site.thx.activateEmail') + }) + + it('renders the thanks redirect button', () => { + expect(wrapper.find('a.btn').text()).toBe('settings.password.reset') + }) + + it('links the redirect button to /forgot-password', () => { + expect(wrapper.find('a.btn').attributes('href')).toBe('/forgot-password') + }) + }) +}) diff --git a/frontend/src/components/Message/Message.vue b/frontend/src/components/Message/Message.vue new file mode 100644 index 000000000..26468f9e3 --- /dev/null +++ b/frontend/src/components/Message/Message.vue @@ -0,0 +1,72 @@ + + + diff --git a/frontend/src/pages/ForgotPassword.vue b/frontend/src/pages/ForgotPassword.vue index 580a0ed97..e357652c8 100644 --- a/frontend/src/pages/ForgotPassword.vue +++ b/frontend/src/pages/ForgotPassword.vue @@ -36,16 +36,21 @@ {{ $t('back') }} + + + diff --git a/frontend/src/pages/ForgotPassword.spec.js b/frontend/src/pages/ForgotPassword.spec.js index e97eb1018..eaf4558e1 100644 --- a/frontend/src/pages/ForgotPassword.spec.js +++ b/frontend/src/pages/ForgotPassword.spec.js @@ -116,11 +116,15 @@ describe('ForgotPassword', () => { await flushPromises() }) - it('shows error message', () => { + it('shows error title, subtitle, login button', () => { expect(wrapper.find('.test-message-headline').text()).toBe('site.thx.errorTitle') expect(wrapper.find('.test-message-subtitle').text()).toBe('error.email-already-sent') expect(wrapper.find('.test-message-button').text()).toBe('login') }) + + it('button link redirects to /login', () => { + expect(wrapper.find('.test-message-button').attributes('href')).toBe('/login') + }) }) describe('success', () => { @@ -136,11 +140,15 @@ describe('ForgotPassword', () => { await flushPromises() }) - it('shows thx, email, send, login button', () => { + it('shows success title, subtitle, login button', () => { expect(wrapper.find('.test-message-headline').text()).toBe('site.thx.title') expect(wrapper.find('.test-message-subtitle').text()).toBe('site.thx.email') expect(wrapper.find('.test-message-button').text()).toBe('login') }) + + it('button link redirects to /login', () => { + expect(wrapper.find('.test-message-button').attributes('href')).toBe('/login') + }) }) }) }) diff --git a/frontend/src/pages/ForgotPassword.vue b/frontend/src/pages/ForgotPassword.vue index 9a1885959..535a7d6d2 100644 --- a/frontend/src/pages/ForgotPassword.vue +++ b/frontend/src/pages/ForgotPassword.vue @@ -37,7 +37,22 @@ - + + + + From ef6b3c78df7ce0c20c082b257b1a8e56b8c41966 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Thu, 21 Apr 2022 08:46:57 +0200 Subject: [PATCH 06/47] Fix translation of ForgotPassword login button text --- frontend/src/pages/ForgotPassword.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/pages/ForgotPassword.vue b/frontend/src/pages/ForgotPassword.vue index 535a7d6d2..85ac6b87d 100644 --- a/frontend/src/pages/ForgotPassword.vue +++ b/frontend/src/pages/ForgotPassword.vue @@ -42,14 +42,14 @@ v-if="success" :headline="$t('site.thx.title')" :subtitle="$t('site.thx.email')" - buttonText="login" + :buttonText="$t('login')" linkTo="/login" /> From 3dddbabb9918eb6ede352fa0af79f3acfd9bdae9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Thu, 21 Apr 2022 09:09:54 +0200 Subject: [PATCH 07/47] Fix error after Ulf's hint --- frontend/src/components/Message/Message.vue | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frontend/src/components/Message/Message.vue b/frontend/src/components/Message/Message.vue index 7a2f7bb9c..092f003ce 100644 --- a/frontend/src/components/Message/Message.vue +++ b/frontend/src/components/Message/Message.vue @@ -5,9 +5,9 @@
-

{{ $t(headline) }}

+

{{ headline }}

-

{{ $t(subtitle) }}

+

{{ subtitle }}


- {{ $t(buttonText) }} + {{ buttonText }}
From 13b5e02c241770073dfb4dd40a7dbd35a133ddc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Thu, 21 Apr 2022 09:16:07 +0200 Subject: [PATCH 08/47] Removed comment after Ulf's suggestion --- frontend/src/pages/ForgotPassword.vue | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/src/pages/ForgotPassword.vue b/frontend/src/pages/ForgotPassword.vue index 85ac6b87d..46adc20d7 100644 --- a/frontend/src/pages/ForgotPassword.vue +++ b/frontend/src/pages/ForgotPassword.vue @@ -98,7 +98,6 @@ export default { }, }, created() { - // Wolle: what shall happen here? change needed? if (this.$route.params.comingFrom) { this.subtitle = 'settings.password.resend_subtitle' } From 097d33fb9702e6ad92e3a716eba6525eeff9a8ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Thu, 21 Apr 2022 09:40:34 +0200 Subject: [PATCH 09/47] Refactor Login page --- frontend/src/components/Message/Message.vue | 2 +- frontend/src/locales/de.json | 3 +- frontend/src/locales/en.json | 5 ++-- frontend/src/pages/Login.vue | 31 +++++++++++++++++++-- 4 files changed, 34 insertions(+), 7 deletions(-) diff --git a/frontend/src/components/Message/Message.vue b/frontend/src/components/Message/Message.vue index 092f003ce..384bc6d1c 100644 --- a/frontend/src/components/Message/Message.vue +++ b/frontend/src/components/Message/Message.vue @@ -2,7 +2,7 @@
- +

{{ headline }}

diff --git a/frontend/src/locales/de.json b/frontend/src/locales/de.json index df25d837c..d69150f90 100644 --- a/frontend/src/locales/de.json +++ b/frontend/src/locales/de.json @@ -230,7 +230,8 @@ "register": "Du bist jetzt registriert, bitte überprüfe deine Emails und klicke auf den Aktivierungslink.", "reset": "Dein Passwort wurde geändert.", "resetPassword": "Den Code den Du genutzt hast ist zu alt bitte fordere ein neuen über die Passwort Reset Seite an.", - "title": "Danke!" + "title": "Danke!", + "unsetPassword": "Dein Passwort wurde noch nicht gesetzt. Bitte setze es neu." } }, "success": "Erfolg", diff --git a/frontend/src/locales/en.json b/frontend/src/locales/en.json index 4734abf00..5da0a1d6b 100644 --- a/frontend/src/locales/en.json +++ b/frontend/src/locales/en.json @@ -222,7 +222,7 @@ "uppercase": "One uppercase letter required." }, "thx": { - "activateEmail": "Your account has not been activated yet, please check your emails and click the activation link or order a new activation link over the password reset page.", + "activateEmail": "Your account has not been activated yet. Please check your emails and click the activation link or order a new activation link over the password reset page.", "checkEmail": "Your email has been successfully verified. You can sign in now.", "email": "We have sent you an email.", "emailActivated": "Thank you your email has been activated.", @@ -230,7 +230,8 @@ "register": "You are registered now, please check your emails and click the activation link.", "reset": "Your password has been changed.", "resetPassword": "The code you used was to old please order a new on over the password reset page.", - "title": "Thank you!" + "title": "Thank you!", + "unsetPassword": "Your password has not been set yet. Please set it again." } }, "success": "Success", diff --git a/frontend/src/pages/Login.vue b/frontend/src/pages/Login.vue index 79532cb21..a84bfc1ab 100755 --- a/frontend/src/pages/Login.vue +++ b/frontend/src/pages/Login.vue @@ -13,7 +13,7 @@
- + @@ -57,11 +57,31 @@ + + + + + +
+ diff --git a/frontend/src/locales/de.json b/frontend/src/locales/de.json index 7cd11d0a7..1b7dc7167 100644 --- a/frontend/src/locales/de.json +++ b/frontend/src/locales/de.json @@ -35,7 +35,9 @@ "error": "Fehler!", "no-account": "Leider konnten wir keinen (aktivierten) Account mit diesen Daten finden.", "no-transactionlist": "Es gab leider einen Fehler. Es wurden keine Transaktionen vom Server übermittelt.", - "session-expired": "Die Sitzung wurde aus Sicherheitsgründen beendet." + "session-expired": "Die Sitzung wurde aus Sicherheitsgründen beendet.", + "unknown-error": "Unbekanter Fehler: ", + "user-already-exists": "Ein Benutzer mit diesen Daten existiert bereits." }, "footer": { "app_version": "App version {version}", @@ -213,6 +215,9 @@ "new_wallet": "Neues Konto erstellen", "signin": "Anmelden" }, + "register": { + "message-button-text": "Alles klar" + }, "signup": { "agree": "Ich stimme der Datenschutzerklärung zu.", "dont_match": "Die Passwörter stimmen nicht überein.", diff --git a/frontend/src/locales/en.json b/frontend/src/locales/en.json index 0c51edb0c..aeff775d4 100644 --- a/frontend/src/locales/en.json +++ b/frontend/src/locales/en.json @@ -35,7 +35,9 @@ "error": "Error!", "no-account": "Unfortunately we could not find an (activated) account to the given data.", "no-transactionlist": "Unfortunately, there was an error. No transactions have been sent from the server.", - "session-expired": "The session was closed for security reasons." + "session-expired": "The session was closed for security reasons.", + "unknown-error": "Unknown error: ", + "user-already-exists": "A user with this data already exists." }, "footer": { "app_version": "App version {version}", @@ -213,6 +215,9 @@ "new_wallet": "Create new account", "signin": "Sign in" }, + "register": { + "message-button-text": "Okay" + }, "signup": { "agree": "I agree to the privacy policy.", "dont_match": "Passwords don't match.", diff --git a/frontend/src/pages/ForgotPassword.vue b/frontend/src/pages/ForgotPassword.vue index bdb57ac7b..630974c52 100644 --- a/frontend/src/pages/ForgotPassword.vue +++ b/frontend/src/pages/ForgotPassword.vue @@ -69,7 +69,6 @@ export default { }, data() { return { - // Wolle disable: 'disabled', form: { email: '', }, diff --git a/frontend/src/pages/Register.vue b/frontend/src/pages/Register.vue index 94441c636..5ee513aaf 100755 --- a/frontend/src/pages/Register.vue +++ b/frontend/src/pages/Register.vue @@ -15,7 +15,7 @@ - + @@ -177,6 +177,23 @@ + + + + + + Date: Wed, 27 Apr 2022 13:04:51 +0200 Subject: [PATCH 17/47] Fix error with undefined this.callback --- frontend/src/components/Message/Message.vue | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/frontend/src/components/Message/Message.vue b/frontend/src/components/Message/Message.vue index 769bd99bf..bf83d7344 100644 --- a/frontend/src/components/Message/Message.vue +++ b/frontend/src/components/Message/Message.vue @@ -13,7 +13,7 @@ v-if="buttonText && (linkTo || callback)" class="test-message-button" :to="linkTo ? linkTo + (code ? `/${code}` : '') : null" - @click="callback()" + @click="optionalCallback()" > {{ buttonText }} @@ -36,5 +36,12 @@ export default { callback: { type: Function, required: false, default: null }, code: { type: String, required: false, default: null }, // Wolle: to be removed by adding it directly to the "linkTo" }, + methods: { + optionalCallback() { + if (this.callback) { + this.callback() + } + }, + }, } From 5c89fe545d37f4abd334a49e7bad23bd8947e06b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Wed, 27 Apr 2022 13:05:37 +0200 Subject: [PATCH 18/47] Change Login page to more general page message --- frontend/src/pages/Login.spec.js | 6 ++++-- frontend/src/pages/Login.vue | 30 +++++++++++++++++------------- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/frontend/src/pages/Login.spec.js b/frontend/src/pages/Login.spec.js index c31b4d77d..5b7ccfefe 100644 --- a/frontend/src/pages/Login.spec.js +++ b/frontend/src/pages/Login.spec.js @@ -211,7 +211,7 @@ describe('Login', () => { await wrapper.find('input[placeholder="form.password"]').setValue('1234') await flushPromises() apolloQueryMock.mockRejectedValue({ - message: '..No user with this credentials', + message: '...No user with this credentials', }) await wrapper.find('form').trigger('submit') await flushPromises() @@ -222,7 +222,9 @@ describe('Login', () => { }) it('toasts an error message', () => { - expect(toastErrorSpy).toBeCalledWith('error.no-account') + expect(toastErrorSpy).toBeCalledWith( + 'error.unknown-error...No user with this credentials', + ) }) describe('login fails with "User email not validated"', () => { diff --git a/frontend/src/pages/Login.vue b/frontend/src/pages/Login.vue index c4f324f1f..935ed9eed 100755 --- a/frontend/src/pages/Login.vue +++ b/frontend/src/pages/Login.vue @@ -60,18 +60,10 @@ - @@ -101,6 +93,8 @@ export default { passwordVisible: false, showPageMessage: false, errorReason: null, + errorSubtitle: '', + errorLinkTo: '', CONFIG, } }, @@ -132,13 +126,23 @@ export default { } }) .catch((error) => { - this.toastError(this.$t('error.no-account')) if (error.message.includes('User email not validated')) { + this.toastError(this.$t('error.no-account')) this.showPageMessage = true - this.errorReason = 'email-unvalidated' + this.errorSubtitle = this.$t('site.thx.activateEmail') + this.errorLinkTo = '/forgot-password' } else if (error.message.includes('User has no password set yet')) { + this.toastError(this.$t('error.no-account')) this.showPageMessage = true - this.errorReason = 'password-unset' + this.errorSubtitle = this.$t('site.thx.unsetPassword') + this.errorLinkTo = '/reset-password/login' + } else { + // appeared errors: 'GraphQL error: No user with this credentials' + const errorMessage = this.$t('error.unknown-error') + error.message + this.toastError(errorMessage) + this.showPageMessage = true + this.errorSubtitle = errorMessage + this.errorLinkTo = '/forgot-password' } loader.hide() }) From f95c11e29a66a73486d3f26de19ea29c6d11dca3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Fri, 29 Apr 2022 12:01:03 +0200 Subject: [PATCH 19/47] Cleanup and clarity --- .../src/components/Message/Message.spec.js | 67 ------------------- frontend/src/components/Message/Message.vue | 4 -- frontend/src/pages/ForgotPassword.spec.js | 2 - frontend/src/pages/ForgotPassword.vue | 2 - frontend/src/pages/Login.spec.js | 2 - frontend/src/pages/Login.vue | 2 - frontend/src/pages/Register.spec.js | 18 ----- frontend/src/pages/Register.vue | 6 +- 8 files changed, 1 insertion(+), 102 deletions(-) diff --git a/frontend/src/components/Message/Message.spec.js b/frontend/src/components/Message/Message.spec.js index e1253e6c2..afbef53cd 100644 --- a/frontend/src/components/Message/Message.spec.js +++ b/frontend/src/components/Message/Message.spec.js @@ -37,74 +37,7 @@ describe('Message', () => { }) it('button link redirects to /login', () => { - // Wolle console.log(wrapper.html()) expect(wrapper.find('a.btn').attributes('href')).toBe('/login') }) }) - - // Wolle: test 'code' prop and have a look if there is other important stuff uncommented below - - // Wolle describe('coming from /forgot-password', () => { - // beforeEach(() => { - // wrapper = Wrapper(createMockObject('forgotPassword')) - // }) - - // it('renders the thanks text', () => { - // expect(wrapper.find('p.h4').text()).toBe('site.thx.email') - // }) - - // it('renders the thanks redirect button', () => { - // expect(wrapper.find('a.btn').text()).toBe('login') - // }) - - // it('links the redirect button to /login', () => { - // expect(wrapper.find('a.btn').attributes('href')).toBe('/login') - // }) - // }) - - // describe('coming from /reset-password', () => { - // beforeEach(() => { - // wrapper = Wrapper(createMockObject('resetPassword')) - // }) - - // it('renders the thanks text', () => { - // expect(wrapper.find('p.h4').text()).toBe('site.thx.reset') - // }) - - // it('renders the thanks redirect button', () => { - // expect(wrapper.find('a.btn').text()).toBe('login') - // }) - - // it('links the redirect button to /login', () => { - // expect(wrapper.find('a.btn').attributes('href')).toBe('/login') - // }) - // }) - - // describe('coming from /register', () => { - // beforeEach(() => { - // wrapper = Wrapper(createMockObject('register')) - // }) - - // it('renders the thanks text', () => { - // expect(wrapper.find('p.h4').text()).toBe('site.thx.register') - // }) - // }) - - // describe('coming from /login', () => { - // beforeEach(() => { - // wrapper = Wrapper(createMockObject('login')) - // }) - - // it('renders the thanks text', () => { - // expect(wrapper.find('p.h4').text()).toBe('site.thx.activateEmail') - // }) - - // it('renders the thanks redirect button', () => { - // expect(wrapper.find('a.btn').text()).toBe('settings.password.reset') - // }) - - // it('links the redirect button to /forgot-password', () => { - // expect(wrapper.find('a.btn').attributes('href')).toBe('/forgot-password') - // }) - // }) }) diff --git a/frontend/src/components/Message/Message.vue b/frontend/src/components/Message/Message.vue index bf83d7344..d9afbd480 100644 --- a/frontend/src/components/Message/Message.vue +++ b/frontend/src/components/Message/Message.vue @@ -4,9 +4,7 @@
-

{{ headline }}

-

{{ subtitle }}


- {{ buttonText }}
@@ -34,7 +31,6 @@ export default { buttonText: { type: String, required: false, default: null }, linkTo: { type: String, required: false, default: null }, callback: { type: Function, required: false, default: null }, - code: { type: String, required: false, default: null }, // Wolle: to be removed by adding it directly to the "linkTo" }, methods: { optionalCallback() { diff --git a/frontend/src/pages/ForgotPassword.spec.js b/frontend/src/pages/ForgotPassword.spec.js index e9aeed552..a7b2b5393 100644 --- a/frontend/src/pages/ForgotPassword.spec.js +++ b/frontend/src/pages/ForgotPassword.spec.js @@ -127,7 +127,6 @@ describe('ForgotPassword', () => { expect(wrapper.find('.test-message-button').attributes('href')).toBe('/login') }) - // Wolle it.skip('click redirects to "/login"', async () => { // wrapper.find('.test-message-button').trigger('click') // await wrapper.vm.$nextTick() @@ -159,7 +158,6 @@ describe('ForgotPassword', () => { expect(wrapper.find('.test-message-button').attributes('href')).toBe('/login') }) - // Wolle it.skip('click redirects to "/login"', () => { // expect(mockRouterPush).toBeCalledWith('/login') }) diff --git a/frontend/src/pages/ForgotPassword.vue b/frontend/src/pages/ForgotPassword.vue index 630974c52..1778c638c 100644 --- a/frontend/src/pages/ForgotPassword.vue +++ b/frontend/src/pages/ForgotPassword.vue @@ -37,7 +37,6 @@
- - diff --git a/frontend/src/pages/Login.spec.js b/frontend/src/pages/Login.spec.js index 5b7ccfefe..b03f24fb2 100644 --- a/frontend/src/pages/Login.spec.js +++ b/frontend/src/pages/Login.spec.js @@ -252,7 +252,6 @@ describe('Login', () => { expect(wrapper.find('.test-message-button').attributes('href')).toBe('/forgot-password') }) - // Wolle it.skip('click redirects to "/forgot-password"', () => { // expect(mockRouterPush).toBeCalledWith('/thx/login') }) @@ -285,7 +284,6 @@ describe('Login', () => { ) }) - // Wolle it.skip('click redirects to "/reset-password/login"', () => { // expect(mockRouterPush).toBeCalledWith('/reset-password/login') }) diff --git a/frontend/src/pages/Login.vue b/frontend/src/pages/Login.vue index 935ed9eed..0bbfe6afc 100755 --- a/frontend/src/pages/Login.vue +++ b/frontend/src/pages/Login.vue @@ -58,14 +58,12 @@ - - diff --git a/frontend/src/pages/Register.spec.js b/frontend/src/pages/Register.spec.js index 55ac36cb9..35ed534c2 100644 --- a/frontend/src/pages/Register.spec.js +++ b/frontend/src/pages/Register.spec.js @@ -228,24 +228,6 @@ describe('Register', () => { await flushPromises() }) - // Wolle: remove? - // it('shows error message', () => { - // expect(wrapper.find('span.alert-text').exists()).toBeTruthy() - // expect(wrapper.find('span.alert-text').text().length !== 0).toBeTruthy() - // expect(wrapper.find('span.alert-text').text()).toContain('error.error') - // expect(wrapper.find('span.alert-text').text()).toContain('Ouch!') - // }) - - // it('button to dismisses error message is present', () => { - // expect(wrapper.find('button.close').exists()).toBeTruthy() - // }) - - // it('dismisses error message', async () => { - // await wrapper.find('button.close').trigger('click') - // await flushPromises() - // expect(wrapper.find('span.alert-text').exists()).not.toBeTruthy() - // }) - it('shows success title, subtitle, login button', () => { expect(wrapper.vm.showPageMessage).toBeTruthy() expect(wrapper.find('.test-message-headline').text()).toBe('site.thx.errorTitle') diff --git a/frontend/src/pages/Register.vue b/frontend/src/pages/Register.vue index 0a0d080aa..52053e6f7 100755 --- a/frontend/src/pages/Register.vue +++ b/frontend/src/pages/Register.vue @@ -179,7 +179,6 @@ - -
@@ -18,7 +17,6 @@
- diff --git a/frontend/src/pages/ForgotPassword.spec.js b/frontend/src/pages/ForgotPassword.spec.js index a7b2b5393..c6c798e22 100644 --- a/frontend/src/pages/ForgotPassword.spec.js +++ b/frontend/src/pages/ForgotPassword.spec.js @@ -1,5 +1,6 @@ import { mount, RouterLinkStub } from '@vue/test-utils' import flushPromises from 'flush-promises' +import { toastErrorSpy } from '@test/testSetup' import ForgotPassword from './ForgotPassword' const mockAPIcall = jest.fn() @@ -132,6 +133,10 @@ describe('ForgotPassword', () => { // await wrapper.vm.$nextTick() expect(mockRouterPush).toBeCalledWith('/login') }) + + it('toasts a standard error message', () => { + expect(toastErrorSpy).toBeCalledWith('error.email-already-sent') + }) }) describe('success', () => { diff --git a/frontend/src/pages/ForgotPassword.vue b/frontend/src/pages/ForgotPassword.vue index 1778c638c..eea54427a 100644 --- a/frontend/src/pages/ForgotPassword.vue +++ b/frontend/src/pages/ForgotPassword.vue @@ -89,9 +89,9 @@ export default { this.success = true }) .catch(() => { - this.toastError(this.$t('error.email-already-sent')) this.showPageMessage = true this.success = false + this.toastError(this.$t('error.email-already-sent')) }) }, }, diff --git a/frontend/src/pages/Login.spec.js b/frontend/src/pages/Login.spec.js index b03f24fb2..36c293451 100644 --- a/frontend/src/pages/Login.spec.js +++ b/frontend/src/pages/Login.spec.js @@ -1,8 +1,7 @@ import { RouterLinkStub, mount } from '@vue/test-utils' import flushPromises from 'flush-promises' -import Login from './Login' - import { toastErrorSpy } from '@test/testSetup' +import Login from './Login' const localVue = global.localVue @@ -205,32 +204,10 @@ describe('Login', () => { }) describe('login fails', () => { - beforeEach(async () => { - jest.clearAllMocks() - await wrapper.find('input[placeholder="Email"]').setValue('user@example.org') - await wrapper.find('input[placeholder="form.password"]').setValue('1234') - await flushPromises() - apolloQueryMock.mockRejectedValue({ - message: '...No user with this credentials', - }) - await wrapper.find('form').trigger('submit') - await flushPromises() - }) - - it('hides the spinner', () => { - expect(spinnerHideMock).toBeCalled() - }) - - it('toasts an error message', () => { - expect(toastErrorSpy).toBeCalledWith( - 'error.unknown-error...No user with this credentials', - ) - }) - describe('login fails with "User email not validated"', () => { beforeEach(async () => { apolloQueryMock.mockRejectedValue({ - message: 'User email not validated', + message: 'GraphQL error: User email not validated', }) wrapper = Wrapper() jest.clearAllMocks() @@ -241,6 +218,10 @@ describe('Login', () => { await flushPromises() }) + it('hides the spinner', () => { + expect(spinnerHideMock).toBeCalled() + }) + it('shows error title, subtitle, login button', () => { expect(wrapper.vm.showPageMessage).toBeTruthy() expect(wrapper.find('.test-message-headline').text()).toBe('site.thx.errorTitle') @@ -255,12 +236,16 @@ describe('Login', () => { it.skip('click redirects to "/forgot-password"', () => { // expect(mockRouterPush).toBeCalledWith('/thx/login') }) + + it('toasts the error message', () => { + expect(toastErrorSpy).toBeCalledWith('error.no-account') + }) }) describe('login fails with "User has no password set yet"', () => { beforeEach(async () => { apolloQueryMock.mockRejectedValue({ - message: 'User has no password set yet', + message: 'GraphQL error: User has no password set yet', }) wrapper = Wrapper() jest.clearAllMocks() @@ -287,6 +272,10 @@ describe('Login', () => { it.skip('click redirects to "/reset-password/login"', () => { // expect(mockRouterPush).toBeCalledWith('/reset-password/login') }) + + it('toasts the error message', () => { + expect(toastErrorSpy).toBeCalledWith('error.no-account') + }) }) }) }) diff --git a/frontend/src/pages/Login.vue b/frontend/src/pages/Login.vue index 0bbfe6afc..4cfd62e69 100755 --- a/frontend/src/pages/Login.vue +++ b/frontend/src/pages/Login.vue @@ -125,22 +125,22 @@ export default { }) .catch((error) => { if (error.message.includes('User email not validated')) { - this.toastError(this.$t('error.no-account')) this.showPageMessage = true this.errorSubtitle = this.$t('site.thx.activateEmail') this.errorLinkTo = '/forgot-password' - } else if (error.message.includes('User has no password set yet')) { this.toastError(this.$t('error.no-account')) + } else if (error.message.includes('User has no password set yet')) { this.showPageMessage = true this.errorSubtitle = this.$t('site.thx.unsetPassword') this.errorLinkTo = '/reset-password/login' + this.toastError(this.$t('error.no-account')) } else { // appeared errors: 'GraphQL error: No user with this credentials' const errorMessage = this.$t('error.unknown-error') + error.message - this.toastError(errorMessage) this.showPageMessage = true this.errorSubtitle = errorMessage this.errorLinkTo = '/forgot-password' + this.toastError(errorMessage) } loader.hide() }) diff --git a/frontend/src/pages/Register.spec.js b/frontend/src/pages/Register.spec.js index 35ed534c2..49984c008 100644 --- a/frontend/src/pages/Register.spec.js +++ b/frontend/src/pages/Register.spec.js @@ -1,5 +1,6 @@ import { mount, RouterLinkStub } from '@vue/test-utils' import flushPromises from 'flush-promises' +import { toastErrorSpy } from '@test/testSetup' import Register from './Register' const localVue = global.localVue @@ -237,6 +238,10 @@ describe('Register', () => { ) }) + it('toasts the error message', () => { + expect(toastErrorSpy).toBeCalledWith('error.user-already-exists') + }) + it('click calls "solveError"', async () => { wrapper.find('.test-message-button').trigger('click') await wrapper.vm.$nextTick() From c574e96dc00ab10593795d613c09f8545fa505ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Fri, 29 Apr 2022 13:28:36 +0200 Subject: [PATCH 21/47] Remove alert --- frontend/src/pages/Register.vue | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/frontend/src/pages/Register.vue b/frontend/src/pages/Register.vue index 52053e6f7..a41952030 100755 --- a/frontend/src/pages/Register.vue +++ b/frontend/src/pages/Register.vue @@ -105,20 +105,6 @@ - - - - - {{ $t('error.error') }} - {{ messageError }} - - {{ $t('publisher.publisherId') }} {{ $store.state.publisherId }} @@ -228,9 +214,7 @@ export default { language: '', showPageMessage: false, submitted: false, - showError: false, messageError: '', - register: true, publisherId: this.$store.state.publisherId, redeemCode: this.$route.params.code, CONFIG, @@ -267,7 +251,6 @@ export default { .catch((error) => { this.showPageMessage = true this.success = false - this.showError = true switch (error.message) { case 'GraphQL error: User already exists.': this.messageError = this.$t('error.user-already-exists') @@ -279,17 +262,8 @@ export default { this.toastError(this.messageError) }) }, - // Wolle: remove this? - closeAlert() { - this.showError = false - this.messageError = '' - this.form.email = '' - this.form.firstname = '' - this.form.lastname = '' - }, solveError() { this.showPageMessage = false - this.showError = false this.messageError = '' this.form.email = '' this.form.firstname = '' From 31dfdc13379acc30dc069775a6bab8e2c5e173d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Mon, 2 May 2022 08:17:03 +0200 Subject: [PATCH 22/47] Fix code coverage in Login.vue test --- frontend/src/pages/Login.spec.js | 62 +++++++++++++++++++++----------- 1 file changed, 42 insertions(+), 20 deletions(-) diff --git a/frontend/src/pages/Login.spec.js b/frontend/src/pages/Login.spec.js index 36c293451..501745b19 100644 --- a/frontend/src/pages/Login.spec.js +++ b/frontend/src/pages/Login.spec.js @@ -204,18 +204,22 @@ describe('Login', () => { }) describe('login fails', () => { + const createError = async (errorMessage) => { + apolloQueryMock.mockRejectedValue({ + message: errorMessage, + }) + wrapper = Wrapper() + jest.clearAllMocks() + await wrapper.find('input[placeholder="Email"]').setValue('user@example.org') + await wrapper.find('input[placeholder="form.password"]').setValue('1234') + await flushPromises() + await wrapper.find('form').trigger('submit') + await flushPromises() + } + describe('login fails with "User email not validated"', () => { beforeEach(async () => { - apolloQueryMock.mockRejectedValue({ - message: 'GraphQL error: User email not validated', - }) - wrapper = Wrapper() - jest.clearAllMocks() - await wrapper.find('input[placeholder="Email"]').setValue('user@example.org') - await wrapper.find('input[placeholder="form.password"]').setValue('1234') - await flushPromises() - await wrapper.find('form').trigger('submit') - await flushPromises() + await createError('GraphQL error: User email not validated') }) it('hides the spinner', () => { @@ -244,16 +248,7 @@ describe('Login', () => { describe('login fails with "User has no password set yet"', () => { beforeEach(async () => { - apolloQueryMock.mockRejectedValue({ - message: 'GraphQL error: User has no password set yet', - }) - wrapper = Wrapper() - jest.clearAllMocks() - await wrapper.find('input[placeholder="Email"]').setValue('user@example.org') - await wrapper.find('input[placeholder="form.password"]').setValue('1234') - await flushPromises() - await wrapper.find('form').trigger('submit') - await flushPromises() + await createError('GraphQL error: User has no password set yet') }) it('shows error title, subtitle, login button', () => { @@ -277,6 +272,33 @@ describe('Login', () => { expect(toastErrorSpy).toBeCalledWith('error.no-account') }) }) + + describe('login fails with an unknow error', () => { + beforeEach(async () => { + await createError(' – Unknow error') + }) + + it('shows error title, subtitle, login button', () => { + expect(wrapper.vm.showPageMessage).toBeTruthy() + expect(wrapper.find('.test-message-headline').text()).toBe('site.thx.errorTitle') + expect(wrapper.find('.test-message-subtitle').text()).toBe( + 'error.unknown-error – Unknow error', + ) + expect(wrapper.find('.test-message-button').text()).toBe('settings.password.reset') + }) + + it('button link directs to "/forgot-password"', () => { + expect(wrapper.find('.test-message-button').attributes('href')).toBe('/forgot-password') + }) + + it.skip('click redirects to "/forgot-password"', () => { + // expect(mockRouterPush).toBeCalledWith('/forgot-password') + }) + + it('toasts the error message', () => { + expect(toastErrorSpy).toBeCalledWith('error.unknown-error – Unknow error') + }) + }) }) }) }) From 4632e83a47871dfd5d7177572120cbfc45a8f1d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Mon, 2 May 2022 08:44:53 +0200 Subject: [PATCH 23/47] Change out commented router test --- frontend/src/pages/Login.spec.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/frontend/src/pages/Login.spec.js b/frontend/src/pages/Login.spec.js index 501745b19..891c656d0 100644 --- a/frontend/src/pages/Login.spec.js +++ b/frontend/src/pages/Login.spec.js @@ -237,8 +237,11 @@ describe('Login', () => { expect(wrapper.find('.test-message-button').attributes('href')).toBe('/forgot-password') }) - it.skip('click redirects to "/forgot-password"', () => { - // expect(mockRouterPush).toBeCalledWith('/thx/login') + it.skip('click redirects to "/forgot-password"', async () => { + // wrapper.find('.test-message-button').trigger('click') + // await flushPromises() + // await wrapper.vm.$nextTick() + // expect(mockRouterPush).toBeCalledWith('/forgot-password') }) it('toasts the error message', () => { From d7ae0bc3b887472f76142da76846bf102db1e7c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Mon, 2 May 2022 09:39:31 +0200 Subject: [PATCH 24/47] Fix code coverage in Register.vue test --- frontend/src/pages/Register.spec.js | 67 +++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 17 deletions(-) diff --git a/frontend/src/pages/Register.spec.js b/frontend/src/pages/Register.spec.js index 49984c008..ca419069c 100644 --- a/frontend/src/pages/Register.spec.js +++ b/frontend/src/pages/Register.spec.js @@ -221,31 +221,64 @@ describe('Register', () => { }) describe('server sends back error', () => { - beforeEach(async () => { + const createError = async (errorMessage) => { registerUserMutationMock.mockRejectedValue({ - message: 'GraphQL error: User already exists.', + message: errorMessage, }) await wrapper.find('form').trigger('submit') await flushPromises() + } + + describe('server sends back error "User already exists."', () => { + beforeEach(async () => { + await createError('GraphQL error: User already exists.') + }) + + it('shows success title, subtitle, login button', () => { + expect(wrapper.vm.showPageMessage).toBeTruthy() + expect(wrapper.find('.test-message-headline').text()).toBe('site.thx.errorTitle') + expect(wrapper.find('.test-message-subtitle').text()).toBe('error.user-already-exists') + expect(wrapper.find('.test-message-button').text()).toBe( + 'site.register.message-button-text', + ) + }) + + it('toasts the error message', () => { + expect(toastErrorSpy).toBeCalledWith('error.user-already-exists') + }) + + it('click calls "solveError"', async () => { + wrapper.find('.test-message-button').trigger('click') + await wrapper.vm.$nextTick() + expect(wrapper.vm.showPageMessage).not.toBeTruthy() + }) }) - it('shows success title, subtitle, login button', () => { - expect(wrapper.vm.showPageMessage).toBeTruthy() - expect(wrapper.find('.test-message-headline').text()).toBe('site.thx.errorTitle') - expect(wrapper.find('.test-message-subtitle').text()).toBe('error.user-already-exists') - expect(wrapper.find('.test-message-button').text()).toBe( - 'site.register.message-button-text', - ) - }) + describe('server sends back error "Unknown error"', () => { + beforeEach(async () => { + await createError(' – Unknown error.') + }) - it('toasts the error message', () => { - expect(toastErrorSpy).toBeCalledWith('error.user-already-exists') - }) + it('shows success title, subtitle, login button', () => { + expect(wrapper.vm.showPageMessage).toBeTruthy() + expect(wrapper.find('.test-message-headline').text()).toBe('site.thx.errorTitle') + expect(wrapper.find('.test-message-subtitle').text()).toBe( + 'error.unknown-error – Unknown error.', + ) + expect(wrapper.find('.test-message-button').text()).toBe( + 'site.register.message-button-text', + ) + }) - it('click calls "solveError"', async () => { - wrapper.find('.test-message-button').trigger('click') - await wrapper.vm.$nextTick() - expect(wrapper.vm.showPageMessage).not.toBeTruthy() + it('toasts the error message', () => { + expect(toastErrorSpy).toBeCalledWith('error.unknown-error – Unknown error.') + }) + + it('click calls "solveError"', async () => { + wrapper.find('.test-message-button').trigger('click') + await wrapper.vm.$nextTick() + expect(wrapper.vm.showPageMessage).not.toBeTruthy() + }) }) }) From f22b391557fe9e7a18f38a212023423ac780efc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Mon, 2 May 2022 10:14:29 +0200 Subject: [PATCH 25/47] Change code after Alex review suggestions --- .../src/components/Message/Message.spec.js | 2 +- frontend/src/components/Message/Message.vue | 11 ++++++-- frontend/src/pages/ForgotPassword.spec.js | 8 +++--- frontend/src/pages/Login.spec.js | 16 ++++++------ frontend/src/pages/Register.spec.js | 26 +++++++++---------- 5 files changed, 35 insertions(+), 28 deletions(-) diff --git a/frontend/src/components/Message/Message.spec.js b/frontend/src/components/Message/Message.spec.js index afbef53cd..db493b44a 100644 --- a/frontend/src/components/Message/Message.spec.js +++ b/frontend/src/components/Message/Message.spec.js @@ -27,7 +27,7 @@ describe('Message', () => { }) it('renders the component', () => { - expect(wrapper.find('div.header').exists()).toBeTruthy() + expect(wrapper.find('div.header').exists()).toBe(true) }) it('renders title, subtitle, and button text', () => { diff --git a/frontend/src/components/Message/Message.vue b/frontend/src/components/Message/Message.vue index cc3bb90a3..b09275ae9 100644 --- a/frontend/src/components/Message/Message.vue +++ b/frontend/src/components/Message/Message.vue @@ -7,9 +7,9 @@

{{ subtitle }}


{{ buttonText }} @@ -29,6 +29,7 @@ export default { buttonText: { type: String, required: false, default: null }, linkTo: { type: String, required: false, default: null }, callback: { type: Function, required: false, default: null }, + code: { type: String, required: false, default: null }, }, methods: { optionalCallback() { @@ -36,6 +37,12 @@ export default { this.callback() } }, + showButton() { + return this.buttonText && (this.linkTo || this.callback) + }, + buttonLinkTo() { + return this.linkTo ? this.linkTo + (this.code ? `/${this.code}` : '') : null + }, }, } diff --git a/frontend/src/pages/ForgotPassword.spec.js b/frontend/src/pages/ForgotPassword.spec.js index c6c798e22..cb22c77be 100644 --- a/frontend/src/pages/ForgotPassword.spec.js +++ b/frontend/src/pages/ForgotPassword.spec.js @@ -47,7 +47,7 @@ describe('ForgotPassword', () => { }) it('renders the component', () => { - expect(wrapper.find('div.forgot-password').exists()).toBeTruthy() + expect(wrapper.find('div.forgot-password').exists()).toBe(true) }) it('has a title', () => { @@ -84,7 +84,7 @@ describe('ForgotPassword', () => { }) it('has a submit button', () => { - expect(form.find('button[type="submit"]').exists()).toBeTruthy() + expect(form.find('button[type="submit"]').exists()).toBe(true) }) describe('invalid Email', () => { @@ -118,7 +118,7 @@ describe('ForgotPassword', () => { }) it('shows error title, subtitle, login button', () => { - expect(wrapper.vm.showPageMessage).toBeTruthy() + expect(wrapper.vm.showPageMessage).toBe(true) expect(wrapper.find('.test-message-headline').text()).toBe('site.thx.errorTitle') expect(wrapper.find('.test-message-subtitle').text()).toBe('error.email-already-sent') expect(wrapper.find('.test-message-button').text()).toBe('login') @@ -153,7 +153,7 @@ describe('ForgotPassword', () => { }) it('shows success title, subtitle, login button', () => { - expect(wrapper.vm.showPageMessage).toBeTruthy() + expect(wrapper.vm.showPageMessage).toBe(true) expect(wrapper.find('.test-message-headline').text()).toBe('site.thx.title') expect(wrapper.find('.test-message-subtitle').text()).toBe('site.thx.email') expect(wrapper.find('.test-message-button').text()).toBe('login') diff --git a/frontend/src/pages/Login.spec.js b/frontend/src/pages/Login.spec.js index 891c656d0..db11a036e 100644 --- a/frontend/src/pages/Login.spec.js +++ b/frontend/src/pages/Login.spec.js @@ -59,7 +59,7 @@ describe('Login', () => { }) it('renders the Login form', () => { - expect(wrapper.find('div.login-form').exists()).toBeTruthy() + expect(wrapper.find('div.login-form').exists()).toBe(true) }) describe('Login header', () => { @@ -102,19 +102,19 @@ describe('Login', () => { describe('Login form', () => { it('has a login form', () => { - expect(wrapper.find('form').exists()).toBeTruthy() + expect(wrapper.find('form').exists()).toBe(true) }) it('has an Email input field', () => { - expect(wrapper.find('input[placeholder="Email"]').exists()).toBeTruthy() + expect(wrapper.find('input[placeholder="Email"]').exists()).toBe(true) }) it('has an Password input field', () => { - expect(wrapper.find('input[placeholder="form.password"]').exists()).toBeTruthy() + expect(wrapper.find('input[placeholder="form.password"]').exists()).toBe(true) }) it('has a Submit button', () => { - expect(wrapper.find('button[type="submit"]').exists()).toBeTruthy() + expect(wrapper.find('button[type="submit"]').exists()).toBe(true) }) }) @@ -227,7 +227,7 @@ describe('Login', () => { }) it('shows error title, subtitle, login button', () => { - expect(wrapper.vm.showPageMessage).toBeTruthy() + expect(wrapper.vm.showPageMessage).toBe(true) expect(wrapper.find('.test-message-headline').text()).toBe('site.thx.errorTitle') expect(wrapper.find('.test-message-subtitle').text()).toBe('site.thx.activateEmail') expect(wrapper.find('.test-message-button').text()).toBe('settings.password.reset') @@ -255,7 +255,7 @@ describe('Login', () => { }) it('shows error title, subtitle, login button', () => { - expect(wrapper.vm.showPageMessage).toBeTruthy() + expect(wrapper.vm.showPageMessage).toBe(true) expect(wrapper.find('.test-message-headline').text()).toBe('site.thx.errorTitle') expect(wrapper.find('.test-message-subtitle').text()).toBe('site.thx.unsetPassword') expect(wrapper.find('.test-message-button').text()).toBe('settings.password.reset') @@ -282,7 +282,7 @@ describe('Login', () => { }) it('shows error title, subtitle, login button', () => { - expect(wrapper.vm.showPageMessage).toBeTruthy() + expect(wrapper.vm.showPageMessage).toBe(true) expect(wrapper.find('.test-message-headline').text()).toBe('site.thx.errorTitle') expect(wrapper.find('.test-message-subtitle').text()).toBe( 'error.unknown-error – Unknow error', diff --git a/frontend/src/pages/Register.spec.js b/frontend/src/pages/Register.spec.js index ca419069c..e889f0ca7 100644 --- a/frontend/src/pages/Register.spec.js +++ b/frontend/src/pages/Register.spec.js @@ -50,7 +50,7 @@ describe('Register', () => { }) it('renders the Register form', () => { - expect(wrapper.find('div#registerform').exists()).toBeTruthy() + expect(wrapper.find('div#registerform').exists()).toBe(true) }) describe('Register header', () => { @@ -94,22 +94,22 @@ describe('Register', () => { describe('Register form', () => { it('has a register form', () => { - expect(wrapper.find('form').exists()).toBeTruthy() + expect(wrapper.find('form').exists()).toBe(true) }) it('has firstname input fields', () => { - expect(wrapper.find('#registerFirstname').exists()).toBeTruthy() + expect(wrapper.find('#registerFirstname').exists()).toBe(true) }) it('has lastname input fields', () => { - expect(wrapper.find('#registerLastname').exists()).toBeTruthy() + expect(wrapper.find('#registerLastname').exists()).toBe(true) }) it('has email input fields', () => { - expect(wrapper.find('#Email-input-field').exists()).toBeTruthy() + expect(wrapper.find('#Email-input-field').exists()).toBe(true) }) it('has Language selected field', () => { - expect(wrapper.find('.selectedLanguage').exists()).toBeTruthy() + expect(wrapper.find('.selectedLanguage').exists()).toBe(true) }) it('selects Language value en', async () => { @@ -118,7 +118,7 @@ describe('Register', () => { }) it('has 1 checkbox input fields', () => { - expect(wrapper.find('#registerCheckbox').exists()).toBeTruthy() + expect(wrapper.find('#registerCheckbox').exists()).toBe(true) }) it('has PublisherId input fields', () => { @@ -235,7 +235,7 @@ describe('Register', () => { }) it('shows success title, subtitle, login button', () => { - expect(wrapper.vm.showPageMessage).toBeTruthy() + expect(wrapper.vm.showPageMessage).toBe(true) expect(wrapper.find('.test-message-headline').text()).toBe('site.thx.errorTitle') expect(wrapper.find('.test-message-subtitle').text()).toBe('error.user-already-exists') expect(wrapper.find('.test-message-button').text()).toBe( @@ -250,7 +250,7 @@ describe('Register', () => { it('click calls "solveError"', async () => { wrapper.find('.test-message-button').trigger('click') await wrapper.vm.$nextTick() - expect(wrapper.vm.showPageMessage).not.toBeTruthy() + expect(wrapper.vm.showPageMessage).toBe(false) }) }) @@ -260,7 +260,7 @@ describe('Register', () => { }) it('shows success title, subtitle, login button', () => { - expect(wrapper.vm.showPageMessage).toBeTruthy() + expect(wrapper.vm.showPageMessage).toBe(true) expect(wrapper.find('.test-message-headline').text()).toBe('site.thx.errorTitle') expect(wrapper.find('.test-message-subtitle').text()).toBe( 'error.unknown-error – Unknown error.', @@ -277,7 +277,7 @@ describe('Register', () => { it('click calls "solveError"', async () => { wrapper.find('.test-message-button').trigger('click') await wrapper.vm.$nextTick() - expect(wrapper.vm.showPageMessage).not.toBeTruthy() + expect(wrapper.vm.showPageMessage).toBe(false) }) }) }) @@ -308,13 +308,13 @@ describe('Register', () => { }) it('shows success title, subtitle', () => { - expect(wrapper.vm.showPageMessage).toBeTruthy() + expect(wrapper.vm.showPageMessage).toBe(true) expect(wrapper.find('.test-message-headline').text()).toBe('site.thx.title') expect(wrapper.find('.test-message-subtitle').text()).toBe('site.thx.register') }) it('button is not present', () => { - expect(wrapper.find('.test-message-button')).toBeTruthy() + expect(wrapper.find('.test-message-button').exists()).toBe(false) }) }) }) From 3a5ba17b6e1df82d423f5845d6f667cf1e299bf9 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Tue, 3 May 2022 14:00:54 +0200 Subject: [PATCH 26/47] fix: Up Migrations --- .../0026-combine_transaction_tables2.ts | 4 ++- .../0027-clean_transaction_table.ts | 16 ++++++------ .../0029-clean_transaction_table.ts | 26 +++++++++++-------- .../0035-admin_pending_creations_decimal.ts | 4 ++- 4 files changed, 29 insertions(+), 21 deletions(-) diff --git a/database/migrations/0026-combine_transaction_tables2.ts b/database/migrations/0026-combine_transaction_tables2.ts index 3abf77354..6896eb27f 100644 --- a/database/migrations/0026-combine_transaction_tables2.ts +++ b/database/migrations/0026-combine_transaction_tables2.ts @@ -28,7 +28,9 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promis */ // rename `state_user_id` to `user_id` - await queryFn('ALTER TABLE `state_user_transactions` RENAME COLUMN state_user_id TO user_id;') + await queryFn( + 'ALTER TABLE `state_user_transactions` CHANGE COLUMN state_user_id user_id int(10);', + ) // Create new `amount` column, with a temporary default of null await queryFn( 'ALTER TABLE `state_user_transactions` ADD COLUMN `amount` bigint(20) DEFAULT NULL AFTER `transaction_type_id`;', diff --git a/database/migrations/0027-clean_transaction_table.ts b/database/migrations/0027-clean_transaction_table.ts index b5a0e0e2e..b1e25abd2 100644 --- a/database/migrations/0027-clean_transaction_table.ts +++ b/database/migrations/0027-clean_transaction_table.ts @@ -11,23 +11,23 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promise>) { // drop column `transaction_id`, it is not needed - await queryFn('ALTER TABLE `transactions` DROP COLUMN `transaction_id`;') + await queryFn('ALTER TABLE `transactions` DROP COLUMN IF EXISTS `transaction_id`;') // drop column `received`, it is a duplicate of balance_date - await queryFn('ALTER TABLE `transactions` DROP COLUMN `received`;') + await queryFn('ALTER TABLE `transactions` DROP COLUMN IF EXISTS `received`;') // drop column `tx_hash`, it is not needed - await queryFn('ALTER TABLE `transactions` DROP COLUMN `tx_hash`;') + await queryFn('ALTER TABLE `transactions` DROP COLUMN IF EXISTS `tx_hash`;') // drop column `signature`, it is not needed - await queryFn('ALTER TABLE `transactions` DROP COLUMN `signature`;') + await queryFn('ALTER TABLE `transactions` DROP COLUMN IF EXISTS `signature`;') // drop column `pubkey`, it is not needed - await queryFn('ALTER TABLE `transactions` DROP COLUMN `pubkey`;') + await queryFn('ALTER TABLE `transactions` DROP COLUMN IF EXISTS `pubkey`;') // drop column `creation_ident_hash`, it is not needed - await queryFn('ALTER TABLE `transactions` DROP COLUMN `creation_ident_hash`;') + await queryFn('ALTER TABLE `transactions` DROP COLUMN IF EXISTS `creation_ident_hash`;') // rename `transaction_type_id` to `type_id` - await queryFn('ALTER TABLE `transactions` RENAME COLUMN transaction_type_id TO type_id;') + await queryFn('ALTER TABLE `transactions` CHANGE COLUMN transaction_type_id type_id int(10);') // rename `linked_state_user_transaction_id` to `linked_transaction_id` await queryFn( - 'ALTER TABLE `transactions` RENAME COLUMN linked_state_user_transaction_id TO linked_transaction_id;', + 'ALTER TABLE `transactions` CHANGE COLUMN linked_state_user_transaction_id linked_transaction_id int(10);', ) } diff --git a/database/migrations/0029-clean_transaction_table.ts b/database/migrations/0029-clean_transaction_table.ts index 0b9e2cc0d..eccec56ea 100644 --- a/database/migrations/0029-clean_transaction_table.ts +++ b/database/migrations/0029-clean_transaction_table.ts @@ -13,35 +13,39 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promis // Delete columns // delete column `amount` - await queryFn('ALTER TABLE `transactions` DROP COLUMN `amount`;') + await queryFn('ALTER TABLE `transactions` DROP COLUMN IF EXISTS `amount`;') // delete column `send_sender_final_balance` - await queryFn('ALTER TABLE `transactions` DROP COLUMN `send_sender_final_balance`;') + await queryFn('ALTER TABLE `transactions` DROP COLUMN IF EXISTS `send_sender_final_balance`;') // delete column `balance` - await queryFn('ALTER TABLE `transactions` DROP COLUMN `balance`;') + await queryFn('ALTER TABLE `transactions` DROP COLUMN IF EXISTS `balance`;') // delete column `temp_dec_send_sender_final_balance` - await queryFn('ALTER TABLE `transactions` DROP COLUMN `temp_dec_send_sender_final_balance`;') + await queryFn( + 'ALTER TABLE `transactions` DROP COLUMN IF EXISTS `temp_dec_send_sender_final_balance`;', + ) // delete column `temp_dec_diff_send_sender_final_balance` - await queryFn('ALTER TABLE `transactions` DROP COLUMN `temp_dec_diff_send_sender_final_balance`;') + await queryFn( + 'ALTER TABLE `transactions` DROP COLUMN IF EXISTS `temp_dec_diff_send_sender_final_balance`;', + ) // delete column `temp_dec_old_balance` - await queryFn('ALTER TABLE `transactions` DROP COLUMN `temp_dec_old_balance`;') + await queryFn('ALTER TABLE `transactions` DROP COLUMN IF EXISTS `temp_dec_old_balance`;') // delete column `temp_dec_diff_balance` - await queryFn('ALTER TABLE `transactions` DROP COLUMN `temp_dec_diff_balance`;') + await queryFn('ALTER TABLE `transactions` DROP COLUMN IF EXISTS `temp_dec_diff_balance`;') // Rename columns // rename column `dec_amount` to `amount` - await queryFn('ALTER TABLE `transactions` RENAME COLUMN `dec_amount` to `amount`;') + await queryFn('ALTER TABLE `transactions` CHANGE COLUMN `dec_amount` `amount` DECIMAL(40,20);') // rename column `dec_balance` to `balance` - await queryFn('ALTER TABLE `transactions` RENAME COLUMN `dec_balance` to `balance`;') + await queryFn('ALTER TABLE `transactions` CHANGE COLUMN `dec_balance` `balance` DECIMAL(40,20);') // rename column `dec_decay` to `decay` - await queryFn('ALTER TABLE `transactions` RENAME COLUMN `dec_decay` to `decay`;') + await queryFn('ALTER TABLE `transactions` CHANGE COLUMN `dec_decay` `decay` DECIMAL(40,20);') // Drop tables // drop `state_balances` - await queryFn('DROP TABLE `state_balances`;') + await queryFn('DROP TABLE IF EXISTS `state_balances`;') } export async function downgrade(queryFn: (query: string, values?: any[]) => Promise>) { diff --git a/database/migrations/0035-admin_pending_creations_decimal.ts b/database/migrations/0035-admin_pending_creations_decimal.ts index d3648f376..60194e8c0 100644 --- a/database/migrations/0035-admin_pending_creations_decimal.ts +++ b/database/migrations/0035-admin_pending_creations_decimal.ts @@ -8,7 +8,9 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promise>) { // rename `amount` to `amount_bigint` - await queryFn('ALTER TABLE `admin_pending_creations` RENAME COLUMN `amount` TO `amount_bigint`;') + await queryFn( + 'ALTER TABLE `admin_pending_creations` CHANGE COLUMN `amount` `amount_bigint` bigint(20);', + ) // add `amount` (decimal) await queryFn( 'ALTER TABLE `admin_pending_creations` ADD COLUMN `amount` DECIMAL(40,20) DEFAULT NULL AFTER `amount_bigint`;', From 83b5b37c2bac3ce9a7b360aeb3c2a27b816a7282 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Tue, 3 May 2022 14:15:31 +0200 Subject: [PATCH 27/47] fix 0035 down migration --- database/migrations/0035-admin_pending_creations_decimal.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/database/migrations/0035-admin_pending_creations_decimal.ts b/database/migrations/0035-admin_pending_creations_decimal.ts index 60194e8c0..f76db7c97 100644 --- a/database/migrations/0035-admin_pending_creations_decimal.ts +++ b/database/migrations/0035-admin_pending_creations_decimal.ts @@ -39,6 +39,8 @@ export async function downgrade(queryFn: (query: string, values?: any[]) => Prom await queryFn( 'ALTER TABLE `admin_pending_creations` MODIFY COLUMN `amount_bigint` bigint(20) NOT NULL;', ) - await queryFn('ALTER TABLE `admin_pending_creations` DROP COLUMN `amount`;') - await queryFn('ALTER TABLE `admin_pending_creations` RENAME COLUMN `amount_bigint` TO `amount`;') + await queryFn('ALTER TABLE `admin_pending_creations` DROP COLUMN IF EXISTS `amount`;') + await queryFn( + 'ALTER TABLE `admin_pending_creations` CHANGE COLUMN `amount_bigint` `amount` bigint(20);', + ) } From 208d4dc4d31200ea13070f8b537d4e9a0546854b Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Tue, 3 May 2022 15:51:28 +0200 Subject: [PATCH 28/47] fix 0029 down --- database/migrations/0029-clean_transaction_table.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/database/migrations/0029-clean_transaction_table.ts b/database/migrations/0029-clean_transaction_table.ts index eccec56ea..c47524b8e 100644 --- a/database/migrations/0029-clean_transaction_table.ts +++ b/database/migrations/0029-clean_transaction_table.ts @@ -70,9 +70,9 @@ export async function downgrade(queryFn: (query: string, values?: any[]) => Prom LEFT JOIN transactions ON t.uid = transactions.user_id AND t.date = transactions.balance_date; `) - await queryFn('ALTER TABLE `transactions` RENAME COLUMN `decay` to `dec_decay`;') - await queryFn('ALTER TABLE `transactions` RENAME COLUMN `balance` to `dec_balance`;') - await queryFn('ALTER TABLE `transactions` RENAME COLUMN `amount` to `dec_amount`;') + await queryFn('ALTER TABLE `transactions` CHANGE COLUMN `decay` `dec_decay` DECIMAL(40,20);') + await queryFn('ALTER TABLE `transactions` CHANGE COLUMN `balance` `dec_balance` DECIMAL(40,20);') + await queryFn('ALTER TABLE `transactions` CHANGE COLUMN `amount` `dec_amount` DECIMAL(40,20);') await queryFn( 'ALTER TABLE `transactions` ADD COLUMN `temp_dec_diff_balance` decimal(40,20) DEFAULT NULL AFTER linked_transaction_id;', From 8d4e691f3d7544ae0f56ffc6aefdea1fa07972a8 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Wed, 4 May 2022 12:55:38 +0200 Subject: [PATCH 29/47] change rename column to change column --- database/migrations/0026-combine_transaction_tables2.ts | 4 +++- database/migrations/0027-clean_transaction_table.ts | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/database/migrations/0026-combine_transaction_tables2.ts b/database/migrations/0026-combine_transaction_tables2.ts index 6896eb27f..b83c5e267 100644 --- a/database/migrations/0026-combine_transaction_tables2.ts +++ b/database/migrations/0026-combine_transaction_tables2.ts @@ -216,5 +216,7 @@ export async function downgrade(queryFn: (query: string, values?: any[]) => Prom await queryFn('ALTER TABLE `state_user_transactions` DROP COLUMN `memo`;') await queryFn('ALTER TABLE `state_user_transactions` DROP COLUMN `send_sender_final_balance`;') await queryFn('ALTER TABLE `state_user_transactions` DROP COLUMN `amount`;') - await queryFn('ALTER TABLE `state_user_transactions` RENAME COLUMN user_id TO state_user_id;') + await queryFn( + 'ALTER TABLE `state_user_transactions` CHANGE COLUMN user_id state_user_id int(10);', + ) } diff --git a/database/migrations/0027-clean_transaction_table.ts b/database/migrations/0027-clean_transaction_table.ts index b1e25abd2..4a427e693 100644 --- a/database/migrations/0027-clean_transaction_table.ts +++ b/database/migrations/0027-clean_transaction_table.ts @@ -41,9 +41,9 @@ export async function downgrade(queryFn: (query: string, values?: any[]) => Prom // - creation_ident_hash (null) await queryFn( - 'ALTER TABLE `transactions` RENAME COLUMN linked_transaction_id TO linked_state_user_transaction_id;', + 'ALTER TABLE `transactions` CHANGE COLUMN linked_transaction_id linked_state_user_transaction_id int(10);', ) - await queryFn('ALTER TABLE `transactions` RENAME COLUMN type_id TO transaction_type_id;') + await queryFn('ALTER TABLE `transactions` CHANGE COLUMN type_id transaction_type_id int(10);') await queryFn( 'ALTER TABLE `transactions` ADD COLUMN `creation_ident_hash` binary(32) DEFAULT NULL AFTER `linked_state_user_transaction_id`;', ) From 9d1a35cf94cef619a9e82a4dce114b577839cf5c Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Wed, 4 May 2022 13:10:53 +0200 Subject: [PATCH 30/47] run dev_reset on stage1 again --- deployment/bare_metal/start.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/deployment/bare_metal/start.sh b/deployment/bare_metal/start.sh index b608952c0..95b89241f 100755 --- a/deployment/bare_metal/start.sh +++ b/deployment/bare_metal/start.sh @@ -105,8 +105,7 @@ yarn install yarn build if [ "$DEPLOY_SEED_DATA" = "true" ]; then yarn dev_up -# As dev_reset is not running properly (0019-replace_login_user_id_with_state_user_id) -# yarn dev_reset + yarn dev_reset else yarn up fi From 264904e74109dd3798280ded2e6c8aa0fe30fa6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Thu, 5 May 2022 10:49:16 +0200 Subject: [PATCH 31/47] Avoid negation by changing showPageMessage into enterData after Alex suggestion --- frontend/src/pages/ForgotPassword.vue | 15 ++++++++++----- frontend/src/pages/Login.vue | 8 +++++++- frontend/src/pages/Register.vue | 5 ++++- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/frontend/src/pages/ForgotPassword.vue b/frontend/src/pages/ForgotPassword.vue index eea54427a..182df5bc3 100644 --- a/frontend/src/pages/ForgotPassword.vue +++ b/frontend/src/pages/ForgotPassword.vue @@ -13,7 +13,7 @@ - + @@ -75,6 +75,11 @@ export default { success: null, } }, + created() { + if (this.$route.params.comingFrom) { + this.subtitle = 'settings.password.resend_subtitle' + } + }, methods: { async onSubmit() { this.$apollo @@ -95,10 +100,10 @@ export default { }) }, }, - created() { - if (this.$route.params.comingFrom) { - this.subtitle = 'settings.password.resend_subtitle' - } + computed: { + enterData() { + return !this.showPageMessage + }, }, } diff --git a/frontend/src/pages/Login.vue b/frontend/src/pages/Login.vue index 4cfd62e69..bda36a0d2 100755 --- a/frontend/src/pages/Login.vue +++ b/frontend/src/pages/Login.vue @@ -13,7 +13,7 @@ - + @@ -136,6 +136,7 @@ export default { this.toastError(this.$t('error.no-account')) } else { // appeared errors: 'GraphQL error: No user with this credentials' + // Wolle: avoid this error message! may be avoid in general? const errorMessage = this.$t('error.unknown-error') + error.message this.showPageMessage = true this.errorSubtitle = errorMessage @@ -146,5 +147,10 @@ export default { }) }, }, + computed: { + enterData() { + return !this.showPageMessage + }, + }, } diff --git a/frontend/src/pages/Register.vue b/frontend/src/pages/Register.vue index a41952030..d6b5f9dba 100755 --- a/frontend/src/pages/Register.vue +++ b/frontend/src/pages/Register.vue @@ -15,7 +15,7 @@ - + @@ -286,6 +286,9 @@ export default { disabled() { return !(this.namesFilled && this.emailFilled && this.form.agree && !!this.language) }, + enterData() { + return !this.showPageMessage + }, }, } From 6a1b8f0fd9d6638f7921dd0ae3e687a596da0d54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Thu, 5 May 2022 11:33:07 +0200 Subject: [PATCH 32/47] Avoid on page error message on Login - Have a translation for 'No user with this credentials'. --- frontend/src/locales/de.json | 1 + frontend/src/locales/en.json | 1 + frontend/src/pages/Login.spec.js | 41 +++++++++++++++++++------------- frontend/src/pages/Login.vue | 10 +++----- 4 files changed, 29 insertions(+), 24 deletions(-) diff --git a/frontend/src/locales/de.json b/frontend/src/locales/de.json index ea288819f..6066ce04a 100644 --- a/frontend/src/locales/de.json +++ b/frontend/src/locales/de.json @@ -35,6 +35,7 @@ "error": "Fehler!", "no-account": "Leider konnten wir keinen (aktivierten) Account mit diesen Daten finden.", "no-transactionlist": "Es gab leider einen Fehler. Es wurden keine Transaktionen vom Server übermittelt.", + "no-user": "Kein Benutzer mit diesen Anmeldedaten.", "session-expired": "Die Sitzung wurde aus Sicherheitsgründen beendet.", "unknown-error": "Unbekanter Fehler: ", "user-already-exists": "Ein Benutzer mit diesen Daten existiert bereits." diff --git a/frontend/src/locales/en.json b/frontend/src/locales/en.json index f5e412086..5a0602098 100644 --- a/frontend/src/locales/en.json +++ b/frontend/src/locales/en.json @@ -35,6 +35,7 @@ "error": "Error!", "no-account": "Unfortunately we could not find an (activated) account to the given data.", "no-transactionlist": "Unfortunately, there was an error. No transactions have been sent from the server.", + "no-user": "No user with this credentials.", "session-expired": "The session was closed for security reasons.", "unknown-error": "Unknown error: ", "user-already-exists": "A user with this data already exists." diff --git a/frontend/src/pages/Login.spec.js b/frontend/src/pages/Login.spec.js index db11a036e..478266676 100644 --- a/frontend/src/pages/Login.spec.js +++ b/frontend/src/pages/Login.spec.js @@ -219,7 +219,7 @@ describe('Login', () => { describe('login fails with "User email not validated"', () => { beforeEach(async () => { - await createError('GraphQL error: User email not validated') + await createError('GraphQL error: User email not validated.') }) it('hides the spinner', () => { @@ -251,7 +251,7 @@ describe('Login', () => { describe('login fails with "User has no password set yet"', () => { beforeEach(async () => { - await createError('GraphQL error: User has no password set yet') + await createError('GraphQL error: User has no password set yet.') }) it('shows error title, subtitle, login button', () => { @@ -276,26 +276,33 @@ describe('Login', () => { }) }) + describe('login fails with "No user with this credentials"', () => { + beforeEach(async () => { + await createError('GraphQL error: No user with this credentials.') + }) + + it('shows no error message on the page', () => { + expect(wrapper.vm.showPageMessage).toBe(false) + expect(wrapper.find('.test-message-headline').exists()).toBe(false) + expect(wrapper.find('.test-message-subtitle').exists()).toBe(false) + expect(wrapper.find('.test-message-button').exists()).toBe(false) + }) + + it('toasts the error message', () => { + expect(toastErrorSpy).toBeCalledWith('error.no-user') + }) + }) + describe('login fails with an unknow error', () => { beforeEach(async () => { await createError(' – Unknow error') }) - it('shows error title, subtitle, login button', () => { - expect(wrapper.vm.showPageMessage).toBe(true) - expect(wrapper.find('.test-message-headline').text()).toBe('site.thx.errorTitle') - expect(wrapper.find('.test-message-subtitle').text()).toBe( - 'error.unknown-error – Unknow error', - ) - expect(wrapper.find('.test-message-button').text()).toBe('settings.password.reset') - }) - - it('button link directs to "/forgot-password"', () => { - expect(wrapper.find('.test-message-button').attributes('href')).toBe('/forgot-password') - }) - - it.skip('click redirects to "/forgot-password"', () => { - // expect(mockRouterPush).toBeCalledWith('/forgot-password') + it('shows no error message on the page', () => { + expect(wrapper.vm.showPageMessage).toBe(false) + expect(wrapper.find('.test-message-headline').exists()).toBe(false) + expect(wrapper.find('.test-message-subtitle').exists()).toBe(false) + expect(wrapper.find('.test-message-button').exists()).toBe(false) }) it('toasts the error message', () => { diff --git a/frontend/src/pages/Login.vue b/frontend/src/pages/Login.vue index bda36a0d2..7544bdcf7 100755 --- a/frontend/src/pages/Login.vue +++ b/frontend/src/pages/Login.vue @@ -134,14 +134,10 @@ export default { this.errorSubtitle = this.$t('site.thx.unsetPassword') this.errorLinkTo = '/reset-password/login' this.toastError(this.$t('error.no-account')) + } else if (error.message.includes('No user with this credentials')) { + this.toastError(this.$t('error.no-user')) } else { - // appeared errors: 'GraphQL error: No user with this credentials' - // Wolle: avoid this error message! may be avoid in general? - const errorMessage = this.$t('error.unknown-error') + error.message - this.showPageMessage = true - this.errorSubtitle = errorMessage - this.errorLinkTo = '/forgot-password' - this.toastError(errorMessage) + this.toastError(this.$t('error.unknown-error') + error.message) } loader.hide() }) From 4a64d1aa2013eb561a4e0c01778367bb3fa31ff2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Thu, 5 May 2022 12:05:04 +0200 Subject: [PATCH 33/47] Avoid any error messages on the Register page, because of boots --- frontend/src/locales/de.json | 3 --- frontend/src/locales/en.json | 3 --- frontend/src/pages/Login.spec.js | 2 ++ frontend/src/pages/Login.vue | 2 ++ frontend/src/pages/Register.spec.js | 40 +++++++++-------------------- frontend/src/pages/Register.vue | 33 +++++------------------- 6 files changed, 22 insertions(+), 61 deletions(-) diff --git a/frontend/src/locales/de.json b/frontend/src/locales/de.json index 6066ce04a..0d496bc3f 100644 --- a/frontend/src/locales/de.json +++ b/frontend/src/locales/de.json @@ -216,9 +216,6 @@ "new_wallet": "Neues Konto erstellen", "signin": "Anmelden" }, - "register": { - "message-button-text": "Alles klar" - }, "signup": { "agree": "Ich stimme der Datenschutzerklärung zu.", "dont_match": "Die Passwörter stimmen nicht überein.", diff --git a/frontend/src/locales/en.json b/frontend/src/locales/en.json index 5a0602098..f5009e04f 100644 --- a/frontend/src/locales/en.json +++ b/frontend/src/locales/en.json @@ -216,9 +216,6 @@ "new_wallet": "Create new account", "signin": "Sign in" }, - "register": { - "message-button-text": "Okay" - }, "signup": { "agree": "I agree to the privacy policy.", "dont_match": "Passwords don't match.", diff --git a/frontend/src/pages/Login.spec.js b/frontend/src/pages/Login.spec.js index 478266676..80177ab2b 100644 --- a/frontend/src/pages/Login.spec.js +++ b/frontend/src/pages/Login.spec.js @@ -282,6 +282,7 @@ describe('Login', () => { }) it('shows no error message on the page', () => { + // don't show any error on the page! against boots expect(wrapper.vm.showPageMessage).toBe(false) expect(wrapper.find('.test-message-headline').exists()).toBe(false) expect(wrapper.find('.test-message-subtitle').exists()).toBe(false) @@ -299,6 +300,7 @@ describe('Login', () => { }) it('shows no error message on the page', () => { + // don't show any error on the page! against boots expect(wrapper.vm.showPageMessage).toBe(false) expect(wrapper.find('.test-message-headline').exists()).toBe(false) expect(wrapper.find('.test-message-subtitle').exists()).toBe(false) diff --git a/frontend/src/pages/Login.vue b/frontend/src/pages/Login.vue index 7544bdcf7..10fcca649 100755 --- a/frontend/src/pages/Login.vue +++ b/frontend/src/pages/Login.vue @@ -135,8 +135,10 @@ export default { this.errorLinkTo = '/reset-password/login' this.toastError(this.$t('error.no-account')) } else if (error.message.includes('No user with this credentials')) { + // don't show any error on the page! against boots this.toastError(this.$t('error.no-user')) } else { + // don't show any error on the page! against boots this.toastError(this.$t('error.unknown-error') + error.message) } loader.hide() diff --git a/frontend/src/pages/Register.spec.js b/frontend/src/pages/Register.spec.js index e889f0ca7..f7a6c0ac8 100644 --- a/frontend/src/pages/Register.spec.js +++ b/frontend/src/pages/Register.spec.js @@ -234,24 +234,17 @@ describe('Register', () => { await createError('GraphQL error: User already exists.') }) - it('shows success title, subtitle, login button', () => { - expect(wrapper.vm.showPageMessage).toBe(true) - expect(wrapper.find('.test-message-headline').text()).toBe('site.thx.errorTitle') - expect(wrapper.find('.test-message-subtitle').text()).toBe('error.user-already-exists') - expect(wrapper.find('.test-message-button').text()).toBe( - 'site.register.message-button-text', - ) + it('shows no error message on the page', () => { + // don't show any error on the page! against boots + expect(wrapper.vm.showPageMessage).toBe(false) + expect(wrapper.find('.test-message-headline').exists()).toBe(false) + expect(wrapper.find('.test-message-subtitle').exists()).toBe(false) + expect(wrapper.find('.test-message-button').exists()).toBe(false) }) it('toasts the error message', () => { expect(toastErrorSpy).toBeCalledWith('error.user-already-exists') }) - - it('click calls "solveError"', async () => { - wrapper.find('.test-message-button').trigger('click') - await wrapper.vm.$nextTick() - expect(wrapper.vm.showPageMessage).toBe(false) - }) }) describe('server sends back error "Unknown error"', () => { @@ -259,26 +252,17 @@ describe('Register', () => { await createError(' – Unknown error.') }) - it('shows success title, subtitle, login button', () => { - expect(wrapper.vm.showPageMessage).toBe(true) - expect(wrapper.find('.test-message-headline').text()).toBe('site.thx.errorTitle') - expect(wrapper.find('.test-message-subtitle').text()).toBe( - 'error.unknown-error – Unknown error.', - ) - expect(wrapper.find('.test-message-button').text()).toBe( - 'site.register.message-button-text', - ) + it('shows no error message on the page', () => { + // don't show any error on the page! against boots + expect(wrapper.vm.showPageMessage).toBe(false) + expect(wrapper.find('.test-message-headline').exists()).toBe(false) + expect(wrapper.find('.test-message-subtitle').exists()).toBe(false) + expect(wrapper.find('.test-message-button').exists()).toBe(false) }) it('toasts the error message', () => { expect(toastErrorSpy).toBeCalledWith('error.unknown-error – Unknown error.') }) - - it('click calls "solveError"', async () => { - wrapper.find('.test-message-button').trigger('click') - await wrapper.vm.$nextTick() - expect(wrapper.vm.showPageMessage).toBe(false) - }) }) }) diff --git a/frontend/src/pages/Register.vue b/frontend/src/pages/Register.vue index d6b5f9dba..39230cb1e 100755 --- a/frontend/src/pages/Register.vue +++ b/frontend/src/pages/Register.vue @@ -165,18 +165,7 @@ - - + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docu/Style/Images/Checkbox_deaktiv.svg b/docu/Style/Images/Checkbox_deaktiv.svg new file mode 100644 index 000000000..4770d4b33 --- /dev/null +++ b/docu/Style/Images/Checkbox_deaktiv.svg @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + From 99f03dac9f8af285715dcd4b31a9e16ae891d126 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Fri, 13 May 2022 11:39:18 +0200 Subject: [PATCH 47/47] Release 1.8.3 --- CHANGELOG.md | 8 ++++++++ admin/package.json | 2 +- backend/package.json | 2 +- database/package.json | 2 +- frontend/package.json | 2 +- package.json | 2 +- 6 files changed, 13 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c9a87058..48eeff9a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,8 +4,16 @@ All notable changes to this project will be documented in this file. Dates are d Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). +#### [1.8.3](https://github.com/gradido/gradido/compare/1.8.2...1.8.3) + +- Checkbox [`#1894`](https://github.com/gradido/gradido/pull/1894) +- fix: Count Deprecated Links as Well [`#1892`](https://github.com/gradido/gradido/pull/1892) + #### [1.8.2](https://github.com/gradido/gradido/compare/1.8.1...1.8.2) +> 12 May 2022 + +- Release 1.8.2 [`#1890`](https://github.com/gradido/gradido/pull/1890) - Update README.md [`#1878`](https://github.com/gradido/gradido/pull/1878) - fix: Unique Previous Column in Transactions Table [`#1879`](https://github.com/gradido/gradido/pull/1879) - fix: Up and Down Migrations for Older SQL Versions [`#1861`](https://github.com/gradido/gradido/pull/1861) diff --git a/admin/package.json b/admin/package.json index 0bd41314b..57711b8be 100644 --- a/admin/package.json +++ b/admin/package.json @@ -3,7 +3,7 @@ "description": "Administraion Interface for Gradido", "main": "index.js", "author": "Moriz Wahl", - "version": "1.8.2", + "version": "1.8.3", "license": "MIT", "private": false, "scripts": { diff --git a/backend/package.json b/backend/package.json index 330bb284c..a9febe918 100644 --- a/backend/package.json +++ b/backend/package.json @@ -1,6 +1,6 @@ { "name": "gradido-backend", - "version": "1.8.2", + "version": "1.8.3", "description": "Gradido unified backend providing an API-Service for Gradido Transactions", "main": "src/index.ts", "repository": "https://github.com/gradido/gradido/backend", diff --git a/database/package.json b/database/package.json index 77f52b559..f5a16fd31 100644 --- a/database/package.json +++ b/database/package.json @@ -1,6 +1,6 @@ { "name": "gradido-database", - "version": "1.8.2", + "version": "1.8.3", "description": "Gradido Database Tool to execute database migrations", "main": "src/index.ts", "repository": "https://github.com/gradido/gradido/database", diff --git a/frontend/package.json b/frontend/package.json index 4f3d027a0..9d70ace58 100755 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,6 +1,6 @@ { "name": "bootstrap-vue-gradido-wallet", - "version": "1.8.2", + "version": "1.8.3", "private": true, "scripts": { "start": "node run/server.js", diff --git a/package.json b/package.json index 80da79a94..20ab8dd35 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gradido", - "version": "1.8.2", + "version": "1.8.3", "description": "Gradido", "main": "index.js", "repository": "git@github.com:gradido/gradido.git",