mirror of
https://github.com/lana-k/sqliteviz.git
synced 2025-12-08 02:58:54 +08:00
Compare commits
9 Commits
3893a66f4e
...
0.25.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3a05b27400 | ||
|
|
108d96a753 | ||
|
|
f55a8caa92 | ||
|
|
87f9f9eb01 | ||
|
|
d6408bdd85 | ||
|
|
378b9fb580 | ||
|
|
244ba9eb08 | ||
|
|
53e5194295 | ||
|
|
04274ef19a |
4
.github/workflows/main.yml
vendored
4
.github/workflows/main.yml
vendored
@@ -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: |
|
||||||
|
|||||||
4
.github/workflows/test.yml
vendored
4
.github/workflows/test.yml
vendored
@@ -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
|
||||||
|
|||||||
@@ -4,11 +4,12 @@
|
|||||||
|
|
||||||
# sqliteviz
|
# sqliteviz
|
||||||
|
|
||||||
Sqliteviz is a single-page offline-first PWA for fully client-side visualisation of SQLite databases or CSV files.
|
Sqliteviz is a single-page offline-first PWA for fully client-side visualisation
|
||||||
|
of SQLite databases, CSV, JSON or NDJSON files.
|
||||||
|
|
||||||
With sqliteviz you can:
|
With sqliteviz you can:
|
||||||
- run SQL queries against a SQLite database and create [Plotly][11] charts and pivot tables based on the result sets
|
- run SQL queries against a SQLite database and create [Plotly][11] charts and pivot tables based on the result sets
|
||||||
- import a CSV file into a SQLite database and visualize imported data
|
- import a CSV/JSON/NDJSON file into a SQLite database and visualize imported data
|
||||||
- export result set to CSV file
|
- export result set to CSV file
|
||||||
- manage inquiries and run them against different databases
|
- manage inquiries and run them against different databases
|
||||||
- import/export inquiries from/to a JSON file
|
- import/export inquiries from/to a JSON file
|
||||||
|
|||||||
7057
package-lock.json
generated
7057
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
12
package.json
12
package.json
@@ -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",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"background_color": "white",
|
"background_color": "white",
|
||||||
"description": "Sqliteviz is a single-page application for fully client-side visualisation of SQLite databases or CSV.",
|
"description": "Sqliteviz is a single-page application for fully client-side visualisation of SQLite databases, CSV, JSON or NDJSON.",
|
||||||
"display": "fullscreen",
|
"display": "fullscreen",
|
||||||
"icons": [
|
"icons": [
|
||||||
{
|
{
|
||||||
|
|||||||
23
src/App.vue
23
src/App.vue
@@ -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";
|
||||||
|
|||||||
@@ -348,7 +348,8 @@ export default {
|
|||||||
this.addedTable = this.tableName
|
this.addedTable = this.tableName
|
||||||
// Inform about import success
|
// Inform about import success
|
||||||
period = time.getPeriod(start, end)
|
period = time.getPeriod(start, end)
|
||||||
importMsg.message = `Importing ${this.typeName} into a SQLite database is completed in ${period}.`
|
importMsg.message = `Importing ${this.typeName} ` +
|
||||||
|
`into a SQLite database is completed in ${period}.`
|
||||||
importMsg.type = 'success'
|
importMsg.type = 'success'
|
||||||
|
|
||||||
// Loading indicator for import is not needed anymore
|
// Loading indicator for import is not needed anymore
|
||||||
@@ -408,7 +409,8 @@ export default {
|
|||||||
return [
|
return [
|
||||||
'/*',
|
'/*',
|
||||||
` * Your NDJSON file has been imported into ${this.addedTable} table.`,
|
` * Your NDJSON file has been imported into ${this.addedTable} table.`,
|
||||||
` * Run this SQL query to get values of property ${firstKey} and make them available for charting.`,
|
` * Run this SQL query to get values of property ${firstKey} ` +
|
||||||
|
'and make them available for charting.',
|
||||||
' */',
|
' */',
|
||||||
`SELECT doc->>'${firstKey}'`,
|
`SELECT doc->>'${firstKey}'`,
|
||||||
`FROM "${this.addedTable}"`
|
`FROM "${this.addedTable}"`
|
||||||
@@ -431,7 +433,8 @@ export default {
|
|||||||
return [
|
return [
|
||||||
'/*',
|
'/*',
|
||||||
` * Your JSON file has been imported into ${this.addedTable} table.`,
|
` * Your JSON file has been imported into ${this.addedTable} table.`,
|
||||||
` * Run this SQL query to get values of property ${firstKey} and make them available for charting.`,
|
` * Run this SQL query to get values of property ${firstKey} ` +
|
||||||
|
'and make them available for charting.',
|
||||||
' */',
|
' */',
|
||||||
'SELECT *',
|
'SELECT *',
|
||||||
`FROM "${this.addedTable}"`,
|
`FROM "${this.addedTable}"`,
|
||||||
|
|||||||
@@ -10,7 +10,8 @@
|
|||||||
@click="browse"
|
@click="browse"
|
||||||
>
|
>
|
||||||
<div class="text">
|
<div class="text">
|
||||||
Drop the database or CSV file here or click to choose a file from your computer.
|
Drop the database, CSV, JSON or NDJSON file here
|
||||||
|
or click to choose a file from your computer.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ export default {
|
|||||||
components: { Pager },
|
components: { Pager },
|
||||||
props: {
|
props: {
|
||||||
dataSet: Object,
|
dataSet: Object,
|
||||||
time: String,
|
time: [String, Number],
|
||||||
pageSize: {
|
pageSize: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 20
|
default: 20
|
||||||
|
|||||||
@@ -34,7 +34,7 @@
|
|||||||
</defs>
|
</defs>
|
||||||
</svg>
|
</svg>
|
||||||
<span class="icon-tooltip" :style="tooltipStyle" ref="tooltip">
|
<span class="icon-tooltip" :style="tooltipStyle" ref="tooltip">
|
||||||
Add new table from CSV
|
Add new table from CSV, JSON or NDJSON
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
<span class="icon-tooltip" :style="tooltipStyle" ref="tooltip">
|
<span class="icon-tooltip" :style="tooltipStyle" ref="tooltip">
|
||||||
Load another database or CSV
|
Load another database, CSV, JSON or NDJSON
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -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 }))
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,5 +60,8 @@ export default {
|
|||||||
},
|
},
|
||||||
setPredefinedInquiriesLoaded (state, value) {
|
setPredefinedInquiriesLoaded (state, value) {
|
||||||
state.predefinedInquiriesLoaded = value
|
state.predefinedInquiriesLoaded = value
|
||||||
|
},
|
||||||
|
setInquiries (state, value) {
|
||||||
|
state.inquiries = value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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)
|
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -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', {
|
||||||
|
|||||||
@@ -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
52
tests/App.spec.js
Normal 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' }
|
||||||
|
])
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -13,7 +13,7 @@ describe('CsvJsonImport.vue', () => {
|
|||||||
let clock
|
let clock
|
||||||
let wrapper
|
let wrapper
|
||||||
const newTabId = 1
|
const newTabId = 1
|
||||||
const file = { name: 'my data.csv' }
|
const file = new File([], 'my data.csv')
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
clock = sinon.useFakeTimers()
|
clock = sinon.useFakeTimers()
|
||||||
@@ -78,6 +78,7 @@ describe('CsvJsonImport.vue', () => {
|
|||||||
await wrapper.vm.open()
|
await wrapper.vm.open()
|
||||||
await wrapper.vm.$nextTick()
|
await wrapper.vm.$nextTick()
|
||||||
expect(wrapper.find('[data-modal="addCsvJson"]').exists()).to.equal(true)
|
expect(wrapper.find('[data-modal="addCsvJson"]').exists()).to.equal(true)
|
||||||
|
expect(wrapper.find('.dialog-header').text()).to.equal('CSV import')
|
||||||
expect(wrapper.find('#csv-json-table-name input').element.value).to.equal('my_data')
|
expect(wrapper.find('#csv-json-table-name input').element.value).to.equal('my_data')
|
||||||
expect(wrapper.findComponent({ name: 'delimiter-selector' }).vm.value).to.equal('|')
|
expect(wrapper.findComponent({ name: 'delimiter-selector' }).vm.value).to.equal('|')
|
||||||
expect(wrapper.find('#quote-char input').element.value).to.equal('"')
|
expect(wrapper.find('#quote-char input').element.value).to.equal('"')
|
||||||
@@ -95,6 +96,34 @@ describe('CsvJsonImport.vue', () => {
|
|||||||
.to.include('Preview parsing is completed in')
|
.to.include('Preview parsing is completed in')
|
||||||
expect(wrapper.find('#import-finish').isVisible()).to.equal(false)
|
expect(wrapper.find('#import-finish').isVisible()).to.equal(false)
|
||||||
expect(wrapper.find('#import-start').isVisible()).to.equal(true)
|
expect(wrapper.find('#import-start').isVisible()).to.equal(true)
|
||||||
|
expect(wrapper.find('#import-start').attributes().disabled).to.equal(undefined)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('disables import if no rows found', async () => {
|
||||||
|
sinon.stub(csv, 'parse').resolves({
|
||||||
|
delimiter: '|',
|
||||||
|
data: {
|
||||||
|
columns: ['col2', 'col1'],
|
||||||
|
values: {
|
||||||
|
col1: [],
|
||||||
|
col2: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
rowCount: 0,
|
||||||
|
messages: []
|
||||||
|
})
|
||||||
|
|
||||||
|
await wrapper.vm.preview()
|
||||||
|
await wrapper.vm.open()
|
||||||
|
await wrapper.vm.$nextTick()
|
||||||
|
const rows = wrapper.findAll('tbody tr')
|
||||||
|
expect(rows).to.have.lengthOf(0)
|
||||||
|
expect(wrapper.findComponent({ name: 'logs' }).text())
|
||||||
|
.to.include('No rows to import.')
|
||||||
|
expect(wrapper.find('.no-data').isVisible()).to.equal(true)
|
||||||
|
expect(wrapper.find('#import-finish').isVisible()).to.equal(false)
|
||||||
|
expect(wrapper.find('#import-start').isVisible()).to.equal(true)
|
||||||
|
expect(wrapper.find('#import-start').attributes().disabled).to.equal('disabled')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('reparses when parameters changes', async () => {
|
it('reparses when parameters changes', async () => {
|
||||||
@@ -231,7 +260,8 @@ describe('CsvJsonImport.vue', () => {
|
|||||||
col2: ['foo']
|
col2: ['foo']
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
rowCount: 1
|
rowCount: 1,
|
||||||
|
messages: []
|
||||||
})
|
})
|
||||||
|
|
||||||
wrapper.vm.preview()
|
wrapper.vm.preview()
|
||||||
@@ -240,7 +270,18 @@ describe('CsvJsonImport.vue', () => {
|
|||||||
|
|
||||||
let resolveParsing
|
let resolveParsing
|
||||||
parse.onCall(1).returns(new Promise(resolve => {
|
parse.onCall(1).returns(new Promise(resolve => {
|
||||||
resolveParsing = resolve
|
resolveParsing = () => resolve({
|
||||||
|
delimiter: '|',
|
||||||
|
data: {
|
||||||
|
columns: ['col1', 'col2'],
|
||||||
|
values: {
|
||||||
|
col1: [1],
|
||||||
|
col2: ['foo']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
rowCount: 1,
|
||||||
|
messages: []
|
||||||
|
})
|
||||||
}))
|
}))
|
||||||
|
|
||||||
await wrapper.find('#csv-json-table-name input').setValue('foo')
|
await wrapper.find('#csv-json-table-name input').setValue('foo')
|
||||||
@@ -715,7 +756,11 @@ describe('CsvJsonImport.vue', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('checks table name', async () => {
|
it('checks table name', async () => {
|
||||||
sinon.stub(csv, 'parse').resolves()
|
sinon.stub(csv, 'parse').resolves({
|
||||||
|
data: {},
|
||||||
|
hasErrors: false,
|
||||||
|
messages: []
|
||||||
|
})
|
||||||
await wrapper.vm.preview()
|
await wrapper.vm.preview()
|
||||||
await wrapper.vm.open()
|
await wrapper.vm.open()
|
||||||
await wrapper.vm.$nextTick()
|
await wrapper.vm.$nextTick()
|
||||||
@@ -743,3 +788,477 @@ describe('CsvJsonImport.vue', () => {
|
|||||||
expect(wrapper.vm.db.addTableFromCsv.called).to.equal(false)
|
expect(wrapper.vm.db.addTableFromCsv.called).to.equal(false)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('CsvJsonImport.vue - json', () => {
|
||||||
|
let state = {}
|
||||||
|
let actions = {}
|
||||||
|
let mutations = {}
|
||||||
|
let store = {}
|
||||||
|
let clock
|
||||||
|
let wrapper
|
||||||
|
const newTabId = 1
|
||||||
|
const file = new File(
|
||||||
|
[new Blob(
|
||||||
|
[JSON.stringify({ foo: [1, 2, 3] }, null, 2)],
|
||||||
|
{ type: 'application/json' }
|
||||||
|
)],
|
||||||
|
'my data.json',
|
||||||
|
{ type: 'application/json' })
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
clock = sinon.useFakeTimers()
|
||||||
|
|
||||||
|
// mock store state and mutations
|
||||||
|
state = {}
|
||||||
|
mutations = {
|
||||||
|
setDb: sinon.stub(),
|
||||||
|
setCurrentTabId: sinon.stub()
|
||||||
|
}
|
||||||
|
actions = {
|
||||||
|
addTab: sinon.stub().resolves(newTabId)
|
||||||
|
}
|
||||||
|
store = new Vuex.Store({ state, mutations, actions })
|
||||||
|
|
||||||
|
const db = {
|
||||||
|
sanitizeTableName: sinon.stub().returns('my_data'),
|
||||||
|
addTableFromCsv: sinon.stub().resolves(),
|
||||||
|
createProgressCounter: sinon.stub().returns(1),
|
||||||
|
deleteProgressCounter: sinon.stub(),
|
||||||
|
validateTableName: sinon.stub().resolves(),
|
||||||
|
execute: sinon.stub().resolves(),
|
||||||
|
refreshSchema: sinon.stub().resolves()
|
||||||
|
}
|
||||||
|
|
||||||
|
// mount the component
|
||||||
|
wrapper = mount(CsvJsonImport, {
|
||||||
|
store,
|
||||||
|
propsData: {
|
||||||
|
file,
|
||||||
|
dialogName: 'addCsvJson',
|
||||||
|
db
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
sinon.restore()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('previews', async () => {
|
||||||
|
await wrapper.vm.preview()
|
||||||
|
await wrapper.vm.open()
|
||||||
|
await wrapper.vm.$nextTick()
|
||||||
|
expect(wrapper.find('[data-modal="addCsvJson"]').exists()).to.equal(true)
|
||||||
|
expect(wrapper.find('.dialog-header').text()).to.equal('JSON import')
|
||||||
|
expect(wrapper.find('#csv-json-table-name input').element.value).to.equal('my_data')
|
||||||
|
expect(wrapper.findComponent({ name: 'delimiter-selector' }).exists()).to.equal(false)
|
||||||
|
expect(wrapper.find('#quote-char input').exists()).to.equal(false)
|
||||||
|
expect(wrapper.find('#escape-char input').exists()).to.equal(false)
|
||||||
|
expect(wrapper.findComponent({ name: 'check-box' }).exists()).to.equal(false)
|
||||||
|
const rows = wrapper.findAll('tbody tr')
|
||||||
|
expect(rows).to.have.lengthOf(1)
|
||||||
|
expect(rows.at(0).findAll('td').at(0).text()).to.equal([
|
||||||
|
'{',
|
||||||
|
' "foo": [',
|
||||||
|
' 1,',
|
||||||
|
' 2,',
|
||||||
|
' 3',
|
||||||
|
' ]',
|
||||||
|
'}'
|
||||||
|
].join('\n')
|
||||||
|
)
|
||||||
|
expect(wrapper.findComponent({ name: 'logs' }).text())
|
||||||
|
.to.include('Preview parsing is completed in')
|
||||||
|
expect(wrapper.find('#import-finish').isVisible()).to.equal(false)
|
||||||
|
expect(wrapper.find('#import-start').isVisible()).to.equal(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('has proper state before parsing is complete', async () => {
|
||||||
|
const getJsonParseResult = sinon.stub(wrapper.vm, 'getJsonParseResult')
|
||||||
|
getJsonParseResult.onCall(0).returns({
|
||||||
|
delimiter: '|',
|
||||||
|
data: {
|
||||||
|
columns: ['doc'],
|
||||||
|
values: {
|
||||||
|
doc: ['{ "foo": [ 1, 2, 3 ] }']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
rowCount: 1,
|
||||||
|
hasErrors: false,
|
||||||
|
messages: []
|
||||||
|
})
|
||||||
|
|
||||||
|
let resolveParsing
|
||||||
|
getJsonParseResult.onCall(1).returns(new Promise(resolve => {
|
||||||
|
resolveParsing = () => resolve({
|
||||||
|
delimiter: '|',
|
||||||
|
data: {
|
||||||
|
columns: ['doc'],
|
||||||
|
values: {
|
||||||
|
doc: ['{ "foo": [ 1, 2, 3 ] }']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
rowCount: 1,
|
||||||
|
hasErrors: false,
|
||||||
|
messages: []
|
||||||
|
})
|
||||||
|
}))
|
||||||
|
|
||||||
|
await wrapper.vm.preview()
|
||||||
|
await wrapper.vm.open()
|
||||||
|
await wrapper.vm.$nextTick()
|
||||||
|
|
||||||
|
await wrapper.find('#csv-json-table-name input').setValue('foo')
|
||||||
|
await wrapper.find('#import-start').trigger('click')
|
||||||
|
await wrapper.vm.$nextTick()
|
||||||
|
|
||||||
|
// "Parsing JSON..." in the logs
|
||||||
|
expect(wrapper.findComponent({ name: 'logs' }).findAll('.msg').at(1).text())
|
||||||
|
.to.equal('Parsing JSON...')
|
||||||
|
|
||||||
|
// After 1 second - loading indicator is shown
|
||||||
|
await clock.tick(1000)
|
||||||
|
expect(
|
||||||
|
wrapper.findComponent({ name: 'logs' }).findComponent({ name: 'LoadingIndicator' }).exists()
|
||||||
|
).to.equal(true)
|
||||||
|
|
||||||
|
// All the dialog controls are disabled
|
||||||
|
expect(wrapper.find('#import-cancel').element.disabled).to.equal(true)
|
||||||
|
expect(wrapper.find('#import-finish').element.disabled).to.equal(true)
|
||||||
|
expect(wrapper.findComponent({ name: 'close-icon' }).vm.disabled).to.equal(true)
|
||||||
|
expect(wrapper.find('#import-finish').isVisible()).to.equal(false)
|
||||||
|
expect(wrapper.find('#import-start').isVisible()).to.equal(true)
|
||||||
|
await resolveParsing()
|
||||||
|
await getJsonParseResult.returnValues[1]
|
||||||
|
|
||||||
|
// Loading indicator is not shown when parsing is compete
|
||||||
|
expect(
|
||||||
|
wrapper.findComponent({ name: 'logs' }).findComponent({ name: 'LoadingIndicator' }).exists()
|
||||||
|
).to.equal(false)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('has proper state before import is completed', async () => {
|
||||||
|
const getJsonParseResult = sinon.spy(wrapper.vm, 'getJsonParseResult')
|
||||||
|
|
||||||
|
let resolveImport = sinon.stub()
|
||||||
|
wrapper.vm.db.addTableFromCsv = sinon.stub()
|
||||||
|
.resolves(new Promise(resolve => { resolveImport = resolve }))
|
||||||
|
|
||||||
|
await wrapper.vm.preview()
|
||||||
|
await wrapper.vm.open()
|
||||||
|
await wrapper.vm.$nextTick()
|
||||||
|
|
||||||
|
await wrapper.find('#csv-json-table-name input').setValue('foo')
|
||||||
|
await wrapper.find('#import-start').trigger('click')
|
||||||
|
await getJsonParseResult.returnValues[1]
|
||||||
|
await wrapper.vm.$nextTick()
|
||||||
|
|
||||||
|
// Parsing success in the logs
|
||||||
|
expect(wrapper.findComponent({ name: 'logs' }).findAll('.msg').at(2).text())
|
||||||
|
.to.equal('Importing JSON into a SQLite database...')
|
||||||
|
|
||||||
|
// After 1 second - loading indicator is shown
|
||||||
|
await clock.tick(1000)
|
||||||
|
expect(
|
||||||
|
wrapper.findComponent({ name: 'logs' }).findComponent({ name: 'LoadingIndicator' }).exists()
|
||||||
|
).to.equal(true)
|
||||||
|
|
||||||
|
// All the dialog controls are disabled
|
||||||
|
expect(wrapper.find('#import-cancel').element.disabled).to.equal(true)
|
||||||
|
expect(wrapper.find('#import-finish').element.disabled).to.equal(true)
|
||||||
|
expect(wrapper.findComponent({ name: 'close-icon' }).vm.disabled).to.equal(true)
|
||||||
|
expect(wrapper.find('#import-finish').isVisible()).to.equal(false)
|
||||||
|
expect(wrapper.find('#import-start').isVisible()).to.equal(true)
|
||||||
|
expect(wrapper.vm.db.addTableFromCsv.getCall(0).args[0]).to.equal('foo') // table name
|
||||||
|
|
||||||
|
// After resolving - loading indicator is not shown
|
||||||
|
await resolveImport()
|
||||||
|
await wrapper.vm.db.addTableFromCsv.returnValues[0]
|
||||||
|
expect(
|
||||||
|
wrapper.findComponent({ name: 'logs' }).findComponent({ name: 'LoadingIndicator' }).exists()
|
||||||
|
).to.equal(false)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('import success', async () => {
|
||||||
|
const getJsonParseResult = sinon.spy(wrapper.vm, 'getJsonParseResult')
|
||||||
|
|
||||||
|
await wrapper.vm.preview()
|
||||||
|
await wrapper.vm.open()
|
||||||
|
await wrapper.vm.$nextTick()
|
||||||
|
|
||||||
|
await wrapper.find('#csv-json-table-name input').setValue('foo')
|
||||||
|
await wrapper.find('#import-start').trigger('click')
|
||||||
|
await getJsonParseResult.returnValues[1]
|
||||||
|
await wrapper.vm.$nextTick()
|
||||||
|
|
||||||
|
// Import success in the logs
|
||||||
|
const logs = wrapper.findComponent({ name: 'logs' }).findAll('.msg')
|
||||||
|
expect(logs).to.have.lengthOf(3)
|
||||||
|
expect(logs.at(2).text()).to.contain('Importing JSON into a SQLite database is completed in')
|
||||||
|
|
||||||
|
// All the dialog controls are enabled
|
||||||
|
expect(wrapper.find('#import-cancel').element.disabled).to.equal(false)
|
||||||
|
expect(wrapper.find('#import-finish').element.disabled).to.equal(false)
|
||||||
|
expect(wrapper.findComponent({ name: 'close-icon' }).vm.disabled).to.equal(false)
|
||||||
|
expect(wrapper.find('#import-finish').isVisible()).to.equal(true)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('CsvJsonImport.vue - ndjson', () => {
|
||||||
|
let state = {}
|
||||||
|
let actions = {}
|
||||||
|
let mutations = {}
|
||||||
|
let store = {}
|
||||||
|
let clock
|
||||||
|
let wrapper
|
||||||
|
const newTabId = 1
|
||||||
|
const file = new File([], 'my data.ndjson')
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
clock = sinon.useFakeTimers()
|
||||||
|
|
||||||
|
// mock store state and mutations
|
||||||
|
state = {}
|
||||||
|
mutations = {
|
||||||
|
setDb: sinon.stub(),
|
||||||
|
setCurrentTabId: sinon.stub()
|
||||||
|
}
|
||||||
|
actions = {
|
||||||
|
addTab: sinon.stub().resolves(newTabId)
|
||||||
|
}
|
||||||
|
store = new Vuex.Store({ state, mutations, actions })
|
||||||
|
|
||||||
|
const db = {
|
||||||
|
sanitizeTableName: sinon.stub().returns('my_data'),
|
||||||
|
addTableFromCsv: sinon.stub().resolves(),
|
||||||
|
createProgressCounter: sinon.stub().returns(1),
|
||||||
|
deleteProgressCounter: sinon.stub(),
|
||||||
|
validateTableName: sinon.stub().resolves(),
|
||||||
|
execute: sinon.stub().resolves(),
|
||||||
|
refreshSchema: sinon.stub().resolves()
|
||||||
|
}
|
||||||
|
|
||||||
|
// mount the component
|
||||||
|
wrapper = mount(CsvJsonImport, {
|
||||||
|
store,
|
||||||
|
propsData: {
|
||||||
|
file,
|
||||||
|
dialogName: 'addCsvJson',
|
||||||
|
db
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
sinon.restore()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('previews', async () => {
|
||||||
|
sinon.stub(csv, 'parse').resolves({
|
||||||
|
delimiter: '|',
|
||||||
|
data: {
|
||||||
|
columns: ['doc'],
|
||||||
|
values: {
|
||||||
|
doc: ['{ "foo": [ 1, 2, 3 ] }']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
rowCount: 1,
|
||||||
|
messages: []
|
||||||
|
})
|
||||||
|
|
||||||
|
wrapper.vm.preview()
|
||||||
|
await wrapper.vm.open()
|
||||||
|
await wrapper.vm.$nextTick()
|
||||||
|
expect(wrapper.find('[data-modal="addCsvJson"]').exists()).to.equal(true)
|
||||||
|
expect(wrapper.find('.dialog-header').text()).to.equal('JSON import')
|
||||||
|
expect(wrapper.find('#csv-json-table-name input').element.value).to.equal('my_data')
|
||||||
|
expect(wrapper.findComponent({ name: 'delimiter-selector' }).exists()).to.equal(false)
|
||||||
|
expect(wrapper.find('#quote-char input').exists()).to.equal(false)
|
||||||
|
expect(wrapper.find('#escape-char input').exists()).to.equal(false)
|
||||||
|
expect(wrapper.findComponent({ name: 'check-box' }).exists()).to.equal(false)
|
||||||
|
const rows = wrapper.findAll('tbody tr')
|
||||||
|
expect(rows).to.have.lengthOf(1)
|
||||||
|
expect(rows.at(0).findAll('td').at(0).text()).to.equal('{ "foo": [ 1, 2, 3 ] }')
|
||||||
|
expect(wrapper.findComponent({ name: 'logs' }).text())
|
||||||
|
.to.include('Preview parsing is completed in')
|
||||||
|
expect(wrapper.find('#import-finish').isVisible()).to.equal(false)
|
||||||
|
expect(wrapper.find('#import-start').isVisible()).to.equal(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('has proper state before parsing is complete', async () => {
|
||||||
|
const parse = sinon.stub(csv, 'parse')
|
||||||
|
parse.onCall(0).resolves({
|
||||||
|
delimiter: '|',
|
||||||
|
data: {
|
||||||
|
columns: ['doc'],
|
||||||
|
values: {
|
||||||
|
doc: ['{ "foo": [ 1, 2, 3 ] }']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
rowCount: 1
|
||||||
|
})
|
||||||
|
|
||||||
|
wrapper.vm.preview()
|
||||||
|
wrapper.vm.open()
|
||||||
|
await wrapper.vm.$nextTick()
|
||||||
|
|
||||||
|
let resolveParsing
|
||||||
|
parse.onCall(1).returns(new Promise(resolve => {
|
||||||
|
resolveParsing = () => resolve({
|
||||||
|
delimiter: '|',
|
||||||
|
data: {
|
||||||
|
columns: ['doc'],
|
||||||
|
values: {
|
||||||
|
doc: ['{ "foo": [ 1, 2, 3 ] }']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
rowCount: 1,
|
||||||
|
messages: []
|
||||||
|
})
|
||||||
|
}))
|
||||||
|
|
||||||
|
await wrapper.find('#csv-json-table-name input').setValue('foo')
|
||||||
|
await wrapper.find('#import-start').trigger('click')
|
||||||
|
await wrapper.vm.$nextTick()
|
||||||
|
|
||||||
|
// "Parsing JSON..." in the logs
|
||||||
|
expect(wrapper.findComponent({ name: 'logs' }).findAll('.msg').at(1).text())
|
||||||
|
.to.equal('Parsing JSON...')
|
||||||
|
|
||||||
|
// After 1 second - loading indicator is shown
|
||||||
|
await clock.tick(1000)
|
||||||
|
expect(
|
||||||
|
wrapper.findComponent({ name: 'logs' }).findComponent({ name: 'LoadingIndicator' }).exists()
|
||||||
|
).to.equal(true)
|
||||||
|
|
||||||
|
// All the dialog controls are disabled
|
||||||
|
expect(wrapper.find('#import-cancel').element.disabled).to.equal(true)
|
||||||
|
expect(wrapper.find('#import-finish').element.disabled).to.equal(true)
|
||||||
|
expect(wrapper.findComponent({ name: 'close-icon' }).vm.disabled).to.equal(true)
|
||||||
|
expect(wrapper.find('#import-finish').isVisible()).to.equal(false)
|
||||||
|
expect(wrapper.find('#import-start').isVisible()).to.equal(true)
|
||||||
|
await resolveParsing()
|
||||||
|
await parse.returnValues[1]
|
||||||
|
|
||||||
|
// Loading indicator is not shown when parsing is compete
|
||||||
|
expect(
|
||||||
|
wrapper.findComponent({ name: 'logs' }).findComponent({ name: 'LoadingIndicator' }).exists()
|
||||||
|
).to.equal(false)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('has proper state before import is completed', async () => {
|
||||||
|
const parse = sinon.stub(csv, 'parse')
|
||||||
|
parse.onCall(0).resolves({
|
||||||
|
delimiter: '|',
|
||||||
|
data: {
|
||||||
|
columns: ['doc'],
|
||||||
|
values: {
|
||||||
|
doc: ['{ "foo": [ 1, 2, 3 ] }']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
rowCount: 1,
|
||||||
|
hasErrors: false,
|
||||||
|
messages: []
|
||||||
|
})
|
||||||
|
|
||||||
|
parse.onCall(1).resolves({
|
||||||
|
delimiter: '|',
|
||||||
|
data: {
|
||||||
|
columns: ['doc'],
|
||||||
|
values: {
|
||||||
|
doc: ['{ "foo": [ 1, 2, 3 ] }']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
rowCount: 1,
|
||||||
|
hasErrors: false,
|
||||||
|
messages: []
|
||||||
|
})
|
||||||
|
|
||||||
|
let resolveImport = sinon.stub()
|
||||||
|
wrapper.vm.db.addTableFromCsv = sinon.stub()
|
||||||
|
.resolves(new Promise(resolve => { resolveImport = resolve }))
|
||||||
|
|
||||||
|
wrapper.vm.preview()
|
||||||
|
wrapper.vm.open()
|
||||||
|
await wrapper.vm.$nextTick()
|
||||||
|
|
||||||
|
await wrapper.find('#csv-json-table-name input').setValue('foo')
|
||||||
|
await wrapper.find('#import-start').trigger('click')
|
||||||
|
await csv.parse.returnValues[1]
|
||||||
|
await wrapper.vm.$nextTick()
|
||||||
|
|
||||||
|
// Parsing success in the logs
|
||||||
|
expect(wrapper.findComponent({ name: 'logs' }).findAll('.msg').at(2).text())
|
||||||
|
.to.equal('Importing JSON into a SQLite database...')
|
||||||
|
|
||||||
|
// After 1 second - loading indicator is shown
|
||||||
|
await clock.tick(1000)
|
||||||
|
expect(
|
||||||
|
wrapper.findComponent({ name: 'logs' }).findComponent({ name: 'LoadingIndicator' }).exists()
|
||||||
|
).to.equal(true)
|
||||||
|
|
||||||
|
// All the dialog controls are disabled
|
||||||
|
expect(wrapper.find('#import-cancel').element.disabled).to.equal(true)
|
||||||
|
expect(wrapper.find('#import-finish').element.disabled).to.equal(true)
|
||||||
|
expect(wrapper.findComponent({ name: 'close-icon' }).vm.disabled).to.equal(true)
|
||||||
|
expect(wrapper.find('#import-finish').isVisible()).to.equal(false)
|
||||||
|
expect(wrapper.find('#import-start').isVisible()).to.equal(true)
|
||||||
|
expect(wrapper.vm.db.addTableFromCsv.getCall(0).args[0]).to.equal('foo') // table name
|
||||||
|
|
||||||
|
// After resolving - loading indicator is not shown
|
||||||
|
await resolveImport()
|
||||||
|
await wrapper.vm.db.addTableFromCsv.returnValues[0]
|
||||||
|
expect(
|
||||||
|
wrapper.findComponent({ name: 'logs' }).findComponent({ name: 'LoadingIndicator' }).exists()
|
||||||
|
).to.equal(false)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('import success', async () => {
|
||||||
|
const parse = sinon.stub(csv, 'parse')
|
||||||
|
parse.onCall(0).resolves({
|
||||||
|
delimiter: '|',
|
||||||
|
data: {
|
||||||
|
columns: ['doc'],
|
||||||
|
values: {
|
||||||
|
doc: ['{ "foo": [ 1, 2, 3 ] }']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
rowCount: 1,
|
||||||
|
hasErrors: false,
|
||||||
|
messages: []
|
||||||
|
})
|
||||||
|
// we need to separate calles because messages will mutate
|
||||||
|
parse.onCall(1).resolves({
|
||||||
|
delimiter: '|',
|
||||||
|
data: {
|
||||||
|
columns: ['doc'],
|
||||||
|
values: {
|
||||||
|
doc: ['{ "foo": [ 1, 2, 3 ] }']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
rowCount: 2,
|
||||||
|
hasErrors: false,
|
||||||
|
messages: []
|
||||||
|
})
|
||||||
|
|
||||||
|
wrapper.vm.preview()
|
||||||
|
wrapper.vm.open()
|
||||||
|
await wrapper.vm.$nextTick()
|
||||||
|
|
||||||
|
await wrapper.find('#csv-json-table-name input').setValue('foo')
|
||||||
|
await wrapper.find('#import-start').trigger('click')
|
||||||
|
await csv.parse.returnValues[1]
|
||||||
|
await wrapper.vm.$nextTick()
|
||||||
|
|
||||||
|
// Import success in the logs
|
||||||
|
const logs = wrapper.findComponent({ name: 'logs' }).findAll('.msg')
|
||||||
|
expect(logs).to.have.lengthOf(3)
|
||||||
|
expect(logs.at(2).text()).to.contain('Importing JSON into a SQLite database is completed in')
|
||||||
|
|
||||||
|
// All the dialog controls are enabled
|
||||||
|
expect(wrapper.find('#import-cancel').element.disabled).to.equal(false)
|
||||||
|
expect(wrapper.find('#import-finish').element.disabled).to.equal(false)
|
||||||
|
expect(wrapper.findComponent({ name: 'close-icon' }).vm.disabled).to.equal(false)
|
||||||
|
expect(wrapper.find('#import-finish').isVisible()).to.equal(true)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ describe('DbUploader.vue', () => {
|
|||||||
|
|
||||||
it('loads db on click and redirects to /workspace', async () => {
|
it('loads db on click and redirects to /workspace', async () => {
|
||||||
// mock getting a file from user
|
// mock getting a file from user
|
||||||
const file = { name: 'test.db' }
|
const file = new File([], 'test.db')
|
||||||
sinon.stub(fu, 'getFileFromUser').resolves(file)
|
sinon.stub(fu, 'getFileFromUser').resolves(file)
|
||||||
|
|
||||||
// mock db loading
|
// mock db loading
|
||||||
@@ -85,7 +85,7 @@ describe('DbUploader.vue', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// mock a file dropped by a user
|
// mock a file dropped by a user
|
||||||
const file = { name: 'test.db' }
|
const file = new File([], 'test.db')
|
||||||
const dropData = { dataTransfer: new DataTransfer() }
|
const dropData = { dataTransfer: new DataTransfer() }
|
||||||
Object.defineProperty(dropData.dataTransfer, 'files', {
|
Object.defineProperty(dropData.dataTransfer, 'files', {
|
||||||
value: [file],
|
value: [file],
|
||||||
@@ -103,7 +103,7 @@ describe('DbUploader.vue', () => {
|
|||||||
|
|
||||||
it("doesn't redirect if already on /workspace", async () => {
|
it("doesn't redirect if already on /workspace", async () => {
|
||||||
// mock getting a file from user
|
// mock getting a file from user
|
||||||
const file = { name: 'test.db' }
|
const file = new File([], 'test.db')
|
||||||
sinon.stub(fu, 'getFileFromUser').resolves(file)
|
sinon.stub(fu, 'getFileFromUser').resolves(file)
|
||||||
|
|
||||||
// mock db loading
|
// mock db loading
|
||||||
@@ -136,7 +136,7 @@ describe('DbUploader.vue', () => {
|
|||||||
|
|
||||||
it('shows parse dialog if gets csv file', async () => {
|
it('shows parse dialog if gets csv file', async () => {
|
||||||
// mock getting a file from user
|
// mock getting a file from user
|
||||||
const file = { name: 'test.csv' }
|
const file = new File([], 'test.csv')
|
||||||
sinon.stub(fu, 'getFileFromUser').resolves(file)
|
sinon.stub(fu, 'getFileFromUser').resolves(file)
|
||||||
|
|
||||||
// mock router
|
// mock router
|
||||||
@@ -168,9 +168,77 @@ describe('DbUploader.vue', () => {
|
|||||||
wrapper.destroy()
|
wrapper.destroy()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('deletes temporary db if CSV import is canceled', async () => {
|
it('shows parse dialog if gets json file', async () => {
|
||||||
// mock getting a file from user
|
// mock getting a file from user
|
||||||
const file = { name: 'test.csv' }
|
const file = new File([], 'test.json', { type: 'application/json' })
|
||||||
|
sinon.stub(fu, 'getFileFromUser').resolves(file)
|
||||||
|
|
||||||
|
// mock router
|
||||||
|
const $router = { push: sinon.stub() }
|
||||||
|
const $route = { path: '/workspace' }
|
||||||
|
|
||||||
|
// mount the component
|
||||||
|
const wrapper = mount(DbUploader, {
|
||||||
|
attachTo: place,
|
||||||
|
store,
|
||||||
|
mocks: { $router, $route },
|
||||||
|
propsData: {
|
||||||
|
type: 'illustrated'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const JsonImport = wrapper.vm.$refs.addCsvJson
|
||||||
|
sinon.stub(JsonImport, 'reset')
|
||||||
|
sinon.stub(JsonImport, 'preview').resolves()
|
||||||
|
sinon.stub(JsonImport, 'open')
|
||||||
|
|
||||||
|
await wrapper.find('.drop-area').trigger('click')
|
||||||
|
await wrapper.vm.$nextTick()
|
||||||
|
expect(JsonImport.reset.calledOnce).to.equal(true)
|
||||||
|
await wrapper.vm.animationPromise
|
||||||
|
expect(JsonImport.preview.calledOnce).to.equal(true)
|
||||||
|
await wrapper.vm.$nextTick()
|
||||||
|
expect(JsonImport.open.calledOnce).to.equal(true)
|
||||||
|
wrapper.destroy()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('shows parse dialog if gets ndjson file', async () => {
|
||||||
|
// mock getting a file from user
|
||||||
|
const file = new File([], 'test.ndjson')
|
||||||
|
sinon.stub(fu, 'getFileFromUser').resolves(file)
|
||||||
|
|
||||||
|
// mock router
|
||||||
|
const $router = { push: sinon.stub() }
|
||||||
|
const $route = { path: '/workspace' }
|
||||||
|
|
||||||
|
// mount the component
|
||||||
|
const wrapper = mount(DbUploader, {
|
||||||
|
attachTo: place,
|
||||||
|
store,
|
||||||
|
mocks: { $router, $route },
|
||||||
|
propsData: {
|
||||||
|
type: 'illustrated'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const JsonImport = wrapper.vm.$refs.addCsvJson
|
||||||
|
sinon.stub(JsonImport, 'reset')
|
||||||
|
sinon.stub(JsonImport, 'preview').resolves()
|
||||||
|
sinon.stub(JsonImport, 'open')
|
||||||
|
|
||||||
|
await wrapper.find('.drop-area').trigger('click')
|
||||||
|
await wrapper.vm.$nextTick()
|
||||||
|
expect(JsonImport.reset.calledOnce).to.equal(true)
|
||||||
|
await wrapper.vm.animationPromise
|
||||||
|
expect(JsonImport.preview.calledOnce).to.equal(true)
|
||||||
|
await wrapper.vm.$nextTick()
|
||||||
|
expect(JsonImport.open.calledOnce).to.equal(true)
|
||||||
|
wrapper.destroy()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('deletes temporary db if import is canceled', async () => {
|
||||||
|
// mock getting a file from user
|
||||||
|
const file = new File([], 'test.csv')
|
||||||
sinon.stub(fu, 'getFileFromUser').resolves(file)
|
sinon.stub(fu, 'getFileFromUser').resolves(file)
|
||||||
|
|
||||||
// mock router
|
// mock router
|
||||||
|
|||||||
@@ -28,7 +28,26 @@ describe('csv.js', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('getResult without fields', () => {
|
it('getResult without fields but with columns', () => {
|
||||||
|
const source = {
|
||||||
|
data: [
|
||||||
|
[1, 'foo', new Date('2021-06-30T14:10:24.717Z')],
|
||||||
|
[2, 'bar', new Date('2021-07-30T14:10:15.717Z')]
|
||||||
|
],
|
||||||
|
meta: {}
|
||||||
|
}
|
||||||
|
const columns = ['id', 'name', 'date']
|
||||||
|
expect(csv.getResult(source, columns)).to.eql({
|
||||||
|
columns: ['id', 'name', 'date'],
|
||||||
|
values: {
|
||||||
|
id: [1, 2],
|
||||||
|
name: ['foo', 'bar'],
|
||||||
|
date: ['2021-06-30T14:10:24.717Z', '2021-07-30T14:10:15.717Z']
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('getResult without fields and columns', () => {
|
||||||
const source = {
|
const source = {
|
||||||
data: [
|
data: [
|
||||||
[1, 'foo', new Date('2021-06-30T14:10:24.717Z')],
|
[1, 'foo', new Date('2021-06-30T14:10:24.717Z')],
|
||||||
|
|||||||
@@ -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)
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -106,10 +106,65 @@ describe('fileIo.js', () => {
|
|||||||
await expect(fIo.readAsArrayBuffer(blob)).to.be.rejectedWith('Problem parsing input file.')
|
await expect(fIo.readAsArrayBuffer(blob)).to.be.rejectedWith('Problem parsing input file.')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('isJSON', () => {
|
||||||
|
let file = { type: 'application/json' }
|
||||||
|
expect(fIo.isJSON(file)).to.equal(true)
|
||||||
|
|
||||||
|
file = { type: 'application/x-sqlite3' }
|
||||||
|
expect(fIo.isJSON(file)).to.equal(false)
|
||||||
|
|
||||||
|
file = { type: '', name: 'test.db' }
|
||||||
|
expect(fIo.isJSON(file)).to.equal(false)
|
||||||
|
|
||||||
|
file = { type: '', name: 'test.sqlite' }
|
||||||
|
expect(fIo.isJSON(file)).to.equal(false)
|
||||||
|
|
||||||
|
file = { type: '', name: 'test.sqlite3' }
|
||||||
|
expect(fIo.isJSON(file)).to.equal(false)
|
||||||
|
|
||||||
|
file = { type: '', name: 'test.csv' }
|
||||||
|
expect(fIo.isJSON(file)).to.equal(false)
|
||||||
|
|
||||||
|
file = { type: '', name: 'test.ndjson' }
|
||||||
|
expect(fIo.isJSON(file)).to.equal(false)
|
||||||
|
|
||||||
|
file = { type: 'text', name: 'test.db' }
|
||||||
|
expect(fIo.isJSON(file)).to.equal(false)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('isNDJSON', () => {
|
||||||
|
let file = { type: 'application/json', name: 'test.json' }
|
||||||
|
expect(fIo.isNDJSON(file)).to.equal(false)
|
||||||
|
|
||||||
|
file = { type: 'application/x-sqlite3', name: 'test.sqlite3' }
|
||||||
|
expect(fIo.isNDJSON(file)).to.equal(false)
|
||||||
|
|
||||||
|
file = { type: '', name: 'test.db' }
|
||||||
|
expect(fIo.isNDJSON(file)).to.equal(false)
|
||||||
|
|
||||||
|
file = { type: '', name: 'test.sqlite' }
|
||||||
|
expect(fIo.isNDJSON(file)).to.equal(false)
|
||||||
|
|
||||||
|
file = { type: '', name: 'test.sqlite3' }
|
||||||
|
expect(fIo.isNDJSON(file)).to.equal(false)
|
||||||
|
|
||||||
|
file = { type: '', name: 'test.csv' }
|
||||||
|
expect(fIo.isNDJSON(file)).to.equal(false)
|
||||||
|
|
||||||
|
file = { type: '', name: 'test.ndjson' }
|
||||||
|
expect(fIo.isNDJSON(file)).to.equal(true)
|
||||||
|
|
||||||
|
file = { type: 'text', name: 'test.db' }
|
||||||
|
expect(fIo.isNDJSON(file)).to.equal(false)
|
||||||
|
})
|
||||||
|
|
||||||
it('isDatabase', () => {
|
it('isDatabase', () => {
|
||||||
let file = { type: 'application/vnd.sqlite3' }
|
let file = { type: 'application/vnd.sqlite3' }
|
||||||
expect(fIo.isDatabase(file)).to.equal(true)
|
expect(fIo.isDatabase(file)).to.equal(true)
|
||||||
|
|
||||||
|
file = { type: 'application/json' }
|
||||||
|
expect(fIo.isDatabase(file)).to.equal(false)
|
||||||
|
|
||||||
file = { type: 'application/x-sqlite3' }
|
file = { type: 'application/x-sqlite3' }
|
||||||
expect(fIo.isDatabase(file)).to.equal(true)
|
expect(fIo.isDatabase(file)).to.equal(true)
|
||||||
|
|
||||||
@@ -125,6 +180,9 @@ describe('fileIo.js', () => {
|
|||||||
file = { type: '', name: 'test.csv' }
|
file = { type: '', name: 'test.csv' }
|
||||||
expect(fIo.isDatabase(file)).to.equal(false)
|
expect(fIo.isDatabase(file)).to.equal(false)
|
||||||
|
|
||||||
|
file = { type: '', name: 'test.ndjson' }
|
||||||
|
expect(fIo.isDatabase(file)).to.equal(false)
|
||||||
|
|
||||||
file = { type: 'text', name: 'test.db' }
|
file = { type: 'text', name: 'test.db' }
|
||||||
expect(fIo.isDatabase(file)).to.equal(false)
|
expect(fIo.isDatabase(file)).to.equal(false)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -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)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -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])
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -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,7 +41,10 @@ describe('Inquiries.vue', () => {
|
|||||||
createdAt: '2020-03-08T19:57:56.299Z'
|
createdAt: '2020-03-08T19:57:56.299Z'
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
sinon.stub(storedInquiries, 'getStoredInquiries').returns([
|
|
||||||
|
const state = {
|
||||||
|
predefinedInquiries: [],
|
||||||
|
inquiries: [
|
||||||
{
|
{
|
||||||
id: 1,
|
id: 1,
|
||||||
name: 'foo',
|
name: 'foo',
|
||||||
@@ -57,15 +61,12 @@ describe('Inquiries.vue', () => {
|
|||||||
viewOptions: [],
|
viewOptions: [],
|
||||||
createdAt: '2020-12-04T18:53:56.299Z'
|
createdAt: '2020-12-04T18:53:56.299Z'
|
||||||
}
|
}
|
||||||
])
|
]
|
||||||
const state = {
|
|
||||||
predefinedInquiries: []
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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,7 +95,10 @@ describe('Inquiries.vue', () => {
|
|||||||
createdAt: '2020-03-08T19:57:56.299Z'
|
createdAt: '2020-03-08T19:57:56.299Z'
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
sinon.stub(storedInquiries, 'getStoredInquiries').returns([
|
|
||||||
|
const state = {
|
||||||
|
predefinedInquiries: [],
|
||||||
|
inquiries: [
|
||||||
{
|
{
|
||||||
id: 1,
|
id: 1,
|
||||||
name: 'foo',
|
name: 'foo',
|
||||||
@@ -111,12 +115,10 @@ describe('Inquiries.vue', () => {
|
|||||||
viewOptions: [],
|
viewOptions: [],
|
||||||
createdAt: '2020-12-04T18:53:56.299Z'
|
createdAt: '2020-12-04T18:53:56.299Z'
|
||||||
}
|
}
|
||||||
])
|
]
|
||||||
const state = {
|
|
||||||
predefinedInquiries: []
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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,7 +140,10 @@ describe('Inquiries.vue', () => {
|
|||||||
createdAt: '2020-03-08T19:57:56.299Z'
|
createdAt: '2020-03-08T19:57:56.299Z'
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
sinon.stub(storedInquiries, 'getStoredInquiries').returns([
|
|
||||||
|
const state = {
|
||||||
|
predefinedInquiries: [],
|
||||||
|
inquiries: [
|
||||||
{
|
{
|
||||||
id: 1,
|
id: 1,
|
||||||
name: 'foo',
|
name: 'foo',
|
||||||
@@ -155,12 +160,10 @@ describe('Inquiries.vue', () => {
|
|||||||
viewOptions: [],
|
viewOptions: [],
|
||||||
createdAt: '2020-12-04T18:53:56.299Z'
|
createdAt: '2020-12-04T18:53:56.299Z'
|
||||||
}
|
}
|
||||||
])
|
]
|
||||||
const state = {
|
|
||||||
predefinedInquiries: []
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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,7 +184,10 @@ describe('Inquiries.vue', () => {
|
|||||||
createdAt: '2020-03-08T19:57:56.299Z'
|
createdAt: '2020-03-08T19:57:56.299Z'
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
sinon.stub(storedInquiries, 'getStoredInquiries').returns([
|
|
||||||
|
const state = {
|
||||||
|
predefinedInquiries: [],
|
||||||
|
inquiries: [
|
||||||
{
|
{
|
||||||
id: 1,
|
id: 1,
|
||||||
name: 'foo',
|
name: 'foo',
|
||||||
@@ -190,15 +196,12 @@ describe('Inquiries.vue', () => {
|
|||||||
viewOptions: [],
|
viewOptions: [],
|
||||||
createdAt: '2020-11-03T19:57:56.299Z'
|
createdAt: '2020-11-03T19:57:56.299Z'
|
||||||
}
|
}
|
||||||
])
|
]
|
||||||
const state = {
|
|
||||||
predefinedInquiries: []
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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,7 +211,11 @@ 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([
|
sinon.stub(storedInquiries, 'serialiseInquiries').returns('I am a serialized inquiry')
|
||||||
|
sinon.stub(fu, 'exportToFile')
|
||||||
|
const state = {
|
||||||
|
predefinedInquiries: [],
|
||||||
|
inquiries: [
|
||||||
{
|
{
|
||||||
id: 1,
|
id: 1,
|
||||||
name: 'foo',
|
name: 'foo',
|
||||||
@@ -217,17 +224,12 @@ describe('Inquiries.vue', () => {
|
|||||||
viewOptions: [],
|
viewOptions: [],
|
||||||
createdAt: '2020-11-03T19:57:56.299Z'
|
createdAt: '2020-11-03T19:57:56.299Z'
|
||||||
}
|
}
|
||||||
])
|
]
|
||||||
sinon.stub(storedInquiries, 'serialiseInquiries').returns('I am a serialized inquiry')
|
|
||||||
sinon.stub(fu, 'exportToFile')
|
|
||||||
const state = {
|
|
||||||
predefinedInquiries: []
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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,23 +360,26 @@ 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([
|
sinon.stub(storedInquiries, 'updateStorage')
|
||||||
|
const state = {
|
||||||
|
tabs: [{ id: 1, name: 'foo' }],
|
||||||
|
predefinedInquiries: [],
|
||||||
|
inquiries: [
|
||||||
{
|
{
|
||||||
id: 1,
|
id: 1,
|
||||||
name: 'foo',
|
name: 'foo',
|
||||||
@@ -389,17 +388,12 @@ describe('Inquiries.vue', () => {
|
|||||||
viewOptions: [],
|
viewOptions: [],
|
||||||
createdAt: '2020-11-03T19:57:56.299Z'
|
createdAt: '2020-11-03T19:57:56.299Z'
|
||||||
}
|
}
|
||||||
])
|
]
|
||||||
sinon.stub(storedInquiries, 'updateStorage')
|
|
||||||
const state = {
|
|
||||||
tabs: [{ id: 1, name: 'foo' }],
|
|
||||||
predefinedInquiries: []
|
|
||||||
}
|
}
|
||||||
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,7 +437,11 @@ 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([
|
sinon.stub(storedInquiries, 'updateStorage')
|
||||||
|
const state = {
|
||||||
|
tabs: [{ id: 1, name: 'foo' }],
|
||||||
|
predefinedInquiries: [],
|
||||||
|
inquiries: [
|
||||||
{
|
{
|
||||||
id: 1,
|
id: 1,
|
||||||
name: 'foo',
|
name: 'foo',
|
||||||
@@ -451,17 +450,12 @@ describe('Inquiries.vue', () => {
|
|||||||
viewOptions: [],
|
viewOptions: [],
|
||||||
createdAt: '2020-11-03T19:57:56.299Z'
|
createdAt: '2020-11-03T19:57:56.299Z'
|
||||||
}
|
}
|
||||||
])
|
]
|
||||||
sinon.stub(storedInquiries, 'updateStorage')
|
|
||||||
const state = {
|
|
||||||
tabs: [{ id: 1, name: 'foo' }],
|
|
||||||
predefinedInquiries: []
|
|
||||||
}
|
}
|
||||||
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,7 +654,10 @@ describe('Inquiries.vue', () => {
|
|||||||
createdAt: '2020-03-08T19:57:56.299Z'
|
createdAt: '2020-03-08T19:57:56.299Z'
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
sinon.stub(storedInquiries, 'getStoredInquiries').returns([
|
|
||||||
|
const state = {
|
||||||
|
predefinedInquiries: [],
|
||||||
|
inquiries: [
|
||||||
{
|
{
|
||||||
id: 1,
|
id: 1,
|
||||||
name: 'foo',
|
name: 'foo',
|
||||||
@@ -675,16 +666,12 @@ describe('Inquiries.vue', () => {
|
|||||||
viewOptions: [],
|
viewOptions: [],
|
||||||
createdAt: '2020-11-03T19:57:56.299Z'
|
createdAt: '2020-11-03T19:57:56.299Z'
|
||||||
}
|
}
|
||||||
])
|
]
|
||||||
|
|
||||||
const state = {
|
|
||||||
predefinedInquiries: []
|
|
||||||
}
|
}
|
||||||
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, {
|
|
||||||
|
sinon.stub(storedInquiries, 'serialiseInquiries').returns('I am a serialized inquiries')
|
||||||
|
sinon.stub(fu, 'exportToFile')
|
||||||
|
|
||||||
|
const state = {
|
||||||
|
predefinedInquiries: [],
|
||||||
|
inquiries: [inquiryInStore, {
|
||||||
id: 2,
|
id: 2,
|
||||||
name: 'bar',
|
name: 'bar',
|
||||||
query: '',
|
query: '',
|
||||||
viewType: 'chart',
|
viewType: 'chart',
|
||||||
viewOptions: [],
|
viewOptions: [],
|
||||||
createdAt: '2020-03-08T19:57:56.299Z'
|
createdAt: '2020-03-08T19:57:56.299Z'
|
||||||
}])
|
}]
|
||||||
|
|
||||||
sinon.stub(storedInquiries, 'serialiseInquiries').returns('I am a serialized inquiries')
|
|
||||||
sinon.stub(fu, 'exportToFile')
|
|
||||||
|
|
||||||
const state = {
|
|
||||||
predefinedInquiries: []
|
|
||||||
}
|
}
|
||||||
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' })
|
||||||
|
|||||||
@@ -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 = {
|
||||||
const $route = { path: '/workspace' }
|
saveInquiry: sinon.stub().returns({
|
||||||
sinon.stub(storedInquiries, 'isTabNeedName').returns(false)
|
|
||||||
sinon.stub(storedInquiries, 'save').returns({
|
|
||||||
name: 'foo',
|
name: 'foo',
|
||||||
id: 1,
|
id: 1,
|
||||||
query: 'SELECT * FROM foo',
|
query: 'SELECT * FROM foo',
|
||||||
viewType: 'chart',
|
viewType: 'chart',
|
||||||
viewOptions: []
|
viewOptions: []
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
const store = new Vuex.Store({ state, mutations, actions })
|
||||||
|
const $route = { path: '/workspace' }
|
||||||
|
sinon.stub(storedInquiries, 'isTabNeedName').returns(false)
|
||||||
|
|
||||||
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 = {
|
||||||
const $route = { path: '/workspace' }
|
saveInquiry: sinon.stub().returns({
|
||||||
sinon.stub(storedInquiries, 'isTabNeedName').returns(true)
|
|
||||||
sinon.stub(storedInquiries, 'save').returns({
|
|
||||||
name: 'foo',
|
name: 'foo',
|
||||||
id: 1,
|
id: 1,
|
||||||
query: 'SELECT * FROM foo',
|
query: 'SELECT * FROM foo',
|
||||||
viewType: 'chart',
|
viewType: 'chart',
|
||||||
viewOptions: []
|
viewOptions: []
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
const store = new Vuex.Store({ state, mutations, actions })
|
||||||
|
const $route = { path: '/workspace' }
|
||||||
|
sinon.stub(storedInquiries, 'isTabNeedName').returns(true)
|
||||||
|
|
||||||
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 = {
|
||||||
const $route = { path: '/workspace' }
|
saveInquiry: sinon.stub().returns({
|
||||||
sinon.stub(storedInquiries, 'isTabNeedName').returns(true)
|
|
||||||
sinon.stub(storedInquiries, 'save').returns({
|
|
||||||
name: 'foo',
|
name: 'foo',
|
||||||
id: 1,
|
id: 1,
|
||||||
query: 'SELECT * FROM foo',
|
query: 'SELECT * FROM foo',
|
||||||
viewType: 'chart',
|
viewType: 'chart',
|
||||||
viewOptions: []
|
viewOptions: []
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
const store = new Vuex.Store({ state, mutations, actions })
|
||||||
|
const $route = { path: '/workspace' }
|
||||||
|
sinon.stub(storedInquiries, 'isTabNeedName').returns(true)
|
||||||
|
|
||||||
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 = {
|
||||||
const $route = { path: '/workspace' }
|
saveInquiry: sinon.stub().returns({
|
||||||
sinon.stub(storedInquiries, 'isTabNeedName').returns(true)
|
|
||||||
sinon.stub(storedInquiries, 'save').returns({
|
|
||||||
name: 'bar',
|
name: 'bar',
|
||||||
id: 2,
|
id: 2,
|
||||||
query: 'SELECT * FROM foo',
|
query: 'SELECT * FROM foo',
|
||||||
viewType: 'chart',
|
viewType: 'chart',
|
||||||
viewOptions: []
|
viewOptions: []
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
const store = new Vuex.Store({ state, mutations, actions })
|
||||||
|
const $route = { path: '/workspace' }
|
||||||
|
sinon.stub(storedInquiries, 'isTabNeedName').returns(true)
|
||||||
|
|
||||||
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 = {
|
||||||
const $route = { path: '/workspace' }
|
saveInquiry: sinon.stub().returns({
|
||||||
sinon.stub(storedInquiries, 'isTabNeedName').returns(true)
|
|
||||||
sinon.stub(storedInquiries, 'save').returns({
|
|
||||||
name: 'bar',
|
name: 'bar',
|
||||||
id: 2,
|
id: 2,
|
||||||
query: 'SELECT * FROM foo',
|
query: 'SELECT * FROM foo',
|
||||||
chart: []
|
chart: []
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
const store = new Vuex.Store({ state, mutations, actions })
|
||||||
|
const $route = { path: '/workspace' }
|
||||||
|
sinon.stub(storedInquiries, 'isTabNeedName').returns(true)
|
||||||
|
|
||||||
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)
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ describe('Schema.vue', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('adds table', async () => {
|
it('adds table', async () => {
|
||||||
const file = { name: 'test.csv' }
|
const file = new File([], 'test.csv')
|
||||||
sinon.stub(fIo, 'getFileFromUser').resolves(file)
|
sinon.stub(fIo, 'getFileFromUser').resolves(file)
|
||||||
|
|
||||||
sinon.stub(csv, 'parse').resolves({
|
sinon.stub(csv, 'parse').resolves({
|
||||||
|
|||||||
Reference in New Issue
Block a user