diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4f887aa14..cf0b061ef 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -212,7 +212,7 @@ jobs: report_name: Coverage Frontend type: lcov result_path: ./coverage/lcov.info - min_coverage: 18 + min_coverage: 19 token: ${{ github.token }} #test: diff --git a/frontend/src/apis/loginAPI.js b/frontend/src/apis/loginAPI.js index f5b0c57f5..55e32e6dd 100644 --- a/frontend/src/apis/loginAPI.js +++ b/frontend/src/apis/loginAPI.js @@ -1,5 +1,7 @@ import axios from 'axios' import CONFIG from '../config' +// eslint-disable-next-line no-unused-vars +import regeneratorRuntime from 'regenerator-runtime' // control email-text sended with email verification code const EMAIL_TYPE = { @@ -86,6 +88,16 @@ const loginAPI = { } return apiPost(CONFIG.LOGIN_API_URL + 'updateUserInfos', payload) }, + updateLanguage: async (sessionId, email, language) => { + const payload = { + session_id: sessionId, + email, + update: { + 'User.language': language, + }, + } + return apiPost(CONFIG.LOGIN_API_URL + 'updateUserInfos', payload) + }, } export default loginAPI diff --git a/frontend/src/components/LanguageSwitch.spec.js b/frontend/src/components/LanguageSwitch.spec.js new file mode 100644 index 000000000..14dc978ac --- /dev/null +++ b/frontend/src/components/LanguageSwitch.spec.js @@ -0,0 +1,95 @@ +import { mount } from '@vue/test-utils' +import LanguageSwitch from './LanguageSwitch' + +const localVue = global.localVue + +describe('LanguageSwitch', () => { + let wrapper + + const state = { + sessionId: 1234, + email: 'he@ho.he', + language: null, + } + + const mocks = { + $store: { + state, + commit: jest.fn(), + }, + $i18n: { + locale: 'en', + }, + } + + const Wrapper = () => { + return mount(LanguageSwitch, { localVue, mocks }) + } + + describe('mount', () => { + beforeEach(() => { + wrapper = Wrapper() + }) + + it('renders the component', () => { + expect(wrapper.find('div.language-switch').exists()).toBeTruthy() + }) + + describe('with locales en and de', () => { + describe('empty store', () => { + it('shows English as default navigator langauge', () => { + expect(wrapper.find('button.dropdown-toggle').text()).toBe('English - en') + }) + + describe('navigator language is "de-DE"', () => { + const mockNavigator = jest.fn(() => { + return 'de' + }) + + it('shows Deutsch as language ', async () => { + wrapper.vm.getNavigatorLanguage = mockNavigator + wrapper.vm.setCurrentLanguage() + await wrapper.vm.$nextTick() + expect(wrapper.find('button.dropdown-toggle').text()).toBe('Deutsch - de') + }) + }) + + describe('navigator language is "es-ES" (not supported)', () => { + const mockNavigator = jest.fn(() => { + return 'es' + }) + + it('shows English as language ', async () => { + wrapper.vm.getNavigatorLanguage = mockNavigator + wrapper.vm.setCurrentLanguage() + await wrapper.vm.$nextTick() + expect(wrapper.find('button.dropdown-toggle').text()).toBe('English - en') + }) + }) + }) + + describe('language "de" in store', () => { + it('shows Deutsch as language', async () => { + wrapper.vm.$store.state.language = 'de' + wrapper.vm.setCurrentLanguage() + await wrapper.vm.$nextTick() + expect(wrapper.find('button.dropdown-toggle').text()).toBe('Deutsch - de') + }) + }) + + describe('dropdown menu', () => { + it('has English and German as languages to choose', () => { + expect(wrapper.findAll('li')).toHaveLength(2) + }) + + it('has English as first language to choose', () => { + expect(wrapper.findAll('li').at(0).text()).toBe('English') + }) + + it('has German as second language to choose', () => { + expect(wrapper.findAll('li').at(1).text()).toBe('Deutsch') + }) + }) + }) + }) +}) diff --git a/frontend/src/components/LanguageSwitch.vue b/frontend/src/components/LanguageSwitch.vue index 0fad036a6..2b160b3e3 100644 --- a/frontend/src/components/LanguageSwitch.vue +++ b/frontend/src/components/LanguageSwitch.vue @@ -1,22 +1,72 @@ diff --git a/frontend/src/components/SidebarPlugin/SideBar.spec.js b/frontend/src/components/SidebarPlugin/SideBar.spec.js index 36230849f..9f9ce8a8f 100644 --- a/frontend/src/components/SidebarPlugin/SideBar.spec.js +++ b/frontend/src/components/SidebarPlugin/SideBar.spec.js @@ -19,6 +19,7 @@ describe('SideBar', () => { state: { email: 'test@example.org', }, + commit: jest.fn(), }, $i18n: { locale: 'en', diff --git a/frontend/src/locales/de.json b/frontend/src/locales/de.json index 558de7813..b840fc34b 100644 --- a/frontend/src/locales/de.json +++ b/frontend/src/locales/de.json @@ -19,7 +19,6 @@ "en": "English" }, "form": { - "attention": "Achtung! Bitte überprüfe alle deine Eingaben sehr genau. Du bist alleine Verantwortlich für deine Entscheidungen. Versendete Gradidos können nicht wieder zurück geholt werden.", "cancel":"Abbrechen", "reset": "Zurücksetzen", "close":"schließen", @@ -49,7 +48,7 @@ "send_transaction_error":"Leider konnte die Transaktion nicht ausgeführt werden!", "validation": { "double": "Das Feld {field} muss eine Dezimalzahl mit zwei Nachkommastellen sein", - "is-not": "Du kannst Dir selbst keine Gradidos überweisen" + "is-not": "Du kannst dir selbst keine Gradidos überweisen" } }, "error": { diff --git a/frontend/src/locales/en.json b/frontend/src/locales/en.json index 2daa1696f..4a7a8b09f 100644 --- a/frontend/src/locales/en.json +++ b/frontend/src/locales/en.json @@ -19,7 +19,6 @@ "en": "English" }, "form": { - "attention": "Attention! Please check all your entries very carefully. You are solely responsible for your decisions. Sent Gradidos cannot be retrieved.", "cancel":"Cancel", "reset": "Reset", "close":"Close", diff --git a/frontend/src/locales/index.js b/frontend/src/locales/index.js new file mode 100644 index 000000000..4cb375b40 --- /dev/null +++ b/frontend/src/locales/index.js @@ -0,0 +1,16 @@ +const locales = [ + { + name: 'English', + code: 'en', + iso: 'en-US', + enabled: true, + }, + { + name: 'Deutsch', + code: 'de', + iso: 'de-DE', + enabled: true, + }, +] + +export default locales diff --git a/frontend/src/store/store.js b/frontend/src/store/store.js index aed286bc6..1d89894fb 100644 --- a/frontend/src/store/store.js +++ b/frontend/src/store/store.js @@ -18,7 +18,8 @@ export const mutations = { export const actions = { login: ({ dispatch, commit }, data) => { commit('sessionId', data.sessionId) - commit('email', data.email) + commit('email', data.user.email) + commit('language', data.user.language) }, logout: ({ commit, state }) => { commit('sessionId', null) @@ -36,7 +37,7 @@ export const store = new Vuex.Store({ state: { sessionId: null, email: '', - language: 'en', + language: null, modals: false, }, getters: {}, diff --git a/frontend/src/store/store.test.js b/frontend/src/store/store.test.js index 655cca7a0..11dd5949b 100644 --- a/frontend/src/store/store.test.js +++ b/frontend/src/store/store.test.js @@ -35,20 +35,37 @@ describe('Vuex store', () => { const commit = jest.fn() const state = {} - it('calls two commits', () => { - login({ commit, state }, { sessionId: 1234, email: 'someone@there.is' }) - expect(commit).toHaveBeenCalledTimes(2) + it('calls three commits', () => { + login( + { commit, state }, + { sessionId: 1234, user: { email: 'someone@there.is', language: 'en' } }, + ) + expect(commit).toHaveBeenCalledTimes(3) }) it('commits sessionId', () => { - login({ commit, state }, { sessionId: 1234, email: 'someone@there.is' }) + login( + { commit, state }, + { sessionId: 1234, user: { email: 'someone@there.is', language: 'en' } }, + ) expect(commit).toHaveBeenNthCalledWith(1, 'sessionId', 1234) }) it('commits email', () => { - login({ commit, state }, { sessionId: 1234, email: 'someone@there.is' }) + login( + { commit, state }, + { sessionId: 1234, user: { email: 'someone@there.is', language: 'en' } }, + ) expect(commit).toHaveBeenNthCalledWith(2, 'email', 'someone@there.is') }) + + it('commits language', () => { + login( + { commit, state }, + { sessionId: 1234, user: { email: 'someone@there.is', language: 'en' } }, + ) + expect(commit).toHaveBeenNthCalledWith(3, 'language', 'en') + }) }) describe('logout', () => { diff --git a/frontend/src/views/Layout/DashboardLayout_gdd.spec.js b/frontend/src/views/Layout/DashboardLayout_gdd.spec.js index 8c1e604c0..84c955042 100644 --- a/frontend/src/views/Layout/DashboardLayout_gdd.spec.js +++ b/frontend/src/views/Layout/DashboardLayout_gdd.spec.js @@ -44,6 +44,9 @@ describe('DashboardLayoutGdd', () => { const store = new Vuex.Store({ state, + mutations: { + language: jest.fn(), + }, }) const Wrapper = () => { diff --git a/frontend/src/views/Layout/DashboardNavbar.vue b/frontend/src/views/Layout/DashboardNavbar.vue index 7c83bef1b..fb819c13f 100755 --- a/frontend/src/views/Layout/DashboardNavbar.vue +++ b/frontend/src/views/Layout/DashboardNavbar.vue @@ -15,7 +15,7 @@ {{ $store.state.email }} - + diff --git a/frontend/src/views/Pages/AccountOverview.spec.js b/frontend/src/views/Pages/AccountOverview.spec.js index d28b295d8..031828129 100644 --- a/frontend/src/views/Pages/AccountOverview.spec.js +++ b/frontend/src/views/Pages/AccountOverview.spec.js @@ -19,10 +19,6 @@ describe('AccountOverview', () => { wrapper = Wrapper() }) - it('has a header', () => { - expect(wrapper.find('base-header-stub').exists()).toBeTruthy() - }) - it('has a status line', () => { expect(wrapper.find('gdd-status-stub').exists()).toBeTruthy() }) diff --git a/frontend/src/views/Pages/AccountOverview.vue b/frontend/src/views/Pages/AccountOverview.vue index cf05b846a..5f262f627 100644 --- a/frontend/src/views/Pages/AccountOverview.vue +++ b/frontend/src/views/Pages/AccountOverview.vue @@ -1,7 +1,6 @@