component-dbs-core
Version:
DTO objects shared among device backend
336 lines • 15.3 kB
JavaScript
;
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