Skip to content

Commit

Permalink
Unit test for user settings menu
Browse files Browse the repository at this point in the history
  • Loading branch information
hiveer committed Dec 25, 2024
1 parent a45d4f2 commit 3734c04
Show file tree
Hide file tree
Showing 2 changed files with 187 additions and 65 deletions.
95 changes: 95 additions & 0 deletions frontend/src/components/__tests__/user_settings/Menu.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { describe, it, expect, beforeEach, vi, afterEach, afterAll } from 'vitest'
import { mount } from '@vue/test-utils'
import Menu from '../../user_settings/Menu.vue'

let userStoreData = {
username: 'test',
nickname: 'testn',
email: '[email protected]',
avatar: 'test_avatar.com'
}
vi.mock('../../../stores/UserStore', () => ({
default: () => (userStoreData)
}))

describe('Menu', () => {
let wrapper

beforeEach(() => {
vi.clearAllMocks()
wrapper = mount(Menu)
})

describe('Initial State', () => {
it('mounts with correct default props', () => {
expect(wrapper.exists()).toBe(true)
expect(wrapper.vm.hasSave).toBe(true)
})
})

describe('template render with email', () => {
it('renders access token navbar', () => {
const link = wrapper.find('a[href="/settings/access-token"]')
expect(link.exists()).toBe(true);
})
it('renders ssh key navbar', () => {
const link = wrapper.find('a[href="/settings/ssh-keys"]')
expect(link.exists()).toBe(true);
})
})

describe('template render without email', () => {
beforeEach(() => {
userStoreData = { username: 'test', nickname: 'testn', avatar: 'test_avatar.com' };
wrapper = mount(Menu)
})
it('renders access token navbar', async () => {
const link = wrapper.find('a[href="/settings/access-token"]')
expect(link.exists()).toBe(false);
})
it('renders ssh key navbar', () => {
const link = wrapper.find('a[href="/settings/ssh-keys"]')
expect(link.exists()).toBe(false);
})
})

describe('click on avatar to jump with saved true', () => {
it('jumps to user profile', async () => {
const avatarDiv = wrapper.find('#user_settings_avatar_div')
await avatarDiv.trigger('click')
expect(window.location.href).toBe(`/profile/${userStoreData.username}`)
})
})

describe('click on avatar to jump with saved false', () => {
beforeEach(() => {
wrapper = mount(Menu, {
props: {
hasSave: false
}
})
})

it('pops up confirm dialog', async () => {
const avatarDiv = wrapper.find('#user_settings_avatar_div')
await avatarDiv.trigger('click')
expect(wrapper.vm.showDialog).toBe(true)
})

it('hide dialog after click on cancel', async () => {
const avatarDiv = wrapper.find('#user_settings_avatar_div')
await avatarDiv.trigger('click')
const cancelBtn = wrapper.find('#user_settings_dialog_cancel')
await cancelBtn.trigger('click')
expect(wrapper.vm.showDialog).toBe(false)
})

it('jumps to user profile after click on confirm', async () => {
const avatarDiv = wrapper.find('#user_settings_avatar_div')
await avatarDiv.trigger('click')
const confirmBtn = wrapper.find('#user_settings_dialog_confirm')
await confirmBtn.trigger('click')
expect(window.location.href).toBe(`/profile/${userStoreData.username}`)
})
})
})
157 changes: 92 additions & 65 deletions frontend/src/components/user_settings/Menu.vue
Original file line number Diff line number Diff line change
@@ -1,76 +1,103 @@
<template>
<div class="pt-6">
<div class="w-[294px] rounded-md mx-[24px] md:w-full md:mx-0">
<div @click="clickProfile" class="flex p-[16px] cursor-pointer">
<el-avatar :size="60" :src="userStore.avatar"> </el-avatar>
<div class="ml-[10px]">
<div class="text-lg leading-[28px] font-semibold">
{{ userStore.nickname || userStore.username }}
</div>
<div class="text-md text-gray-500 leading-[24px] font-light">@{{ userStore.username }}</div>
<div class="pt-6">
<div class="w-[294px] rounded-md mx-[24px] md:w-full md:mx-0">
<div
@click="clickProfile"
class="flex p-[16px] cursor-pointer"
id="user_settings_avatar_div">
<el-avatar
:size="60"
:src="userStore.avatar">
</el-avatar>
<div class="ml-[10px]">
<div class="text-lg leading-[28px] font-semibold">
{{ userStore.nickname || userStore.username }}
</div>
<div class="text-md text-gray-500 leading-[24px] font-light">
@{{ userStore.username }}
</div>
</div>
<div class="flex flex-col md:hidden">
<!-- profile -->
<a href="/settings/profile"
class="p-[16px] hover:bg-gray-50 border-gray-200 text-md text-gray-500 leading-[24px] cursor-pointer"
:class="menuClass('/settings/profile')"
>
{{ $t('profile.accountSetting')}}
</a>

