1
0
mirror of https://github.com/lana-k/sqliteviz.git synced 2025-12-07 02:28:54 +08:00

6 Commits

Author SHA1 Message Date
lana-k
3a05b27400 #121 0.25.1 2025-01-12 22:03:06 +01:00
lana-k
108d96a753 #121 fix lint 2025-01-12 22:00:48 +01:00
lana-k
f55a8caa92 #121 tests 2025-01-12 21:42:17 +01:00
lana-k
87f9f9eb01 use actions, add store tests 2025-01-05 22:30:12 +01:00
lana-k
d6408bdd85 #121 save inquiries in store 2025-01-05 21:06:06 +01:00
lana-k
378b9fb580 #113 upgrade plotly 2024-09-23 16:46:50 +02:00
18 changed files with 3609 additions and 4490 deletions

View File

@@ -14,10 +14,10 @@ jobs:
- name: Use Node.js - name: Use Node.js
uses: actions/setup-node@v1 uses: actions/setup-node@v1
with: with:
node-version: 10.x node-version: 16.x
- name: Update npm - name: Update npm
run: npm install -g npm@7 run: npm install -g npm@8
- name: npm install and build - name: npm install and build
run: | run: |

View File

@@ -17,7 +17,7 @@ jobs:
- name: Use Node.js - name: Use Node.js
uses: actions/setup-node@v1 uses: actions/setup-node@v1
with: with:
node-version: 10.x node-version: 16.x
- name: Install browsers - name: Install browsers
run: | run: |
export DEBIAN_FRONTEND=noninteractive export DEBIAN_FRONTEND=noninteractive
@@ -25,7 +25,7 @@ jobs:
sudo apt-get install -y chromium-browser firefox sudo apt-get install -y chromium-browser firefox
- name: Update npm - name: Update npm
run: npm install -g npm@7 run: npm install -g npm@8
- name: Install the project - name: Install the project
run: npm install run: npm install

