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) }) })