component-dbs-core
Version:
DTO objects shared among device backend
787 lines • 28.6 kB
JavaScript
"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());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const graphql_tag_1 = __importDefault(require("graphql-tag"));
const aws_sdk_1 = __importDefault(require("aws-sdk"));
const uuid_1 = require("uuid");
const aws_appsync_1 = require("aws-appsync");
const appsyncClient_1 = require("../appsyncClient");
const dynamodb_1 = require("aws-sdk/clients/dynamodb");
const auth0_1 = require("auth0");
describe('device backend service integration test suite', () => {
const appsyncEndpoint = process.env.APPSYNC_ENDPOINT || '';
const apiKey = process.env.API_KEY;
const componentName = 'dbs-api';
const stage = process.env.STAGE;
const auth0ClientId = process.env.AUTH0_CLIENT_ID;
const auth0ClientSecret = process.env.AUTH0_CLIENT_SECRET;
const auth0Domain = process.env.AUTH0_DOMAIN;
const deviceTable = `${stage}-${componentName}-Devices`;
const appsyncApiKeyClient = appsyncClient_1.createClient(appsyncEndpoint, {
type: aws_appsync_1.AUTH_TYPE.API_KEY,
apiKey: apiKey,
});
let deviceUuid;
let entityUuid;
const email = `${uuid_1.v4()}@gmail.com`;
const password = 'abcABC123!@#';
let accessToken;
let refreshToken;
beforeAll(() => {
aws_sdk_1.default.config.update({ region: 'ap-southeast-2' });
});
afterAll(() => __awaiter(void 0, void 0, void 0, function* () {
if (auth0ClientId && auth0ClientSecret && auth0Domain) {
const auth0Management = new auth0_1.ManagementClient({
domain: auth0Domain,
clientId: auth0ClientId,
clientSecret: auth0ClientSecret,
scope: 'delete:users',
});
console.log(`Deleting test user ${email} from auth0`);
const user = yield auth0Management.getUsersByEmail(email);
yield auth0Management.deleteUser({ id: user[0].user_id });
console.log(`Test user deleted.`);
}
}));
it('should be able to generate device uuid', () => __awaiter(void 0, void 0, void 0, function* () {
const model = uuid_1.v4().slice(-16);
const serial = uuid_1.v4().slice(-16);
return (yield appsyncApiKeyClient.hydrated())
.mutate({
mutation: graphql_tag_1.default `
mutation getDeviceUuid($model: String!, $serial: String!) {
getDeviceUuid(input: { model: $model, serial: $serial }) {
id
}
}
`,
variables: {
model,
serial,
},
})
.then(({ data }) => {
deviceUuid = data.getDeviceUuid.id;
expect(typeof data.getDeviceUuid.id).toBe('string');
})
.catch((err) => {
console.error(err);
throw err;
});
}));
it('should be able to signup', () => __awaiter(void 0, void 0, void 0, function* () {
console.log('test user signup:', email, password);
return (yield appsyncApiKeyClient.hydrated())
.mutate({
mutation: graphql_tag_1.default `
mutation identitySignUp(
$deviceUuid: ID!
$email: String!
$password: String!
) {
identitySignUp(
input: {
deviceUuid: $deviceUuid
email: $email
password: $password
}
) {
valid
accessToken
refreshToken
idToken
}
}
`,
variables: { deviceUuid, email, password },
})
.then(({ data }) => {
accessToken = data.identitySignUp.accessToken;
expect(typeof accessToken).toBe('string');
expect(typeof data.identitySignUp.refreshToken).toBe('string');
expect(typeof data.identitySignUp.idToken).toBe('string');
expect(typeof data.identitySignUp.valid).toBe('boolean');
});
}));
it('should be able to login', () => __awaiter(void 0, void 0, void 0, function* () {
console.log('test user login:', email, password);
return (yield appsyncApiKeyClient.hydrated())
.mutate({
mutation: graphql_tag_1.default `
mutation identityLogin(
$deviceUuid: ID!
$email: String!
$password: String!
) {
identityLogin(
input: {
deviceUuid: $deviceUuid
email: $email
password: $password
}
) {
valid
accessToken
refreshToken
idToken
}
}
`,
variables: { deviceUuid, email, password },
})
.then(({ data }) => {
accessToken = data.identityLogin.accessToken;
refreshToken = data.identityLogin.refreshToken;
expect(typeof accessToken).toBe('string');
expect(typeof refreshToken).toBe('string');
expect(typeof data.identityLogin.idToken).toBe('string');
expect(typeof data.identityLogin.valid).toBe('boolean');
});
}));
it('should be able to update device settings', () => __awaiter(void 0, void 0, void 0, function* () {
const settings = {
id: deviceUuid,
name: 'zeller device name',
site: {
name: 'zeller site name',
pin: '1203',
siteUuid: uuid_1.v4(),
},
receipt: {
businessAddress: 'Melbourne, Australia',
businessName: 'NPCO ltd.',
footer: 'link://footer',
logo: 'link://logo',
enabled: true,
},
};
const res = yield updateDeviceSettings(settings);
expect(res.updateDeviceSettings).toBeTruthy();
}));
it('should be able to check access token', () => __awaiter(void 0, void 0, void 0, function* () {
return (yield appsyncApiKeyClient.hydrated())
.mutate({
mutation: graphql_tag_1.default `
mutation checkAccessToken(
$deviceUuid: ID!
$accessToken: String!
$refreshToken: String!
) {
checkAccessToken(
input: {
deviceUuid: $deviceUuid
accessToken: $accessToken
refreshToken: $refreshToken
}
) {
valid
accessToken
refreshToken
idToken
}
}
`,
variables: { deviceUuid, accessToken, refreshToken },
})
.then(({ data }) => {
accessToken = data.checkAccessToken.accessToken;
refreshToken = data.checkAccessToken.refreshToken;
expect(typeof accessToken).toBe('string');
expect(typeof refreshToken).toBe('string');
// expect(typeof data.checkAccessToken.idToken).toBe('string');
expect(typeof data.checkAccessToken.valid).toBe('boolean');
});
}));
it('should be able to register phone', () => __awaiter(void 0, void 0, void 0, function* () {
return (yield appsyncClient_1.createClient(appsyncEndpoint, {
type: aws_appsync_1.AUTH_TYPE.OPENID_CONNECT,
jwtToken: () => accessToken,
}).hydrated())
.mutate({
mutation: graphql_tag_1.default `
mutation identityPhoneRegister($deviceUuid: ID!, $phone: String!) {
identityPhoneRegister(deviceUuid: $deviceUuid, phone: $phone) {
codeSent
validUntil
}
}
`,
variables: { deviceUuid, phone: '1234' },
})
.then(({ data }) => {
expect(data.identityPhoneRegister.codeSent).toBeTruthy();
expect(typeof data.identityPhoneRegister.validUntil).toBe('string');
});
}));
it('should be able to verify phone', () => __awaiter(void 0, void 0, void 0, function* () {
return (yield appsyncClient_1.createClient(appsyncEndpoint, {
type: aws_appsync_1.AUTH_TYPE.OPENID_CONNECT,
jwtToken: () => accessToken,
}).hydrated())
.mutate({
mutation: graphql_tag_1.default `
mutation identityPhoneVerify($deviceUuid: ID!, $code: String!) {
identityPhoneVerify(deviceUuid: $deviceUuid, code: $code) {
codeVerified
}
}
`,
variables: { deviceUuid, code: '1234' },
})
.then(({ data }) => {
expect(data.identityPhoneVerify.codeVerified).toBeTruthy();
});
}));
it('should be able to set pin', () => __awaiter(void 0, void 0, void 0, function* () {
return (yield appsyncClient_1.createClient(appsyncEndpoint, {
type: aws_appsync_1.AUTH_TYPE.OPENID_CONNECT,
jwtToken: () => accessToken,
}).hydrated())
.mutate({
mutation: graphql_tag_1.default `
mutation identitySetPin($deviceUuid: ID!, $pin: String!) {
identitySetPin(deviceUuid: $deviceUuid, pin: $pin)
}
`,
variables: { deviceUuid, pin: '1234' },
})
.then(({ data }) => {
expect(data.identitySetPin).toBeTruthy();
});
}));
it('should be able to verify pin', () => __awaiter(void 0, void 0, void 0, function* () {
return (yield appsyncClient_1.createClient(appsyncEndpoint, {
type: aws_appsync_1.AUTH_TYPE.OPENID_CONNECT,
jwtToken: () => accessToken,
}).hydrated())
.mutate({
mutation: graphql_tag_1.default `
mutation identityVerifyPin($deviceUuid: ID!, $pin: String!) {
identityVerifyPin(deviceUuid: $deviceUuid, pin: $pin)
}
`,
variables: { deviceUuid, pin: '1234' },
})
.then(({ data }) => {
expect(data.identityVerifyPin).toBeTruthy();
});
}));
it('should be able to support forgot password', () => __awaiter(void 0, void 0, void 0, function* () {
return (yield appsyncApiKeyClient.hydrated())
.mutate({
mutation: graphql_tag_1.default `
mutation identityForgotPassword($email: String!) {
identityForgotPassword(email: $email)
}
`,
variables: { email },
})
.then(({ data }) => {
expect(data.identityForgotPassword).toBeTruthy();
});
}));
it('should be able to change password', () => __awaiter(void 0, void 0, void 0, function* () {
return (yield appsyncClient_1.createClient(appsyncEndpoint, {
type: aws_appsync_1.AUTH_TYPE.OPENID_CONNECT,
jwtToken: () => accessToken,
}).hydrated())
.mutate({
mutation: graphql_tag_1.default `
mutation identityChangePassword($email: String!, $password: String!) {
identityChangePassword(
input: { email: $email, password: $password }
)
}
`,
variables: { email, password },
})
.then(({ data }) => {
expect(data.identityChangePassword).toBeFalsy();
});
}));
it('should be able to query transactions', () => __awaiter(void 0, void 0, void 0, function* () {
return (yield appsyncClient_1.createClient(appsyncEndpoint, {
type: aws_appsync_1.AUTH_TYPE.OPENID_CONNECT,
jwtToken: () => accessToken,
}).hydrated())
.query({
query: graphql_tag_1.default `
query {
getTransactions(limit: 10) {
transactions {
id
}
}
}
`,
})
.then(({ data }) => {
expect(typeof data.getTransactions.transactions).toBe('object');
});
}));
it('should be able to query transactions with OR operator in filter', () => __awaiter(void 0, void 0, void 0, function* () {
return (yield appsyncClient_1.createClient(appsyncEndpoint, {
type: aws_appsync_1.AUTH_TYPE.OPENID_CONNECT,
jwtToken: () => accessToken,
}).hydrated())
.query({
query: graphql_tag_1.default `
query {
getTransactions(
limit: 5
filter: {
or: [
{ reference: { eq: "3498349384" } }
{ maskedPan: { eq: "…0009" } }
]
}
) {
transactions {
status
}
}
}
`,
})
.then(({ data }) => {
expect(typeof data.getTransactions.transactions).toBe('object');
});
}));
it('should be able to query individual transaction', () => __awaiter(void 0, void 0, void 0, function* () {
return (yield appsyncClient_1.createClient(appsyncEndpoint, {
type: aws_appsync_1.AUTH_TYPE.OPENID_CONNECT,
jwtToken: () => accessToken,
}).hydrated())
.query({
query: graphql_tag_1.default `
query {
getTransaction(transactionUuid: "unknown") {
id
}
}
`,
})
.then(({ data }) => {
fail();
})
.catch((err) => {
expect(err).not.toBeUndefined();
expect(err).not.toBeNull();
});
}));
it('should be able to query deposits', () => __awaiter(void 0, void 0, void 0, function* () {
return (yield appsyncClient_1.createClient(appsyncEndpoint, {
type: aws_appsync_1.AUTH_TYPE.OPENID_CONNECT,
jwtToken: () => accessToken,
}).hydrated())
.query({
query: graphql_tag_1.default `
query {
getDeposits(limit: 10) {
deposits {
id
}
}
}
`,
})
.then(({ data }) => {
expect(typeof data.getDeposits.deposits).toBe('object');
});
}));
it('should fail to query deposit with incorrect uuid', () => __awaiter(void 0, void 0, void 0, function* () {
return (yield appsyncClient_1.createClient(appsyncEndpoint, {
type: aws_appsync_1.AUTH_TYPE.OPENID_CONNECT,
jwtToken: () => accessToken,
}).hydrated())
.query({
query: graphql_tag_1.default `
query {
getDeposit(depositUuid: "unknown") {
id
}
}
`,
})
.then(({ data }) => {
fail();
})
.catch((err) => {
expect(err).not.toBeUndefined();
expect(err).not.toBeNull();
});
}));
it('should be able to subscribe transaction update', () => new Promise((resolve, reject) => __awaiter(void 0, void 0, void 0, function* () {
const transaction = {
id: deviceUuid,
transactionUuid: uuid_1.v4(),
siteUuid: uuid_1.v4(),
entityUuid: uuid_1.v4(),
type: `transaction.${new Date().getTime()}`,
timestamp: new Date().toISOString(),
amount: 0,
saleAmount: 0,
scheme: "AMEX" /* AMEX */,
transactionType: "PURCHASE" /* PURCHASE */,
status: "APPROVED" /* APPROVED */,
maskedPan: uuid_1.v4(),
reference: uuid_1.v4(),
};
console.log('subscribe transaction on device:', deviceUuid, ',transaction:', transaction.transactionUuid);
const client = yield appsyncClient_1.createClient(appsyncEndpoint, {
type: aws_appsync_1.AUTH_TYPE.OPENID_CONNECT,
jwtToken: () => accessToken,
}).hydrated();
const subscribe = client
.subscribe({
query: graphql_tag_1.default `
subscription onTransactionUpdate($deviceUuid: ID!) {
onTransactionUpdate(deviceUuid: $deviceUuid) {
id
deviceUuid
siteUuid
entityUuid
timestamp
amount
saleAmount
scheme
transactionType
status
maskedPan
reference
}
}
`,
variables: {
deviceUuid,
},
})
.subscribe({
next: ({ data }) => {
console.log(JSON.stringify(data));
const { onTransactionUpdate: update } = data;
expect(update).toEqual({
id: transaction.transactionUuid,
deviceUuid: transaction.id,
siteUuid: transaction.siteUuid,
entityUuid: transaction.entityUuid,
timestamp: transaction.timestamp,
amount: transaction.amount,
saleAmount: transaction.saleAmount,
scheme: transaction.scheme,
transactionType: transaction.transactionType,
status: transaction.status,
maskedPan: transaction.maskedPan,
reference: transaction.reference,
__typename: 'Transaction',
});
subscribe.unsubscribe();
resolve();
},
});
setTimeout(() => __awaiter(void 0, void 0, void 0, function* () {
const dbClient = new dynamodb_1.DocumentClient();
yield dbClient
.put({
TableName: deviceTable,
Item: transaction,
})
.promise();
}), 2000);
})), 10000);
it('should be able to subscribe for deposit update', () => new Promise((resolve, reject) => __awaiter(void 0, void 0, void 0, function* () {
const deposit = {
id: deviceUuid,
depositUuid: uuid_1.v4(),
entityUuid: uuid_1.v4(),
type: `deposit.${new Date().getTime()}`,
timestamp: new Date().toISOString(),
totalAmount: 0,
status: "DEPOSITED" /* DEPOSITED */,
dailyTotals: [
{
amount: 100,
date: new Date().toISOString(),
},
],
};
console.log('subscribe deposit on device:', deviceUuid, ', deposit:', deposit.depositUuid);
const client = yield appsyncClient_1.createClient(appsyncEndpoint, {
type: aws_appsync_1.AUTH_TYPE.OPENID_CONNECT,
jwtToken: () => accessToken,
}).hydrated();
const subscribe = client
.subscribe({
query: graphql_tag_1.default `
subscription {
onDepositUpdate {
id
entityUuid
timestamp
status
}
}
`,
})
.subscribe({
next: ({ data }) => {
const { onDepositUpdate: update } = data;
expect(update).toEqual({
id: deposit.depositUuid,
entityUuid: deposit.entityUuid,
timestamp: deposit.timestamp,
status: deposit.status,
dailyTotals: [
{
amount: deposit.dailyTotals[0].amount,
date: deposit.dailyTotals[0].date,
__typename: 'DailyTotal',
},
],
totalAmount: deposit.totalAmount,
__typename: 'Deposit',
});
subscribe.unsubscribe();
resolve();
},
}, (error) => {
console.log(JSON.stringify(error));
});
setTimeout(() => __awaiter(void 0, void 0, void 0, function* () {
const dbClient = new dynamodb_1.DocumentClient();
yield dbClient
.put({
TableName: deviceTable,
Item: deposit,
})
.promise();
console.log('depisit added to db');
}), 2000);
})), 10000);
describe('site api test suite', () => {
it('it should be able to query list of sites', () => __awaiter(void 0, void 0, void 0, function* () {
return (yield appsyncClient_1.createClient(appsyncEndpoint, {
type: aws_appsync_1.AUTH_TYPE.OPENID_CONNECT,
jwtToken: () => accessToken,
}).hydrated())
.query({
query: graphql_tag_1.default `
query {
getSites(limit: 10) {
sites {
id
name
address
state
devices {
id
model
serial
name
}
}
}
}
`,
})
.then(({ data }) => {
expect(typeof data.getSites.sites).toBe('object');
})
.catch((err) => {
console.error(err);
fail();
});
}));
it('it should be able to create a site', () => __awaiter(void 0, void 0, void 0, function* () {
return (yield appsyncClient_1.createClient(appsyncEndpoint, {
type: aws_appsync_1.AUTH_TYPE.OPENID_CONNECT,
jwtToken: () => accessToken,
}).hydrated())
.mutate({
mutation: graphql_tag_1.default `
mutation {
createSite(
input: { name: "name", address: "address", state: "state" }
)
}
`,
})
.then(({ data }) => {
expect(typeof data.getSite).toBeTruthy();
})
.catch((err) => {
fail();
});
}));
it('it should be able to query individual site', () => __awaiter(void 0, void 0, void 0, function* () {
return (yield appsyncClient_1.createClient(appsyncEndpoint, {
type: aws_appsync_1.AUTH_TYPE.OPENID_CONNECT,
jwtToken: () => accessToken,
}).hydrated())
.query({
query: graphql_tag_1.default `
query {
getSite(siteUuid: "xxx") {
id
name
address
state
devices {
id
model
serial
name
}
}
}
`,
})
.then(() => {
fail();
})
.catch((err) => {
expect(err).not.toBeNull();
});
}));
});
it('should be able to get device settings', () => __awaiter(void 0, void 0, void 0, function* () {
const id = deviceUuid;
return (yield appsyncClient_1.createClient(appsyncEndpoint, {
type: aws_appsync_1.AUTH_TYPE.OPENID_CONNECT,
jwtToken: () => accessToken,
}).hydrated())
.query({
query: graphql_tag_1.default `
query getDeviceSettings($id: ID!) {
getDeviceSettings(deviceUuid: $id) {
id
name
site {
name
pin
}
receipt {
businessName
logo
}
}
}
`,
variables: {
id,
},
})
.then(({ data }) => {
console.log(data);
const settings = data.getDeviceSettings;
expect(settings).toHaveProperty('name');
expect(settings).toHaveProperty('site');
expect(settings).toHaveProperty('receipt');
})
.catch((err) => {
console.error(err);
throw err;
});
}));
function updateDeviceSettings(settings) {
return __awaiter(this, void 0, void 0, function* () {
return (yield appsyncClient_1.createClient(appsyncEndpoint, {
type: aws_appsync_1.AUTH_TYPE.OPENID_CONNECT,
jwtToken: () => accessToken,
}).hydrated())
.mutate({
mutation: graphql_tag_1.default `
mutation updateDeviceSettings($settings: DeviceSettingsInput!) {
updateDeviceSettings(deviceSettings: $settings)
}
`,
variables: {
settings,
},
})
.then(({ data }) => {
console.log(data);
return data;
})
.catch((err) => {
console.error(err);
throw err;
});
});
}
it('should be able to subscribe for deviceSettings update', () => new Promise((resolve, reject) => __awaiter(void 0, void 0, void 0, function* () {
const deviceSettings = {
id: deviceUuid,
name: 'zeller device name',
site: {
name: 'zeller site name',
pin: '1203',
siteUuid: uuid_1.v4(),
},
receipt: {
businessAddress: 'Victoria, Australia',
businessName: 'NPCO ltd.',
footer: 'link://footer_changed',
logo: 'link://logo',
enabled: true,
},
};
console.log('subscribe deviceSettingsUpdate on device:', deviceUuid);
const client = yield appsyncClient_1.createClient(appsyncEndpoint, {
type: aws_appsync_1.AUTH_TYPE.OPENID_CONNECT,
jwtToken: () => accessToken,
}).hydrated();
const id = deviceUuid;
const subscribe = client
.subscribe({
query: graphql_tag_1.default `
subscription OnSettingsUpdate($id:ID!) {
onDeviceSettingsUpdate(id:$id) {
id
name
site {
name
pin
}
receipt {
businessAddress
footer
logo
}
}
}
`,
variables: {
id
}
})
.subscribe({
next: ({ data }) => {
console.log(data);
const { onDeviceSettingsUpdate: update } = data;
expect(update).toMatchObject(deviceSettings);
subscribe.unsubscribe();
resolve();
},
}, (error) => {
console.log(JSON.stringify(error));
});
setTimeout(() => __awaiter(void 0, void 0, void 0, function* () {
yield updateDeviceSettings(deviceSettings);
console.log('device settings updated');
}), 2000);
})), 10000);
});
//# sourceMappingURL=integration.spec.js.map