7069
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{ {
"name": "sqliteviz", "name": "sqliteviz",
"version": "0.25.0", "version": "0.25.1",
"license": "Apache-2.0", "license": "Apache-2.0",
"private": true, "private": true,
"scripts": { "scripts": {
@@ -10,7 +10,7 @@
"lint": "vue-cli-service lint" "lint": "vue-cli-service lint"
}, },
"dependencies": { "dependencies": {
"codemirror": "^5.57.0", "codemirror": "^5.65.18",
"core-js": "^3.6.5", "core-js": "^3.6.5",
"dataurl-to-blob": "^0.0.1", "dataurl-to-blob": "^0.0.1",
"html2canvas": "^1.1.4", "html2canvas": "^1.1.4",
@@ -18,11 +18,11 @@
"nanoid": "^3.1.12", "nanoid": "^3.1.12",
"papaparse": "^5.4.1", "papaparse": "^5.4.1",
"pivottable": "^2.23.0", "pivottable": "^2.23.0",
"plotly.js": "^1.58.4", "plotly.js": "^2.35.2",
"promise-worker": "^2.0.1", "promise-worker": "^2.0.1",
"react": "^16.13.1", "react": "^16.14.0",
"react-chart-editor": "^0.45.0", "react-chart-editor": "^0.46.1",
"react-dom": "^16.13.1", "react-dom": "^16.14.0",
"sql.js": "file:./lib/sql-js", "sql.js": "file:./lib/sql-js",
"vue": "^2.6.11", "vue": "^2.6.11",
"vue-codemirror": "^4.0.6", "vue-codemirror": "^4.0.6",

View File

@@ -4,6 +4,29 @@
</div> </div>
</template> </template>
<script>
import storedInquiries from '@/lib/storedInquiries'
export default {
created () {
this.$store.commit('setInquiries', storedInquiries.getStoredInquiries())
},
computed: {
inquiries () {
return this.$store.state.inquiries
}
},
watch: {
inquiries: {
deep: true,
handler () {
storedInquiries.updateStorage(this.inquiries)
}
}
}
}
</script>
<style> <style>
@font-face { @font-face {
font-family: "Open Sans"; font-family: "Open Sans";

View File

@@ -36,38 +36,6 @@ export default {
return inquiryTab.isPredefined || !inquiryTab.name return inquiryTab.isPredefined || !inquiryTab.name
}, },
save (inquiryTab, newName) {
const value = {
id: inquiryTab.isPredefined ? nanoid() : inquiryTab.id,
query: inquiryTab.query,
viewType: inquiryTab.dataView.mode,
viewOptions: inquiryTab.dataView.getOptionsForSave(),
name: newName || inquiryTab.name
}
// Get inquiries from local storage
const myInquiries = this.getStoredInquiries()
// Set createdAt
if (newName) {
value.createdAt = new Date()
} else {
var inquiryIndex = myInquiries.findIndex(oldInquiry => oldInquiry.id === inquiryTab.id)
value.createdAt = myInquiries[inquiryIndex].createdAt
}
// Insert in inquiries list
if (newName) {
myInquiries.push(value)
} else {
myInquiries[inquiryIndex] = value
}
// Save to local storage
this.updateStorage(myInquiries)
return value
},
updateStorage (inquiries) { updateStorage (inquiries) {
localStorage.setItem('myInquiries', JSON.stringify({ version: this.version, inquiries })) localStorage.setItem('myInquiries', JSON.stringify({ version: this.version, inquiries }))
}, },

View File

@@ -1,4 +1,5 @@
import Tab from '@/lib/tab' import Tab from '@/lib/tab'
import { nanoid } from 'nanoid'
export default { export default {
async addTab ({ state }, inquiry = {}) { async addTab ({ state }, inquiry = {}) {
@@ -13,5 +14,69 @@ export default {
} }
return inquiry.id return inquiry.id
},
async saveInquiry ({ state }, { inquiryTab, newName }) {
const value = {
id: inquiryTab.isPredefined ? nanoid() : inquiryTab.id,
query: inquiryTab.query,
viewType: inquiryTab.dataView.mode,
viewOptions: inquiryTab.dataView.getOptionsForSave(),
name: newName || inquiryTab.name
}
// Get inquiries from local storage
const myInquiries = state.inquiries
// Set createdAt
if (newName) {
value.createdAt = new Date()
} else {
var inquiryIndex = myInquiries.findIndex(oldInquiry => oldInquiry.id === inquiryTab.id)
value.createdAt = myInquiries[inquiryIndex].createdAt
}
// Insert in inquiries list
if (newName) {
myInquiries.push(value)
} else {
myInquiries.splice(inquiryIndex, 1, value)
}
return value
},
addInquiry ({ state }, newInquiry) {
state.inquiries.push(newInquiry)
},
deleteInquiries ({ state, commit }, inquiryIdSet) {
state.inquiries = state.inquiries.filter(
inquiry => !inquiryIdSet.has(inquiry.id)
)
// Close deleted inquiries if it was opened
const tabs = state.tabs
let i = tabs.length - 1
while (i > -1) {
if (inquiryIdSet.has(tabs[i].id)) {
commit('deleteTab', tabs[i])
}
i--
}
},
renameInquiry ({ state, commit }, { inquiryId, newName }) {
const renamingInquiry = state.inquiries
.find(inquiry => inquiry.id === inquiryId)
renamingInquiry.name = newName
// update tab, if renamed inquiry is opened
const tab = state.tabs.find(tab => tab.id === renamingInquiry.id)
if (tab) {
commit('updateTab', {
tab,
newValues: {
name: newName
}
})
}
} }
} }

View File

@@ -60,5 +60,8 @@ export default {
}, },
setPredefinedInquiriesLoaded (state, value) { setPredefinedInquiriesLoaded (state, value) {
state.predefinedInquiriesLoaded = value state.predefinedInquiriesLoaded = value
},
setInquiries (state, value) {
state.inquiries = value
} }
} }

View File

@@ -3,6 +3,7 @@ export default {
currentTab: null, currentTab: null,
currentTabId: null, currentTabId: null,
untitledLastIndex: 0, untitledLastIndex: 0,
inquiries: [],
predefinedInquiries: [], predefinedInquiries: [],
loadingPredefinedInquiries: false, loadingPredefinedInquiries: false,
predefinedInquiriesLoaded: false, predefinedInquiriesLoaded: false,

View File

@@ -183,7 +183,6 @@ export default {
mixins: [tooltipMixin], mixins: [tooltipMixin],
data () { data () {
return { return {
inquiries: [],
filter: null, filter: null,
newName: null, newName: null,
processedInquiryId: null, processedInquiryId: null,
@@ -198,6 +197,9 @@ export default {
} }
}, },
computed: { computed: {
inquiries () {
return this.$store.state.inquiries
},
predefinedInquiries () { predefinedInquiries () {
return this.$store.state.predefinedInquiries.map(inquiry => { return this.$store.state.predefinedInquiries.map(inquiry => {
inquiry.isPredefined = true inquiry.isPredefined = true
@@ -258,7 +260,6 @@ export default {
} }
}, },
async created () { async created () {
this.inquiries = storedInquiries.getStoredInquiries()
const loadingPredefinedInquiries = this.$store.state.loadingPredefinedInquiries const loadingPredefinedInquiries = this.$store.state.loadingPredefinedInquiries
const predefinedInquiriesLoaded = this.$store.state.predefinedInquiriesLoaded const predefinedInquiriesLoaded = this.$store.state.predefinedInquiriesLoaded
if (!predefinedInquiriesLoaded && !loadingPredefinedInquiries) { if (!predefinedInquiriesLoaded && !loadingPredefinedInquiries) {
@@ -330,31 +331,17 @@ export default {
this.errorMsg = "Inquiry name can't be empty" this.errorMsg = "Inquiry name can't be empty"
return return
} }
const processedInquiry = this.inquiries[this.processedInquiryIndex] this.$store.dispatch('renameInquiry', {
processedInquiry.name = this.newName inquiryId: this.processedInquiryId,
this.$set(this.inquiries, this.processedInquiryIndex, processedInquiry) newName: this.newName
})
// update inquiries in local storage
storedInquiries.updateStorage(this.inquiries)
// update tab, if renamed inquiry is opened
const tab = this.$store.state.tabs
.find(tab => tab.id === processedInquiry.id)
if (tab) {
this.$store.commit('updateTab', {
tab,
newValues: {
name: this.newName
}
})
}
// hide dialog // hide dialog
this.$modal.hide('rename') this.$modal.hide('rename')
}, },
duplicateInquiry (index) { duplicateInquiry (index) {
const newInquiry = storedInquiries.duplicateInquiry(this.showedInquiries[index]) const newInquiry = storedInquiries.duplicateInquiry(this.showedInquiries[index])
this.inquiries.push(newInquiry) this.$store.dispatch('addInquiry', newInquiry)
storedInquiries.updateStorage(this.inquiries)
}, },
showDeleteDialog (idsSet) { showDeleteDialog (idsSet) {
this.deleteGroup = idsSet.size > 1 this.deleteGroup = idsSet.size > 1
@@ -366,39 +353,19 @@ export default {
deleteInquiry () { deleteInquiry () {
this.$modal.hide('delete') this.$modal.hide('delete')
if (!this.deleteGroup) { if (!this.deleteGroup) {
this.inquiries.splice(this.processedInquiryIndex, 1) this.$store.dispatch('deleteInquiries', new Set().add(this.processedInquiryId))
// Close deleted inquiry tab if it was opened
const tab = this.$store.state.tabs
.find(tab => tab.id === this.processedInquiryId)
if (tab) {
this.$store.commit('deleteTab', tab)
}
// Clear checkbox // Clear checkbox
if (this.selectedInquiriesIds.has(this.processedInquiryId)) { if (this.selectedInquiriesIds.has(this.processedInquiryId)) {
this.selectedInquiriesIds.delete(this.processedInquiryId) this.selectedInquiriesIds.delete(this.processedInquiryId)
} }
} else { } else {
this.inquiries = this.inquiries.filter( this.$store.dispatch('deleteInquiries', this.selectedInquiriesIds)
inquiry => !this.selectedInquiriesIds.has(inquiry.id)
)
// Close deleted inquiries if it was opened
const tabs = this.$store.state.tabs
let i = tabs.length - 1
while (i > -1) {
if (this.selectedInquiriesIds.has(tabs[i].id)) {
this.$store.commit('deleteTab', tabs[i])
}
i--
}
// Clear checkboxes // Clear checkboxes
this.selectedInquiriesIds.clear() this.selectedInquiriesIds.clear()
} }
this.selectedInquiriesCount = this.selectedInquiriesIds.size this.selectedInquiriesCount = this.selectedInquiriesIds.size
storedInquiries.updateStorage(this.inquiries)
}, },
exportToFile (inquiryList, fileName) { exportToFile (inquiryList, fileName) {
storedInquiries.export(inquiryList, fileName) storedInquiries.export(inquiryList, fileName)
@@ -414,8 +381,7 @@ export default {
importInquiries () { importInquiries () {
storedInquiries.importInquiries() storedInquiries.importInquiries()
.then(importedInquiries => { .then(importedInquiries => {
this.inquiries = this.inquiries.concat(importedInquiries) this.$store.commit('setInquiries', this.inquiries.concat(importedInquiries))
storedInquiries.updateStorage(this.inquiries)
}) })
}, },

View File

@@ -122,7 +122,7 @@ export default {
this.saveInquiry() this.saveInquiry()
} }
}, },
saveInquiry () { async saveInquiry () {
const isNeedName = storedInquiries.isTabNeedName(this.currentInquiry) const isNeedName = storedInquiries.isTabNeedName(this.currentInquiry)
if (isNeedName && !this.name) { if (isNeedName && !this.name) {
this.errorMsg = 'Inquiry name can\'t be empty' this.errorMsg = 'Inquiry name can\'t be empty'
@@ -132,7 +132,10 @@ export default {
const tabView = this.currentInquiry.view const tabView = this.currentInquiry.view
// Save inquiry // Save inquiry
const value = storedInquiries.save(this.currentInquiry, this.name) const value = await this.$store.dispatch('saveInquiry', {
inquiryTab: this.currentInquiry,
newName: this.name
})
// Update tab in store // Update tab in store
this.$store.commit('updateTab', { this.$store.commit('updateTab', {

View File

@@ -25,7 +25,7 @@
<script> <script>
import plotly from 'plotly.js' import plotly from 'plotly.js'
import 'react-chart-editor/lib/react-chart-editor.min.css' import 'react-chart-editor/lib/react-chart-editor.css'
import PlotlyEditor from 'react-chart-editor' import PlotlyEditor from 'react-chart-editor'
import chartHelper from '@/lib/chartHelper' import chartHelper from '@/lib/chartHelper'

52
tests/App.spec.js Normal file
View File

@@ -0,0 +1,52 @@
import { expect } from 'chai'
import sinon from 'sinon'
import { shallowMount } from '@vue/test-utils'
import Vuex from 'vuex'
import App from '@/App'
import storedInquiries from '@/lib/storedInquiries'
import mutations from '@/store/mutations'
describe('App.vue', () => {
afterEach(() => {
sinon.restore()
})
it('Gets inquiries', () => {
sinon.stub(storedInquiries, 'getStoredInquiries').returns([
{ id: 1 }, { id: 2 }, { id: 3 }
])
const state = {
predefinedInquiries: [],
inquiries: []
}
const store = new Vuex.Store({ state, mutations })
shallowMount(App, { store, stubs: ['router-view'] })
expect(state.inquiries).to.eql([{ id: 1 }, { id: 2 }, { id: 3 }])
})
it('Updates inquiries when they change in store', async () => {
sinon.stub(storedInquiries, 'getStoredInquiries').returns([
{ id: 1, name: 'foo' }, { id: 2, name: 'baz' }, { id: 3, name: 'bar' }
])
sinon.spy(storedInquiries, 'updateStorage')
const state = {
predefinedInquiries: [],
inquiries: []
}
const store = new Vuex.Store({ state, mutations })
const wrapper = shallowMount(App, { store, stubs: ['router-view'] })
store.state.inquiries.splice(0, 1, { id: 1, name: 'new foo name' })
await wrapper.vm.$nextTick()
expect(storedInquiries.updateStorage.calledTwice).to.equal(true)
expect(storedInquiries.updateStorage.args[1][0]).to.eql([
{ id: 1, name: 'new foo name' },
{ id: 2, name: 'baz' },
{ id: 3, name: 'bar' }
])
})
})

View File

@@ -342,87 +342,4 @@ describe('storedInquiries.js', () => {
createdAt: '2020-11-03T14:17:49.524Z' createdAt: '2020-11-03T14:17:49.524Z'
}]) }])
}) })
it('save adds new inquiry in the storage', () => {
const now = new Date()
const nowPlusMinute = new Date(now.getTime() + 60 * 1000)
const tab = {
id: 1,
query: 'select * from foo',
viewType: 'chart',
viewOptions: [],
name: null,
dataView: {
getOptionsForSave () {
return ['chart']
}
}
}
const value = storedInquiries.save(tab, 'foo')
expect(value.id).to.equal(tab.id)
expect(value.name).to.equal('foo')
expect(value.query).to.equal(tab.query)
expect(value.viewOptions).to.eql(['chart'])
expect(value).to.have.property('createdAt').which.within(now, nowPlusMinute)
const inquiries = storedInquiries.getStoredInquiries()
expect(JSON.stringify(inquiries)).to.equal(JSON.stringify([value]))
})
it('save updates existing inquiry in the storage', () => {
const tab = {
id: 1,
query: 'select * from foo',
viewType: 'chart',
viewOptions: [],
name: null,
dataView: {
getOptionsForSave () {
return ['chart']
}
}
}
const first = storedInquiries.save(tab, 'foo')
tab.name = 'foo'
tab.query = 'select * from foo'
storedInquiries.save(tab)
const inquiries = storedInquiries.getStoredInquiries()
const second = inquiries[0]
expect(inquiries).has.lengthOf(1)
expect(second.id).to.equal(first.id)
expect(second.name).to.equal(first.name)
expect(second.query).to.equal(tab.query)
expect(second.viewOptions).to.eql(['chart'])
expect(new Date(second.createdAt).getTime()).to.equal(first.createdAt.getTime())
})
it("save adds a new inquiry with new id if it's based on predefined inquiry", () => {
const now = new Date()
const nowPlusMinute = new Date(now.getTime() + 60 * 1000)
const tab = {
id: 1,
query: 'select * from foo',
viewType: 'chart',
viewOptions: [],
name: 'foo predefined',
dataView: {
getOptionsForSave () {
return ['chart']
}
},
isPredefined: true
}
storedInquiries.save(tab, 'foo')
const inquiries = storedInquiries.getStoredInquiries()
expect(inquiries).has.lengthOf(1)
expect(inquiries[0]).to.have.property('id').which.not.equal(tab.id)
expect(inquiries[0].name).to.equal('foo')
expect(inquiries[0].query).to.equal(tab.query)
expect(inquiries[0].viewOptions).to.eql(['chart'])
expect(new Date(inquiries[0].createdAt)).to.be.within(now, nowPlusMinute)
})
}) })

View File

@@ -1,7 +1,14 @@
import { expect } from 'chai' import { expect } from 'chai'
import actions from '@/store/actions' import actions from '@/store/actions'
import sinon from 'sinon'
const { addTab } = actions const {
addTab,
addInquiry,
deleteInquiries,
renameInquiry,
saveInquiry
} = actions
describe('actions', () => { describe('actions', () => {
it('addTab adds new blank tab', async () => { it('addTab adds new blank tab', async () => {
@@ -81,4 +88,156 @@ describe('actions', () => {
expect(state.tabs).to.have.lengthOf(2) expect(state.tabs).to.have.lengthOf(2)
expect(state.untitledLastIndex).to.equal(0) expect(state.untitledLastIndex).to.equal(0)
}) })
it('addInquiry', async () => {
const state = {
inquiries: [1, 2, 3]
}
await addInquiry({ state }, 4)
expect(state.inquiries).to.eql([1, 2, 3, 4])
})
it('deleteInquiries', async () => {
const state = {
inquiries: [{ id: 1 }, { id: 2 }, { id: 3 }],
tabs: [{ id: 3 }, { id: 2 }]
}
const commit = sinon.spy()
await deleteInquiries({ state, commit }, new Set().add(2))
expect(state.inquiries).to.eql([{ id: 1 }, { id: 3 }])
expect(commit.calledWith('deleteTab', { id: 2 })).to.equal(true)
})
it('renameInquiry', async () => {
const state = {
inquiries: [
{ id: 1, name: 'foo' },
{ id: 2, name: 'bar' },
{ id: 3, name: 'baz' }
],
tabs: [{ id: 1, name: 'foo' }, { id: 2, name: 'bar' }]
}
const commit = sinon.spy()
await renameInquiry({ state, commit }, { inquiryId: 2, newName: 'new name' })
expect(state.inquiries).to.eql([
{ id: 1, name: 'foo' },
{ id: 2, name: 'new name' },
{ id: 3, name: 'baz' }
])
expect(commit.calledWith('updateTab', {
tab: { id: 2, name: 'bar' },
newValues: {
name: 'new name'
}
})).to.equal(true)
})
it('saveInquiry adds new inquiry in the storage', async () => {
const now = new Date()
const nowPlusMinute = new Date(now.getTime() + 60 * 1000)
const tab = {
id: 1,
query: 'select * from foo',
viewType: 'chart',
viewOptions: [],
name: null,
dataView: {
getOptionsForSave () {
return ['chart']
}
}
}
const state = {
inquiries: [],
tabs: [tab]
}
const value = await saveInquiry({ state }, {
inquiryTab: tab,
newName: 'foo'
})
expect(value.id).to.equal(tab.id)
expect(value.name).to.equal('foo')
expect(value.query).to.equal(tab.query)
expect(value.viewOptions).to.eql(['chart'])
expect(value).to.have.property('createdAt').which.within(now, nowPlusMinute)
expect(state.inquiries).to.eql([value])
})
it('save updates existing inquiry in the storage', async () => {
const tab = {
id: 1,
query: 'select * from foo',
viewType: 'chart',
viewOptions: [],
name: null,
dataView: {
getOptionsForSave () {
return ['chart']
}
}
}
const state = {
inquiries: [],
tabs: [tab]
}
const first = await saveInquiry({ state }, {
inquiryTab: tab,
newName: 'foo'
})
tab.name = 'foo'
tab.query = 'select * from foo'
await saveInquiry({ state }, { inquiryTab: tab })
const inquiries = state.inquiries
const second = inquiries[0]
expect(inquiries).has.lengthOf(1)
expect(second.id).to.equal(first.id)
expect(second.name).to.equal(first.name)
expect(second.query).to.equal(tab.query)
expect(second.viewOptions).to.eql(['chart'])
expect(new Date(second.createdAt).getTime()).to.equal(first.createdAt.getTime())
})
it("save adds a new inquiry with new id if it's based on predefined inquiry", async () => {
const now = new Date()
const nowPlusMinute = new Date(now.getTime() + 60 * 1000)
const tab = {
id: 1,
query: 'select * from foo',
viewType: 'chart',
viewOptions: [],
name: 'foo predefined',
dataView: {
getOptionsForSave () {
return ['chart']
}
},
isPredefined: true
}
const state = {
inquiries: [],
tabs: [tab]
}
await saveInquiry({ state }, {
inquiryTab: tab,
newName: 'foo'
})
const inquiries = state.inquiries
expect(inquiries).has.lengthOf(1)
expect(inquiries[0]).to.have.property('id').which.not.equal(tab.id)
expect(inquiries[0].name).to.equal('foo')
expect(inquiries[0].query).to.equal(tab.query)
expect(inquiries[0].viewOptions).to.eql(['chart'])
expect(new Date(inquiries[0].createdAt)).to.be.within(now, nowPlusMinute)
})
}) })

View File

@@ -8,7 +8,8 @@ const {
updatePredefinedInquiries, updatePredefinedInquiries,
setDb, setDb,
setLoadingPredefinedInquiries, setLoadingPredefinedInquiries,
setPredefinedInquiriesLoaded setPredefinedInquiriesLoaded,
setInquiries
} = mutations } = mutations
describe('mutations', () => { describe('mutations', () => {
@@ -360,4 +361,13 @@ describe('mutations', () => {
setPredefinedInquiriesLoaded(state, true) setPredefinedInquiriesLoaded(state, true)
expect(state.predefinedInquiriesLoaded).to.equal(true) expect(state.predefinedInquiriesLoaded).to.equal(true)
}) })
it('setInquiries', () => {
const state = {
inquiries: []
}
setInquiries(state, [1, 2, 3])
expect(state.inquiries).to.eql([1, 2, 3])
})
}) })

View File

@@ -5,6 +5,7 @@ import Vuex from 'vuex'
import Inquiries from '@/views/Main/Inquiries' import Inquiries from '@/views/Main/Inquiries'
import storedInquiries from '@/lib/storedInquiries' import storedInquiries from '@/lib/storedInquiries'
import mutations from '@/store/mutations' import mutations from '@/store/mutations'
import actions from '@/store/actions'
import fu from '@/lib/utils/fileIo' import fu from '@/lib/utils/fileIo'
describe('Inquiries.vue', () => { describe('Inquiries.vue', () => {
@@ -14,16 +15,16 @@ describe('Inquiries.vue', () => {
it('Shows start-guide message if there are no saved and predefined inquiries', () => { it('Shows start-guide message if there are no saved and predefined inquiries', () => {
sinon.stub(storedInquiries, 'readPredefinedInquiries').resolves([]) sinon.stub(storedInquiries, 'readPredefinedInquiries').resolves([])
sinon.stub(storedInquiries, 'getStoredInquiries').returns([])
const state = { const state = {
predefinedInquiries: [] predefinedInquiries: [],
inquiries: []
} }
const mutations = { const mutations = {
setPredefinedInquiriesLoaded: sinon.stub(), setPredefinedInquiriesLoaded: sinon.stub(),
updatePredefinedInquiries: sinon.stub(), updatePredefinedInquiries: sinon.stub(),
setLoadingPredefinedInquiries: sinon.stub() setLoadingPredefinedInquiries: sinon.stub()
} }
const store = new Vuex.Store({ state, mutations }) const store = new Vuex.Store({ state, mutations, actions })
const wrapper = shallowMount(Inquiries, { store }) const wrapper = shallowMount(Inquiries, { store })
expect(wrapper.find('#start-guide').exists()).to.equal(true) expect(wrapper.find('#start-guide').exists()).to.equal(true)
@@ -40,32 +41,32 @@ describe('Inquiries.vue', () => {
createdAt: '2020-03-08T19:57:56.299Z' createdAt: '2020-03-08T19:57:56.299Z'
} }
]) ])
sinon.stub(storedInquiries, 'getStoredInquiries').returns([
{
id: 1,
name: 'foo',
query: '',
viewType: 'chart',
viewOptions: [],
createdAt: '2020-11-03T19:57:56.299Z'
},
{
id: 2,
name: 'bar',
query: '',
viewType: 'chart',
viewOptions: [],
createdAt: '2020-12-04T18:53:56.299Z'
}
])
const state = { const state = {
predefinedInquiries: [] predefinedInquiries: [],
inquiries: [
{
id: 1,
name: 'foo',
query: '',
viewType: 'chart',
viewOptions: [],
createdAt: '2020-11-03T19:57:56.299Z'
},
{
id: 2,
name: 'bar',
query: '',
viewType: 'chart',
viewOptions: [],
createdAt: '2020-12-04T18:53:56.299Z'
}
]
} }
const store = new Vuex.Store({ state, mutations }) const store = new Vuex.Store({ state, mutations, actions })
const wrapper = shallowMount(Inquiries, { store }) const wrapper = shallowMount(Inquiries, { store })
await storedInquiries.readPredefinedInquiries.returnValues[0] await storedInquiries.readPredefinedInquiries.returnValues[0]
await storedInquiries.getStoredInquiries.returnValues[0]
await wrapper.vm.$nextTick() await wrapper.vm.$nextTick()
expect(wrapper.find('#start-guide').exists()).to.equal(false) expect(wrapper.find('#start-guide').exists()).to.equal(false)
@@ -94,29 +95,30 @@ describe('Inquiries.vue', () => {
createdAt: '2020-03-08T19:57:56.299Z' createdAt: '2020-03-08T19:57:56.299Z'
} }
]) ])
sinon.stub(storedInquiries, 'getStoredInquiries').returns([
{
id: 1,
name: 'foo',
query: '',
viewType: 'chart',
viewOptions: [],
createdAt: '2020-11-03T19:57:56.299Z'
},
{
id: 2,
name: 'bar',
query: '',
viewType: 'chart',
viewOptions: [],
createdAt: '2020-12-04T18:53:56.299Z'
}
])
const state = { const state = {
predefinedInquiries: [] predefinedInquiries: [],
inquiries: [
{
id: 1,
name: 'foo',
query: '',
viewType: 'chart',
viewOptions: [],
createdAt: '2020-11-03T19:57:56.299Z'
},
{
id: 2,
name: 'bar',
query: '',
viewType: 'chart',
viewOptions: [],
createdAt: '2020-12-04T18:53:56.299Z'
}
]
} }
const store = new Vuex.Store({ state, mutations }) const store = new Vuex.Store({ state, mutations, actions })
const wrapper = mount(Inquiries, { store }) const wrapper = mount(Inquiries, { store })
await wrapper.find('#toolbar-search input').setValue('OO') await wrapper.find('#toolbar-search input').setValue('OO')
await wrapper.vm.$nextTick() await wrapper.vm.$nextTick()
@@ -138,29 +140,30 @@ describe('Inquiries.vue', () => {
createdAt: '2020-03-08T19:57:56.299Z' createdAt: '2020-03-08T19:57:56.299Z'
} }
]) ])
sinon.stub(storedInquiries, 'getStoredInquiries').returns([
{
id: 1,
name: 'foo',
query: '',
viewType: 'chart',
viewOptions: [],
createdAt: '2020-11-03T19:57:56.299Z'
},
{
id: 2,
name: 'bar',
query: '',
viewType: 'chart',
viewOptions: [],
createdAt: '2020-12-04T18:53:56.299Z'
}
])
const state = { const state = {
predefinedInquiries: [] predefinedInquiries: [],
inquiries: [
{
id: 1,
name: 'foo',
query: '',
viewType: 'chart',
viewOptions: [],
createdAt: '2020-11-03T19:57:56.299Z'
},
{
id: 2,
name: 'bar',
query: '',
viewType: 'chart',
viewOptions: [],
createdAt: '2020-12-04T18:53:56.299Z'
}
]
} }
const store = new Vuex.Store({ state, mutations }) const store = new Vuex.Store({ state, mutations, actions })
const wrapper = mount(Inquiries, { store }) const wrapper = mount(Inquiries, { store })
await wrapper.find('#toolbar-search input').setValue('baz') await wrapper.find('#toolbar-search input').setValue('baz')
await wrapper.vm.$nextTick() await wrapper.vm.$nextTick()
@@ -181,24 +184,24 @@ describe('Inquiries.vue', () => {
createdAt: '2020-03-08T19:57:56.299Z' createdAt: '2020-03-08T19:57:56.299Z'
} }
]) ])
sinon.stub(storedInquiries, 'getStoredInquiries').returns([
{
id: 1,
name: 'foo',
query: '',
viewType: 'chart',
viewOptions: [],
createdAt: '2020-11-03T19:57:56.299Z'
}
])
const state = { const state = {
predefinedInquiries: [] predefinedInquiries: [],
inquiries: [
{
id: 1,
name: 'foo',
query: '',
viewType: 'chart',
viewOptions: [],
createdAt: '2020-11-03T19:57:56.299Z'
}
]
} }
const store = new Vuex.Store({ state, mutations }) const store = new Vuex.Store({ state, mutations, actions })
const wrapper = shallowMount(Inquiries, { store }) const wrapper = shallowMount(Inquiries, { store })
await storedInquiries.readPredefinedInquiries.returnValues[0] await storedInquiries.readPredefinedInquiries.returnValues[0]
await storedInquiries.getStoredInquiries.returnValues[0]
await wrapper.vm.$nextTick() await wrapper.vm.$nextTick()
const rows = wrapper.findAll('tbody tr') const rows = wrapper.findAll('tbody tr')
@@ -208,26 +211,25 @@ describe('Inquiries.vue', () => {
it('Exports one inquiry', async () => { it('Exports one inquiry', async () => {
sinon.stub(storedInquiries, 'readPredefinedInquiries').resolves([]) sinon.stub(storedInquiries, 'readPredefinedInquiries').resolves([])
sinon.stub(storedInquiries, 'getStoredInquiries').returns([
{
id: 1,
name: 'foo',
query: '',
viewType: 'chart',
viewOptions: [],
createdAt: '2020-11-03T19:57:56.299Z'
}
])
sinon.stub(storedInquiries, 'serialiseInquiries').returns('I am a serialized inquiry') sinon.stub(storedInquiries, 'serialiseInquiries').returns('I am a serialized inquiry')
sinon.stub(fu, 'exportToFile') sinon.stub(fu, 'exportToFile')
const state = { const state = {
predefinedInquiries: [] predefinedInquiries: [],
inquiries: [
{
id: 1,
name: 'foo',
query: '',
viewType: 'chart',
viewOptions: [],
createdAt: '2020-11-03T19:57:56.299Z'
}
]
} }
const store = new Vuex.Store({ state, mutations }) const store = new Vuex.Store({ state, mutations, actions })
const wrapper = mount(Inquiries, { store }) const wrapper = mount(Inquiries, { store })
await storedInquiries.readPredefinedInquiries.returnValues[0] await storedInquiries.readPredefinedInquiries.returnValues[0]
await storedInquiries.getStoredInquiries.returnValues[0]
await wrapper.vm.$nextTick() await wrapper.vm.$nextTick()
await wrapper.findComponent({ name: 'ExportIcon' }).find('svg').trigger('click') await wrapper.findComponent({ name: 'ExportIcon' }).find('svg').trigger('click')
expect(fu.exportToFile.calledOnceWith('I am a serialized inquiry', 'foo.json')).to.equals(true) expect(fu.exportToFile.calledOnceWith('I am a serialized inquiry', 'foo.json')).to.equals(true)
@@ -243,7 +245,6 @@ describe('Inquiries.vue', () => {
viewOptions: [], viewOptions: [],
createdAt: '2020-11-03T19:57:56.299Z' createdAt: '2020-11-03T19:57:56.299Z'
} }
sinon.stub(storedInquiries, 'getStoredInquiries').returns([inquiryInStorage])
sinon.stub(storedInquiries, 'updateStorage') sinon.stub(storedInquiries, 'updateStorage')
const newInquiry = { const newInquiry = {
id: 2, id: 2,
@@ -255,13 +256,13 @@ describe('Inquiries.vue', () => {
} }
sinon.stub(storedInquiries, 'duplicateInquiry').returns(newInquiry) sinon.stub(storedInquiries, 'duplicateInquiry').returns(newInquiry)
const state = { const state = {
predefinedInquiries: [] predefinedInquiries: [],
inquiries: [inquiryInStorage]
} }
const store = new Vuex.Store({ state, mutations }) const store = new Vuex.Store({ state, mutations, actions })
const wrapper = mount(Inquiries, { store }) const wrapper = mount(Inquiries, { store })
await storedInquiries.readPredefinedInquiries.returnValues[0] await storedInquiries.readPredefinedInquiries.returnValues[0]
await storedInquiries.getStoredInquiries.returnValues[0]
await wrapper.vm.$nextTick() await wrapper.vm.$nextTick()
await wrapper.findComponent({ name: 'CopyIcon' }).find('svg').trigger('click') await wrapper.findComponent({ name: 'CopyIcon' }).find('svg').trigger('click')
@@ -271,9 +272,7 @@ describe('Inquiries.vue', () => {
expect(rows).to.have.lengthOf(2) expect(rows).to.have.lengthOf(2)
expect(rows.at(1).findAll('td').at(0).text()).to.equals('foo copy') expect(rows.at(1).findAll('td').at(0).text()).to.equals('foo copy')
expect(rows.at(1).findAll('td').at(1).text()).to.contains('3 December 2020 20:57') expect(rows.at(1).findAll('td').at(1).text()).to.contains('3 December 2020 20:57')
expect( expect(state.inquiries).to.eql([inquiryInStorage, newInquiry])
storedInquiries.updateStorage.calledOnceWith(sinon.match([inquiryInStorage, newInquiry]))
).to.equals(true)
}) })
it('The copy of the inquiry is not selected if all inquiries were selected before duplication', it('The copy of the inquiry is not selected if all inquiries were selected before duplication',
@@ -287,8 +286,6 @@ describe('Inquiries.vue', () => {
viewOptions: [], viewOptions: [],
createdAt: '2020-11-03T19:57:56.299Z' createdAt: '2020-11-03T19:57:56.299Z'
} }
sinon.stub(storedInquiries, 'getStoredInquiries').returns([inquiryInStorage])
sinon.stub(storedInquiries, 'updateStorage')
const newInquiry = { const newInquiry = {
id: 2, id: 2,
name: 'foo copy', name: 'foo copy',
@@ -299,13 +296,13 @@ describe('Inquiries.vue', () => {
} }
sinon.stub(storedInquiries, 'duplicateInquiry').returns(newInquiry) sinon.stub(storedInquiries, 'duplicateInquiry').returns(newInquiry)
const state = { const state = {
predefinedInquiries: [] predefinedInquiries: [],
inquiries: [inquiryInStorage]
} }
const store = new Vuex.Store({ state, mutations }) const store = new Vuex.Store({ state, mutations, actions })
const wrapper = mount(Inquiries, { store }) const wrapper = mount(Inquiries, { store })
await storedInquiries.readPredefinedInquiries.returnValues[0] await storedInquiries.readPredefinedInquiries.returnValues[0]
await storedInquiries.getStoredInquiries.returnValues[0]
await wrapper.vm.$nextTick() await wrapper.vm.$nextTick()
await wrapper.findComponent({ ref: 'mainCheckBox' }).find('.checkbox-container') await wrapper.findComponent({ ref: 'mainCheckBox' }).find('.checkbox-container')
.trigger('click') .trigger('click')
@@ -326,11 +323,11 @@ describe('Inquiries.vue', () => {
viewOptions: [], viewOptions: [],
createdAt: '2020-11-03T19:57:56.299Z' createdAt: '2020-11-03T19:57:56.299Z'
} }
sinon.stub(storedInquiries, 'getStoredInquiries').returns([inquiryInStorage])
const state = { const state = {
tabs: [], tabs: [],
predefinedInquiries: [] predefinedInquiries: [],
inquiries: [inquiryInStorage]
} }
const actions = { addTab: sinon.stub().resolves(1) } const actions = { addTab: sinon.stub().resolves(1) }
sinon.spy(mutations, 'setCurrentTabId') sinon.spy(mutations, 'setCurrentTabId')
@@ -342,7 +339,6 @@ describe('Inquiries.vue', () => {
mocks: { $router } mocks: { $router }
}) })
await storedInquiries.readPredefinedInquiries.returnValues[0] await storedInquiries.readPredefinedInquiries.returnValues[0]
await storedInquiries.getStoredInquiries.returnValues[0]
await wrapper.vm.$nextTick() await wrapper.vm.$nextTick()
await wrapper.find('tbody tr').trigger('click') await wrapper.find('tbody tr').trigger('click')
@@ -364,42 +360,40 @@ describe('Inquiries.vue', () => {
createdAt: '2020-03-08T19:57:56.299Z' createdAt: '2020-03-08T19:57:56.299Z'
} }
]) ])
sinon.stub(storedInquiries, 'getStoredInquiries').returns([])
const state = { const state = {
predefinedInquiries: [] predefinedInquiries: [],
inquiries: []
} }
const store = new Vuex.Store({ state, mutations }) const store = new Vuex.Store({ state, mutations, actions })
const wrapper = mount(Inquiries, { store }) const wrapper = mount(Inquiries, { store })
await storedInquiries.readPredefinedInquiries.returnValues[0] await storedInquiries.readPredefinedInquiries.returnValues[0]
await storedInquiries.getStoredInquiries.returnValues[0]
await wrapper.vm.$nextTick() await wrapper.vm.$nextTick()
expect(wrapper.findComponent({ name: 'RenameIcon' }).exists()).to.equals(false) expect(wrapper.findComponent({ name: 'RenameIcon' }).exists()).to.equals(false)
}) })
it('Renames an inquiry', async () => { it('Renames an inquiry', async () => {
sinon.stub(storedInquiries, 'readPredefinedInquiries').resolves([]) sinon.stub(storedInquiries, 'readPredefinedInquiries').resolves([])
sinon.stub(storedInquiries, 'getStoredInquiries').returns([
{
id: 1,
name: 'foo',
query: '',
viewType: 'chart',
viewOptions: [],
createdAt: '2020-11-03T19:57:56.299Z'
}
])
sinon.stub(storedInquiries, 'updateStorage') sinon.stub(storedInquiries, 'updateStorage')
const state = { const state = {
tabs: [{ id: 1, name: 'foo' }], tabs: [{ id: 1, name: 'foo' }],
predefinedInquiries: [] predefinedInquiries: [],
inquiries: [
{
id: 1,
name: 'foo',
query: '',
viewType: 'chart',
viewOptions: [],
createdAt: '2020-11-03T19:57:56.299Z'
}
]
} }
const store = new Vuex.Store({ state, mutations }) const store = new Vuex.Store({ state, mutations, actions })
const wrapper = mount(Inquiries, { store }) const wrapper = mount(Inquiries, { store })
await storedInquiries.readPredefinedInquiries.returnValues[0] await storedInquiries.readPredefinedInquiries.returnValues[0]
await storedInquiries.getStoredInquiries.returnValues[0]
await wrapper.vm.$nextTick() await wrapper.vm.$nextTick()
// click Rename icon in the grid // click Rename icon in the grid
@@ -419,19 +413,20 @@ describe('Inquiries.vue', () => {
.findAll('.dialog-buttons-container button').wrappers .findAll('.dialog-buttons-container button').wrappers
.find(button => button.text() === 'Rename') .find(button => button.text() === 'Rename')
.trigger('click') .trigger('click')
await wrapper.vm.$nextTick()
// check that the name in the grid is changed // check that the name in the grid is changed
expect(wrapper.find('tbody tr td').text()).to.equals('bar') expect(wrapper.find('tbody tr td').text()).to.equals('bar')
// check that storage is updated // check that storage is updated
expect(storedInquiries.updateStorage.calledOnceWith(sinon.match([{ expect(state.inquiries).to.eql([{
id: 1, id: 1,
name: 'bar', name: 'bar',
query: '', query: '',
viewType: 'chart', viewType: 'chart',
viewOptions: [], viewOptions: [],
createdAt: '2020-11-03T19:57:56.299Z' createdAt: '2020-11-03T19:57:56.299Z'
}]))).to.equals(true) }])
// check that coresponding tab also changed the name // check that coresponding tab also changed the name
expect(state.tabs[0].name).to.equals('bar') expect(state.tabs[0].name).to.equals('bar')
@@ -442,26 +437,25 @@ describe('Inquiries.vue', () => {
it('Shows an error if try to rename to empty string', async () => { it('Shows an error if try to rename to empty string', async () => {
sinon.stub(storedInquiries, 'readPredefinedInquiries').resolves([]) sinon.stub(storedInquiries, 'readPredefinedInquiries').resolves([])
sinon.stub(storedInquiries, 'getStoredInquiries').returns([
{
id: 1,
name: 'foo',
query: '',
viewType: 'chart',
viewOptions: [],
createdAt: '2020-11-03T19:57:56.299Z'
}
])
sinon.stub(storedInquiries, 'updateStorage') sinon.stub(storedInquiries, 'updateStorage')
const state = { const state = {
tabs: [{ id: 1, name: 'foo' }], tabs: [{ id: 1, name: 'foo' }],
predefinedInquiries: [] predefinedInquiries: [],
inquiries: [
{
id: 1,
name: 'foo',
query: '',
viewType: 'chart',
viewOptions: [],
createdAt: '2020-11-03T19:57:56.299Z'
}
]
} }
const store = new Vuex.Store({ state, mutations }) const store = new Vuex.Store({ state, mutations, actions })
const wrapper = mount(Inquiries, { store }) const wrapper = mount(Inquiries, { store })
await storedInquiries.readPredefinedInquiries.returnValues[0] await storedInquiries.readPredefinedInquiries.returnValues[0]
await storedInquiries.getStoredInquiries.returnValues[0]
await wrapper.vm.$nextTick() await wrapper.vm.$nextTick()
// click Rename icon in the grid // click Rename icon in the grid
@@ -492,7 +486,6 @@ describe('Inquiries.vue', () => {
viewOptions: [], viewOptions: [],
createdAt: '2020-11-03T19:57:56.299Z' createdAt: '2020-11-03T19:57:56.299Z'
} }
sinon.stub(storedInquiries, 'getStoredInquiries').returns([inquiryInStorage])
sinon.stub(storedInquiries, 'updateStorage') sinon.stub(storedInquiries, 'updateStorage')
const importedInquiry = { const importedInquiry = {
id: 2, id: 2,
@@ -504,13 +497,13 @@ describe('Inquiries.vue', () => {
} }
sinon.stub(storedInquiries, 'importInquiries').resolves([importedInquiry]) sinon.stub(storedInquiries, 'importInquiries').resolves([importedInquiry])
const state = { const state = {
predefinedInquiries: [] predefinedInquiries: [],
inquiries: [inquiryInStorage]
} }
const store = new Vuex.Store({ state, mutations }) const store = new Vuex.Store({ state, mutations, actions })
const wrapper = shallowMount(Inquiries, { store }) const wrapper = shallowMount(Inquiries, { store })
await storedInquiries.readPredefinedInquiries.returnValues[0] await storedInquiries.readPredefinedInquiries.returnValues[0]
await storedInquiries.getStoredInquiries.returnValues[0]
await wrapper.vm.$nextTick() await wrapper.vm.$nextTick()
// click Import // click Import
@@ -520,9 +513,7 @@ describe('Inquiries.vue', () => {
expect(rows).to.have.lengthOf(2) expect(rows).to.have.lengthOf(2)
expect(rows.at(1).findAll('td').at(0).text()).to.equals('bar') expect(rows.at(1).findAll('td').at(0).text()).to.equals('bar')
expect(rows.at(1).findAll('td').at(1).text()).to.equals('3 December 2020 20:57') expect(rows.at(1).findAll('td').at(1).text()).to.equals('3 December 2020 20:57')
expect(storedInquiries.updateStorage.calledOnceWith( expect(state.inquiries).to.eql([inquiryInStorage, importedInquiry])
sinon.match([inquiryInStorage, importedInquiry])
)).to.equals(true)
}) })
it('Imported inquiries are not selected if master check box was checked', async () => { it('Imported inquiries are not selected if master check box was checked', async () => {
@@ -535,7 +526,6 @@ describe('Inquiries.vue', () => {
viewOptions: [], viewOptions: [],
createdAt: '2020-11-03T19:57:56.299Z' createdAt: '2020-11-03T19:57:56.299Z'
} }
sinon.stub(storedInquiries, 'getStoredInquiries').returns([inquiryInStorage])
sinon.stub(storedInquiries, 'updateStorage') sinon.stub(storedInquiries, 'updateStorage')
const importedInquiry = { const importedInquiry = {
id: 2, id: 2,
@@ -547,13 +537,13 @@ describe('Inquiries.vue', () => {
} }
sinon.stub(storedInquiries, 'importInquiries').resolves([importedInquiry]) sinon.stub(storedInquiries, 'importInquiries').resolves([importedInquiry])
const state = { const state = {
predefinedInquiries: [] predefinedInquiries: [],
inquiries: [inquiryInStorage]
} }
const store = new Vuex.Store({ state, mutations }) const store = new Vuex.Store({ state, mutations, actions })
const wrapper = mount(Inquiries, { store }) const wrapper = mount(Inquiries, { store })
await storedInquiries.readPredefinedInquiries.returnValues[0] await storedInquiries.readPredefinedInquiries.returnValues[0]
await storedInquiries.getStoredInquiries.returnValues[0]
await wrapper.vm.$nextTick() await wrapper.vm.$nextTick()
// click on master checkbox // click on master checkbox
@@ -580,16 +570,15 @@ describe('Inquiries.vue', () => {
createdAt: '2020-03-08T19:57:56.299Z' createdAt: '2020-03-08T19:57:56.299Z'
} }
]) ])
sinon.stub(storedInquiries, 'getStoredInquiries').returns([])
const state = { const state = {
predefinedInquiries: [] predefinedInquiries: [],
inquiries: []
} }
const store = new Vuex.Store({ state, mutations }) const store = new Vuex.Store({ state, mutations, actions })
const wrapper = mount(Inquiries, { store }) const wrapper = mount(Inquiries, { store })
await storedInquiries.readPredefinedInquiries.returnValues[0] await storedInquiries.readPredefinedInquiries.returnValues[0]
await storedInquiries.getStoredInquiries.returnValues[0]
await wrapper.vm.$nextTick() await wrapper.vm.$nextTick()
expect(wrapper.findComponent({ name: 'DeleteIcon' }).exists()).to.equals(false) expect(wrapper.findComponent({ name: 'DeleteIcon' }).exists()).to.equals(false)
}) })
@@ -612,18 +601,17 @@ describe('Inquiries.vue', () => {
viewOptions: [], viewOptions: [],
createdAt: '2020-11-03T19:57:56.299Z' createdAt: '2020-11-03T19:57:56.299Z'
} }
sinon.stub(storedInquiries, 'getStoredInquiries').returns([foo, bar])
sinon.stub(storedInquiries, 'updateStorage') sinon.stub(storedInquiries, 'updateStorage')
const state = { const state = {
tabs: [{ id: 1 }, { id: 2 }], tabs: [{ id: 1 }, { id: 2 }],
predefinedInquiries: [] predefinedInquiries: [],
inquiries: [foo, bar]
} }
const store = new Vuex.Store({ state, mutations }) const store = new Vuex.Store({ state, mutations, actions })
const wrapper = mount(Inquiries, { store }) const wrapper = mount(Inquiries, { store })
await storedInquiries.readPredefinedInquiries.returnValues[0] await storedInquiries.readPredefinedInquiries.returnValues[0]
await storedInquiries.getStoredInquiries.returnValues[0]
await wrapper.vm.$nextTick() await wrapper.vm.$nextTick()
// click Delete icon in the first row of the grid // click Delete icon in the first row of the grid
await wrapper.findComponent({ name: 'DeleteIcon' }).find('svg').trigger('click') await wrapper.findComponent({ name: 'DeleteIcon' }).find('svg').trigger('click')
@@ -649,7 +637,7 @@ describe('Inquiries.vue', () => {
expect(state.tabs[0].id).to.equals(2) expect(state.tabs[0].id).to.equals(2)
// check that storage is updated // check that storage is updated
expect(storedInquiries.updateStorage.calledOnceWith(sinon.match([bar]))).to.equals(true) expect(state.inquiries).to.eql([bar])
// check that delete dialog is closed // check that delete dialog is closed
expect(wrapper.find('[data-modal="delete"]').exists()).to.equal(false) expect(wrapper.find('[data-modal="delete"]').exists()).to.equal(false)
@@ -666,25 +654,24 @@ describe('Inquiries.vue', () => {
createdAt: '2020-03-08T19:57:56.299Z' createdAt: '2020-03-08T19:57:56.299Z'
} }
]) ])
sinon.stub(storedInquiries, 'getStoredInquiries').returns([
{
id: 1,
name: 'foo',
query: '',
viewType: 'chart',
viewOptions: [],
createdAt: '2020-11-03T19:57:56.299Z'
}
])
const state = { const state = {
predefinedInquiries: [] predefinedInquiries: [],
inquiries: [
{
id: 1,
name: 'foo',
query: '',
viewType: 'chart',
viewOptions: [],
createdAt: '2020-11-03T19:57:56.299Z'
}
]
} }
const store = new Vuex.Store({ state, mutations }) const store = new Vuex.Store({ state, mutations, actions })
const wrapper = mount(Inquiries, { store }) const wrapper = mount(Inquiries, { store })
await storedInquiries.readPredefinedInquiries.returnValues[0] await storedInquiries.readPredefinedInquiries.returnValues[0]
await storedInquiries.getStoredInquiries.returnValues[0]
await wrapper.vm.$nextTick() await wrapper.vm.$nextTick()
expect(wrapper.find('#toolbar-btns-export').isVisible()).to.equal(false) expect(wrapper.find('#toolbar-btns-export').isVisible()).to.equal(false)
@@ -726,26 +713,25 @@ describe('Inquiries.vue', () => {
viewOptions: [], viewOptions: [],
createdAt: '2020-03-08T19:57:56.299Z' createdAt: '2020-03-08T19:57:56.299Z'
} }
sinon.stub(storedInquiries, 'getStoredInquiries').returns([inquiryInStore, {
id: 2,
name: 'bar',
query: '',
viewType: 'chart',
viewOptions: [],
createdAt: '2020-03-08T19:57:56.299Z'
}])
sinon.stub(storedInquiries, 'serialiseInquiries').returns('I am a serialized inquiries') sinon.stub(storedInquiries, 'serialiseInquiries').returns('I am a serialized inquiries')
sinon.stub(fu, 'exportToFile') sinon.stub(fu, 'exportToFile')
const state = { const state = {
predefinedInquiries: [] predefinedInquiries: [],
inquiries: [inquiryInStore, {
id: 2,
name: 'bar',
query: '',
viewType: 'chart',
viewOptions: [],
createdAt: '2020-03-08T19:57:56.299Z'
}]
} }
const store = new Vuex.Store({ state, mutations }) const store = new Vuex.Store({ state, mutations, actions })
const wrapper = mount(Inquiries, { store }) const wrapper = mount(Inquiries, { store })
await storedInquiries.readPredefinedInquiries.returnValues[0] await storedInquiries.readPredefinedInquiries.returnValues[0]
await storedInquiries.getStoredInquiries.returnValues[0]
await wrapper.vm.$nextTick() await wrapper.vm.$nextTick()
const rows = wrapper.findAll('tbody tr') const rows = wrapper.findAll('tbody tr')
@@ -783,19 +769,18 @@ describe('Inquiries.vue', () => {
viewOptions: [], viewOptions: [],
createdAt: '2020-03-08T19:57:56.299Z' createdAt: '2020-03-08T19:57:56.299Z'
} }
sinon.stub(storedInquiries, 'getStoredInquiries').returns([inquiryInStore])
sinon.stub(storedInquiries, 'serialiseInquiries').returns('I am a serialized inquiries') sinon.stub(storedInquiries, 'serialiseInquiries').returns('I am a serialized inquiries')
sinon.stub(fu, 'exportToFile') sinon.stub(fu, 'exportToFile')
const state = { const state = {
predefinedInquiries: [] predefinedInquiries: [],
inquiries: [inquiryInStore]
} }
const store = new Vuex.Store({ state, mutations }) const store = new Vuex.Store({ state, mutations, actions })
const wrapper = mount(Inquiries, { store }) const wrapper = mount(Inquiries, { store })
await storedInquiries.readPredefinedInquiries.returnValues[0] await storedInquiries.readPredefinedInquiries.returnValues[0]
await storedInquiries.getStoredInquiries.returnValues[0]
await wrapper.vm.$nextTick() await wrapper.vm.$nextTick()
await wrapper.findComponent({ ref: 'mainCheckBox' }).find('.checkbox-container') await wrapper.findComponent({ ref: 'mainCheckBox' }).find('.checkbox-container')
@@ -846,19 +831,18 @@ describe('Inquiries.vue', () => {
viewOptions: [], viewOptions: [],
createdAt: '2020-03-08T19:57:56.299Z' createdAt: '2020-03-08T19:57:56.299Z'
} }
sinon.stub(storedInquiries, 'getStoredInquiries').returns([foo, bar, baz])
sinon.stub(storedInquiries, 'updateStorage') sinon.stub(storedInquiries, 'updateStorage')
const state = { const state = {
tabs: [{ id: 1 }, { id: 2 }, { id: 0 }, { id: 3 }], tabs: [{ id: 1 }, { id: 2 }, { id: 0 }, { id: 3 }],
predefinedInquiries: [] predefinedInquiries: [],
inquiries: [foo, bar, baz]
} }
const store = new Vuex.Store({ state, mutations }) const store = new Vuex.Store({ state, mutations, actions })
const wrapper = mount(Inquiries, { store }) const wrapper = mount(Inquiries, { store })
await storedInquiries.readPredefinedInquiries.returnValues[0] await storedInquiries.readPredefinedInquiries.returnValues[0]
await storedInquiries.getStoredInquiries.returnValues[0]
await wrapper.vm.$nextTick() await wrapper.vm.$nextTick()
const rows = wrapper.findAll('tbody tr') const rows = wrapper.findAll('tbody tr')
@@ -893,7 +877,7 @@ describe('Inquiries.vue', () => {
expect(state.tabs[1].id).to.equals(3) expect(state.tabs[1].id).to.equals(3)
// check that storage is updated // check that storage is updated
expect(storedInquiries.updateStorage.calledOnceWith(sinon.match([baz]))).to.equals(true) expect(state.inquiries).to.eql([baz])
// check that delete dialog is closed // check that delete dialog is closed
expect(wrapper.find('[data-modal="delete"]').exists()).to.equal(false) expect(wrapper.find('[data-modal="delete"]').exists()).to.equal(false)
@@ -925,18 +909,17 @@ describe('Inquiries.vue', () => {
viewOptions: [], viewOptions: [],
createdAt: '2020-03-08T19:57:56.299Z' createdAt: '2020-03-08T19:57:56.299Z'
} }
sinon.stub(storedInquiries, 'getStoredInquiries').returns([foo, bar])
sinon.stub(storedInquiries, 'updateStorage') sinon.stub(storedInquiries, 'updateStorage')
const state = { const state = {
tabs: [], tabs: [],
predefinedInquiries: [] predefinedInquiries: [],
inquiries: [foo, bar]
} }
const store = new Vuex.Store({ state, mutations }) const store = new Vuex.Store({ state, mutations, actions })
const wrapper = mount(Inquiries, { store }) const wrapper = mount(Inquiries, { store })
await storedInquiries.readPredefinedInquiries.returnValues[0] await storedInquiries.readPredefinedInquiries.returnValues[0]
await storedInquiries.getStoredInquiries.returnValues[0]
await wrapper.vm.$nextTick() await wrapper.vm.$nextTick()
const rows = wrapper.findAll('tbody tr') const rows = wrapper.findAll('tbody tr')
@@ -968,7 +951,7 @@ describe('Inquiries.vue', () => {
expect(wrapper.findAll('tbody tr').at(1).find('td').text()).to.equals('bar') expect(wrapper.findAll('tbody tr').at(1).find('td').text()).to.equals('bar')
// check that storage is updated // check that storage is updated
expect(storedInquiries.updateStorage.calledOnceWith(sinon.match([bar]))).to.equals(true) expect(state.inquiries).to.eql([bar])
// check that delete dialog is closed // check that delete dialog is closed
expect(wrapper.find('[data-modal="delete"]').exists()).to.equal(false) expect(wrapper.find('[data-modal="delete"]').exists()).to.equal(false)
@@ -1000,18 +983,17 @@ describe('Inquiries.vue', () => {
viewOptions: [], viewOptions: [],
createdAt: '2020-03-08T19:57:56.299Z' createdAt: '2020-03-08T19:57:56.299Z'
} }
sinon.stub(storedInquiries, 'getStoredInquiries').returns([foo, bar])
sinon.stub(storedInquiries, 'updateStorage') sinon.stub(storedInquiries, 'updateStorage')
const state = { const state = {
tabs: [], tabs: [],
predefinedInquiries: [] predefinedInquiries: [],
inquiries: [foo, bar]
} }
const store = new Vuex.Store({ state, mutations }) const store = new Vuex.Store({ state, mutations, actions })
const wrapper = mount(Inquiries, { store }) const wrapper = mount(Inquiries, { store })
await storedInquiries.readPredefinedInquiries.returnValues[0] await storedInquiries.readPredefinedInquiries.returnValues[0]
await storedInquiries.getStoredInquiries.returnValues[0]
await wrapper.vm.$nextTick() await wrapper.vm.$nextTick()
await wrapper.findComponent({ ref: 'mainCheckBox' }).find('.checkbox-container') await wrapper.findComponent({ ref: 'mainCheckBox' }).find('.checkbox-container')
@@ -1039,7 +1021,7 @@ describe('Inquiries.vue', () => {
expect(wrapper.findAll('tbody tr').at(0).find('td').text()).to.contains('hello_world') expect(wrapper.findAll('tbody tr').at(0).find('td').text()).to.contains('hello_world')
// check that storage is updated // check that storage is updated
expect(storedInquiries.updateStorage.calledOnceWith(sinon.match([]))).to.equals(true) expect(state.inquiries).to.eql([])
// check that delete dialog is closed // check that delete dialog is closed
expect(wrapper.find('[data-modal="delete"]').exists()).to.equal(false) expect(wrapper.find('[data-modal="delete"]').exists()).to.equal(false)
@@ -1063,16 +1045,15 @@ describe('Inquiries.vue', () => {
viewOptions: [], viewOptions: [],
createdAt: '2020-03-08T19:57:56.299Z' createdAt: '2020-03-08T19:57:56.299Z'
} }
sinon.stub(storedInquiries, 'getStoredInquiries').returns([foo, bar])
const state = { const state = {
predefinedInquiries: [] predefinedInquiries: [],
inquiries: [foo, bar]
} }
const store = new Vuex.Store({ state, mutations }) const store = new Vuex.Store({ state, mutations, actions })
const wrapper = mount(Inquiries, { store }) const wrapper = mount(Inquiries, { store })
await storedInquiries.readPredefinedInquiries.returnValues[0] await storedInquiries.readPredefinedInquiries.returnValues[0]
await storedInquiries.getStoredInquiries.returnValues[0]
await wrapper.vm.$nextTick() await wrapper.vm.$nextTick()
const mainCheckBox = wrapper.findComponent({ ref: 'mainCheckBox' }) const mainCheckBox = wrapper.findComponent({ ref: 'mainCheckBox' })
@@ -1122,16 +1103,15 @@ describe('Inquiries.vue', () => {
viewOptions: [], viewOptions: [],
createdAt: '2020-03-08T19:57:56.299Z' createdAt: '2020-03-08T19:57:56.299Z'
} }
sinon.stub(storedInquiries, 'getStoredInquiries').returns([foo, bar])
const state = { const state = {
predefinedInquiries: [] predefinedInquiries: [],
inquiries: [foo, bar]
} }
const store = new Vuex.Store({ state, mutations }) const store = new Vuex.Store({ state, mutations, actions })
const wrapper = mount(Inquiries, { store }) const wrapper = mount(Inquiries, { store })
await storedInquiries.readPredefinedInquiries.returnValues[0] await storedInquiries.readPredefinedInquiries.returnValues[0]
await storedInquiries.getStoredInquiries.returnValues[0]
await wrapper.vm.$nextTick() await wrapper.vm.$nextTick()
const mainCheckBox = wrapper.findComponent({ ref: 'mainCheckBox' }) const mainCheckBox = wrapper.findComponent({ ref: 'mainCheckBox' })

View File

@@ -349,16 +349,18 @@ describe('MainMenu.vue', () => {
const mutations = { const mutations = {
updateTab: sinon.stub() updateTab: sinon.stub()
} }
const store = new Vuex.Store({ state, mutations }) const actions = {
saveInquiry: sinon.stub().returns({
name: 'foo',
id: 1,
query: 'SELECT * FROM foo',
viewType: 'chart',
viewOptions: []
})
}
const store = new Vuex.Store({ state, mutations, actions })
const $route = { path: '/workspace' } const $route = { path: '/workspace' }
sinon.stub(storedInquiries, 'isTabNeedName').returns(false) sinon.stub(storedInquiries, 'isTabNeedName').returns(false)
sinon.stub(storedInquiries, 'save').returns({
name: 'foo',
id: 1,
query: 'SELECT * FROM foo',
viewType: 'chart',
viewOptions: []
})
wrapper = mount(MainMenu, { wrapper = mount(MainMenu, {
store, store,
@@ -371,8 +373,11 @@ describe('MainMenu.vue', () => {
// check that the dialog is closed // check that the dialog is closed
expect(wrapper.find('[data-modal="save"]').exists()).to.equal(false) expect(wrapper.find('[data-modal="save"]').exists()).to.equal(false)
// check that the inquiry was saved via storedInquiries.save (newName='') // check that the inquiry was saved via saveInquiry (newName='')
expect(storedInquiries.save.calledOnceWith(state.currentTab, '')).to.equal(true) expect(actions.saveInquiry.calledOnce).to.equal(true)
expect(actions.saveInquiry.args[0][1]).to.eql({
inquiryTab: state.currentTab, newName: ''
})
// check that the tab was updated // check that the tab was updated
expect(mutations.updateTab.calledOnceWith(state, sinon.match({ expect(mutations.updateTab.calledOnceWith(state, sinon.match({
@@ -408,16 +413,18 @@ describe('MainMenu.vue', () => {
const mutations = { const mutations = {
updateTab: sinon.stub() updateTab: sinon.stub()
} }
const store = new Vuex.Store({ state, mutations }) const actions = {
saveInquiry: sinon.stub().returns({
name: 'foo',
id: 1,
query: 'SELECT * FROM foo',
viewType: 'chart',
viewOptions: []
})
}
const store = new Vuex.Store({ state, mutations, actions })
const $route = { path: '/workspace' } const $route = { path: '/workspace' }
sinon.stub(storedInquiries, 'isTabNeedName').returns(true) sinon.stub(storedInquiries, 'isTabNeedName').returns(true)
sinon.stub(storedInquiries, 'save').returns({
name: 'foo',
id: 1,
query: 'SELECT * FROM foo',
viewType: 'chart',
viewOptions: []
})
wrapper = mount(MainMenu, { wrapper = mount(MainMenu, {
store, store,
@@ -458,16 +465,18 @@ describe('MainMenu.vue', () => {
const mutations = { const mutations = {
updateTab: sinon.stub() updateTab: sinon.stub()
} }
const store = new Vuex.Store({ state, mutations }) const actions = {
saveInquiry: sinon.stub().returns({
name: 'foo',
id: 1,
query: 'SELECT * FROM foo',
viewType: 'chart',
viewOptions: []
})
}
const store = new Vuex.Store({ state, mutations, actions })
const $route = { path: '/workspace' } const $route = { path: '/workspace' }
sinon.stub(storedInquiries, 'isTabNeedName').returns(true) sinon.stub(storedInquiries, 'isTabNeedName').returns(true)
sinon.stub(storedInquiries, 'save').returns({
name: 'foo',
id: 1,
query: 'SELECT * FROM foo',
viewType: 'chart',
viewOptions: []
})
wrapper = mount(MainMenu, { wrapper = mount(MainMenu, {
store, store,
@@ -489,11 +498,17 @@ describe('MainMenu.vue', () => {
.find(button => button.text() === 'Save') .find(button => button.text() === 'Save')
.trigger('click') .trigger('click')
await wrapper.vm.$nextTick()
// check that the dialog is closed // check that the dialog is closed
expect(wrapper.find('[data-modal="save"]').exists()).to.equal(false) expect(wrapper.find('[data-modal="save"]').exists()).to.equal(false)
// check that the inquiry was saved via storedInquiries.save (newName='foo') // check that the inquiry was saved via saveInquiry (newName='foo')
expect(storedInquiries.save.calledOnceWith(state.currentTab, 'foo')).to.equal(true) expect(actions.saveInquiry.calledOnce).to.equal(true)
expect(actions.saveInquiry.args[0][1]).to.eql({
inquiryTab: state.currentTab,
newName: 'foo'
})
// check that the tab was updated // check that the tab was updated
expect(mutations.updateTab.calledOnceWith(state, sinon.match({ expect(mutations.updateTab.calledOnceWith(state, sinon.match({
@@ -538,16 +553,18 @@ describe('MainMenu.vue', () => {
const mutations = { const mutations = {
updateTab: sinon.stub() updateTab: sinon.stub()
} }
const store = new Vuex.Store({ state, mutations }) const actions = {
saveInquiry: sinon.stub().returns({
name: 'bar',
id: 2,
query: 'SELECT * FROM foo',
viewType: 'chart',
viewOptions: []
})
}
const store = new Vuex.Store({ state, mutations, actions })
const $route = { path: '/workspace' } const $route = { path: '/workspace' }
sinon.stub(storedInquiries, 'isTabNeedName').returns(true) sinon.stub(storedInquiries, 'isTabNeedName').returns(true)
sinon.stub(storedInquiries, 'save').returns({
name: 'bar',
id: 2,
query: 'SELECT * FROM foo',
viewType: 'chart',
viewOptions: []
})
wrapper = mount(MainMenu, { wrapper = mount(MainMenu, {
store, store,
@@ -572,11 +589,17 @@ describe('MainMenu.vue', () => {
.find(button => button.text() === 'Save') .find(button => button.text() === 'Save')
.trigger('click') .trigger('click')
await wrapper.vm.$nextTick()
// check that the dialog is closed // check that the dialog is closed
expect(wrapper.find('[data-modal="save"]').exists()).to.equal(false) expect(wrapper.find('[data-modal="save"]').exists()).to.equal(false)
// check that the inquiry was saved via storedInquiries.save (newName='bar') // check that the inquiry was saved via saveInquiry (newName='bar')
expect(storedInquiries.save.calledOnceWith(state.currentTab, 'bar')).to.equal(true) expect(actions.saveInquiry.calledOnce).to.equal(true)
expect(actions.saveInquiry.args[0][1]).to.eql({
inquiryTab: state.currentTab,
newName: 'bar'
})
// check that the tab was updated // check that the tab was updated
expect(mutations.updateTab.calledOnceWith(state, sinon.match({ expect(mutations.updateTab.calledOnceWith(state, sinon.match({
@@ -625,15 +648,17 @@ describe('MainMenu.vue', () => {
const mutations = { const mutations = {
updateTab: sinon.stub() updateTab: sinon.stub()
} }
const store = new Vuex.Store({ state, mutations }) const actions = {
saveInquiry: sinon.stub().returns({
name: 'bar',
id: 2,
query: 'SELECT * FROM foo',
chart: []
})
}
const store = new Vuex.Store({ state, mutations, actions })
const $route = { path: '/workspace' } const $route = { path: '/workspace' }
sinon.stub(storedInquiries, 'isTabNeedName').returns(true) sinon.stub(storedInquiries, 'isTabNeedName').returns(true)
sinon.stub(storedInquiries, 'save').returns({
name: 'bar',
id: 2,
query: 'SELECT * FROM foo',
chart: []
})
wrapper = mount(MainMenu, { wrapper = mount(MainMenu, {
store, store,
@@ -656,7 +681,7 @@ describe('MainMenu.vue', () => {
expect(wrapper.find('[data-modal="save"]').exists()).to.equal(false) expect(wrapper.find('[data-modal="save"]').exists()).to.equal(false)
// check that the inquiry was not saved via storedInquiries.save // check that the inquiry was not saved via storedInquiries.save
expect(storedInquiries.save.called).to.equal(false) expect(actions.saveInquiry.called).to.equal(false)
// check that the tab was not updated // check that the tab was not updated
expect(mutations.updateTab.called).to.equal(false) expect(mutations.updateTab.called).to.equal(false)