2020-04-14 10:49:10 +02:00
|
|
|
import {
|
2020-03-24 11:56:48 +01:00
|
|
|
getRecordApiFromTemplateApi,
|
|
|
|
getIndexApiFromTemplateApi,
|
|
|
|
} from "./specHelpers"
|
|
|
|
import { upgradeData } from "../src/templateApi/upgradeData"
|
|
|
|
import { setup } from "./upgradeDataSetup"
|
|
|
|
import { $, splitKey } from "../src/common"
|
|
|
|
import { keys, filter } from "lodash/fp"
|
|
|
|
import { _listItems } from "../src/indexApi/listItems"
|
|
|
|
import { _save } from "../src/recordApi/save"
|
2020-03-26 15:32:09 +01:00
|
|
|
import { _getNew } from "../src/recordApi/getNew"
|
2020-03-24 11:56:48 +01:00
|
|
|
|
|
|
|
describe("upgradeData", () => {
|
|
|
|
|
|
|
|
it("should delete all records and child records, when root record node deleted", async () => {
|
|
|
|
const { oldSetup, newSetup, recordApi } = await configure()
|
|
|
|
newSetup.root.children = newSetup.root.children.filter(n => n.name !== "contact")
|
|
|
|
|
|
|
|
await upgradeData(oldSetup.app)(newSetup.root)
|
|
|
|
|
|
|
|
const remainingKeys = $(recordApi._storeHandle.data, [
|
|
|
|
keys,
|
|
|
|
filter(k => splitKey(k)[0] === "contacts"),
|
|
|
|
])
|
|
|
|
|
|
|
|
expect(remainingKeys.length).toBe(0)
|
2020-04-14 10:49:10 +02:00
|
|
|
|
2020-03-24 11:56:48 +01:00
|
|
|
})
|
|
|
|
|
|
|
|
it("should not delete other root record types, when root record node deleted", async () => {
|
|
|
|
const { oldSetup, newSetup, recordApi } = await configure()
|
|
|
|
newSetup.root.children = newSetup.root.children.filter(n => n.name !== "contact")
|
|
|
|
|
|
|
|
await upgradeData(oldSetup.app)(newSetup.root)
|
|
|
|
|
|
|
|
const remainingKeys = $(recordApi._storeHandle.data, [
|
|
|
|
keys,
|
|
|
|
filter(k => splitKey(k)[0] === "leads"),
|
|
|
|
])
|
|
|
|
|
|
|
|
expect(remainingKeys.length > 0).toBe(true)
|
2020-04-14 10:49:10 +02:00
|
|
|
|
2020-03-24 11:56:48 +01:00
|
|
|
})
|
|
|
|
|
|
|
|
it("should delete all child records, when child record node deleted", async () => {
|
|
|
|
const { oldSetup, newSetup, recordApi } = await configure()
|
|
|
|
newSetup.contact.children = newSetup.contact.children.filter(n => n.name !== "deal")
|
|
|
|
|
|
|
|
const startingKeys = $(recordApi._storeHandle.data, [
|
|
|
|
keys,
|
|
|
|
filter(k => k.includes("/deals/")),
|
|
|
|
])
|
|
|
|
|
|
|
|
expect(startingKeys.length > 0).toBe(true)
|
|
|
|
|
|
|
|
await upgradeData(oldSetup.app)(newSetup.root)
|
|
|
|
|
|
|
|
const remainingKeys = $(recordApi._storeHandle.data, [
|
|
|
|
keys,
|
|
|
|
filter(k => k.includes("/deals/")),
|
|
|
|
])
|
|
|
|
|
|
|
|
expect(remainingKeys.length).toBe(0)
|
|
|
|
})
|
|
|
|
|
|
|
|
it("should build a new root index", async () => {
|
|
|
|
const { oldSetup, newSetup } = await configure()
|
|
|
|
const newIndex = newSetup.templateApi.getNewIndexTemplate(newSetup.root)
|
|
|
|
newIndex.name = "more_contacts"
|
|
|
|
newIndex.allowedRecordNodeIds = [newSetup.contact.nodeId]
|
|
|
|
|
|
|
|
await upgradeData(oldSetup.app)(newSetup.root)
|
|
|
|
|
|
|
|
const itemsInNewIndex = await _listItems(newSetup.app, "/more_contacts")
|
|
|
|
|
|
|
|
expect(itemsInNewIndex.length).toBe(2)
|
|
|
|
})
|
|
|
|
|
|
|
|
it("should update a root index", async () => {
|
|
|
|
const { oldSetup, newSetup } = await configure()
|
|
|
|
const contact_index = indexByName(newSetup.root, "contact_index")
|
|
|
|
contact_index.filter = "record.name === 'bobby'"
|
|
|
|
|
|
|
|
await upgradeData(oldSetup.app)(newSetup.root)
|
|
|
|
|
|
|
|
const itemsInNewIndex = await _listItems(newSetup.app, "/contact_index")
|
|
|
|
|
|
|
|
expect(itemsInNewIndex.length).toBe(1)
|
|
|
|
})
|
|
|
|
|
|
|
|
it("should delete a root index", async () => {
|
|
|
|
const { oldSetup, newSetup } = await configure()
|
|
|
|
|
|
|
|
// no exception
|
|
|
|
await _listItems(newSetup.app, "/contact_index")
|
|
|
|
|
|
|
|
newSetup.root.indexes = newSetup.root.indexes.filter(i => i.name !== "contact_index")
|
|
|
|
|
|
|
|
await upgradeData(oldSetup.app)(newSetup.root)
|
|
|
|
|
|
|
|
let er
|
|
|
|
try {
|
|
|
|
await _listItems(newSetup.app, "/contact_index")
|
|
|
|
} catch (e) {
|
|
|
|
er = e
|
|
|
|
}
|
|
|
|
|
|
|
|
expect(er).toBeDefined()
|
|
|
|
})
|
|
|
|
|
|
|
|
it("should build a new child index", async () => {
|
|
|
|
const { oldSetup, newSetup, records } = await configure()
|
|
|
|
const newIndex = newSetup.templateApi.getNewIndexTemplate(newSetup.contact)
|
|
|
|
newIndex.name = "more_deals"
|
|
|
|
newIndex.allowedRecordNodeIds = [newSetup.deal.nodeId]
|
|
|
|
|
|
|
|
await upgradeData(oldSetup.app)(newSetup.root)
|
|
|
|
|
|
|
|
const itemsInNewIndex = await _listItems(newSetup.app, `${records.contact1.key}/more_deals`)
|
|
|
|
|
|
|
|
expect(itemsInNewIndex.length).toBe(2)
|
|
|
|
})
|
|
|
|
|
|
|
|
it("should update a child index", async () => {
|
|
|
|
const { oldSetup, newSetup, records } = await configure()
|
|
|
|
const deal_index = indexByName(newSetup.contact, "deal_index")
|
|
|
|
deal_index.filter = "record.status === 'new'"
|
|
|
|
|
|
|
|
let itemsInIndex = await _listItems(newSetup.app, `${records.contact1.key}/deal_index`)
|
|
|
|
expect(itemsInIndex.length).toBe(2)
|
|
|
|
|
|
|
|
await upgradeData(oldSetup.app)(newSetup.root)
|
|
|
|
|
|
|
|
itemsInIndex = await _listItems(newSetup.app, `${records.contact1.key}/deal_index`)
|
|
|
|
expect(itemsInIndex.length).toBe(1)
|
|
|
|
})
|
|
|
|
|
|
|
|
it("should delete a child index", async () => {
|
|
|
|
const { oldSetup, newSetup, records } = await configure()
|
|
|
|
|
|
|
|
// no exception
|
|
|
|
await _listItems(newSetup.app, `${records.contact1.key}/deal_index`)
|
|
|
|
|
|
|
|
newSetup.contact.indexes = newSetup.contact.indexes.filter(i => i.name !== "deal_index")
|
|
|
|
|
|
|
|
await upgradeData(oldSetup.app)(newSetup.root)
|
|
|
|
|
|
|
|
let er
|
|
|
|
try {
|
|
|
|
await _listItems(newSetup.app, `${records.contact1.key}/deal_index`)
|
|
|
|
} catch (e) {
|
|
|
|
er = e
|
|
|
|
}
|
|
|
|
|
|
|
|
expect(er).toBeDefined()
|
|
|
|
})
|
|
|
|
|
|
|
|
it("should build a new reference index", async () => {
|
|
|
|
const { oldSetup, newSetup, records, recordApi } = await configure()
|
|
|
|
const newIndex = newSetup.templateApi.getNewIndexTemplate(newSetup.lead)
|
|
|
|
newIndex.name = "contact_leads"
|
|
|
|
newIndex.allowedRecordNodeIds = [newSetup.lead.nodeId]
|
|
|
|
newIndex.indexType = "reference"
|
|
|
|
|
|
|
|
const leadField = newSetup.templateApi.getNewField("string")
|
|
|
|
leadField.name = "lead"
|
|
|
|
leadField.type = "reference"
|
|
|
|
leadField.typeOptions = {
|
2020-04-14 10:49:10 +02:00
|
|
|
reverseIndexNodeKeys: [newIndex.nodeKey()],
|
2020-03-24 11:56:48 +01:00
|
|
|
indexNodeKey: "/lead_index",
|
|
|
|
displayValue: "name"
|
|
|
|
}
|
|
|
|
|
|
|
|
newSetup.templateApi.addField(newSetup.contact, leadField)
|
2020-04-14 10:49:10 +02:00
|
|
|
|
2020-03-24 11:56:48 +01:00
|
|
|
await upgradeData(oldSetup.app)(newSetup.root)
|
|
|
|
|
|
|
|
const indexKey = `${records.lead1.key}/contact_leads`
|
|
|
|
|
|
|
|
let itemsInNewIndex = await _listItems(newSetup.app, indexKey)
|
|
|
|
|
|
|
|
expect(itemsInNewIndex.length).toBe(0)
|
|
|
|
|
|
|
|
records.contact1.lead = records.lead1
|
|
|
|
records.contact1.isNew = false
|
|
|
|
|
|
|
|
await _save(newSetup.app, records.contact1)
|
|
|
|
|
|
|
|
itemsInNewIndex = await _listItems(newSetup.app, indexKey)
|
|
|
|
|
|
|
|
expect(itemsInNewIndex.length).toBe(1)
|
|
|
|
|
|
|
|
})
|
|
|
|
|
2020-03-26 15:32:09 +01:00
|
|
|
it("should initialise a new root record", async () => {
|
|
|
|
const { oldSetup, newSetup } = await configure()
|
2020-04-14 10:49:10 +02:00
|
|
|
const invoice = newSetup.templateApi.getNewModelTemplate(newSetup.root, "invoice", true)
|
2020-03-26 15:32:09 +01:00
|
|
|
invoice.collectionName = "invoices"
|
|
|
|
|
|
|
|
const nameField = newSetup.templateApi.getNewField("string")
|
|
|
|
nameField.name = "name"
|
|
|
|
newSetup.templateApi.addField(invoice, nameField)
|
|
|
|
|
|
|
|
await upgradeData(oldSetup.app)(newSetup.root)
|
|
|
|
|
|
|
|
let itemsInNewIndex = await _listItems(newSetup.app, "/invoice_index")
|
|
|
|
|
|
|
|
expect(itemsInNewIndex.length).toBe(0)
|
|
|
|
|
2020-04-14 10:49:10 +02:00
|
|
|
const newInvoice = _getNew(invoice, "/invoices")
|
2020-03-26 15:32:09 +01:00
|
|
|
await _save(newSetup.app, newInvoice)
|
|
|
|
|
|
|
|
itemsInNewIndex = await _listItems(newSetup.app, "/invoice_index")
|
|
|
|
|
|
|
|
expect(itemsInNewIndex.length).toBe(1)
|
|
|
|
})
|
|
|
|
|
|
|
|
it("should initialise a new child record", async () => {
|
|
|
|
const { oldSetup, newSetup, records } = await configure()
|
2020-04-14 10:49:10 +02:00
|
|
|
const invoice = newSetup.templateApi.getNewModelTemplate(newSetup.contact, "invoice", true)
|
2020-03-26 15:32:09 +01:00
|
|
|
invoice.collectionName = "invoices"
|
|
|
|
|
|
|
|
const nameField = newSetup.templateApi.getNewField("string")
|
|
|
|
nameField.name = "name"
|
|
|
|
newSetup.templateApi.addField(invoice, nameField)
|
|
|
|
|
|
|
|
await upgradeData(oldSetup.app)(newSetup.root)
|
|
|
|
|
|
|
|
let itemsInNewIndex = await _listItems(newSetup.app, `${records.contact1.key}/invoice_index`)
|
|
|
|
|
|
|
|
expect(itemsInNewIndex.length).toBe(0)
|
|
|
|
|
2020-04-14 10:49:10 +02:00
|
|
|
const newInvoice = _getNew(invoice, `${records.contact1.key}/invoices`)
|
2020-03-26 15:32:09 +01:00
|
|
|
await _save(newSetup.app, newInvoice)
|
|
|
|
|
|
|
|
itemsInNewIndex = await _listItems(newSetup.app, `${records.contact1.key}/invoice_index`)
|
|
|
|
|
|
|
|
expect(itemsInNewIndex.length).toBe(1)
|
|
|
|
})
|
|
|
|
|
2020-03-24 11:56:48 +01:00
|
|
|
})
|
|
|
|
|
2020-04-02 07:21:52 +02:00
|
|
|
it("should rebuild affected index when field is removed", async () => {
|
|
|
|
const { oldSetup, newSetup, records } = await configure()
|
|
|
|
newSetup.contact.fields = newSetup.contact.fields.filter(f => f.name !== "status")
|
|
|
|
|
|
|
|
let itemsInIndex = await _listItems(oldSetup.app, "/contact_index")
|
|
|
|
expect(itemsInIndex.length).toBe(2)
|
|
|
|
expect(itemsInIndex[0].status).toBeDefined()
|
|
|
|
expect(itemsInIndex[0].status).toBe(records.contact1.status)
|
|
|
|
|
|
|
|
await upgradeData(oldSetup.app)(newSetup.root)
|
|
|
|
|
|
|
|
itemsInIndex = await _listItems(newSetup.app, "/contact_index")
|
|
|
|
expect(itemsInIndex.length).toBe(2)
|
|
|
|
expect(itemsInIndex[0].status).toBeUndefined()
|
|
|
|
})
|
|
|
|
|
|
|
|
it("should rebuild affected index when field is added", async () => {
|
|
|
|
const { oldSetup, newSetup, records } = await configure()
|
2020-04-14 10:49:10 +02:00
|
|
|
|
2020-04-02 07:21:52 +02:00
|
|
|
const aliveField = newSetup.templateApi.getNewField("string")
|
|
|
|
aliveField.name = "isalive"
|
|
|
|
newSetup.templateApi.addField(newSetup.contact, aliveField)
|
|
|
|
|
|
|
|
let itemsInIndex = await _listItems(oldSetup.app, "/contact_index")
|
|
|
|
expect(itemsInIndex.length).toBe(2)
|
|
|
|
expect(itemsInIndex[0].isalive).toBeUndefined()
|
|
|
|
|
|
|
|
await upgradeData(oldSetup.app)(newSetup.root)
|
|
|
|
|
|
|
|
itemsInIndex = await _listItems(newSetup.app, "/contact_index")
|
|
|
|
expect(itemsInIndex.length).toBe(2)
|
|
|
|
expect(itemsInIndex[0].isalive).toBe(null)
|
|
|
|
})
|
|
|
|
|
2020-03-24 11:56:48 +01:00
|
|
|
const configure = async () => {
|
|
|
|
const oldSetup = await setup()
|
2020-04-14 10:49:10 +02:00
|
|
|
|
2020-03-24 11:56:48 +01:00
|
|
|
const recordApi = await getRecordApiFromTemplateApi(oldSetup.templateApi)
|
|
|
|
const indexApi = await getIndexApiFromTemplateApi(oldSetup.templateApi)
|
2020-04-14 10:49:10 +02:00
|
|
|
|
2020-03-24 11:56:48 +01:00
|
|
|
const newSetup = await setup(oldSetup.store)
|
|
|
|
|
|
|
|
const records = await createSomeRecords(recordApi)
|
|
|
|
|
|
|
|
return { oldSetup, newSetup, recordApi, records, indexApi }
|
|
|
|
}
|
|
|
|
|
|
|
|
const createSomeRecords = async recordApi => {
|
|
|
|
const contact1 = recordApi.getNew("/contacts", "contact")
|
|
|
|
contact1.name = "bobby"
|
2020-04-02 07:21:52 +02:00
|
|
|
contact1.status = "New"
|
2020-03-24 11:56:48 +01:00
|
|
|
const contact2 = recordApi.getNew("/contacts", "contact")
|
|
|
|
contact2.name = "poppy"
|
2020-04-02 07:21:52 +02:00
|
|
|
contact2.status = "Complete"
|
2020-03-24 11:56:48 +01:00
|
|
|
|
|
|
|
await recordApi.save(contact1)
|
|
|
|
await recordApi.save(contact2)
|
|
|
|
|
|
|
|
const deal1 = recordApi.getNew(`${contact1.key}/deals`, "deal")
|
|
|
|
deal1.name = "big mad deal"
|
|
|
|
deal1.status = "new"
|
|
|
|
const deal2 = recordApi.getNew(`${contact1.key}/deals`, "deal")
|
|
|
|
deal2.name = "smaller deal"
|
|
|
|
deal2.status = "old"
|
|
|
|
const deal3 = recordApi.getNew(`${contact2.key}/deals`, "deal")
|
|
|
|
deal3.name = "ok deal"
|
|
|
|
deal3.status = "new"
|
|
|
|
|
|
|
|
await recordApi.save(deal1)
|
|
|
|
await recordApi.save(deal2)
|
|
|
|
await recordApi.save(deal3)
|
|
|
|
|
|
|
|
const lead1 = recordApi.getNew("/leads", "lead")
|
|
|
|
lead1.name = "big new lead"
|
|
|
|
|
|
|
|
await recordApi.save(lead1)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
contact1, contact2, deal1, deal2, deal3, lead1,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const indexByName = (parent, name) => parent.indexes.find(i => i.name === name)
|