diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c6e1bbc8e..002118f5b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -50,13 +50,7 @@ jobs: ########################################################################## - name: login server | Build `release` image run: | - docker build --target release -t "gradido/login_server:release" -f ./login_server/Dockerfile login_server/ - #docker save "gradido/login_server:test" > /tmp/login_server.tar - #- name: Upload Artifact - # uses: actions/upload-artifact@v2 - #with: - # name: docker-login-server-test - #path: /tmp/login_server.tar + docker build -t "gradido/login_server:release" -f ./login_server/Dockerfile login_server/ ############################################################################## # JOB: DOCKER BUILD TEST COMMUNITY SERVER #################################### @@ -212,7 +206,7 @@ jobs: report_name: Coverage Frontend type: lcov result_path: ./coverage/lcov.info - min_coverage: 28 + min_coverage: 32 token: ${{ github.token }} ############################################################################## @@ -251,7 +245,7 @@ jobs: ########################################################################## - name: login server | Build `test` image run: | - docker build --target test -t "gradido/login_server:test" -f ./login_server/Dockerfile login_server/ + docker build -t "gradido/login_server:test" -f ./login_server/Dockerfiles/ubuntu/Dockerfile.test login_server/ ########################################################################## # UNIT TESTS BACKEND LOGIN-SERVER ####################################### ########################################################################## @@ -268,7 +262,7 @@ jobs: report_name: Coverage Backend Login type: lcov result_path: ./coverage/coverage.info - min_coverage: 13 + min_coverage: 25 token: ${{ github.token }} ############################################################################## @@ -300,7 +294,7 @@ jobs: run: echo "::set-output name=id::$(docker network ls | grep github_network | awk '{ print $1 }')" id: network - name: Start Login-Server - run: docker run --network ${{ steps.network.outputs.id }} --name=login-server -d gradido/login_server:default + run: docker run --network ${{ steps.network.outputs.id }} --name=login-server -d gradido/login_server:with-config - name: get login-server container id run: echo "::set-output name=id::$(docker container ls | grep login_server | awk '{ print $1 }')" id: login_server_container @@ -341,7 +335,7 @@ jobs: report_name: Coverage Backend Community type: phpunit result_path: ./coverage/coverage.info - min_coverage: 10 + min_coverage: 14 token: ${{ github.token }} #test: diff --git a/CHANGELOG.md b/CHANGELOG.md index a71ad2fd4..e949f98e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,8 +4,52 @@ 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.1.0](https://github.com/gradido/gradido/compare/1.0.2...1.1.0) + +- fix: API Call for Reset Password [`#571`](https://github.com/gradido/gradido/pull/571) +- Login reset password [`#570`](https://github.com/gradido/gradido/pull/570) +- Hide unuse components in profil [`#566`](https://github.com/gradido/gradido/pull/566) +- fix: Thousend Dividers on GDD Send Amount Field [`#567`](https://github.com/gradido/gradido/pull/567) +- reorganisiere Dockerfiles [`#550`](https://github.com/gradido/gradido/pull/550) +- hot fixes shown by test [`#551`](https://github.com/gradido/gradido/pull/551) +- fix to big text ths [`#565`](https://github.com/gradido/gradido/pull/565) +- feat: Trim Email on Blur [`#556`](https://github.com/gradido/gradido/pull/556) +- Mobile UI send gdd form [`#562`](https://github.com/gradido/gradido/pull/562) +- fix: Change Password Form [`#561`](https://github.com/gradido/gradido/pull/561) +- change userdata button disable rules [`#548`](https://github.com/gradido/gradido/pull/548) +- Change password require old password [`#519`](https://github.com/gradido/gradido/pull/519) +- feat: Test Forget Password [`#546`](https://github.com/gradido/gradido/pull/546) +- feat: Validate Change Username [`#545`](https://github.com/gradido/gradido/pull/545) +- Remove base input example login vue [`#524`](https://github.com/gradido/gradido/pull/524) +- Feature: Change Username [`#490`](https://github.com/gradido/gradido/pull/490) +- feat: Toaster to Display Messages [`#512`](https://github.com/gradido/gradido/pull/512) +- fix: Validation of GDD Send Amount Field [`#525`](https://github.com/gradido/gradido/pull/525) +- Community coverage [`#496`](https://github.com/gradido/gradido/pull/496) +- compare with last transaction sended [`#523`](https://github.com/gradido/gradido/pull/523) +- remove check decays for being at least 100 GDD cent [`#526`](https://github.com/gradido/gradido/pull/526) +- fix: Remove Target Date in Send Coins Request [`#518`](https://github.com/gradido/gradido/pull/518) +- Feature profile page bugs [`#511`](https://github.com/gradido/gradido/pull/511) +- fix: GDD Send Amount Input Field [`#491`](https://github.com/gradido/gradido/pull/491) +- change transfer confirmation email [`#485`](https://github.com/gradido/gradido/pull/485) +- Login wait on passwords with missing chars [`#487`](https://github.com/gradido/gradido/pull/487) +- fix problem with create User [`#486`](https://github.com/gradido/gradido/pull/486) +- Feature: Profile Page + Update API [`#474`](https://github.com/gradido/gradido/pull/474) +- add new API Call checkUsername [`#482`](https://github.com/gradido/gradido/pull/482) +- feat: Pagination Buttons for Transaction List [`#473`](https://github.com/gradido/gradido/pull/473) +- Login-Server & Community-Server Coverage [`#472`](https://github.com/gradido/gradido/pull/472) +- login without hedera [`#478`](https://github.com/gradido/gradido/pull/478) +- fix: Show Correct Version Number in Footer [`#475`](https://github.com/gradido/gradido/pull/475) +- refactor: Remove Element-UI [`#476`](https://github.com/gradido/gradido/pull/476) +- remove components Charts, Notification, SearchUser, ButtonCheckbox, Button RadioGroup, Breadcrumb [`159bff7`](https://github.com/gradido/gradido/commit/159bff71df20a5c48f93389b2f990f7fe54e53b9) +- fix bug, update dockerfiles to use dependencies without grpc [`dedcebd`](https://github.com/gradido/gradido/commit/dedcebdb95ee0f3dfd2ad62074d4181af38476a2) +- add warning to able to forward warnings from community server to client [`2fc3fe9`](https://github.com/gradido/gradido/commit/2fc3fe94a09bae199bf2f34f9df90e8fc3879c2b) + #### [1.0.2](https://github.com/gradido/gradido/compare/1.0.1...1.0.2) +> 27 May 2021 + +- feat: Test Transaction List [`#470`](https://github.com/gradido/gradido/pull/470) +- fixed problem with finding cpsp parse binary under windows with conan [`#471`](https://github.com/gradido/gradido/pull/471) - fix: GDD Amount is Always Displayed with Two Digits [`#468`](https://github.com/gradido/gradido/pull/468) - fix: Date Time Formats [`#469`](https://github.com/gradido/gradido/pull/469) - Community ipv6 localhost [`#466`](https://github.com/gradido/gradido/pull/466) diff --git a/community_server/src/Controller/AppController.php b/community_server/src/Controller/AppController.php index eb11299ce..2c6344511 100644 --- a/community_server/src/Controller/AppController.php +++ b/community_server/src/Controller/AppController.php @@ -289,7 +289,7 @@ class AppController extends Controller } } else { if(!$redirect) { - return ['state' => 'not found', 'msg' => 'invalid session']; + return ['state' => 'not found', 'msg' => 'invalid session', 'details' => $json]; } if ($json['state'] === 'not found') { $this->Flash->error(__('invalid session')); diff --git a/community_server/src/Model/Table/TransactionsTable.php b/community_server/src/Model/Table/TransactionsTable.php index 460759b1e..301e9b70b 100644 --- a/community_server/src/Model/Table/TransactionsTable.php +++ b/community_server/src/Model/Table/TransactionsTable.php @@ -192,7 +192,7 @@ class TransactionsTable extends Table $calculated_decay = $stateBalancesTable->calculateDecay($prev->balance, $prev->balance_date, $current->balance_date, true); $balance = floatval($prev->balance - $calculated_decay['balance']); - if($balance) + if($balance > 100) { $final_transactions['decay'] = [ 'balance' => $balance, diff --git a/community_server/tests/TestCase/Controller/AppRequestControllerTest.php b/community_server/tests/TestCase/Controller/AppRequestControllerTest.php index 118f25a32..bff10d997 100644 --- a/community_server/tests/TestCase/Controller/AppRequestControllerTest.php +++ b/community_server/tests/TestCase/Controller/AppRequestControllerTest.php @@ -109,9 +109,11 @@ class AppRequestControllerTest extends TestCase 'public_hex' => '8190bda585ee5f1d9fbf7d06e81e69ec18e13376104cff54b7457eb7d3ef710d' ] ]); - + $this->getAndParse('/api/get-balance/' . 1211, - ['state' => 'not found', 'msg' => 'invalid session'] + ['state' => 'not found', 'msg' => 'invalid session', + 'details' => ['msg' => 'session not found', 'state' => 'not found'] + ] ); } @@ -128,7 +130,9 @@ class AppRequestControllerTest extends TestCase ]); $this->getAndParse('/api/get-balance/' , - ['state' => 'not found', 'msg' => 'invalid session'] + ['state' => 'not found', 'msg' => 'invalid session', + 'details' => ['msg' => 'session not found', 'state' => 'not found'] + ] ); } diff --git a/docker-compose.override.yml b/docker-compose.override.yml index 1060002ba..dfc980a86 100644 --- a/docker-compose.override.yml +++ b/docker-compose.override.yml @@ -26,8 +26,7 @@ services: ######################################################### login-server: build: - target: login_server_alpine_debug - dockerfile: Dockerfile.alpine-debug + dockerfile: Dockerfiles/alpine/Dockerfile.debug security_opt: - seccomp:unconfined cap_add: diff --git a/docker-compose.test.yml b/docker-compose.test.yml index b9d44363e..457faf950 100644 --- a/docker-compose.test.yml +++ b/docker-compose.test.yml @@ -26,7 +26,7 @@ services: login-server: build: context: ./login_server/ - target: test + dockerfile: Dockerfiles/ubuntu/Dockerfile.test security_opt: - seccomp:unconfined cap_add: diff --git a/docker-compose.yml b/docker-compose.yml index 2cc2ceff7..35e015f4e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -55,7 +55,6 @@ services: login-server: build: context: ./login_server/ - target: login_server depends_on: - mariadb networks: diff --git a/docu/login_server.api.md b/docu/login_server.api.md index fb9409cf0..3682f310e 100644 --- a/docu/login_server.api.md +++ b/docu/login_server.api.md @@ -230,7 +230,8 @@ with: "User.description" : "Tischler", "User.disabled": 0, "User.language": "de", - "User.password": "1234" + "User.password": "1234", + "User.password_old": "4321" } } ``` @@ -240,6 +241,7 @@ Notes: - User will be disabled if he wants his account deleted, but has transactions. Until transactions are saved in real blockchain, we need this data because the public key is in db only saved in state_users so if we delete this entry, validating all transactions is no longer possible. - Disabled Users can neither login nor receive transactions. - It is not required to provide all fields of `update`, it can be a subset depending on what you intend to change. +- `User.password`: to change user password, needed current passwort in `User.password_old` (only if user was logged in with his password, not by reset password email code) ### Response In case of success: @@ -252,7 +254,7 @@ In case of success: } ``` -- `valid_values`: should contain count of entries in update if no error occurred (User.password will not be counted) +- `valid_values`: should contain count of entries in update if no error occurred (User.password will now be counted also) - `errors`: contain on error string for every entry in update, which type isn't like expected - `password`: - "new password is the same as old password": no change taking place @@ -503,6 +505,29 @@ The link can be modified in the Login-Server config: For the docker build, you can find the config here: `configs/login_server/grd_login.properties` +### Request +`POST http://localhost/login_api/resetPassword` + +with: + +```json +{ + "session_id": 12452361, + "password":"hasu/282?sjS" +} +``` + +### Response +In case of success returns: + +```json +{ + "state":"success" +} +``` + + + ## Check Running Transactions / password encryption Check if transactions on login-server for user are processed diff --git a/frontend/package.json b/frontend/package.json index 910644e2c..b53826746 100755 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,6 +1,6 @@ { "name": "bootstrap-vue-gradido-wallet", - "version": "1.0.2", + "version": "1.1.0", "private": true, "scripts": { "start": "node run/server.js", diff --git a/frontend/src/apis/loginAPI.js b/frontend/src/apis/loginAPI.js index 3453bd296..f71e7634f 100644 --- a/frontend/src/apis/loginAPI.js +++ b/frontend/src/apis/loginAPI.js @@ -15,7 +15,7 @@ const apiGet = async (url) => { if (result.status !== 200) { throw new Error('HTTP Status Error ' + result.status) } - if (result.data.state !== 'success') { + if (!['success', 'warning'].includes(result.data.state)) { throw new Error(result.data.msg) } return { success: true, result } @@ -102,19 +102,17 @@ const loginAPI = { const payload = { session_id: sessionId, email, - update: { - 'User.password': password, - }, + password, } - return apiPost(CONFIG.LOGIN_API_URL + 'updateUserInfos', payload) + return apiPost(CONFIG.LOGIN_API_URL + 'resetPassword', payload) }, changePasswordProfile: async (sessionId, email, password, passwordNew) => { const payload = { session_id: sessionId, email, update: { - 'User.password': password, - 'User.passwordNew': passwordNew, + 'User.password_old': password, + 'User.password': passwordNew, }, } return apiPost(CONFIG.LOGIN_API_URL + 'updateUserInfos', payload) @@ -139,6 +137,9 @@ const loginAPI = { } return apiPost(CONFIG.LOGIN_API_URL + 'updateUserInfos', payload) }, + checkUsername: async (username, groupId = 1) => { + return apiGet(CONFIG.LOGIN_API_URL + `checkUsername?username=${username}&group_id=${groupId}`) + }, } export default loginAPI diff --git a/frontend/src/components/SidebarPlugin/SideBar.vue b/frontend/src/components/SidebarPlugin/SideBar.vue index 756e72d2a..495dec3d2 100755 --- a/frontend/src/components/SidebarPlugin/SideBar.vue +++ b/frontend/src/components/SidebarPlugin/SideBar.vue @@ -85,7 +85,7 @@ export default { default: 'img/brand/green.png', description: 'Gradido Sidebar app logo', }, - value: { type: Array }, + value: { type: String }, autoClose: { type: Boolean, default: true, diff --git a/frontend/src/i18n.js b/frontend/src/i18n.js index d91acfb79..98e4ec971 100644 --- a/frontend/src/i18n.js +++ b/frontend/src/i18n.js @@ -38,6 +38,12 @@ const numberFormats = { minimumFractionDigits: 2, maximumFractionDigits: 2, }, + ungroupedDecimal: { + style: 'decimal', + minimumFractionDigits: 2, + maximumFractionDigits: 2, + useGrouping: false, + }, }, de: { decimal: { @@ -45,6 +51,12 @@ const numberFormats = { minimumFractionDigits: 2, maximumFractionDigits: 2, }, + ungroupedDecimal: { + style: 'decimal', + minimumFractionDigits: 2, + maximumFractionDigits: 2, + useGrouping: false, + }, }, } diff --git a/frontend/src/locales/de.json b/frontend/src/locales/de.json index 6536a143b..4d85269c5 100644 --- a/frontend/src/locales/de.json +++ b/frontend/src/locales/de.json @@ -39,6 +39,7 @@ "password_new":"neues Passwort", "password_new_repeat":"neues Passwort wiederholen", "change": "ändern", + "change-password": "Passwort ändern", "amount":"Betrag", "memo":"Nachricht für den Empfänger", "message":"Nachricht", @@ -57,12 +58,15 @@ "send_transaction_error":"Leider konnte die Transaktion nicht ausgeführt werden!", "validation": { "gddSendAmount": "Das Feld {_field_} muss eine Zahl zwischen {min} und {max} mit höchstens zwei Nachkommastellen sein", - "is-not": "Du kannst dir selbst keine Gradidos überweisen" + "is-not": "Du kannst dir selbst keine Gradidos überweisen", + "usernmae-unique": "Der Username ist bereits vergeben.", + "usernmae-regex": "Der Username muss mit einem Buchstaben beginnen auf den mindestens zwei alfanumerische Zeichen folgen müssen." }, - "change_username_info": "Das ändern des Usernamens bedarf mehrerer Schritte." + "change_username_info": "Einmal gespeichert, kann der Username ncht mehr geändert werden!" }, "error": { - "error":"Fehler" + "error":"Fehler", + "change-password": "Fehler beim Ändern des Passworts" }, "transaction":{ "show_all":"Alle {count} Transaktionen ansehen", diff --git a/frontend/src/locales/en.json b/frontend/src/locales/en.json index f611e4b91..987605bd8 100644 --- a/frontend/src/locales/en.json +++ b/frontend/src/locales/en.json @@ -39,6 +39,7 @@ "password_new":"New password", "password_new_repeat":"Repeat new password", "change": "change", + "change-password": "Change password", "amount":"Amount", "memo":"Message for the recipient", "message":"Message", @@ -57,12 +58,15 @@ "send_transaction_error":"Unfortunately, the transaction could not be executed!", "validation": { "gddSendAmount": "The {_field_} field must be a number between {min} and {max} with at most two digits", - "is-not": "You cannot send Gradidos to yourself" + "is-not": "You cannot send Gradidos to yourself", + "usernmae-unique": "The username is already taken.", + "usernmae-regex": "The username must start with a letter, followed by at least two alphanumeric characters." }, - "change_username_info": "Changing the username requires several steps." + "change_username_info": "Once saved, the username cannot be changed again!" }, "error": { - "error":"Error" + "error":"Error", + "change-password": "Error while changing password" }, "transaction":{ "show_all":"View all {count} transactions.", diff --git a/frontend/src/main.js b/frontend/src/main.js index 160ff73c7..1eda3eaca 100755 --- a/frontend/src/main.js +++ b/frontend/src/main.js @@ -9,6 +9,8 @@ import { required, email, min, max, is_not } from 'vee-validate/dist/rules' // store import { store } from './store/store' +import loginAPI from './apis/loginAPI' + // router setup import router from './routes/router' @@ -58,12 +60,27 @@ extend('gddSendAmount', { }, params: ['min', 'max'], message: (_, values) => { - values.min = i18n.n(values.min) - values.max = i18n.n(values.max) + values.min = i18n.n(values.min, 'ungroupedDecimal') + values.max = i18n.n(values.max, 'ungroupedDecimal') return i18n.t('form.validation.gddSendAmount', values) }, }) +extend('gddUsernameUnique', { + async validate(value) { + const result = await loginAPI.checkUsername(value) + return result.result.data.state === 'success' + }, + message: (_, values) => i18n.t('form.validation.usernmae-unique', values), +}) + +extend('gddUsernameRgex', { + validate(value) { + return !!value.match(/^[a-zA-Z][-_a-zA-Z0-9]{2,}$/) + }, + message: (_, values) => i18n.t('form.validation.usernmae-regex', values), +}) + // eslint-disable-next-line camelcase extend('is_not', { // eslint-disable-next-line camelcase diff --git a/frontend/src/views/Layout/DashboardLayout_gdd.spec.js b/frontend/src/views/Layout/DashboardLayout_gdd.spec.js index 62ce94322..9221ff59a 100644 --- a/frontend/src/views/Layout/DashboardLayout_gdd.spec.js +++ b/frontend/src/views/Layout/DashboardLayout_gdd.spec.js @@ -1,16 +1,12 @@ import { mount, RouterLinkStub } from '@vue/test-utils' -import VueRouter from 'vue-router' import Vuex from 'vuex' import flushPromises from 'flush-promises' -import routes from '../../routes/routes' import DashboardLayoutGdd from './DashboardLayout_gdd' jest.useFakeTimers() const localVue = global.localVue -const router = new VueRouter({ routes }) - const transitionStub = () => ({ render(h) { return this.$options._renderChildren @@ -26,6 +22,14 @@ describe('DashboardLayoutGdd', () => { }, $t: jest.fn((t) => t), $n: jest.fn(), + $route: { + meta: { + hideFooter: false, + }, + }, + $router: { + push: jest.fn(), + }, } const state = { @@ -40,6 +44,7 @@ describe('DashboardLayoutGdd', () => { const stubs = { RouterLink: RouterLinkStub, FadeTransition: transitionStub(), + RouterView: transitionStub(), } const store = new Vuex.Store({ @@ -50,7 +55,7 @@ describe('DashboardLayoutGdd', () => { }) const Wrapper = () => { - return mount(DashboardLayoutGdd, { localVue, mocks, router, store, stubs }) + return mount(DashboardLayoutGdd, { localVue, mocks, store, stubs }) } describe('mount', () => { diff --git a/frontend/src/views/Layout/DashboardLayout_gdd.vue b/frontend/src/views/Layout/DashboardLayout_gdd.vue index 4d65aed70..9990b91f2 100755 --- a/frontend/src/views/Layout/DashboardLayout_gdd.vue +++ b/frontend/src/views/Layout/DashboardLayout_gdd.vue @@ -144,9 +144,6 @@ export default { mounted() { this.initScrollbar() }, - created() { - this.updateTransactions({ firstPage: 1, items: 5 }) - }, } diff --git a/frontend/src/views/Pages/UserProfile/UserCard_FormUsername.spec.js b/frontend/src/views/Pages/UserProfile/UserCard_FormUsername.spec.js new file mode 100644 index 000000000..b1d705952 --- /dev/null +++ b/frontend/src/views/Pages/UserProfile/UserCard_FormUsername.spec.js @@ -0,0 +1,121 @@ +import { mount } from '@vue/test-utils' +import { extend } from 'vee-validate' +import UserCardFormUsername from './UserCard_FormUsername' +import loginAPI from '../../../apis/loginAPI' +import flushPromises from 'flush-promises' + +jest.mock('../../../apis/loginAPI') + +extend('gddUsernameRgex', { + validate(value) { + return true + }, +}) + +extend('gddUsernameUnique', { + validate(value) { + return true + }, +}) + +const localVue = global.localVue + +const mockAPIcall = jest.fn((args) => { + return { success: true } +}) + +loginAPI.changeUsernameProfile = mockAPIcall + +describe('UserCard_FormUsername', () => { + let wrapper + + const mocks = { + $t: jest.fn((t) => t), + $store: { + state: { + sessionId: 1, + email: 'user@example.org', + username: '', + }, + commit: jest.fn(), + }, + $toast: { + success: jest.fn(), + }, + } + + const Wrapper = () => { + return mount(UserCardFormUsername, { localVue, mocks }) + } + + describe('mount', () => { + beforeEach(() => { + wrapper = Wrapper() + }) + + it('renders the component', () => { + expect(wrapper.find('div#formusername').exists()).toBeTruthy() + }) + + describe('username in store is empty', () => { + it('renders an empty username', () => { + expect(wrapper.find('div.display-username').text()).toEqual('@') + }) + + it('has an edit icon', () => { + expect(wrapper.find('svg.bi-pencil').exists()).toBeTruthy() + }) + + describe('edit username', () => { + beforeEach(async () => { + await wrapper.find('svg.bi-pencil').trigger('click') + }) + + it('shows an input field for the username', () => { + expect(wrapper.find('input[placeholder="Username"]').exists()).toBeTruthy() + }) + + it('shows an cancel icon', () => { + expect(wrapper.find('svg.bi-x-circle').exists()).toBeTruthy() + }) + + it('closes the input when cancel icon is clicked', async () => { + wrapper.find('svg.bi-x-circle').trigger('click') + await wrapper.vm.$nextTick() + expect(wrapper.find('input[placeholder="Username"]').exists()).toBeFalsy() + }) + + it('does not change the username when cancel is clicked', async () => { + wrapper.find('input[placeholder="Username"]').setValue('username') + wrapper.find('svg.bi-x-circle').trigger('click') + await wrapper.vm.$nextTick() + expect(wrapper.find('div.display-username').text()).toEqual('@') + }) + + it('has a submit button', () => { + expect(wrapper.find('button[type="submit"]').exists()).toBeTruthy() + }) + + describe('successfull submit', () => { + beforeEach(async () => { + await wrapper.find('input[placeholder="Username"]').setValue('username') + await wrapper.find('form').trigger('submit') + await flushPromises() + }) + + it('calls the loginAPI', () => { + expect(mockAPIcall).toHaveBeenCalledWith(1, 'user@example.org', 'username') + }) + + it('displays the new username', () => { + expect(wrapper.find('div.display-username').text()).toEqual('@username') + }) + + it('has no edit button anymore', () => { + expect(wrapper.find('svg.bi-pencil').exists()).toBeFalsy() + }) + }) + }) + }) + }) +}) diff --git a/frontend/src/views/Pages/UserProfile/UserCard_FormUsername.vue b/frontend/src/views/Pages/UserProfile/UserCard_FormUsername.vue index 2b3b451fe..e908fd08c 100644 --- a/frontend/src/views/Pages/UserProfile/UserCard_FormUsername.vue +++ b/frontend/src/views/Pages/UserProfile/UserCard_FormUsername.vue @@ -1,20 +1,19 @@ @@ -66,7 +73,7 @@ export default { name: 'FormUsername', data() { return { - editUsername: true, + showUsername: true, username: this.$store.state.username, form: { username: this.$store.state.username, @@ -74,6 +81,10 @@ export default { } }, methods: { + cancelEdit() { + this.username = this.$store.state.username + this.showUsername = true + }, async onSubmit() { const result = await loginAPI.changeUsernameProfile( this.$store.state.sessionId, @@ -82,13 +93,21 @@ export default { ) if (result.success) { this.$store.commit('username', this.form.username) - this.editUserdata = this.editUsername = !this.editUsername - alert('Dein Username wurde geändert.') + this.username = this.form.username + this.showUsername = true + this.$toast.success(this.$t('site.profil.user-data.change-success')) } else { - alert(result.result.message) + this.$toast.error(result.result.message) + this.showUsername = true + this.username = this.$store.state.username + this.form.username = this.$store.state.username } }, }, } - + diff --git a/frontend/src/views/Pages/UserProfileOverview.spec.js b/frontend/src/views/Pages/UserProfileOverview.spec.js index 617e0ade0..0fab63d4b 100644 --- a/frontend/src/views/Pages/UserProfileOverview.spec.js +++ b/frontend/src/views/Pages/UserProfileOverview.spec.js @@ -27,9 +27,9 @@ describe('UserProfileOverview', () => { expect(wrapper.findComponent({ name: 'FormUserData' }).exists()).toBeTruthy() }) - it('has a user name form', () => { - expect(wrapper.findComponent({ name: 'FormUsername' }).exists()).toBeTruthy() - }) + // it('has a user name form', () => { + // expect(wrapper.findComponent({ name: 'FormUsername' }).exists()).toBeTruthy() + // }) it('has a user password form', () => { expect(wrapper.findComponent({ name: 'FormUserPasswort' }).exists()).toBeTruthy() diff --git a/frontend/src/views/Pages/UserProfileOverview.vue b/frontend/src/views/Pages/UserProfileOverview.vue index 0708a2329..67073fa60 100644 --- a/frontend/src/views/Pages/UserProfileOverview.vue +++ b/frontend/src/views/Pages/UserProfileOverview.vue @@ -2,21 +2,21 @@ - +