<!-- access token -->
<a v-if="hasEmail"
href="/settings/access-token"
class="p-[16px] hover:bg-gray-50 border-gray-200 text-md text-gray-500 leading-[24px] cursor-pointer"
:class="menuClass('/settings/access-token')"
>
{{ $t('profile.menu.gitToken')}}
</a>
</div>
<div class="flex flex-col md:hidden">
<!-- profile -->
<a
href="/settings/profile"
class="p-[16px] hover:bg-gray-50 border-gray-200 text-md text-gray-500 leading-[24px] cursor-pointer"
:class="menuClass('/settings/profile')">
{{ $t('profile.accountSetting') }}
</a>

<!-- ssh key -->
<a v-if="hasEmail"
href="/settings/ssh-keys"
class="p-[16px] hover:bg-gray-50 border-gray-200 text-md text-gray-500 leading-[24px] cursor-pointer"
:class="menuClass('/settings/ssh-keys')"
>
{{ $t('profile.menu.sshKey')}}
</a>
<!-- access token -->
<a
v-if="hasEmail"
href="/settings/access-token"
class="p-[16px] hover:bg-gray-50 border-gray-200 text-md text-gray-500 leading-[24px] cursor-pointer"
:class="menuClass('/settings/access-token')">
{{ $t('profile.menu.gitToken') }}
</a>

</div>
<!-- mobile tabs -->
<div class="profileTabs hidden md:block">
<el-tabs v-model="activeTab" @tabClick="handleTabClick">
<el-tab-pane :label="$t('profile.accountSetting')" name="/settings/profile"></el-tab-pane>
<el-tab-pane v-if="hasEmail" :label="$t('profile.menu.gitToken')" name="/settings/access-token"></el-tab-pane>
<el-tab-pane v-if="hasEmail" :label="$t('profile.menu.starshipAccessToken')" name="/settings/starship-access-token"></el-tab-pane>
<el-tab-pane v-if="hasEmail" :label="$t('profile.menu.syncAccessToken')" name="/settings/sync-access-token"></el-tab-pane>
<el-tab-pane v-if="hasEmail" :label="$t('profile.menu.sshKey')" name="/settings/ssh-keys"></el-tab-pane>
<!-- ssh key -->
<a
v-if="hasEmail"
href="/settings/ssh-keys"
class="p-[16px] hover:bg-gray-50 border-gray-200 text-md text-gray-500 leading-[24px] cursor-pointer"
:class="menuClass('/settings/ssh-keys')">
{{ $t('profile.menu.sshKey') }}
</a>
</div>
<!-- mobile tabs -->
<div class="profileTabs hidden md:block">
<el-tabs
v-model="activeTab"
@tabClick="handleTabClick">
<el-tab-pane
:label="$t('profile.accountSetting')"
name="/settings/profile"></el-tab-pane>
<el-tab-pane
v-if="hasEmail"
:label="$t('profile.menu.gitToken')"
name="/settings/access-token"></el-tab-pane>
<el-tab-pane
v-if="hasEmail"
:label="$t('profile.menu.sshKey')"
name="/settings/ssh-keys"></el-tab-pane>
</el-tabs>
</div>

</div>
</div>
<el-dialog
v-model="showDialog"
width="350"
:style="{ borderRadius: '10px' }"
>
<template #header>
{{ $t('profile.menu.warningTip') }}
</template>
<div class="flex justify-center flex-col m-auto w-full relative">
{{ $t('profile.menu.warningTipDesc') }}
</div>

<el-dialog
v-model="showDialog"
width="350"
:style="{ borderRadius: '10px' }">
<template #header>
{{ $t('profile.menu.warningTip') }}
</template>
<div class="flex justify-center flex-col m-auto w-full relative">
{{ $t('profile.menu.warningTipDesc') }}
</div>
<template #footer>
<div class="dialog-footer flex justify-between">
<el-button
id="user_settings_dialog_cancel"
class="flex-1 mr-3 text-gray-700"
size="large"
@click="showDialog = false"
>{{ $t('organization.members.cancel') }}</el-button
>
<el-button
id="user_settings_dialog_confirm"
class="flex-1"
size="large"
color="#3250BD"
type="primary"
:loading="loading"
@click="handleConfirm">
{{ $t('organization.members.confirm') }}
</el-button>
</div>
<template #footer>
<div class="dialog-footer flex justify-between">
<el-button class="flex-1 mr-3 text-gray-700" size="large" @click="showDialog = false">{{ $t('organization.members.cancel') }}</el-button>
<el-button class="flex-1" size="large" color="#3250BD" type="primary" :loading="loading" @click="handleConfirm">
{{ $t('organization.members.confirm') }}
</el-button>
</div>
</template>
</el-dialog>
</template>
</el-dialog>
</template>

<script setup>
Expand Down Expand Up @@ -116,7 +143,7 @@
}
</script>
<style>
.profileTabs .el-tabs__nav-scroll {
.profileTabs .el-tabs__nav-scroll {
@media screen and (max-width: 768px) {
padding-left: 0px !important;
}
Expand Down

0 comments on commit 3734c04

Please sign in to comment.