diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index bcb0d30c..08a3c2f9 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -37,6 +37,7 @@
"typescript": "~5.2.2",
"vite": "^4.3.9",
"vitest": "^0.32.4",
+ "vitest-fetch-mock": "^0.2.2",
"vue-cli-plugin-vuetify": "~2.5.8",
"vue-tsc": "^1.6.5"
}
@@ -3501,6 +3502,15 @@
"integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
"dev": true
},
+ "node_modules/cross-fetch": {
+ "version": "3.1.8",
+ "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz",
+ "integrity": "sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==",
+ "dev": true,
+ "dependencies": {
+ "node-fetch": "^2.6.12"
+ }
+ },
"node_modules/cross-spawn": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
@@ -6892,6 +6902,48 @@
"integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
"dev": true
},
+ "node_modules/node-fetch": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
+ "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
+ "dev": true,
+ "dependencies": {
+ "whatwg-url": "^5.0.0"
+ },
+ "engines": {
+ "node": "4.x || >=6.0.0"
+ },
+ "peerDependencies": {
+ "encoding": "^0.1.0"
+ },
+ "peerDependenciesMeta": {
+ "encoding": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/node-fetch/node_modules/tr46": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
+ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
+ "dev": true
+ },
+ "node_modules/node-fetch/node_modules/webidl-conversions": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
+ "dev": true
+ },
+ "node_modules/node-fetch/node_modules/whatwg-url": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
+ "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
+ "dev": true,
+ "dependencies": {
+ "tr46": "~0.0.3",
+ "webidl-conversions": "^3.0.0"
+ }
+ },
"node_modules/node-gyp": {
"version": "9.4.0",
"resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-9.4.0.tgz",
@@ -10417,6 +10469,21 @@
}
}
},
+ "node_modules/vitest-fetch-mock": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/vitest-fetch-mock/-/vitest-fetch-mock-0.2.2.tgz",
+ "integrity": "sha512-XmH6QgTSjCWrqXoPREIdbj40T7i1xnGmAsTAgfckoO75W1IEHKR8hcPCQ7SO16RsdW1t85oUm6pcQRLeBgjVYQ==",
+ "dev": true,
+ "dependencies": {
+ "cross-fetch": "^3.0.6"
+ },
+ "engines": {
+ "node": ">=14.14.0"
+ },
+ "peerDependencies": {
+ "vitest": ">=0.16.0"
+ }
+ },
"node_modules/vue": {
"version": "3.3.4",
"resolved": "https://registry.npmjs.org/vue/-/vue-3.3.4.tgz",
diff --git a/frontend/package.json b/frontend/package.json
index f840a8ae..53e94b77 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -43,6 +43,7 @@
"typescript": "~5.2.2",
"vite": "^4.3.9",
"vitest": "^0.32.4",
+ "vitest-fetch-mock": "^0.2.2",
"vue-cli-plugin-vuetify": "~2.5.8",
"vue-tsc": "^1.6.5"
}
diff --git a/frontend/src/components/HeaderDetailPage.vue b/frontend/src/components/HeaderDetailPage.vue
index 7c521099..f924913f 100644
--- a/frontend/src/components/HeaderDetailPage.vue
+++ b/frontend/src/components/HeaderDetailPage.vue
@@ -1,14 +1,14 @@
@@ -20,13 +20,13 @@
- About
- Contact
+ About
+ Contact
-
+
diff --git a/frontend/src/components/SearchBar.vue b/frontend/src/components/SearchBar.vue
index a1c7557c..a718c62b 100644
--- a/frontend/src/components/SearchBar.vue
+++ b/frontend/src/components/SearchBar.vue
@@ -40,7 +40,11 @@ const props = withDefaults(defineProps(), {
>
-
+
search
diff --git a/frontend/src/components/__tests__/HeaderDefault.spec.ts b/frontend/src/components/__tests__/HeaderDefault.spec.ts
index e6cfb70f..b409c194 100644
--- a/frontend/src/components/__tests__/HeaderDefault.spec.ts
+++ b/frontend/src/components/__tests__/HeaderDefault.spec.ts
@@ -1,48 +1,24 @@
-import { describe, it, expect } from 'vitest'
+import { describe, it, expect, vi } from 'vitest'
import { mount } from '@vue/test-utils'
import HeaderDefault from '../HeaderDefault.vue'
import { createVuetify } from 'vuetify'
import * as components from 'vuetify/components'
import * as directives from 'vuetify/directives'
+import { createRouter, createWebHistory } from 'vue-router'
+import { routes } from '@/router'
const vuetify = createVuetify({
components,
directives
})
-import { createRouter, createWebHistory } from 'vue-router'
-import HomeView from '@/views/HomeView.vue'
-import AboutView from '@/views/AboutView.vue'
-import ContactView from '@/views/ContactView.vue'
-import GeneDetailsView from '@/views/GeneDetailView.vue'
-
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
- routes: [
- {
- path: '/',
- name: 'home',
- component: HomeView
- },
- {
- path: '/about',
- name: 'about',
- component: AboutView
- },
- {
- path: '/contact',
- name: 'contact',
- component: ContactView
- },
- {
- path: '/gene/:searchTerm',
- name: 'gene',
- component: GeneDetailsView,
- props: (route) => ({ searchTerm: route.params.searchTerm })
- }
- ]
+ routes: routes
})
+// Mock router push
+router.push = vi.fn()
global.ResizeObserver = require('resize-observer-polyfill')
@@ -61,8 +37,11 @@ describe('HeaderDefault.vue', () => {
}
}
)
+
const logo = wrapper.find('#logo')
+ const title = wrapper.find('a[href="/"]')
expect(logo.exists()).toBe(true)
+ expect(title.text()).toBe('Explanation and Evaluation of Variants')
})
it('renders the navigation links', () => {
@@ -79,6 +58,7 @@ describe('HeaderDefault.vue', () => {
}
}
)
+
const aboutLink = wrapper.find('#about')
const contactLink = wrapper.find('#contact')
expect(aboutLink.exists()).toBe(true)
diff --git a/frontend/src/components/__tests__/HeaderDetailPage.spec.ts b/frontend/src/components/__tests__/HeaderDetailPage.spec.ts
index 43d2b507..9d360fbd 100644
--- a/frontend/src/components/__tests__/HeaderDetailPage.spec.ts
+++ b/frontend/src/components/__tests__/HeaderDetailPage.spec.ts
@@ -1,94 +1,90 @@
import { describe, expect, it, vi } from 'vitest'
-import { useRouter } from 'vue-router'
+import { mount } from '@vue/test-utils'
+import { createRouter, createWebHistory } from 'vue-router'
+import { routes } from '@/router'
import { createTestingPinia } from '@pinia/testing'
-import { mount, RouterLinkStub } from '@vue/test-utils'
import { useGeneInfoStore } from '@/stores/geneInfo'
import { createVuetify } from 'vuetify'
import * as components from 'vuetify/components'
import * as directives from 'vuetify/directives'
import HeaderDetailPage from '../HeaderDetailPage.vue'
+import { StoreState } from '@/stores/geneInfo'
-// const vuetify = createVuetify({
-// components,
-// directives,
-// })
+const vuetify = createVuetify({
+ components,
+ directives
+})
-// vi.mock('vue-router', () => ({
-// useRouter: () => ({
-// push: vi.fn()
-// })
-// }))
+const router = createRouter({
+ history: createWebHistory(import.meta.env.BASE_URL),
+ routes: routes
+})
+// Mock router push
+router.push = vi.fn()
-// const makeWrapper = (geneData = {}) => {
-// return mount(HeaderDetailPage, {
-// // shallow: true,
-// global: {
-// plugins: [
-// vuetify,
-// // createTestingPinia({
-// // initialState: { data: geneData },
-// // createSpy: vi.fn()
-// // })
-// ]
-// }
-// })
-// }
+global.ResizeObserver = require('resize-observer-polyfill')
describe('HeaderDetailPage', async () => {
- const vuetify = createVuetify({
- components,
- directives
- })
+ it('renders the gene symbol and nav links', () => {
+ const geneData = {
+ storeState: 'active',
+ geneSymbol: 'BRCA1',
+ geneInfo: {
+ symbol: 'BRCA1',
+ name: 'Test Gene',
+ hgncId: '12345',
+ ensemblId: 'ENSG00000000000001',
+ entrezId: '12345'
+ }
+ }
- // vi.mock('vue-router', () => ({
- // useRouter: () => ({
- // push: vi.fn()
- // })
- // }))
+ const wrapper = mount(
+ {
+ template: ''
+ },
+ {
+ global: {
+ plugins: [vuetify, router, createTestingPinia({ createSpy: vi.fn() })],
+ components: {
+ HeaderDetailPage
+ }
+ }
+ }
+ )
- // it('renders the gene symbol and nav links', () => {
- // const geneData = {
- // geneSymbol: 'BRCA1',
- // geneInfo: {
- // symbol: 'BRCA1',
- // name: 'Test Gene',
- // hgncId: '12345',
- // ensemblId: 'ENSG00000000000001',
- // entrezId: '12345'
- // }
- // }
+ const store = useGeneInfoStore()
+ store.storeState = StoreState.Active
+ store.geneSymbol = geneData.geneSymbol
+ store.geneInfo = JSON.parse(JSON.stringify(geneData.geneInfo))
- // const wrapper = makeWrapper(geneData)
- // const store = useGeneInfoStore()
- // const logo = wrapper.find('#logo')
- // const aboutLink = wrapper.find('v-btn[to="/about"]')
- // const contactLink = wrapper.find('v-btn[to="/contact"]')
- // expect(logo.exists()).toBe(true)
- // expect(aboutLink.exists()).toBe(true)
- // expect(contactLink.exists()).toBe(true)
- // })
+ const logo = wrapper.find('#logo')
+ const aboutLink = wrapper.find('#about')
+ const contactLink = wrapper.find('#contact')
+ expect(logo.exists()).toBe(true)
+ expect(aboutLink.exists()).toBe(true)
+ expect(contactLink.exists()).toBe(true)
+ })
it('redirects if gene data is null', async () => {
- // const geneData = {geneSymbol: '', geneInfo: null}
- // const wrapper = makeWrapper(geneData)
+ const store = useGeneInfoStore()
+ store.storeState = StoreState.Initial
+ store.geneSymbol = null
+ store.geneInfo = null
+
const wrapper = mount(
{
- template: ''
+ template: ''
},
{
global: {
- plugins: [vuetify],
+ plugins: [vuetify, router, createTestingPinia({ createSpy: vi.fn() })],
components: {
HeaderDetailPage
- },
- stubs: {
- RouterLink: RouterLinkStub
}
}
}
)
- console.log(wrapper.html())
- // const router = useRouter()
- // expect(router.push).toHaveBeenCalled()
+
+ expect(router.push).toHaveBeenCalled()
})
})
diff --git a/frontend/src/components/__tests__/SearchBar.spec.ts b/frontend/src/components/__tests__/SearchBar.spec.ts
index 9b485793..e70f9985 100644
--- a/frontend/src/components/__tests__/SearchBar.spec.ts
+++ b/frontend/src/components/__tests__/SearchBar.spec.ts
@@ -1,47 +1,53 @@
-import { describe, it, expect } from 'vitest'
-
+import { describe, it, expect, vi } from 'vitest'
import { mount } from '@vue/test-utils'
+import { createRouter, createWebHistory } from 'vue-router'
+import { routes } from '@/router'
+import { createVuetify } from 'vuetify'
+import * as components from 'vuetify/components'
+import * as directives from 'vuetify/directives'
import SearchBar from '../SearchBar.vue'
+const vuetify = createVuetify({
+ components,
+ directives
+})
+
+const router = createRouter({
+ history: createWebHistory(import.meta.env.BASE_URL),
+ routes: routes
+})
+// Mock router push
+router.push = vi.fn()
+
+global.ResizeObserver = require('resize-observer-polyfill')
+
describe('SearchBar.vue', () => {
it('renders the search bar with the correct default props', () => {
- const wrapper = mount(SearchBar)
- const textField = wrapper.find('v-text-field')
- const select = wrapper.find('v-select')
- const searchButton = wrapper.find('v-btn')
+ const wrapper = mount(
+ {
+ template: ''
+ },
+ {
+ global: {
+ plugins: [vuetify, router],
+ components: {
+ SearchBar
+ }
+ }
+ }
+ )
+
+ const textField = wrapper.find('.v-text-field')
+ const select = wrapper.find('.v-select')
+ const searchButton = wrapper.find('#search')
expect(textField.exists()).toBe(true)
expect(select.exists()).toBe(true)
expect(searchButton.exists()).toBe(true)
- expect(textField.attributes('label')).toMatch('Enter search term')
- expect(select.attributes('label')).toMatch('Genome Release')
- expect(select.attributes('item-title')).toMatch('label')
- expect(select.attributes('item-value')).toMatch('value')
- expect(select.attributes('model-value')).toMatch('grch37')
- expect(searchButton.text()).toMatch('search')
- })
-
- it.skip('emits events correctly', () => {
- const wrapper = mount(SearchBar)
- const textField = wrapper.find('v-text-field')
- const select = wrapper.find('v-select')
- const searchButton = wrapper.find('v-btn')
-
- // Simulate input in the text field and check if event is emitted
- textField.setValue('sample term')
- textField.trigger('input')
- expect(wrapper.emitted('update:searchTerm')).toBeTruthy()
- expect(wrapper.emitted('update:searchTerm')![0][0]).toBe('sample term')
-
- // Simulate selecting an option in the select component and check if event is emitted
- select.setValue('grch38')
- select.trigger('update:model-value', 'grch38')
- expect(wrapper.emitted('update:genomeRelease')).toBeTruthy()
- expect(wrapper.emitted('update:genomeRelease')![0][0]).toBe('grch38')
-
- // Simulate clicking the search button and check if event is emitted
- searchButton.trigger('click')
- expect(wrapper.emitted('clickSearch')).toBeTruthy()
- expect(wrapper.emitted('clickSearch')![0][0]).toBe('sample term')
- expect(wrapper.emitted('clickSearch')![0][1]).toBe('grch38')
+ expect(textField.html()).toMatch('Enter search term')
+ expect(select.html()).toMatch('Genome Release')
+ expect(select.html()).toMatch('label')
+ expect(select.html()).toMatch('value')
+ expect(select.html()).toMatch('GRCh37')
+ expect(searchButton.html()).toMatch('search')
})
})
diff --git a/frontend/src/router/index.ts b/frontend/src/router/index.ts
index dd2a2120..6bedcd75 100644
--- a/frontend/src/router/index.ts
+++ b/frontend/src/router/index.ts
@@ -5,31 +5,35 @@ import AboutView from '@/views/AboutView.vue'
import ContactView from '@/views/ContactView.vue'
import GeneDetailsView from '@/views/GeneDetailView.vue'
+const routes = [
+ {
+ path: '/',
+ name: 'home',
+ component: HomeView
+ },
+ {
+ path: '/about',
+ name: 'about',
+ component: AboutView
+ },
+ {
+ path: '/contact',
+ name: 'contact',
+ component: ContactView
+ },
+ {
+ path: '/gene/:searchTerm',
+ name: 'gene',
+ component: GeneDetailsView,
+ props: (route) => ({ searchTerm: route.params.searchTerm })
+ }
+]
+
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
- routes: [
- {
- path: '/',
- name: 'home',
- component: HomeView
- },
- {
- path: '/about',
- name: 'about',
- component: AboutView
- },
- {
- path: '/contact',
- name: 'contact',
- component: ContactView
- },
- {
- path: '/gene/:searchTerm',
- name: 'gene',
- component: GeneDetailsView,
- props: (route) => ({ searchTerm: route.params.searchTerm })
- }
- ]
+ routes
})
+export { routes }
+
export default router
diff --git a/frontend/src/stores/__tests__/geneInfo.spec.ts b/frontend/src/stores/__tests__/geneInfo.spec.ts
index bd6dfd16..a50db4b5 100644
--- a/frontend/src/stores/__tests__/geneInfo.spec.ts
+++ b/frontend/src/stores/__tests__/geneInfo.spec.ts
@@ -1,24 +1,15 @@
import { beforeEach, describe, it, expect, vi } from 'vitest'
import { setActivePinia, createPinia } from 'pinia'
import { useGeneInfoStore, StoreState } from '../geneInfo'
+import createFetchMock from 'vitest-fetch-mock'
-const mockFetchGeneInfo = (hgncId: string) => {
- expect(hgncId).toBe('BRCA1')
- return Promise.resolve({ gene: 'info' })
-}
-
-class MockAnnonarsClient {
- fetchGeneInfo = mockFetchGeneInfo
-}
-
-// vi.mock('@/api/annonars', () => ({
-// const Client = vi.fn().mockImplementation(MockAnnonarsClient)
-// return { Client }
-// }))
+const fetchMocker = createFetchMock(vi)
describe('geneInfo Store', () => {
beforeEach(() => {
setActivePinia(createPinia())
+ fetchMocker.enableMocks()
+ fetchMocker.resetMocks()
})
it('should have initial state', () => {
@@ -29,22 +20,22 @@ describe('geneInfo Store', () => {
expect(store.geneInfo).toBe(null)
})
- it.skip('should clear state', () => {
+ it('should clear state', () => {
const store = useGeneInfoStore()
-
store.storeState = StoreState.Active
store.geneSymbol = 'BRCA1'
- store.geneInfo = { gene: 'info' }
+ store.geneInfo = JSON.parse(JSON.stringify({ gene: 'info' }))
- store.$clear()
+ store.clearData()
expect(store.storeState).toBe(StoreState.Initial)
expect(store.geneSymbol).toBe(null)
expect(store.geneInfo).toBe(null)
})
- it.skip('should load data', async () => {
+ it('should load data', async () => {
const store = useGeneInfoStore()
+ fetchMocker.mockResponseOnce(JSON.stringify({ genes: { BRCA1: { gene: 'info' } } }))
await store.loadData('BRCA1')
@@ -54,33 +45,30 @@ describe('geneInfo Store', () => {
})
it('should fail to load data with invalid request', async () => {
+ // Disable error logging
+ vi.spyOn(console, 'error').mockImplementation(vi.fn())
const store = useGeneInfoStore()
+ fetchMocker.mockResponseOnce(JSON.stringify({ foo: 'bar' }), { status: 400 })
- await store.loadData('123')
+ await store.loadData('invalid')
expect(store.storeState).toBe(StoreState.Error)
expect(store.geneSymbol).toBe(null)
expect(store.geneInfo).toBe(null)
})
- it.skip('should not load data if gene symbol is the same', async () => {
+ it('should not load data if gene symbol is the same', async () => {
const store = useGeneInfoStore()
-
- const mockFetch = (url: string, options: any) => {
- expect(url).toBe('/proxy/annonars/genes/info?hgnc-id=BRCA1')
- expect(options.method).toBe('GET')
- return Promise.resolve({
- json: () => Promise.resolve({ gene: 'info' })
- })
- }
-
- globalThis.fetch = mockFetch
+ fetchMocker.mockResponse(JSON.stringify({ genes: { BRCA1: { gene: 'info' } } }))
- await store.loadData('BRCA1')
await store.loadData('BRCA1')
expect(store.storeState).toBe(StoreState.Active)
expect(store.geneSymbol).toBe('BRCA1')
expect(store.geneInfo).toEqual({ gene: 'info' })
+
+ await store.loadData('BRCA1')
+
+ expect(fetchMocker.mock.calls.length).toBe(1)
})
})
diff --git a/frontend/src/stores/geneInfo.ts b/frontend/src/stores/geneInfo.ts
index 736e4646..5c5ee8c0 100644
--- a/frontend/src/stores/geneInfo.ts
+++ b/frontend/src/stores/geneInfo.ts
@@ -30,7 +30,7 @@ export const useGeneInfoStore = defineStore('geneInfo', () => {
geneInfo.value = JSON.parse(localStorage.getItem('geneInfo')!)
}
- const $clear = () => {
+ function clearData() {
storeState.value = StoreState.Initial
geneSymbol.value = null
geneInfo.value = null
@@ -43,7 +43,7 @@ export const useGeneInfoStore = defineStore('geneInfo', () => {
}
// Clear against artifact
- $clear()
+ clearData()
// Load data via API
storeState.value = StoreState.Loading
@@ -65,6 +65,7 @@ export const useGeneInfoStore = defineStore('geneInfo', () => {
storeState,
geneSymbol,
geneInfo,
- loadData
+ loadData,
+ clearData
}
})
diff --git a/frontend/src/views/__tests__/AboutView.spec.ts b/frontend/src/views/__tests__/AboutView.spec.ts
index 59d294e2..c11acc74 100644
--- a/frontend/src/views/__tests__/AboutView.spec.ts
+++ b/frontend/src/views/__tests__/AboutView.spec.ts
@@ -1,8 +1,67 @@
-import { describe, it } from 'vitest'
-
+import { describe, expect, it, vi } from 'vitest'
import { mount } from '@vue/test-utils'
+import { createRouter, createWebHistory } from 'vue-router'
+import { routes } from '@/router'
+import { createVuetify } from 'vuetify'
+import * as components from 'vuetify/components'
+import * as directives from 'vuetify/directives'
import AboutView from '../AboutView.vue'
-describe('AboutView.vue', () => {
- it.todo('renders the about page')
+const vuetify = createVuetify({
+ components,
+ directives
+})
+
+const router = createRouter({
+ history: createWebHistory(import.meta.env.BASE_URL),
+ routes: routes
+})
+// Mock router push
+router.push = vi.fn()
+
+global.ResizeObserver = require('resize-observer-polyfill')
+
+describe('AboutView', async () => {
+ it('renders the header', () => {
+ const wrapper = mount(
+ {
+ template: ''
+ },
+ {
+ global: {
+ plugins: [vuetify, router],
+ components: {
+ AboutView
+ }
+ }
+ }
+ )
+
+ const logo = wrapper.find('#logo')
+ const aboutLink = wrapper.find('#about')
+ const contactLink = wrapper.find('#contact')
+ expect(logo.exists()).toBe(true)
+ expect(aboutLink.exists()).toBe(true)
+ expect(contactLink.exists()).toBe(true)
+ })
+
+ it('renders the main content', () => {
+ const wrapper = mount(
+ {
+ template: ''
+ },
+ {
+ global: {
+ plugins: [vuetify, router],
+ components: {
+ AboutView
+ }
+ }
+ }
+ )
+
+ const mainContent = wrapper.find('.about-view')
+ expect(mainContent.exists()).toBe(true)
+ expect(mainContent.html()).toMatch('REEV: Explanation and Evaluation of Variants')
+ })
})
diff --git a/frontend/src/views/__tests__/ContactView.spec.ts b/frontend/src/views/__tests__/ContactView.spec.ts
index aa41151b..3d84fe80 100644
--- a/frontend/src/views/__tests__/ContactView.spec.ts
+++ b/frontend/src/views/__tests__/ContactView.spec.ts
@@ -1,8 +1,73 @@
-import { describe, it } from 'vitest'
-
+import { describe, expect, it, vi } from 'vitest'
import { mount } from '@vue/test-utils'
+import { createRouter, createWebHistory } from 'vue-router'
+import { routes } from '@/router'
+import { createVuetify } from 'vuetify'
+import * as components from 'vuetify/components'
+import * as directives from 'vuetify/directives'
import ContactView from '../ContactView.vue'
-describe('ContactView.vue', () => {
- it.todo('renders the contact page')
+const vuetify = createVuetify({
+ components,
+ directives
+})
+
+const router = createRouter({
+ history: createWebHistory(import.meta.env.BASE_URL),
+ routes: routes
+})
+// Mock router push
+router.push = vi.fn()
+
+global.ResizeObserver = require('resize-observer-polyfill')
+
+describe('ContactView', async () => {
+ it('renders the header', () => {
+ const wrapper = mount(
+ {
+ template: ''
+ },
+ {
+ global: {
+ plugins: [vuetify, router],
+ components: {
+ ContactView
+ }
+ }
+ }
+ )
+
+ const logo = wrapper.find('#logo')
+ const aboutLink = wrapper.find('#about')
+ const contactLink = wrapper.find('#contact')
+ expect(logo.exists()).toBe(true)
+ expect(aboutLink.exists()).toBe(true)
+ expect(contactLink.exists()).toBe(true)
+ })
+
+ it('renders the main content', () => {
+ const wrapper = mount(
+ {
+ template: ''
+ },
+ {
+ global: {
+ plugins: [vuetify, router],
+ components: {
+ ContactView
+ }
+ }
+ }
+ )
+
+ const mainContent = wrapper.find('.contact-view')
+ const githubLink = wrapper.find('.mdi-github')
+ const emailLink = wrapper.find('.mdi-email')
+ expect(mainContent.exists()).toBe(true)
+ expect(mainContent.html()).toMatch(
+ 'Feel free to reach out to us through any of the following channels:'
+ )
+ expect(githubLink.exists()).toBe(true)
+ expect(emailLink.exists()).toBe(true)
+ })
})
diff --git a/frontend/src/views/__tests__/GeneDetailView.spec.ts b/frontend/src/views/__tests__/GeneDetailView.spec.ts
new file mode 100644
index 00000000..590a2662
--- /dev/null
+++ b/frontend/src/views/__tests__/GeneDetailView.spec.ts
@@ -0,0 +1,115 @@
+import { describe, expect, it, vi } from 'vitest'
+import { mount } from '@vue/test-utils'
+import { createRouter, createWebHistory } from 'vue-router'
+import { routes } from '@/router'
+import { createTestingPinia } from '@pinia/testing'
+import { useGeneInfoStore } from '@/stores/geneInfo'
+import { createVuetify } from 'vuetify'
+import * as components from 'vuetify/components'
+import * as directives from 'vuetify/directives'
+import GeneDetailView from '../GeneDetailView.vue'
+import { StoreState } from '@/stores/geneInfo'
+import { before, beforeEach } from 'node:test'
+
+const vuetify = createVuetify({
+ components,
+ directives
+})
+
+const router = createRouter({
+ history: createWebHistory(import.meta.env.BASE_URL),
+ routes: routes
+})
+// Mock router push
+router.push = vi.fn()
+
+global.ResizeObserver = require('resize-observer-polyfill')
+
+describe('GeneDetailView', async () => {
+ beforeEach(() => {
+ createTestingPinia({ createSpy: vi.fn() })
+ })
+ it.skip('renders the header', () => {
+ const geneData = {
+ storeState: 'active',
+ geneSymbol: 'BRCA1',
+ geneInfo: {
+ genes: {
+ BRCA1: {
+ symbol: 'BRCA1',
+ name: 'Test Gene',
+ hgncId: '12345',
+ ensemblId: 'ENSG00000000000001',
+ entrezId: '12345'
+ }
+ }
+ }
+ }
+
+ const store = useGeneInfoStore()
+ store.storeState = StoreState.Active
+ store.geneSymbol = geneData.geneSymbol
+ store.geneInfo = JSON.parse(JSON.stringify(geneData.geneInfo))
+
+ const wrapper = mount(
+ {
+ template: ''
+ },
+ {
+ global: {
+ plugins: [vuetify, router, createTestingPinia({ createSpy: vi.fn() })],
+ components: {
+ GeneDetailView
+ }
+ }
+ }
+ )
+
+ const logo = wrapper.find('#logo')
+ const aboutLink = wrapper.find('#about')
+ const contactLink = wrapper.find('#contact')
+ expect(logo.exists()).toBe(true)
+ expect(aboutLink.exists()).toBe(true)
+ expect(contactLink.exists()).toBe(true)
+ })
+
+ it.skip('renders the search bar', () => {
+ const geneData = {
+ storeState: 'active',
+ geneSymbol: 'BRCA1',
+ geneInfo: {
+ symbol: 'BRCA1',
+ name: 'Test Gene',
+ hgncId: '12345',
+ ensemblId: 'ENSG00000000000001',
+ entrezId: '12345'
+ }
+ }
+
+ const wrapper = mount(
+ {
+ template: ''
+ },
+ {
+ global: {
+ plugins: [vuetify, router, createTestingPinia({ createSpy: vi.fn() })],
+ components: {
+ GeneDetailView
+ }
+ }
+ }
+ )
+
+ const store = useGeneInfoStore()
+ store.storeState = StoreState.Active
+ store.geneSymbol = geneData.geneSymbol
+ store.geneInfo = JSON.parse(JSON.stringify(geneData.geneInfo))
+
+ const textField = wrapper.find('.v-text-field')
+ const select = wrapper.find('.v-select')
+ const searchButton = wrapper.find('#search')
+ expect(textField.exists()).toBe(true)
+ expect(select.exists()).toBe(true)
+ expect(searchButton.exists()).toBe(true)
+ })
+})
diff --git a/frontend/src/views/__tests__/HomeView.spec.ts b/frontend/src/views/__tests__/HomeView.spec.ts
index 92e1e214..8a863b5f 100644
--- a/frontend/src/views/__tests__/HomeView.spec.ts
+++ b/frontend/src/views/__tests__/HomeView.spec.ts
@@ -1,8 +1,107 @@
-import { describe, it } from 'vitest'
-
+import { describe, expect, it, vi } from 'vitest'
import { mount } from '@vue/test-utils'
+import { createRouter, createWebHistory } from 'vue-router'
+import { routes } from '@/router'
+import { createTestingPinia } from '@pinia/testing'
+import { useGeneInfoStore } from '@/stores/geneInfo'
+import { createVuetify } from 'vuetify'
+import * as components from 'vuetify/components'
+import * as directives from 'vuetify/directives'
import HomeView from '../HomeView.vue'
+import { StoreState } from '@/stores/geneInfo'
+
+const vuetify = createVuetify({
+ components,
+ directives
+})
+
+const router = createRouter({
+ history: createWebHistory(import.meta.env.BASE_URL),
+ routes: routes
+})
+// Mock router push
+router.push = vi.fn()
+
+global.ResizeObserver = require('resize-observer-polyfill')
+
+describe('HomeView', async () => {
+ it('renders the header', () => {
+ const geneData = {
+ storeState: 'active',
+ geneSymbol: 'BRCA1',
+ geneInfo: {
+ symbol: 'BRCA1',
+ name: 'Test Gene',
+ hgncId: '12345',
+ ensemblId: 'ENSG00000000000001',
+ entrezId: '12345'
+ }
+ }
+
+ const wrapper = mount(
+ {
+ template: ''
+ },
+ {
+ global: {
+ plugins: [vuetify, router, createTestingPinia({ createSpy: vi.fn() })],
+ components: {
+ HomeView
+ }
+ }
+ }
+ )
+
+ const store = useGeneInfoStore()
+ store.storeState = StoreState.Active
+ store.geneSymbol = geneData.geneSymbol
+ store.geneInfo = JSON.parse(JSON.stringify(geneData.geneInfo))
+
+ const logo = wrapper.find('#logo')
+ const aboutLink = wrapper.find('#about')
+ const contactLink = wrapper.find('#contact')
+ expect(logo.exists()).toBe(true)
+ expect(aboutLink.exists()).toBe(true)
+ expect(contactLink.exists()).toBe(true)
+ })
+
+ it('renders the search bar', () => {
+ const geneData = {
+ storeState: 'active',
+ geneSymbol: 'BRCA1',
+ geneInfo: {
+ symbol: 'BRCA1',
+ name: 'Test Gene',
+ hgncId: '12345',
+ ensemblId: 'ENSG00000000000001',
+ entrezId: '12345'
+ }
+ }
+
+ const wrapper = mount(
+ {
+ template: ''
+ },
+ {
+ global: {
+ plugins: [vuetify, router, createTestingPinia({ createSpy: vi.fn() })],
+ components: {
+ HomeView
+ }
+ }
+ }
+ )
+
+ const store = useGeneInfoStore()
+ store.storeState = StoreState.Active
+ store.geneSymbol = geneData.geneSymbol
+ store.geneInfo = JSON.parse(JSON.stringify(geneData.geneInfo))
-describe('HomeView.vue', () => {
- it.todo('renders the home page')
+ const textField = wrapper.find('.v-text-field')
+ const select = wrapper.find('.v-select')
+ const searchButton = wrapper.find('#search')
+ expect(textField.exists()).toBe(true)
+ expect(select.exists()).toBe(true)
+ expect(searchButton.exists()).toBe(true)
+ })
})
diff --git a/frontend/vitest.config.ts b/frontend/vitest.config.ts
index 17ae9bca..404b305b 100644
--- a/frontend/vitest.config.ts
+++ b/frontend/vitest.config.ts
@@ -22,7 +22,3 @@ export default mergeConfig(
}
})
)
-// "vite-plugin-vuetify": "^1.0.2",
-
-// "vite": "^4.4.9",
-// "vitest": "^0.34.3"