budibase/packages/core/test/recordApi.reindex.spec.js

647 lines
20 KiB
JavaScript

import {
setupApphierarchy,
basicAppHierarchyCreator_WithFields,
basicAppHierarchyCreator_WithFields_AndIndexes,
} from "./specHelpers"
import { joinKey } from "../src/common"
import { some, isArray, isObjectLike } from "lodash"
describe("recordApi > create > reindex", () => {
it("should add to default index, when record created", async () => {
const { recordApi, indexApi } = await setupApphierarchy(
basicAppHierarchyCreator_WithFields_AndIndexes
)
const record = recordApi.getNew("/customers", "customer")
record.surname = "Ledog"
record.isalive = true
record.age = 9
record.createddate = new Date()
await recordApi.save(record)
const items = await indexApi.listItems("/customer_index")
expect(items.length).toBe(1)
expect(items[0].surname).toBe("Ledog")
expect(items[0].key).toBeDefined()
expect(items[0].key).toEqual(record.key)
})
it("should add to index with filter, when record created and passes filter", async () => {
const { recordApi, indexApi } = await setupApphierarchy(
basicAppHierarchyCreator_WithFields_AndIndexes
)
const record = recordApi.getNew("/customers", "customer")
record.surname = "Ledog"
record.isalive = false
record.age = 9
record.createddate = new Date()
await recordApi.save(record)
const items = await indexApi.listItems("/deceased")
expect(items.length).toBe(1)
expect(items[0].surname).toBe("Ledog")
expect(items[0].key).toBeDefined()
expect(items[0].key).toEqual(record.key)
})
it("should not add to index with filter, when record created and fails filter", async () => {
const { recordApi, indexApi } = await setupApphierarchy(
basicAppHierarchyCreator_WithFields_AndIndexes
)
const record = recordApi.getNew("/customers", "customer")
record.surname = "Ledog"
record.isalive = true
record.age = 9
record.createddate = new Date()
await recordApi.save(record)
const items = await indexApi.listItems("/deceased")
expect(items.length).toBe(0)
})
it("should be able to add to and list subcollection, after save (i.e. save initialiieses collection)", async () => {
const { recordApi, indexApi } = await setupApphierarchy(
basicAppHierarchyCreator_WithFields
)
const customer = recordApi.getNew("/customers", "customer")
await recordApi.save(customer)
const invoicesCollectionKey = joinKey(customer.key, "invoices")
const invoice = recordApi.getNew(invoicesCollectionKey, "invoice")
invoice.totalIncVat = 10.5
invoice.createdDate = new Date()
await recordApi.save(invoice)
const invoices = await indexApi.listItems(
joinKey(customer.key, "invoice_index")
)
expect(isArray(invoices)).toBeTruthy()
expect(invoices.length).toBe(1)
expect(invoices[0].totalIncVat).toBe(10.5)
})
it("should add to global index, when required", async () => {
const { recordApi, indexApi } = await setupApphierarchy(
basicAppHierarchyCreator_WithFields
)
const customer = recordApi.getNew("/customers", "customer")
customer.surname = "Ledog"
customer.age = 9
;(customer.isalive = true), (customer.createdDate = new Date())
await recordApi.save(customer)
const customers = await indexApi.listItems("/customersReference")
expect(isArray(customers)).toBeTruthy()
expect(customers.length).toBe(1)
expect(customers[0].name).toBe("Ledog")
})
it("should add reference field to index and reparse", async () => {
const { recordApi, indexApi } = await setupApphierarchy(
basicAppHierarchyCreator_WithFields
)
const partner = recordApi.getNew("/partners", "partner")
partner.businessName = "ACME"
partner.phone = "098766e6"
await recordApi.save(partner)
const customer = recordApi.getNew("/customers", "customer")
customer.surname = "Ledog"
customer.age = 9
;(customer.isalive = true), (customer.createdDate = new Date())
customer.partner = partner
await recordApi.save(customer)
const customers = await indexApi.listItems("/customer_index")
expect(customers.length).toBe(1)
expect(isObjectLike(customer.partner)).toBeTruthy()
expect(customers[0].partner.key).toBe(partner.key)
expect(customers[0].partner.name).toBe(partner.businessName)
expect(customers[0].partner.phone).toBe(partner.phone)
})
it("should add to reverse reference index, when required", async () => {
const { recordApi, indexApi } = await setupApphierarchy(
basicAppHierarchyCreator_WithFields
)
const referredByCustomer = recordApi.getNew("/customers", "customer")
referredByCustomer.surname = "Ledog"
referredByCustomer.age = 9
;(referredByCustomer.isalive = true),
(referredByCustomer.createdDate = new Date())
await recordApi.save(referredByCustomer)
const referredCustomer = recordApi.getNew("/customers", "customer")
referredCustomer.surname = "Zeecat"
referredCustomer.age = 9
;(referredCustomer.isalive = true),
(referredCustomer.createdDate = new Date())
referredCustomer.referredBy = {
key: referredByCustomer.key,
value: referredByCustomer.surname,
}
await recordApi.save(referredCustomer)
const customersReferredTo = await indexApi.listItems(
joinKey(referredByCustomer.key, "referredToCustomers")
)
expect(isArray(customersReferredTo)).toBeTruthy()
expect(customersReferredTo.length).toBe(1)
expect(customersReferredTo[0].surname).toBe("Zeecat")
})
it("should add to sharded index, when record created, and should add into correct shards", async () => {
const { recordApi, indexApi } = await setupApphierarchy(
basicAppHierarchyCreator_WithFields_AndIndexes
)
const record1 = recordApi.getNew("/customers", "customer")
record1.surname = "Ledog"
await recordApi.save(record1)
const record2 = recordApi.getNew("/customers", "customer")
record2.surname = "Zeecat"
await recordApi.save(record2)
const items = await indexApi.listItems("/customersBySurname")
expect(items.length).toBe(2)
expect(items[0].surname).toBe("Ledog")
expect(items[0].key).toEqual(record1.key)
expect(items[1].surname).toBe("Zeecat")
expect(items[1].key).toEqual(record2.key)
})
})
describe("recordApi > delete > reindex", () => {
it("should remove from default index", async () => {
const { recordApi, indexApi } = await setupApphierarchy(
basicAppHierarchyCreator_WithFields_AndIndexes
)
const record = recordApi.getNew("/customers", "customer")
record.surname = "Ledog"
record.isalive = true
record.age = 9
record.createddate = new Date()
await recordApi.save(record)
await recordApi.delete(record.key)
const itemsAfterDelete = await indexApi.listItems("/customer_index")
expect(itemsAfterDelete.length).toBe(0)
})
it("should remove from sharded index", async () => {
const { recordApi, indexApi } = await setupApphierarchy(
basicAppHierarchyCreator_WithFields_AndIndexes
)
const record1 = recordApi.getNew("/customers", "customer")
record1.surname = "Ledog"
await recordApi.save(record1)
const record2 = recordApi.getNew("/customers", "customer")
record2.surname = "Zeecat"
await recordApi.save(record2)
await recordApi.delete(record1.key)
const itemsAfterDelete = await indexApi.listItems("/customersBySurname")
expect(itemsAfterDelete.length).toBe(1)
expect(itemsAfterDelete[0].surname).toBe("Zeecat")
})
it("should remove from all indexes", async () => {
const { recordApi, indexApi } = await setupApphierarchy(
basicAppHierarchyCreator_WithFields_AndIndexes
)
const referredBy = recordApi.getNew("/customers", "customer")
referredBy.surname = "Zeecat"
await recordApi.save(referredBy)
const record = recordApi.getNew("/customers", "customer")
record.surname = "Ledog"
record.isalive = false
record.age = 9
record.createddate = new Date()
record.referredBy = {
key: referredBy.key,
value: referredBy.surname,
}
await recordApi.save(record)
await recordApi.delete(record.key)
const itemsAfterDelete = await indexApi.listItems("/customer_index")
expect(itemsAfterDelete.length).toBe(1)
expect(itemsAfterDelete[0].surname).toBe("Zeecat")
const deceasedItemsAfterDelete = await indexApi.listItems("/deceased")
expect(deceasedItemsAfterDelete.length).toBe(0)
const referredToItemsAfterDelete = await indexApi.listItems(
`${referredBy.key}/referredToCustomers`
)
expect(referredToItemsAfterDelete.length).toBe(0)
})
it("should only remove relevant record from all indexes", async () => {
const { recordApi, indexApi } = await setupApphierarchy(
basicAppHierarchyCreator_WithFields_AndIndexes
)
const record = recordApi.getNew("/customers", "customer")
record.surname = "Ledog"
record.isalive = false
record.age = 9
record.createddate = new Date()
await recordApi.save(record)
const otherRecord = recordApi.getNew("/customers", "customer")
otherRecord.surname = "Zeecat"
otherRecord.isalive = false
otherRecord.age = 12
record.createddate = new Date()
await recordApi.save(otherRecord)
await recordApi.delete(record.key)
const itemsAfterDelete = await indexApi.listItems("/customer_index")
expect(itemsAfterDelete.length).toBe(1)
expect(itemsAfterDelete[0].surname).toBe("Zeecat")
const deceasedItemsAfterDelete = await indexApi.listItems("/deceased")
expect(deceasedItemsAfterDelete.length).toBe(1)
expect(deceasedItemsAfterDelete[0].surname).toBe("Zeecat")
})
it("should remove from global index", async () => {
const { recordApi, indexApi } = await setupApphierarchy(
basicAppHierarchyCreator_WithFields
)
const customer = recordApi.getNew("/customers", "customer")
customer.surname = "Ledog"
customer.age = 9
;(customer.isalive = true), (customer.createdDate = new Date())
await recordApi.save(customer)
await recordApi.delete(customer.key)
const customers = await indexApi.listItems("/customersReference")
expect(isArray(customers)).toBeTruthy()
expect(customers.length).toBe(0)
})
})
describe("recordApi > update > reindex", () => {
it("should update values in indexes", async () => {
const { recordApi, indexApi } = await setupApphierarchy(
basicAppHierarchyCreator_WithFields_AndIndexes
)
const record = recordApi.getNew("/customers", "customer")
record.surname = "Ledog"
record.isalive = false
record.age = 9
record.createddate = new Date()
await recordApi.save(record)
const loadedRecord = await recordApi.load(record.key)
loadedRecord.surname = "Zeedog"
await recordApi.save(loadedRecord)
const itemsDefault = await indexApi.listItems("/customer_index")
expect(itemsDefault[0].surname).toBe("Zeedog")
expect(itemsDefault.length).toBe(1)
})
it("should update values in sharded index", async () => {
const { recordApi, indexApi } = await setupApphierarchy(
basicAppHierarchyCreator_WithFields_AndIndexes
)
const record = recordApi.getNew("/customers", "customer")
record.surname = "Ledog"
await recordApi.save(record)
const loadedRecord = await recordApi.load(record.key)
loadedRecord.surname = "Zeedog"
await recordApi.save(loadedRecord)
const itemsDefault = await indexApi.listItems("/customersBySurname")
expect(itemsDefault[0].surname).toBe("Zeedog")
expect(itemsDefault.length).toBe(1)
})
it("should only update values of relevant item", async () => {
const { recordApi, indexApi } = await setupApphierarchy(
basicAppHierarchyCreator_WithFields_AndIndexes
)
const record = recordApi.getNew("/customers", "customer")
record.surname = "Ledog"
record.isalive = false
record.age = 9
record.createddate = new Date()
await recordApi.save(record)
const otherRecord = recordApi.getNew("/customers", "customer")
otherRecord.surname = "Zeecat"
otherRecord.isalive = false
otherRecord.age = 12
record.createddate = new Date()
await recordApi.save(otherRecord)
const loadedRecord = await recordApi.load(record.key)
loadedRecord.surname = "Zeedog"
await recordApi.save(loadedRecord)
const items = await indexApi.listItems("/customer_index")
const hasItemWithSurname = sn => some(items, i => i.surname === sn)
expect(hasItemWithSurname("Zeedog")).toEqual(true)
expect(hasItemWithSurname("Ledog")).toEqual(false)
expect(hasItemWithSurname("Zeecat")).toEqual(true)
expect(items.length).toBe(2)
})
it("should update global index", async () => {
const { recordApi, indexApi } = await setupApphierarchy(
basicAppHierarchyCreator_WithFields
)
const customer = recordApi.getNew("/customers", "customer")
customer.surname = "Ledog"
customer.age = 9
;(customer.isalive = true), (customer.createdDate = new Date())
await recordApi.save(customer)
const loadedCustomer = await recordApi.load(customer.key)
loadedCustomer.surname = "Zeecat"
await recordApi.save(loadedCustomer)
const customers = await indexApi.listItems("/customersReference")
expect(isArray(customers)).toBeTruthy()
expect(customers.length).toBe(1)
expect(customers[0].name).toBe("Zeecat")
})
it("should remove from one reference index and add to another when field changed", async () => {
const { recordApi, indexApi } = await setupApphierarchy(
basicAppHierarchyCreator_WithFields
)
const partner1 = recordApi.getNew("/partners", "partner")
partner1.businessName = "ACME inc"
await recordApi.save(partner1)
const partner2 = recordApi.getNew("/partners", "partner")
partner2.businessName = "Big Corp ltd"
await recordApi.save(partner2)
const customer = recordApi.getNew("/customers", "customer")
customer.surname = "Ledog"
customer.partner = {
key: partner1.key,
value: partner1.businessName,
}
const customerSaved = await recordApi.save(customer)
customerSaved.partner = {
key: partner2.key,
value: partner2.businessName,
}
await recordApi.save(customerSaved)
const partner1Customer = await indexApi.listItems(
`${partner1.key}/partnerCustomers`
)
expect(partner1Customer.length).toBe(0)
const partner2Customer = await indexApi.listItems(
`${partner2.key}/partnerCustomers`
)
expect(partner2Customer.length).toBe(1)
})
it("should remove from reference index when reference blanked", async () => {
const { recordApi, indexApi } = await setupApphierarchy(
basicAppHierarchyCreator_WithFields
)
const partner1 = recordApi.getNew("/partners", "partner")
partner1.businessName = "ACME inc"
await recordApi.save(partner1)
const customer = recordApi.getNew("/customers", "customer")
customer.surname = "Ledog"
customer.partner = {
key: partner1.key,
value: partner1.businessName,
}
const customerSaved = await recordApi.save(customer)
customerSaved.partner = {
key: "",
value: "",
}
await recordApi.save(customerSaved)
const partner1Customer = await indexApi.listItems(
`${partner1.key}/partnerCustomers`
)
expect(partner1Customer.length).toBe(0)
})
it("should remove from reference index when filter no longer passes", async () => {
const { recordApi, indexApi } = await setupApphierarchy(
basicAppHierarchyCreator_WithFields
)
const partner1 = recordApi.getNew("/partners", "partner")
partner1.businessName = "ACME inc"
await recordApi.save(partner1)
const customer = recordApi.getNew("/customers", "customer")
customer.surname = "Ledog"
customer.partner = {
key: partner1.key,
value: partner1.businessName,
}
const customerSaved = await recordApi.save(customer)
customerSaved.isalive = false
await recordApi.save(customerSaved)
const partner1Customer = await indexApi.listItems(
`${partner1.key}/partnerCustomers`
)
expect(partner1Customer.length).toBe(0)
})
it("should not add to reference index when filter does not pass", async () => {
const { recordApi, indexApi } = await setupApphierarchy(
basicAppHierarchyCreator_WithFields
)
const partner1 = recordApi.getNew("/partners", "partner")
partner1.businessName = "ACME inc"
await recordApi.save(partner1)
const customer = recordApi.getNew("/customers", "customer")
customer.surname = "Ledog"
customer.partner = {
key: partner1.key,
value: partner1.businessName,
}
customer.isalive = false
await recordApi.save(customer)
const partner1Customer = await indexApi.listItems(
`${partner1.key}/partnerCustomers`
)
expect(partner1Customer.length).toBe(0)
})
it("should remove from reference index, and not re-added when no longer passes filter, but reference is changed", async () => {
const { recordApi, indexApi } = await setupApphierarchy(
basicAppHierarchyCreator_WithFields
)
const partner1 = recordApi.getNew("/partners", "partner")
partner1.businessName = "ACME inc"
await recordApi.save(partner1)
const partner2 = recordApi.getNew("/partners", "partner")
partner2.businessName = "Big Corp ltd"
await recordApi.save(partner2)
const customer = recordApi.getNew("/customers", "customer")
customer.surname = "Ledog"
customer.partner = {
key: partner1.key,
value: partner1.businessName,
}
const customerSaved = await recordApi.save(customer)
customerSaved.partner = {
key: partner2.key,
value: partner2.businessName,
}
customerSaved.isalive = false
await recordApi.save(customerSaved)
const partner1Customer = await indexApi.listItems(
`${partner1.key}/partnerCustomers`
)
expect(partner1Customer.length).toBe(0)
const partner2Customer = await indexApi.listItems(
`${partner2.key}/partnerCustomers`
)
expect(partner2Customer.length).toBe(0)
})
it("should add to reference index, when reference is changed, and did not previsouly pass filter", async () => {
const { recordApi, indexApi } = await setupApphierarchy(
basicAppHierarchyCreator_WithFields
)
const partner1 = recordApi.getNew("/partners", "partner")
partner1.businessName = "ACME inc"
await recordApi.save(partner1)
const partner2 = recordApi.getNew("/partners", "partner")
partner2.businessName = "Big Corp ltd"
await recordApi.save(partner2)
const customer = recordApi.getNew("/customers", "customer")
customer.surname = "Ledog"
customer.partner = {
key: partner1.key,
value: partner1.businessName,
}
customer.isalive = false
const customerSaved = await recordApi.save(customer)
customerSaved.partner = {
key: partner2.key,
value: partner2.businessName,
}
customerSaved.isalive = true
await recordApi.save(customerSaved)
const partner1Customer = await indexApi.listItems(
`${partner1.key}/partnerCustomers`
)
expect(partner1Customer.length).toBe(0)
const partner2Customer = await indexApi.listItems(
`${partner2.key}/partnerCustomers`
)
expect(partner2Customer.length).toBe(1)
})
})
describe("referenced object changed", () => {
it("should update the reference", async () => {
const { recordApi } = await setupApphierarchy(
basicAppHierarchyCreator_WithFields
)
const partner1 = recordApi.getNew("/partners", "partner")
partner1.businessName = "ACME inc"
const savedPartner = await recordApi.save(partner1)
const customer = recordApi.getNew("/customers", "customer")
customer.surname = "Ledog"
customer.partner = {
key: partner1.key,
value: partner1.businessName,
}
await recordApi.save(customer)
savedPartner.businessName = "A.C.M.E Inc"
await recordApi.save(savedPartner)
const updatedCustomer = await recordApi.load(customer.key)
expect(updatedCustomer.partner.name).toBe(savedPartner.businessName)
})
})