import { setupApphierarchy, basicAppHierarchyCreator_WithFields_AndIndexes, } from "./specHelpers" import { permission } from "../src/authApi/permissions" describe("aggregates", () => { it("should calculate correct totals, when no condition supplied", async () => { const { createInvoice, indexApi } = await setup() await createInvoice(10) await createInvoice(20) await createInvoice(30) const result = await indexApi.aggregates("/Outstanding Invoices") expect(result.all_invoices_by_type.Important.count).toBe(3) expect(result.all_invoices_by_type.Important.totalIncVat.max).toBe(30) expect(result.all_invoices_by_type.Important.totalIncVat.min).toBe(10) expect(result.all_invoices_by_type.Important.totalIncVat.sum).toBe(60) expect(result.all_invoices_by_type.Important.totalIncVat.mean).toBe(60 / 3) }) it("should split totals into correct groups", async () => { const { createInvoice, indexApi } = await setup() await createInvoice(10, 0, "Important") await createInvoice(20, 0, "NotImportant") await createInvoice(30, 0, "NotImportant") const result = await indexApi.aggregates("/Outstanding Invoices") expect(result.all_invoices_by_type.Important.count).toBe(1) expect(result.all_invoices_by_type.NotImportant.count).toBe(2) expect(result.all_invoices_by_type.Important.totalIncVat.sum).toBe(10) expect(result.all_invoices_by_type.NotImportant.totalIncVat.sum).toBe(50) }) it("should include all when all match condition", async () => { const { createInvoice, indexApi } = await setup() await createInvoice(10, 0, "Important", true) await createInvoice(10, 0, "Important", true) await createInvoice(10, 0, "Important", true) const result = await indexApi.aggregates("/Outstanding Invoices") expect(result.written_off.Important.count).toBe(3) expect(result.written_off.Important.totalIncVat.sum).toBe(30) }) it("should add to '(none)' when group is blank, null or undefined", async () => { const { createInvoice, indexApi } = await setup() await createInvoice(10, 0, "", true) await createInvoice(10, 0, null, true) const result = await indexApi.aggregates("/Outstanding Invoices") expect(result.all_invoices_by_type["(none)"].count).toBe(2) expect(result.all_invoices_by_type["(none)"].totalIncVat.sum).toBe(20) }) it("should not include those that do not match condition", async () => { const { createInvoice, indexApi } = await setup() await createInvoice(10, 0, "Important", true) await createInvoice(10, 0, "Important", true) await createInvoice(10, 0, "Important", false) const result = await indexApi.aggregates("/Outstanding Invoices") expect(result.written_off.Important.count).toBe(2) expect(result.written_off.Important.totalIncVat.sum).toBe(20) }) it("should have 'all' group when no grouping supplied", async () => { const { createInvoice, indexApi } = await setup() await createInvoice(10, 0, "Important", true) await createInvoice(20, 0, "Important", true) const result = await indexApi.aggregates("/Outstanding Invoices") expect(result.all_invoices.all.count).toBe(2) }) it("should calculate correct totals, sharded index - all records", async () => { const { createInvoice, indexApi, invoicesByOutstandingKey } = await setup() await createInvoice(10, 0, "Important") await createInvoice(20, 20, "Important") await createInvoice(30, 30, "Important") const result = await indexApi.aggregates(invoicesByOutstandingKey) expect(result.all_invoices_by_type.Important.count).toBe(3) expect(result.all_invoices_by_type.Important.totalIncVat.max).toBe(30) expect(result.all_invoices_by_type.Important.totalIncVat.min).toBe(10) expect(result.all_invoices_by_type.Important.totalIncVat.sum).toBe(60) expect(result.all_invoices_by_type.Important.totalIncVat.mean).toBe(60 / 3) }) it("should calculate correct totals, sharded index - bounded by sharding", async () => { const { createInvoice, indexApi, invoicesByOutstandingKey } = await setup() await createInvoice(10, 0, "Important") await createInvoice(20, 20, "Important") await createInvoice(30, 30, "Important") const result = await indexApi.aggregates( invoicesByOutstandingKey, { totalIncVat: 10, paidAmount: 10 }, { totalIncVat: 10, paidAmount: 10 } ) expect(result.all_invoices_by_type.Important.count).toBe(2) expect(result.all_invoices_by_type.Important.totalIncVat.max).toBe(30) expect(result.all_invoices_by_type.Important.totalIncVat.min).toBe(20) expect(result.all_invoices_by_type.Important.totalIncVat.sum).toBe(50) expect(result.all_invoices_by_type.Important.totalIncVat.mean).toBe(50 / 2) }) it("should throw error when user user does not have permission", async () => { const { app, indexApi } = await setup() app.removePermission(permission.readIndex.get("/customer_index")) let err try { await indexApi.aggregates("/customer_index") } catch (e) { err = e } expect(err).toBeDefined() expect(err.message.startsWith("Unauthorized")).toBeTruthy() //expect(indexApi.aggregates("/customer_index")).rejects.toThrow(/Unauthorized/); }) it("should not depend on having any other permissions", async () => { const { app, indexApi } = await setup() app.withOnlyThisPermission(permission.readIndex.get("/customer_index")) await indexApi.aggregates("/customer_index") }) }) const setup = async () => { const { recordApi, app, indexApi } = await setupApphierarchy( basicAppHierarchyCreator_WithFields_AndIndexes ) const customer = recordApi.getNew("/customers", "customer") await recordApi.save(customer) const createInvoice = async ( totalAmount = 10, paidAmount = 0, type = "Important", writtenOff = false ) => { const invoice = recordApi.getNew( `/customers/${customer.id}/invoices`, "invoice" ) invoice.totalIncVat = totalAmount invoice.paidAmount = paidAmount invoice.invoiceType = type invoice.isWrittenOff = writtenOff return await recordApi.save(invoice) } const invoicesByOutstandingKey = `/customers/${customer.id}/invoicesByOutstanding` return { createInvoice, indexApi, invoicesByOutstandingKey, app } }