Skip to content

Commit

Permalink
chore: Various test updates (#38) (#45)
Browse files Browse the repository at this point in the history
  • Loading branch information
gromdimon authored Sep 7, 2023
1 parent d5838f8 commit cc378b8
Show file tree
Hide file tree
Showing 18 changed files with 370 additions and 41 deletions.
13 changes: 13 additions & 0 deletions frontend/src/api/__tests__/annonars.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,19 @@ describe.concurrent('Annonars Client', () => {
expect(JSON.stringify(result)).toEqual(JSON.stringify(BRCA1VariantInfo))
})

it('do removes chr prefix from chromosome if genome release is grch38', async () => {
fetchMocker.mockResponse((req) => {
if (req.url.includes('chr')) {
return Promise.resolve(JSON.stringify(BRCA1VariantInfo))
}
return Promise.resolve(JSON.stringify({ status: 400 }))
})

const client = new AnnonarsClient()
const result = await client.fetchVariantInfo('grch38', 'chr17', 43044295, 'A', 'G')
expect(JSON.stringify(result)).toEqual(JSON.stringify(BRCA1VariantInfo))
})

it('fails to fetch variant info with wrong variant', async () => {
fetchMocker.mockResponse((req) => {
if (req.url.includes('alternative=G')) {
Expand Down
5 changes: 5 additions & 0 deletions frontend/src/api/__tests__/utils.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ describe('separateIt method', () => {
const result = separateIt(123456789.12345)
expect(result).toBe(' 123 456 789 ')
})

it('should handle values less then 0', () => {
const result = separateIt(0.0134)
expect(result).toBe('0 ')
})
})

describe('isVariantMt method', () => {
Expand Down
18 changes: 10 additions & 8 deletions frontend/src/components/VariantDetails/VariantValidator.vue
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ const activeIdentifier = ref<string>('')
<tbody>
<tr
v-if="
data.primary_assembly_loci &&
data.primary_assembly_loci.grch37 &&
data.primary_assembly_loci.grch37.hgvs_genomic_description
"
Expand All @@ -153,15 +154,16 @@ const activeIdentifier = ref<string>('')
{{ data.primary_assembly_loci.grch37.hgvs_genomic_description }}
</td>
<td>
GRCh37:{{ data.primary_assembly_loci.grch37.vcf.chr }}:{{
data.primary_assembly_loci.grch37.vcf.pos
}}:{{ data.primary_assembly_loci.grch37.vcf.ref }}:{{
data.primary_assembly_loci.grch37.vcf.alt
GRCh37:{{ data.primary_assembly_loci.grch37?.vcf?.chr }}:{{
data.primary_assembly_loci.grch37?.vcf?.pos
}}:{{ data.primary_assembly_loci.grch37?.vcf?.ref }}:{{
data.primary_assembly_loci.grch37?.vcf?.alt
}}
</td>
</tr>
<tr
v-if="
data.primary_assembly_loci &&
data.primary_assembly_loci.grch38 &&
data.primary_assembly_loci.grch38.hgvs_genomic_description
"
Expand All @@ -170,10 +172,10 @@ const activeIdentifier = ref<string>('')
{{ data.primary_assembly_loci.grch38.hgvs_genomic_description }}
</td>
<td>
GRCh38:{{ data.primary_assembly_loci.grch38.vcf.chr }}:{{
data.primary_assembly_loci.grch38.vcf.pos
}}:{{ data.primary_assembly_loci.grch38.vcf.ref }}:{{
data.primary_assembly_loci.grch38.vcf.alt
GRCh38:{{ data.primary_assembly_loci.grch38?.vcf?.chr }}:{{
data.primary_assembly_loci.grch38?.vcf?.pos
}}:{{ data.primary_assembly_loci.grch38?.vcf?.ref }}:{{
data.primary_assembly_loci.grch38?.vcf?.alt
}}
</td>
</tr>
Expand Down
16 changes: 14 additions & 2 deletions frontend/src/components/__tests__/ClinVar.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,20 @@ describe.concurrent('ClinVar', async () => {
const wrapper = makeWrapper(clinVarInfo)
expect(wrapper.text()).toContain('Note that REEV is using a local copy of Clinvar')
expect(wrapper.text()).toContain('VCV000041833')
const starts = wrapper.findAll('.mdi-star-outline')
expect(starts.length).toBe(5)
const starsOutline = wrapper.findAll('.mdi-star-outline')
expect(starsOutline.length).toBe(5)
})

it('renders the ClinVar info with stars', async () => {
const clinVarInfoStars = structuredClone(clinVarInfo)
clinVarInfoStars.summary_clinvar_gold_stars = 3
const wrapper = makeWrapper(clinVarInfoStars)
expect(wrapper.text()).toContain('Note that REEV is using a local copy of Clinvar')
expect(wrapper.text()).toContain('VCV000041833')
const stars = wrapper.findAll('.mdi-star-outline')
expect(stars.length).toBe(2)
const starsOutline = wrapper.findAll('.mdi-star-outline')
expect(starsOutline.length).toBe(2)
})

it('renders the ClinVar info (not found)', async () => {
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/components/__tests__/FreqsAutosomal.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const smallVariantInfo = {
hgnc_id: 'HGNC:1100'
}

const makeWrapper = (variantData: Object) => {
const makeWrapper = (variantData: Object | null) => {
return mount(FreqsAutosomal, {
props: {
smallVar: smallVariantInfo,
Expand All @@ -59,7 +59,7 @@ describe.concurrent('FreqsAutosomal', async () => {
})

it('renders the FreqsAutosomal info with no data', async () => {
const wrapper = makeWrapper({})
const wrapper = makeWrapper(null)
expect(wrapper.text()).toContain('gnomAD Genomes')
expect(wrapper.text()).toContain('No allele frequency information available in local database.')
})
Expand Down
33 changes: 30 additions & 3 deletions frontend/src/components/__tests__/FreqsMitochondrial.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,11 @@ const variantInfo = {
}
}

const makeWrapper = () => {
const makeWrapper = (variantData: Object) => {
return mount(FreqsMitochondrial, {
props: {
smallVar: smallVariantInfo,
varAnnos: variantInfo
varAnnos: variantData
},
global: {
plugins: [vuetify, router, createTestingPinia({ createSpy: vi.fn() })],
Expand All @@ -69,10 +69,37 @@ const makeWrapper = () => {

describe.concurrent('FreqsMitochondrial', async () => {
it('renders the FreqsMitochondrial info', async () => {
const wrapper = makeWrapper()
const wrapper = makeWrapper(variantInfo)
expect(wrapper.html()).toContain('HelixMTdb')
expect(wrapper.html()).toContain('gnomAD-MT')
const table = wrapper.find('table')
expect(table.exists()).toBe(true)
})

it('renders the FreqsMitochondrial info with no helixmtdb', async () => {
const variantInfoNoHelixmtdb: any = structuredClone(variantInfo)
variantInfoNoHelixmtdb.helixmtdb = {}
const wrapper = makeWrapper(variantInfoNoHelixmtdb)
expect(wrapper.html()).toContain('HelixMTdb')
expect(wrapper.html()).toContain('gnomAD-MT')
const table = wrapper.find('table')
expect(table.exists()).toBe(true)
})

it('renders the FreqsMitochondrial info with no gnomad-mtdna', async () => {
const variantInfoNoGnomad: any = structuredClone(variantInfo)
variantInfoNoGnomad['gnomad-mtdna'] = {}
const wrapper = makeWrapper(variantInfoNoGnomad)
expect(wrapper.html()).toContain('HelixMTdb')
expect(wrapper.html()).toContain('gnomAD-MT')
const table = wrapper.find('table')
expect(table.exists()).toBe(true)
})

it.skip('renders the FreqsMitochondrial info with invalid data', async () => {
const wrapper = makeWrapper(smallVariantInfo)
console.log(wrapper.html())
const alertIcon = wrapper.find('.mdi-alert-circle-outline')
expect(alertIcon.exists()).toBe(true)
})
})
22 changes: 19 additions & 3 deletions frontend/src/components/__tests__/VariantFreqs.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import * as directives from 'vuetify/directives'

import VariantFreqs from '@/components/VariantDetails/VariantFreqs.vue'
import VariantDetailsFreqsAutosomal from '@/components/VariantDetails/FreqsAutosomal.vue'
import VariantDetailsFreqsMitochondrial from '@/components/VariantDetails/FreqsMitochondrial.vue'
import * as BRCA1VariantInfo from '@/assets/__tests__/BRCA1VariantInfo.json'

const vuetify = createVuetify({
Expand All @@ -35,10 +36,19 @@ const smallVariantInfo = {
hgnc_id: 'HGNC:1100'
}

const makeWrapper = () => {
const smallVariantInfoMitochondrial = {
release: 'grch37',
chromosome: 'chrM',
start: '70',
end: '70',
reference: 'G',
alternative: 'A',
hgnc_id: 'HGNC:1100'
}
const makeWrapper = (variantInfo: Object) => {
return mount(VariantFreqs, {
props: {
smallVar: smallVariantInfo,
smallVar: variantInfo,
varAnnos: BRCA1VariantInfo
},
global: {
Expand All @@ -52,8 +62,14 @@ const makeWrapper = () => {

describe.concurrent('VariantFreqs', async () => {
it('renders the VariantFreqs info', async () => {
const wrapper = makeWrapper()
const wrapper = makeWrapper(smallVariantInfo)
const freqsAutosomal = wrapper.findComponent(VariantDetailsFreqsAutosomal)
expect(freqsAutosomal.exists()).toBe(true)
})

it('renders the VariantFreqs info for Mitochondrial Variants', async () => {
const wrapper = makeWrapper(smallVariantInfoMitochondrial)
const freqsAutosomal = wrapper.findComponent(VariantDetailsFreqsMitochondrial)
expect(freqsAutosomal.exists()).toBe(true)
})
})
2 changes: 2 additions & 0 deletions frontend/src/components/__tests__/VariantTools.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,7 @@ describe.concurrent('VariantTools', async () => {
expect(wrapper.text()).toContain('External Resources')
expect(wrapper.text()).toContain('IGV')
expect(wrapper.text()).toContain('Precomputed Scores')
const launchIcons = wrapper.findAll('.mdi-launch')
expect(launchIcons.length).toBe(8)
})
})
27 changes: 22 additions & 5 deletions frontend/src/components/__tests__/VariantValidator.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,30 @@ const makeWrapper = () => {
})
}

// Mock fetch
global.fetch = vi.fn((): any =>
Promise.resolve({ json: () => Promise.resolve(VariantValidatorInfo) })
)

describe.concurrent('VariantValidator', async () => {
it('renders the VariantValidator info', async () => {
// Mock fetch
global.fetch = vi.fn((): any =>
Promise.resolve({ ok: true, json: () => Promise.resolve(VariantValidatorInfo) })
)
const wrapper = makeWrapper()
expect(wrapper.text()).toContain('to submit the variant to VariantValidator.org.')

const submitButton = wrapper.find('button')
expect(submitButton.exists()).toBe(true)
submitButton.trigger('click')
await nextTick()
expect(wrapper.text()).toContain('Loading ...')
const icon = wrapper.find('.v-progress-circular')
expect(icon.exists()).toBe(true)
await nextTick()
})

it('renders the VariantValidator info with error', async () => {
// Mock fetch
global.fetch = vi.fn((): any =>
Promise.resolve({ ok: false, json: () => Promise.resolve({ foo: 'foo' }) })
)
const wrapper = makeWrapper()
expect(wrapper.text()).toContain('to submit the variant to VariantValidator.org.')

Expand Down
72 changes: 70 additions & 2 deletions frontend/src/stores/__tests__/genesList.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,12 @@ const exampleGenesList = {
score: 0.75,
data: {
hgnc_id: 'HGNC:3333',
symbol: 'EMP1'
symbol: 'EMP1',
name: 'epithelial membrane protein 1',
alias_symbol: ['TMP', 'CL-20'],
alias_name: [],
ensembl_gene_id: 'ENSG00000134531',
ncbi_gene_id: '2012'
}
},
{
Expand Down Expand Up @@ -80,6 +85,24 @@ describe.concurrent('geneInfo Store', () => {
expect(store.genesList).toBe(null)
})

it('should fail to load data with invalid fetchGenes response', async () => {
// Disable error logging
vi.spyOn(console, 'error').mockImplementation(() => {})
const store = useGenesListStore()
fetchMocker.mockResponseOnce(JSON.stringify({ genes: [] }))

await store.loadData({ q: 'EMP', fields: 'hgnc_id,ensembl_gene_id,ncbi_gene_id,symbol' })

expect(console.error).toHaveBeenCalled()
expect(console.error).toHaveBeenCalledWith(
'There was an error while searching for genes.',
new Error('No data returned from API.')
)
expect(store.storeState).toBe(StoreState.Error)
expect(store.query).toBe(null)
expect(store.genesList).toBe(null)
})

it('should not load data if gene symbol is the same', async () => {
const store = useGenesListStore()
fetchMocker.mockResponse(JSON.stringify(exampleGenesList))
Expand All @@ -95,7 +118,7 @@ describe.concurrent('geneInfo Store', () => {
expect(fetchMocker.mock.calls.length).toBe(1)
})

it('should redirect if the searchTerm has match', async () => {
it('should redirect if the searchTerm matched symbol', async () => {
const store = useGenesListStore()
fetchMocker.mockResponse(JSON.stringify(exampleGenesList))

Expand All @@ -108,4 +131,49 @@ describe.concurrent('geneInfo Store', () => {

expect(fetchMocker.mock.calls.length).toBe(1)
})

it('should redirect if the searchTerm matched hgnc_id', async () => {
const store = useGenesListStore()
fetchMocker.mockResponse(JSON.stringify(exampleGenesList))

await store.loadData({ q: 'HGNC:3333', fields: 'hgnc_id,ensembl_gene_id,ncbi_gene_id,symbol' })

expect(store.storeState).toBe(StoreState.Redirect)
expect(store.redirectHgncId).toBe('HGNC:3333')
expect(store.query).toBe('q=HGNC:3333&fields=hgnc_id,ensembl_gene_id,ncbi_gene_id,symbol')
expect(store.genesList).toEqual(exampleGenesList.genes)

expect(fetchMocker.mock.calls.length).toBe(1)
})

it('should redirect if the searchTerm matched ensembl_gene_id', async () => {
const store = useGenesListStore()
fetchMocker.mockResponse(JSON.stringify(exampleGenesList))

await store.loadData({
q: 'ENSG00000134531',
fields: 'hgnc_id,ensembl_gene_id,ncbi_gene_id,symbol'
})

expect(store.storeState).toBe(StoreState.Redirect)
expect(store.redirectHgncId).toBe('HGNC:3333')
expect(store.query).toBe('q=ENSG00000134531&fields=hgnc_id,ensembl_gene_id,ncbi_gene_id,symbol')
expect(store.genesList).toEqual(exampleGenesList.genes)

expect(fetchMocker.mock.calls.length).toBe(1)
})

it('should redirect if the searchTerm matched ncbi_gene_id', async () => {
const store = useGenesListStore()
fetchMocker.mockResponse(JSON.stringify(exampleGenesList))

await store.loadData({ q: '2012', fields: 'hgnc_id,ensembl_gene_id,ncbi_gene_id,symbol' })

expect(store.storeState).toBe(StoreState.Redirect)
expect(store.redirectHgncId).toBe('HGNC:3333')
expect(store.query).toBe('q=2012&fields=hgnc_id,ensembl_gene_id,ncbi_gene_id,symbol')
expect(store.genesList).toEqual(exampleGenesList.genes)

expect(fetchMocker.mock.calls.length).toBe(1)
})
})
10 changes: 10 additions & 0 deletions frontend/src/stores/__tests__/misc.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,14 @@ describe.concurrent('miscInfo Store', () => {
expect(store.storeState).toBe(StoreState.Active)
expect(store.appVersion).toBe('v0.0.0')
})

it('should handle error', async () => {
const store = useMiscStore()
fetchMocker.mockRejectOnce('error')

await store.initialize()

expect(store.storeState).toBe(StoreState.Error)
expect(store.appVersion).toBe(null)
})
})
Loading

0 comments on commit cc378b8

Please sign in to comment.