diff --git a/cypress/e2e/LogIn.cy.ts b/cypress/e2e/LogIn.cy.ts new file mode 100644 index 0000000000000000000000000000000000000000..5d26ad9b4a82bc34e5817e00a5b2e077b6ac2d7d --- /dev/null +++ b/cypress/e2e/LogIn.cy.ts @@ -0,0 +1,26 @@ +describe('Login spec', () => { + it('Can log in', () => { + cy.visit('/login') + + cy.get('[data-testid="LogInButton"]').should('be.disabled') + + cy.get('[data-testid="NameInput"]').type("JohnSmith12") + cy.get('[data-testid="NameInput"]').should('have.value', "JohnSmith12") + + cy.get('[data-testid="LogInButton"]').should('be.disabled') + + cy.get('[data-testid="PasswordInput"]').type("password") + cy.get('[data-testid="PasswordInput"]').should('have.value', "password") + + cy.get('[data-testid="LogInButton"]').should('be.enabled') + cy.get('[data-testid="LogInButton"]').click() + cy.url().should('include', '/homepage') + }) + + it('Can navigate to new user', () => { + cy.visit('/login') + cy.get('[data-testid="NewUserLink"]').click() + cy.url().should('include', '/signup') + + }) +}) \ No newline at end of file diff --git a/src/components/__tests__/BadgeInfo.spec.ts b/src/components/__tests__/BadgeInfo.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..72a293d02f3d4eee4a1c92ab697cb03dd6425be3 --- /dev/null +++ b/src/components/__tests__/BadgeInfo.spec.ts @@ -0,0 +1,30 @@ +import { mount } from '@vue/test-utils'; +import BadgeInfo from '@/components/profile/BadgeInfo.vue'; +import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; +import { createPinia, setActivePinia } from 'pinia'; + +describe('Component', () => { + beforeEach(() => { + setActivePinia(createPinia()); + }); + + it('renders badges with correct data', async () => { + const wrapper = mount(BadgeInfo, { + props: { title: 'Test Title' } + }); + + await wrapper.vm.$nextTick(); + + const badges = wrapper.findAll('.badge'); + + badges.forEach((badge, index) => { + const achievement = (wrapper.vm as any).achievements[index]; + const img = badge.find('.badge-img'); + const title = badge.find('.badge-title'); + + expect(img.attributes('src')).toBe(achievement.img); + expect(img.attributes('alt')).toBe(achievement.title); + expect(title.text()).toBe(achievement.title); + }); + }); +}); diff --git a/src/components/__tests__/BankAccountInfo.spec.ts b/src/components/__tests__/BankAccountInfo.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..c0aea7c471cf73be88260cefab94974490a6d73b --- /dev/null +++ b/src/components/__tests__/BankAccountInfo.spec.ts @@ -0,0 +1,22 @@ +// Import necessary dependencies +import { mount } from '@vue/test-utils' +import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; +import BankAccountInfo from '@/components/profile/BankAccountInfo.vue'; +import { createPinia, setActivePinia } from 'pinia' + +describe('AccountInfo.vue', () => { + let wrapper:any + + beforeEach(() => { + setActivePinia(createPinia()); + wrapper = mount(BankAccountInfo) + }) + + afterEach(() => { + wrapper.unmount() + }) + + it('renders correctly', () => { + expect(wrapper.html()).toMatchSnapshot() + }) +}) diff --git a/src/components/__tests__/IncomeInfo.spec.ts b/src/components/__tests__/IncomeInfo.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..779f8b376ee7331cd2b45ca451cf1bd128c16ea2 --- /dev/null +++ b/src/components/__tests__/IncomeInfo.spec.ts @@ -0,0 +1,21 @@ +import { mount } from '@vue/test-utils'; +import IncomeInfo from '@/components/profile/IncomeInfo.vue' +import { describe, it, expect, beforeEach } from 'vitest' +import { createPinia, setActivePinia } from 'pinia' + +describe('IncomeInfo', () => { + + beforeEach(() => { + setActivePinia(createPinia()); + }); + + it('renders correctly', async () => { + const wrapper = mount(IncomeInfo); + + expect(wrapper.exists()).toBe(true); + + expect(wrapper.findAll('.input-field')).toHaveLength(3); + + expect(wrapper.find('.save-button').exists()).toBe(true); + }); +}); diff --git a/src/components/__tests__/PasswordInfo.spec.ts b/src/components/__tests__/PasswordInfo.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..f8e6d79ed7346ef47adb6e1b3c71fe1c136267b6 --- /dev/null +++ b/src/components/__tests__/PasswordInfo.spec.ts @@ -0,0 +1,25 @@ +import { mount } from '@vue/test-utils' +import PasswordInfo from '@/components/profile/PasswordInfo.vue' +import { describe, it, expect, beforeEach } from 'vitest' +import { createPinia, setActivePinia } from 'pinia' + +describe('PasswordComponent', () => { + + beforeEach(() => { + setActivePinia(createPinia()); + }); + + it('renders correctly', async () => { + const wrapper = mount(PasswordInfo) + + expect(wrapper.exists()).toBe(true) + + expect(wrapper.find('.title').text()).toBe('Passord') + + expect(wrapper.find('.save-button').exists()).toBe(true) + + expect(wrapper.find('[data-testid="current-password-input"]').exists()).toBe(true) + + expect(wrapper.find('[data-testid="new-password-input"]').exists()).toBe(true) + }) +}) diff --git a/src/components/__tests__/UserInfo.spec.ts b/src/components/__tests__/UserInfo.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..8e44d8f598da0cf4c13bc1a4347496c88266e5d5 --- /dev/null +++ b/src/components/__tests__/UserInfo.spec.ts @@ -0,0 +1,40 @@ +import { mount } from '@vue/test-utils' +import UserInfo from '@/components/profile/UserInfo.vue' +import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; +import { updateUserInfo } from '../../utils/profileutils' + +// Mocking getUserInfo and updateUserInfo functions +vi.mock('@/utils/profileutils', () => ({ + getUserInfo: vi.fn(), + updateUserInfo: vi.fn() +})) + +// Mocking useTokenStore +vi.mock('@/stores/token', () => ({ + useTokenStore: vi.fn(() => ({ jwtToken: 'mockedToken' })) +})) + +describe('UserInfo', () => { + let wrapper:any + + beforeEach(() => { + wrapper = mount(UserInfo) + }) + + afterEach(() => { + wrapper.unmount() + }) + + it('saves user info when save button is clicked', async () => { + wrapper.vm.email = 'newemail@example.com' + wrapper.vm.profilePictureBase64 = 'newBase64String' + + await wrapper.find('.save-button').trigger('click') + + expect(updateUserInfo).toHaveBeenCalledWith( + 'mockedToken', + 'newemail@example.com', + 'newBase64String' + ) + }) +}) diff --git a/src/components/__tests__/__snapshots__/BankAccountInfo.spec.ts.snap b/src/components/__tests__/__snapshots__/BankAccountInfo.spec.ts.snap new file mode 100644 index 0000000000000000000000000000000000000000..7501cf70f56288cd8cbfb48835ee3a1c1ab1419a --- /dev/null +++ b/src/components/__tests__/__snapshots__/BankAccountInfo.spec.ts.snap @@ -0,0 +1,23 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`AccountInfo.vue > renders correctly 1`] = ` +"<div data-v-d2243dda="" class="account-info"> + <div data-v-d2243dda="" class="header"> + <h3 data-v-d2243dda="" class="title">Konto opplysninger</h3><button data-v-d2243dda="" class="save-button"> + <h3 data-v-d2243dda="" class="save-button-title">Lagre</h3> + </button> + </div> + <div data-v-d2243dda="" class="input-fields"> + <div data-v-d2243dda="" class="input-collection"> + <h4 data-v-d2243dda="">Forbrukskonto: </h4><select data-v-d2243dda="" class="accounts"></select> + </div> + <div data-v-d2243dda="" class="input-collection"> + <h4 data-v-d2243dda="">Sparekonto: </h4><select data-v-d2243dda="" class="accounts"></select> + </div> + <div data-v-d2243dda="" class="alert-box"> + <!--v-if--> + <!--v-if--> + </div> + </div> +</div>" +`; diff --git a/src/components/profile/PasswordInfo.vue b/src/components/profile/PasswordInfo.vue index dff3599bed71b23e98712a462bb0daf84fd9226e..29dbbceb5ec22b7b014c0c79be4a6301d7de79a0 100644 --- a/src/components/profile/PasswordInfo.vue +++ b/src/components/profile/PasswordInfo.vue @@ -73,7 +73,8 @@ const clearInput = () => { <input class="input" :class="{'error': currentPasswordError}" type="password" - v-model="currentPassword"> + v-model="currentPassword" + data-testid="current-password-input"> <div class="alert-box"> <h4 v-if="currentPasswordError" class="error-message">{{currentPasswordError}}</h4> </div> @@ -84,7 +85,8 @@ const clearInput = () => { <input class="input" :class="{'error': newPasswordError}" type="password" - v-model="newPassword"> + v-model="newPassword" + data-testid="new-password-input"> <div class="alert-box"> <h4 v-if="newPasswordError" class="error-message">{{newPasswordError}}</h4> <h4 v-if="passwordError" class="error-message">{{passwordError}}</h4> diff --git a/src/views/FrontPage/LoginView.vue b/src/views/FrontPage/LoginView.vue index 97845e4e6e69d0098d49a33b570bd0a207543de9..f95861ec8541cdbcfc7856d31316c565824dd929 100644 --- a/src/views/FrontPage/LoginView.vue +++ b/src/views/FrontPage/LoginView.vue @@ -36,15 +36,22 @@ async function login() { <div id="LoginFields"> <div id="UserDiv"> <h2 id="Username">Brukernavn</h2> - <input id="NameField" placeholder="Skriv inn dit brukernavn" v-model="username"> + <input id="NameField" placeholder="Skriv inn dit brukernavn" v-model="username" data-testid="NameInput"> </div> <div id="PasswordDiv"> <h2 id="Password">Passord</h2> - <input id="PasswordField" type="password" placeholder="Skriv inn dit passord" v-model="password"> + <input id="PasswordField" type="password" placeholder="Skriv inn dit passord" v-model="password" data-testid="PasswordInput"> </div> </div> - <button id="LogInButton" @click="login" :disabled="!username || password.length < 8" :class="{ 'disabled-button': !username || password.length < 8 }">LogIn</button> - <h2 tabindex="0" @keyup.enter="navigateToNewUser()" @click="navigateToNewUser()" id="NewUser">Ny til Sparesti? Trykk her for å lage en profil!</h2> + + <button id="LogInButton" + @click="login" + :disabled="!username || password.length < 8" + :class="{ 'disabled-button': !username || password.length < 8 }" + data-testid="LogInButton"> + LogIn + </button> + <h2 tabindex="0" @keyup.enter="navigateToNewUser()" @click="navigateToNewUser()" id="NewUser" data-testid="NewUserLink">Ny til Sparesti? Trykk her for å lage en profil!</h2> </div> </template>