UNPKG

component-dbs-core

Version:

DTO objects shared among device backend

336 lines 15.3 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const uuid_1 = require("uuid"); const transactionDb_1 = require("./transactionDb"); const common_services_1 = require("../common_services"); jest.mock('../common_services/dynamodb/dynamodbService'); describe('get transaction main table test suite', () => { let dbService; let documentClient; const deviceUuid = uuid_1.v4(); const entityUuid = uuid_1.v4(); const siteUuid = uuid_1.v4(); const total = 100; const transactions = []; let db; beforeAll(() => __awaiter(void 0, void 0, void 0, function* () { dbService = new common_services_1.DynamodbService({}, {}); documentClient = dbService.documentClient; const proms = []; const sleep = () => new Promise((resolve) => setTimeout(resolve, 10)); db = new transactionDb_1.TransactionDb('Devices', dbService, 'transactionGsi', 'accessTokenGsi', 'entityUuidGsi', 'siteUuidGsi'); for (let i = 0; i < total; i++) { const txn = { id: deviceUuid, type: `transaction.${new Date().getTime()}`, transactionUuid: uuid_1.v4(), timestamp: new Date().toISOString(), entityUuid: entityUuid, deviceName: uuid_1.v4(), siteUuid: siteUuid, siteName: uuid_1.v4(), amount: 200, saleAmount: 0, tipAmount: 100, taxAmounts: [ { name: 'tax', amount: 300, }, ], feeAmount: 400, surchargeAmount: 500, scheme: "AMEX" /* AMEX */, transactionType: i % 2 === 0 ? "PURCHASE" /* PURCHASE */ : "REFUND" /* REFUND */, status: "APPROVED" /* APPROVED */, maskedPan: 'masked', depositUuid: uuid_1.v4(), depositDate: new Date().toISOString(), reference: uuid_1.v4(), par: uuid_1.v4(), panToken: uuid_1.v4(), }; transactions.push(txn); proms.push(sleep()); const params = { TableName: 'Devices', Item: txn, }; proms.push(documentClient.put(params).promise()); } yield Promise.all(proms); })); it('should be able to query transaction history', () => __awaiter(void 0, void 0, void 0, function* () { const response = yield db.getTransactions({ limit: 10, deviceUuid, }); const items = response.Items; console.log(items); expect(items.length).toBe(10); for (let i = 1; i < items.length - 1; i++) { const prevTs = parseInt(items[i - 1].type.split('.')[1]); const ts = parseInt(items[i].type.split('.')[1]); expect(prevTs).toBeGreaterThan(ts); } })); it('should be able to query pagination', () => __awaiter(void 0, void 0, void 0, function* () { let response = yield db.getTransactions({ limit: total - 5, deviceUuid: deviceUuid, }); const items = response.Items; expect(items.length).toBe(total - 5); const nextToken = response.LastEvaluatedKey.id; expect(nextToken).not.toBeUndefined(); response = yield db.getTransactions({ limit: 10, deviceUuid: deviceUuid, nextToken: response.LastEvaluatedKey, }); expect(response.Items.length).toBe(5); expect(parseInt(items[items.length - 1].type.split('.')[1])).toBeGreaterThan(parseInt(response.Items[0].type.split('.')[1])); })); it('should return empty query if not found', () => __awaiter(void 0, void 0, void 0, function* () { let response = yield db.getTransactions({ limit: total - 5, deviceUuid: 'unknown', }); const items = response.Items; expect(items.length).toBe(0); })); it('should be able to apply filter on scheme', () => __awaiter(void 0, void 0, void 0, function* () { let filter = { expression: '(#scheme = :scheme_eq)', expressionNames: { '#scheme': 'scheme' }, expressionValues: { ':scheme_eq': { S: "AMEX" /* AMEX */ }, }, }; let response = yield db.getTransactions({ limit: 5, deviceUuid, filter: JSON.stringify(filter), }); const items = response.Items; expect(items.length).toBe(5); })); it('should response empty result if none transaction match the transaction type filter', () => __awaiter(void 0, void 0, void 0, function* () { let filter = { expression: '(#transactionType = :transactionType_eq)', expressionNames: { '#transactionType': 'transactionType' }, expressionValues: { ':transactionType_eq': { S: 'unknown' }, }, }; let response = yield db.getTransactions({ limit: 5, deviceUuid, filter: JSON.stringify(filter), }); const items = response.Items; expect(items.length).toBe(0); })); it('should be able to query transaction by uuid', () => __awaiter(void 0, void 0, void 0, function* () { const proms = transactions.map(({ transactionUuid }) => db.getTransaction(transactionUuid)); const outputs = yield Promise.all(proms); outputs.forEach((output, i) => { expect(output.Items.length).toBe(1); expect(output.Items[0].transactionUuid).toBe(transactions[i].transactionUuid); }); })); it('should return empty result if transaction uuid not found', () => __awaiter(void 0, void 0, void 0, function* () { const output = yield db.getTransaction('unknown'); expect(output.Items.length).toBe(0); })); it('should be able to query multiple filters', () => __awaiter(void 0, void 0, void 0, function* () { let filter = { expression: '(#transactionType = :transactionType_eq) AND (#amount > :amount_gt)', expressionNames: { '#transactionType': 'transactionType', '#amount': 'amount', }, expressionValues: { ':transactionType_eq': { S: "REFUND" /* REFUND */ }, ':amount_gt': { N: 20 }, }, }; let response = yield db.getTransactions({ limit: 5, deviceUuid, filter: JSON.stringify(filter), }); const items = response.Items; expect(items.length).toBe(5); })); describe('query with timestamp test suite', () => { it('should be able to get transaction based on time range with multiple queries', () => __awaiter(void 0, void 0, void 0, function* () { let filter = { expression: '((#timestampFilter < :timestampFilter_lt) AND (#timestampFilter > :timestampFilter_gt))', expressionNames: { '#timestampFilter': 'timestamp' }, expressionValues: { ':timestampFilter_gt': { S: transactions[20].timestamp }, ':timestampFilter_lt': { S: transactions[30].timestamp }, }, }; let response = yield db.getTransactions({ limit: 5, deviceUuid, timestampFilter: JSON.stringify(filter), }); const items = response.Items; expect(items.length).toBe(5); })); it('should be able to extract timestamp from filter to create sort key confition', () => __awaiter(void 0, void 0, void 0, function* () { let filter = { expression: '(#timestampFilter < :timestampFilter_lt) AND (#timestampFilter > :timestampFilter_gt)', expressionNames: { '#timestampFilter': 'timestamp' }, expressionValues: { ':timestampFilter_gt': { S: '2020-01-10T00:00:00Z' }, ':timestampFilter_lt': { S: new Date().getTime() }, }, }; let response = yield db.getTransactions({ limit: 5, deviceUuid, timestampFilter: JSON.stringify(filter), }); const items = response.Items; expect(items.length).toBe(5); })); }); describe('query entityUuid index test suite', () => { it('should be able to query entityUuidGsi', () => __awaiter(void 0, void 0, void 0, function* () { let filter = { expression: '(#timestampFilter < :timestampFilter_gt)', expressionNames: { '#timestampFilter': 'timestampFilter' }, expressionValues: { ':timestampFilter_gt': { S: transactions[30].timestamp }, }, }; let response = yield db.getTransactions({ limit: 500, timestampFilter: JSON.stringify(filter), }, entityUuid); const items = response.Items; expect(items.length).toBe(69); })); }); describe('query siteUuidGsi test suite', () => { it('should be able to query siteUuidGsi', () => __awaiter(void 0, void 0, void 0, function* () { let filter = { expression: '(#timestampFilter < :timestampFilter_gt)', expressionNames: { '#timestampFilter': 'timestampFilter' }, expressionValues: { ':timestampFilter_gt': { S: transactions[30].timestamp }, }, }; let response = yield db.getTransactions({ limit: 500, siteUuid, timestampFilter: JSON.stringify(filter), }); const items = response.Items; expect(items.length).toBe(69); })); }); it('should be able to query timestamp with other filters', () => __awaiter(void 0, void 0, void 0, function* () { let timestampFilter = { expression: '(#timestampFilter < :timestampFilter_lt) AND (#timestampFilter > :timestampFilter_gt)', expressionNames: { '#timestampFilter': 'timestampFilter' }, expressionValues: { ':timestampFilter_gt': { S: transactions[5].timestamp }, ':timestampFilter_lt': { S: transactions[90].timestamp }, }, }; const filter = { expression: '(#transactionType = :transactionType_eq)', expressionNames: { '#transactionType': 'transactionType' }, expressionValues: { ':transactionType_eq': { S: "PURCHASE" /* PURCHASE */ }, }, }; let response = yield db.getTransactions({ limit: 20, deviceUuid, filter: JSON.stringify(filter), timestampFilter: JSON.stringify(timestampFilter), }); const items = response.Items; expect(items.length).toBe(20); })); it('should be able to query customised timestamp range', () => __awaiter(void 0, void 0, void 0, function* () { let filter = { expression: '(#timestampFilter BETWEEN :timestampFilter_between_start AND :timestampFilter_between_end)', expressionNames: { '#timestampFilter': 'timestamp' }, expressionValues: { ':timestampFilter_between_start': { S: transactions[30].timestamp }, ':timestampFilter_between_end': { S: transactions[50].timestamp }, }, }; let response = yield db.getTransactions({ limit: 50, deviceUuid, timestampFilter: JSON.stringify(filter), }); const items = response.Items; expect(items.length).toBeLessThanOrEqual(21); })); it('should be able to query customised timestamp with end date', () => __awaiter(void 0, void 0, void 0, function* () { let filter = { expression: '(#timestampFilter < :timestampFilter_lt)', expressionNames: { '#timestampFilter': 'timestamp' }, expressionValues: { ':timestampFilter_lt': { S: transactions[30].timestamp }, }, }; let response = yield db.getTransactions({ limit: 500, deviceUuid, timestampFilter: JSON.stringify(filter), }); const items = response.Items; expect(items.length).toBeGreaterThanOrEqual(30); })); it('should be able to query customised timestamp with start date', () => __awaiter(void 0, void 0, void 0, function* () { let filter = { expression: '(#timestampFilter < :timestampFilter_gt)', expressionNames: { '#timestampFilter': 'timestamp' }, expressionValues: { ':timestampFilter_gt': { S: transactions[30].timestamp }, }, }; let response = yield db.getTransactions({ limit: 500, deviceUuid, timestampFilter: JSON.stringify(filter), }); const items = response.Items; expect(items.length).toBeGreaterThanOrEqual(69); })); it('should be able to query transactions by reference', () => __awaiter(void 0, void 0, void 0, function* () { const filter = { expression: '(#reference = :reference_eq)', expressionNames: { '#reference': 'reference' }, expressionValues: { ':reference_eq': { S: transactions[0].reference } }, }; const response = yield db.getTransactions({ limit: 10, deviceUuid, filter: JSON.stringify(filter) }); expect(response.Items[0].transactionUuid).toBe(transactions[0].transactionUuid); })); }); describe('transactionDb util method test suite', () => { let db = new transactionDb_1.TransactionDb('', null, 'transactionGsi', 'accessTokenGsi', 'entityUuidGsi', 'siteUuidGsi'); it('should query entityUuidGsi if none of uuid is specified', () => expect(db.getIndexName()).toBe('entityUuidGsi')); it('should query siteUuidGsi if site uuid is speicified', () => expect(db.getIndexName(undefined, 'siteuuid')).toBe('siteUuidGsi')); it('should query main table if device uuid is speicified', () => expect(db.getIndexName('device uuid', undefined)).toBeUndefined()); }); //# sourceMappingURL=transactionDb.spec.js.map