import { setupApphierarchy, basicAppHierarchyCreator_WithFields_AndIndexes, } from "./specHelpers" import { joinKey } from "../src/common" import { getLockFileContent } from "../src/common/lock" import { some, isArray } from "lodash" import { cleanup } from "../src/transactions/cleanup" import { LOCK_FILE_KEY } from "../src/transactions/transactionsCommon" import { getRecordInfo } from "../src/recordApi/recordInfo" describe("cleanup transactions", () => { it("testing disable of cleanupTransactions, just for test purposes", async () => { const { recordApi, app, indexApi } = await setupApphierarchy( basicAppHierarchyCreator_WithFields_AndIndexes, true ) const record1 = recordApi.getNew("/customers", "customer") record1.surname = "Zeecat" const record2 = recordApi.getNew("/customers", "customer") record2.surname = "Ledog" await recordApi.save(record1) await recordApi.save(record2) const records = await indexApi.listItems("/customer_index") // cleanup should be disabled as above expect(records.length).toBe(0) }) it("should index 2 new create transactions", async () => { // cleanup is disabled, with true parameter const { recordApi, app, indexApi } = await setupApphierarchy( basicAppHierarchyCreator_WithFields_AndIndexes, true ) const record1 = recordApi.getNew("/customers", "customer") record1.surname = "Zeecat" const record2 = recordApi.getNew("/customers", "customer") record2.surname = "Ledog" await recordApi.save(record1) await recordApi.save(record2) await cleanup(app) const records = await indexApi.listItems("/customer_index") expect(records.length).toBe(2) expect(some(records, r => r.surname === "Zeecat")).toBeTruthy() expect(some(records, r => r.surname === "Ledog")).toBeTruthy() }) it("when create and update transaction for the same record, index should be latest record", async () => { const { recordApi, app, indexApi } = await setupApphierarchy( basicAppHierarchyCreator_WithFields_AndIndexes, true ) const record = recordApi.getNew("/customers", "customer") record.surname = "Ledog" const savedRecord = await recordApi.save(record) savedRecord.surname = "Zeecat" await recordApi.save(savedRecord) await cleanup(app) const records = await indexApi.listItems("/customer_index") expect(records.length).toBe(1) expect(some(records, r => r.surname === "Zeecat")).toBeTruthy() }) it("should choose current version of record when multiple update transactions found", async () => { const { recordApi, app, indexApi } = await setupApphierarchy( basicAppHierarchyCreator_WithFields_AndIndexes, true ) const record = recordApi.getNew("/customers", "customer") record.surname = "Ledog" const savedRecord = await recordApi.save(record) savedRecord.surname = "Zeecat" await recordApi.save(savedRecord) savedRecord.surname = "Afish" await recordApi.save(savedRecord) savedRecord.surname = "Lelapin" await recordApi.save(savedRecord) await cleanup(app) const records = await indexApi.listItems("/customer_index") expect(records.length).toBe(1) expect(some(records, r => r.surname === "Lelapin")).toBeTruthy() }) it("should not reindex when transactionId does not match that of the record", async () => { const { recordApi, app, indexApi } = await setupApphierarchy( basicAppHierarchyCreator_WithFields_AndIndexes, true ) const record = recordApi.getNew("/customers", "customer") record.surname = "Ledog" const savedRecord = await recordApi.save(record) await cleanup(app) savedRecord.surname = "Zeecat" await recordApi.save(savedRecord) savedRecord.transactionId = "something else" const recordInfo = getRecordInfo(app.hierarchy, savedRecord.key) await recordApi._storeHandle.updateJson( recordInfo.child("record.json"), savedRecord ) await cleanup(app) const records = await indexApi.listItems("/customer_index") expect(records.length).toBe(1) expect(records[0].surname).toBe("Ledog") }) it("should not reindex when transactionId does not match that of the record, and has multiple transactions", async () => { const { recordApi, app, indexApi } = await setupApphierarchy( basicAppHierarchyCreator_WithFields_AndIndexes, true ) const record = recordApi.getNew("/customers", "customer") record.surname = "Ledog" const savedRecord = await recordApi.save(record) await cleanup(app) savedRecord.surname = "Zeecat" await recordApi.save(savedRecord) savedRecord.surname = "Lefish" await recordApi.save(savedRecord) savedRecord.transactionId = "something else" const recordInfo = getRecordInfo(app.hierarchy, savedRecord.key) await recordApi._storeHandle.updateJson( recordInfo.child("record.json"), savedRecord ) await cleanup(app) const records = await indexApi.listItems("/customer_index") expect(records.length).toBe(1) expect(records[0].surname).toBe("Ledog") }) it("should remove from index when delete and update transactions exists", async () => { const { recordApi, app, indexApi } = await setupApphierarchy( basicAppHierarchyCreator_WithFields_AndIndexes, true ) const record = recordApi.getNew("/customers", "customer") record.surname = "Ledog" const savedRecord = await recordApi.save(record) await cleanup(app) savedRecord.surname = "Zeecat" await recordApi.save(savedRecord) await recordApi.delete(savedRecord.key) await cleanup(app) const records = await indexApi.listItems("/customer_index") expect(records.length).toBe(0) }) it("should not add to index when create and delete found", async () => { const { recordApi, app, indexApi } = await setupApphierarchy( basicAppHierarchyCreator_WithFields_AndIndexes, true ) const record = recordApi.getNew("/customers", "customer") record.surname = "Ledog" const savedRecord = await recordApi.save(record) await recordApi.delete(savedRecord.key) await cleanup(app) const records = await indexApi.listItems("/customer_index") expect(records.length).toBe(0) }) it("should correctly remove from indexes, when multiple update transactions exist", async () => { const { recordApi, app, indexApi } = await setupApphierarchy( basicAppHierarchyCreator_WithFields_AndIndexes, true ) const record = recordApi.getNew("/customers", "customer") record.surname = "Ledog" record.isalive = false const savedRecord = await recordApi.save(record) await cleanup(app) const preUpdateRecords = await indexApi.listItems("/deceased") expect(preUpdateRecords.length).toBe(1) savedRecord.surname = "Ledog" await recordApi.save(savedRecord) savedRecord.isalive = true await recordApi.save(savedRecord) await cleanup(app) const records = await indexApi.listItems("/deceased") expect(records.length).toBe(0) }) it("should not add to index when created, then updated to be filtered out of index", async () => { const { recordApi, app, indexApi } = await setupApphierarchy( basicAppHierarchyCreator_WithFields_AndIndexes, true ) const record = recordApi.getNew("/customers", "customer") record.surname = "Ledog" record.isalive = false const savedRecord = await recordApi.save(record) savedRecord.surname = "Ledog" savedRecord.isalive = true await recordApi.save(savedRecord) await cleanup(app) const records = await indexApi.listItems("/deceased") expect(records.length).toBe(0) }) it("should do nothing when lockfile exists", async () => { const { recordApi, app, indexApi } = await setupApphierarchy( basicAppHierarchyCreator_WithFields_AndIndexes, true ) const record = recordApi.getNew("/customers", "customer") record.surname = "Ledog" await recordApi.save(record) const currentTime = await app.getEpochTime() await recordApi._storeHandle.createFile( LOCK_FILE_KEY, getLockFileContent(30000, currentTime + 30000) ) await cleanup(app) let records = await indexApi.listItems("/customer_index") expect(records.length).toBe(0) await recordApi._storeHandle.deleteFile(LOCK_FILE_KEY) await cleanup(app) records = await indexApi.listItems("/customer_index") expect(records.length).toBe(1) }) it("should take control when lockfile is timedout", async () => { const { recordApi, app, indexApi } = await setupApphierarchy( basicAppHierarchyCreator_WithFields_AndIndexes, true ) const record = recordApi.getNew("/customers", "customer") record.surname = "Ledog" await recordApi.save(record) await recordApi._storeHandle.createFile( LOCK_FILE_KEY, getLockFileContent(30000, new Date(1990, 1, 1, 0, 0, 0, 0).getTime()) ) await cleanup(app) let records = await indexApi.listItems("/customer_index") expect(records.length).toBe(1) }) })