Skip to content
This repository has been archived by the owner on Jun 15, 2023. It is now read-only.

Gpl 568 ui for log errors #15

Merged
merged 10 commits into from
Aug 3, 2020
1 change: 1 addition & 0 deletions layouts/default.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
<b-nav-item href="sentinel_cherrypick"
>Sentinel Cherrypick</b-nav-item
>
<b-nav-item href="imports">Imports</b-nav-item>
</b-navbar-nav>
</b-navbar>
</div>
Expand Down
19 changes: 18 additions & 1 deletion modules/lighthouse_service.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,21 @@ const createPlatesFromBarcodes = async (moduleOptions) => {
return responses
}

export { createPlatesFromBarcodes }
const getImports = async () => {
try {
const response = await axios.get(
`${config.privateRuntimeConfig.lighthouseBaseURL}/imports?max_results=10000`
)
return {
success: true,
data: response.data
}
} catch (error) {
return {
success: false,
error
}
}
}

export { createPlatesFromBarcodes, getImports }
123 changes: 123 additions & 0 deletions pages/imports.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
<template>
<b-container>
<h1>Imports</h1>

<b-alert
ref="alert"
dismissible
:show="showDismissibleAlert"
:variant="alertData.variant"
>
{{ alertData.message }}
</b-alert>
<br/>
<b-form-group label="Filter"
label-cols-sm="1"
label-align-sm="right"
label-for="filterInput"
class="mb-0">
<b-input-group>
<b-form-input v-model="filter"
type="search"
id="filterInput"
placeholder="Type to Search">
</b-form-input>
<b-input-group-append>
<b-button :disabled="!filter" @click="filter = ''">Clear</b-button>
</b-input-group-append>
</b-input-group>
</b-form-group>
<br/>
<b-table
id="imports-table"
show-empty
responsive
:items="items"
:fields="fields"
:sort-by.sync="sortBy"
:sort-desc.sync="sortDesc"
:filter="filter"
hover
:per-page="perPage"
:current-page="currentPage"
>
<template v-slot:cell(errors)="row">
<ul>
<li v-for="error in row.item.errors" :key="error">
{{ error }}
</li>
</ul>
</template>
</b-table>
<b-pagination
v-model="currentPage"
:total-rows="rows"
:per-page="perPage"
aria-table="imports-table"
></b-pagination>
</b-container>
</template>

<script>
import { getImports } from '../modules/lighthouse_service'

export default {
data() {
return {
fields: [
{
key: 'date',
label: 'Date',
sortable: true,
formatter: (value, key, item) => {
const d = new Date(value)
return d.toLocaleString()
},
filterByFormatted: true
},
{ key: 'centre_name', label: 'Centre', sortable: true },
{ key: 'csv_file_used', label: 'File', sortable: true },
{ key: 'number_of_records', label: 'Num of records', sortable: true },
{ key: 'errors', label: 'Errors', sortable: true }
],
sortBy: 'date',
sortDesc: true,
perPage: 10,
currentPage: 1,
showDismissibleAlert: false,
alertData: { variant: '', message: '' },
items: [],
filter: null
}
},
computed: {
rows() {
return this.items.length
}
},
methods: {
async getItemsProvider() {
const resp = await getImports()
return this.handleItemsResponse(resp)
},
handleItemsResponse(response) {
if (response.success) {
return response.data._items
} else {
this.alertData.variant = 'danger'
this.alertData.message = response.error
this.showDismissibleAlert = true
return []
}
},
async provider() {
this.items = await this.getItemsProvider()
}
},
created() {
this.provider()
}
}
</script>

<style></style>
2 changes: 1 addition & 1 deletion test/layouts/default.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ describe('Index', () => {

it('has a navbar', () => {
expect(wrapper.findComponent({ ref: 'navbar' }).text()).toMatch(
/Lighthouse {2}Reports Sentinel Sample Creation/
/Lighthouse {2}Reports Sentinel Sample Creation Sentinel Cherrypick Imports/
)
})
})
27 changes: 27 additions & 0 deletions test/modules/lighthouse_service.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -170,4 +170,31 @@ describe('lighthouse_service api', () => {
)
})
})

describe('#getImports', () => {
let mock, response, expected

beforeEach(() => {
mock = jest.spyOn(axios, 'get')
})

afterEach(() => {
mock.mockRestore()
})

it('returns data successfully', async () => {
expected = { data: { items: [] } }
mock.mockResolvedValue(expected)
response = await Modules.getImports()
expect(response.data).toEqual(expected.data)
})

it('when there is an error', async () => {
mock.mockImplementationOnce(() =>
Promise.reject(new Error('There was an error'))
)
response = await Modules.getImports()
expect(response.error).toEqual(new Error('There was an error'))
})
})
})
106 changes: 106 additions & 0 deletions test/pages/imports.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import BootstrapVue from 'bootstrap-vue'
import { mount, createLocalVue } from '@vue/test-utils'
import Imports from '@/pages/imports'
import * as lighthouseServiceModule from '@/modules/lighthouse_service'

const localVue = createLocalVue()
localVue.use(BootstrapVue)

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

beforeEach(() => {
wrapper = mount(Imports, {
localVue,
data() {
return {
items: []
}
}
})
wrapper.vm.provider = jest.fn()
})

it('is a Vue instance', () => {
expect(wrapper.findComponent(Imports).exists()).toBeTruthy()
})

describe('#getItemsProvider', () => {
it('calls the correct functions', async () => {
const items = [{ test: 1 }]
const expectedResponse = { success: true, data: { _items: items } }

lighthouseServiceModule.getImports = jest.fn()
wrapper.vm.handleItemsResponse = jest.fn()

lighthouseServiceModule.getImports.mockReturnValue(expectedResponse)

await wrapper.vm.getItemsProvider()

expect(lighthouseServiceModule.getImports).toBeCalled()
expect(wrapper.vm.handleItemsResponse).toBeCalledWith(expectedResponse)
})
})

describe('#handleItemsResponse', () => {
let response, errorMsg

it('handles success', () => {
const items = [{ test: 1 }]
response = { success: true, data: { _items: items } }

const resp = wrapper.vm.handleItemsResponse(response)
expect(resp).toEqual(items)
})

it('handles failure', () => {
errorMsg = 'an error message'
response = { success: false, error: errorMsg }
const resp = wrapper.vm.handleItemsResponse(response)

expect(wrapper.vm.alertData).toEqual({
variant: 'danger',
message: errorMsg
})
expect(wrapper.vm.showDismissibleAlert).toEqual(true)
expect(resp).toEqual([])
})

it('on failure it shows an error message', () => {
response = { success: false, error: 'an error message' }
wrapper.vm.handleItemsResponse(response)

wrapper.vm.$nextTick(() => {
expect(wrapper.findComponent({ ref: 'alert' }).text()).toMatch(
/an error message/
)
})
})
})

describe('table filtering', () => {
beforeEach(() => {
wrapper = mount(Imports, {
localVue,
data() {
return {
items: [
{ centre_name: 'I should be hidden' },
{ centre_name: 'pick me!' }
]
}
}
})
wrapper.vm.provider = jest.fn()
})

it('filters based on entered search term', () => {
wrapper.vm.filter = 'me'

wrapper.vm.$nextTick(() => {
expect(wrapper.find('#imports-table').html()).toMatch(/pick me!/)
expect(wrapper.find('#imports-table').html()).not.toMatch(/I should be hidden/)
})
})
})
})