390 lines
12 KiB
JavaScript
390 lines
12 KiB
JavaScript
// const fetch = require('node-fetch');
|
|
// const {test, expect} = require('jest')
|
|
const axios = require('axios');
|
|
|
|
const url = 'http://localhost:42001/cutler/rest/web/index.php?r=';
|
|
const auth = "Basic ZG9vcl9zeXN0ZW06ZG9vcnN5c3RlbTE=";
|
|
const TEST_CARD_NUMBER = "10WMVXMZ";
|
|
const TEST_KEY = "f100";
|
|
const TEST_AUTH_HEADER = {
|
|
'Authorization': auth
|
|
};
|
|
|
|
function fail(reason = "fail was called in a test.") {
|
|
throw new Error(reason);
|
|
}
|
|
function secondsSinceEpoch(d){
|
|
return Math.floor( d.getTime() / 1000 );
|
|
}
|
|
global.fail = fail;
|
|
|
|
function formatDateTime(date){
|
|
let s = date.getFullYear()
|
|
+ "-"
|
|
+ (date.getMonth() + 1+"").padStart(2,"0")
|
|
+ "-"
|
|
+ (date.getDate() +"").padStart(2,"0")
|
|
+ " "
|
|
+ (date.getHours()+"").padStart(2,"0")
|
|
+ ":"
|
|
+ (date.getMinutes()+"").padStart(2,"0")
|
|
+ ":"
|
|
+ "00";
|
|
return s;
|
|
}
|
|
|
|
// This test fails because 1 !== 2
|
|
test('Testing to see if Jest works', () => {
|
|
expect(1).toBe(1)
|
|
})
|
|
|
|
axios.interceptors.request.use(request => {
|
|
// console.info(request.url);
|
|
// console.log('Starting Request', JSON.stringify(request, null, 2))
|
|
return request
|
|
});
|
|
|
|
axios.interceptors.response.use(response => {
|
|
console.info(response.status);
|
|
if ( response.status >=400){
|
|
console.info(response.request.url)
|
|
console.info(response.request.data)
|
|
}
|
|
// console.info(response.url);
|
|
// console.log('Response:', JSON.stringify(response.status , null, 2))
|
|
// console.log('Response:', JSON.stringify(response.statusText , null, 2))
|
|
return response
|
|
})
|
|
|
|
|
|
class Client {
|
|
|
|
async reset($cardNumber) {
|
|
return await axios.get(url + 'door/reset&cardNumber=' + $cardNumber, {
|
|
headers: {...TEST_AUTH_HEADER}
|
|
});
|
|
}
|
|
|
|
async getInfo($cardNumber) {
|
|
return await axios.get(url + 'door/info&cardNumber=' + $cardNumber, {
|
|
headers: {...TEST_AUTH_HEADER}
|
|
});
|
|
}
|
|
|
|
async createDoorLog(doorlog) {
|
|
return await axios.post(url + 'door/create-door-log', doorlog,{
|
|
headers: {...TEST_AUTH_HEADER},
|
|
});
|
|
}
|
|
|
|
async move(data, headers) {
|
|
return await axios.get(url + 'door/move', {
|
|
headers: {
|
|
...TEST_AUTH_HEADER,
|
|
...headers
|
|
},
|
|
data: {
|
|
// verifyOnly: false,
|
|
direction: 'IN',
|
|
device: 'Q',
|
|
validateOnly: false,
|
|
cardNumber: '10WMVXMZ',
|
|
...data
|
|
}
|
|
});
|
|
}
|
|
|
|
async checkoutKey(cardNumber,keyNumber) {
|
|
return await axios.get(url + `door/checkout-key&cardNumber=${cardNumber}&keyNumber=${keyNumber}`, {
|
|
headers: {
|
|
...TEST_AUTH_HEADER,
|
|
}
|
|
});
|
|
}
|
|
|
|
async revokeKey(cardNumber,keyNumber) {
|
|
return await axios.get(url + `door/revoke-key&cardNumber=${cardNumber}&keyNumber=${keyNumber}`, {
|
|
headers: {
|
|
...TEST_AUTH_HEADER,
|
|
}
|
|
});
|
|
}
|
|
|
|
async moveWithInfo(data, headers) {
|
|
await this.checkoutKey(TEST_CARD_NUMBER,TEST_KEY);
|
|
const before = await this.getInfo(data.cardNumber);
|
|
const response = await this.move(data, headers);
|
|
const after = await this.getInfo(data.cardNumber);
|
|
return {
|
|
before,
|
|
response,
|
|
after
|
|
}
|
|
}
|
|
}
|
|
|
|
test('Emergency open', async () => {
|
|
try {
|
|
const client = new Client();
|
|
await client.reset(TEST_CARD_NUMBER)
|
|
let before = await client.getInfo(TEST_CARD_NUMBER);
|
|
let response = await client.move({direction: 'IN', device: 'E'})
|
|
expect(response.status).toBe(204);
|
|
let after = await client.getInfo(TEST_CARD_NUMBER);
|
|
expect(after.data.doorLogs.length).toBe(0);
|
|
expect(after.data.doorLogCount).toBe("" + (parseInt(before.data.doorLogCount) + 1));
|
|
expect(after.data.lastDoorLog?.direction).toBe(128);
|
|
} catch (e) {
|
|
throw e;
|
|
}
|
|
|
|
})
|
|
|
|
test('Error if card not exists', async () => {
|
|
const client = new Client();
|
|
try {
|
|
await client.move({cardNumber: 'notexists', direction: 'IN'});
|
|
} catch (e) {
|
|
expect(e?.response?.status).toBe(400);
|
|
|
|
}
|
|
expect.assertions(1);
|
|
},10000);
|
|
|
|
test('Allow card type employee', async () => {
|
|
const client = new Client();
|
|
let createdAt = new Date();
|
|
createdAt.setHours(18);
|
|
const info = await client.moveWithInfo({cardNumber: 'employee', direction: 'IN', device: 'C', createdAt: formatDateTime(createdAt)});
|
|
const lastLog = info.after.data.lastDoorLog;
|
|
expect(lastLog.id_card).not.toBeNull();
|
|
expect(lastLog.direction).toBe(7);
|
|
},10000)
|
|
|
|
|
|
test('Normal Ticket: usage count will be increased on entry', async () => {
|
|
const client = new Client();
|
|
await client.reset(TEST_CARD_NUMBER);
|
|
const info = await client.moveWithInfo({cardNumber: TEST_CARD_NUMBER, device: 'C', direction: 'IN'});
|
|
expect(info?.response?.status).toBe(200);
|
|
const ticketBefore = info?.before.data?.tickets[0];
|
|
const ticketAfter = info?.after.data?.tickets[0];
|
|
expect(ticketBefore.usage_count + 1).toBe(ticketAfter.usage_count);
|
|
|
|
await client.revokeKey(TEST_CARD_NUMBER,TEST_KEY);
|
|
await client.move({cardNumber: TEST_CARD_NUMBER, device: 'C', direction: 'OUT'});
|
|
|
|
const info2 = await client.moveWithInfo({cardNumber: TEST_CARD_NUMBER,device: 'C', direction: 'IN'});
|
|
expect(info?.response?.status).toBe(200);
|
|
const ticketAfter2 = info2?.after.data?.tickets[0];
|
|
expect(ticketAfter.usage_count).toBe(ticketAfter2.usage_count);
|
|
},20000);
|
|
|
|
test('Normal Ticket: flag door in will be set on entry', async () => {
|
|
const client = new Client();
|
|
await client.reset(TEST_CARD_NUMBER);
|
|
const info = await client.moveWithInfo({cardNumber: TEST_CARD_NUMBER,device: 'C', direction: 'IN'});
|
|
expect(info?.response?.status).toBe(200);
|
|
expect(info.before.data.card.flag).toBe(0);
|
|
expect(info.after.data.card.flag).toBe(2);
|
|
})
|
|
|
|
|
|
test('Normal Ticket: increase door log after 3 hours', async () => {
|
|
const client = new Client();
|
|
await client.reset(TEST_CARD_NUMBER);
|
|
let info = await client.getInfo(TEST_CARD_NUMBER);
|
|
// First log on this day
|
|
let date = new Date();
|
|
date.setHours(1);
|
|
date.setMinutes(0,0,0);
|
|
await client.createDoorLog({
|
|
'created_at' : formatDateTime( date ),
|
|
'id_card': info.data.card.id_card,
|
|
'id_customer': info.data.customer.id_customer,
|
|
'id_ticket_current' : info.data.tickets[0].id_ticket,
|
|
'direction' : 'IN'
|
|
});
|
|
return;
|
|
// second door in @ 2:00 am. Less then 3 hours since first door log, so no
|
|
// usage_count must be consumed
|
|
let createdAt = new Date();
|
|
createdAt.setHours(2);
|
|
createdAt.setMinutes(0,0,0);
|
|
info = await client.moveWithInfo({
|
|
cardNumber: TEST_CARD_NUMBER,
|
|
direction: 'IN',
|
|
createdAt: formatDateTime(createdAt),
|
|
device: 'C'
|
|
});
|
|
return;
|
|
let ticketBefore = info?.before.data?.tickets[0];
|
|
let ticketAfter = info?.after.data?.tickets[0];
|
|
expect(ticketBefore.usage_count).toBe(ticketAfter.usage_count);
|
|
await client.revokeKey(TEST_CARD_NUMBER,TEST_KEY);
|
|
await client.move({
|
|
cardNumber: TEST_CARD_NUMBER,
|
|
direction: 'OUT',
|
|
createdAt: formatDateTime(createdAt),
|
|
device: 'C'
|
|
});
|
|
|
|
return;
|
|
|
|
// @4:00 'IN' hours already passed, we need consume usage count
|
|
createdAt = new Date();
|
|
createdAt.setHours(4);
|
|
createdAt.setMinutes(0,0,0);
|
|
info = await client.moveWithInfo({
|
|
cardNumber: TEST_CARD_NUMBER,
|
|
direction: 'IN',
|
|
createdAt: formatDateTime(createdAt),
|
|
device: 'C'
|
|
});
|
|
ticketBefore = info?.before.data?.tickets[0];
|
|
ticketAfter = info?.after.data?.tickets[0];
|
|
expect(ticketBefore.usage_count+1).toBe(ticketAfter.usage_count);
|
|
await client.revokeKey(TEST_CARD_NUMBER,TEST_KEY);
|
|
await client.move({
|
|
cardNumber: TEST_CARD_NUMBER,
|
|
direction: 'OUT',
|
|
createdAt: formatDateTime(createdAt),
|
|
device: 'C'
|
|
});
|
|
|
|
// @6:00 2 hours passed since 4, we don't need consume usage count
|
|
createdAt = new Date();
|
|
await client.revokeKey(TEST_CARD_NUMBER,TEST_KEY);
|
|
createdAt.setHours('OUT');
|
|
createdAt.setMinutes(0,0,0);
|
|
info = await client.moveWithInfo({
|
|
cardNumber: TEST_CARD_NUMBER,
|
|
direction: 'IN',
|
|
createdAt: formatDateTime(createdAt),
|
|
device: 'C'
|
|
});
|
|
ticketBefore = info?.before.data?.tickets[0];
|
|
ticketAfter = info?.after.data?.tickets[0];
|
|
expect(ticketBefore.usage_count).toBe(ticketAfter.usage_count);
|
|
await client.revokeKey(TEST_CARD_NUMBER,TEST_KEY);
|
|
await client.move({
|
|
cardNumber: TEST_CARD_NUMBER,
|
|
direction: 'OUT',
|
|
createdAt: formatDateTime(createdAt),
|
|
device: 'C'
|
|
});
|
|
|
|
// @20:15 Need to consume usage count
|
|
createdAt = new Date();
|
|
createdAt.setHours(20);
|
|
createdAt.setMinutes(15,0,0);
|
|
info = await client.moveWithInfo({
|
|
cardNumber: TEST_CARD_NUMBER,
|
|
direction: 'IN',
|
|
createdAt: formatDateTime(createdAt),
|
|
device: 'C'
|
|
});
|
|
ticketBefore = info?.before.data?.tickets[0];
|
|
ticketAfter = info?.after.data?.tickets[0];
|
|
expect(ticketBefore.usage_count+1).toBe(ticketAfter.usage_count);
|
|
},20000)
|
|
|
|
test('Normal Ticket: can\'t move 2 times in without move out', async () => {
|
|
|
|
const client = new Client();
|
|
await client.reset(TEST_CARD_NUMBER);
|
|
await client.checkoutKey(TEST_CARD_NUMBER,TEST_KEY);
|
|
|
|
await client.move({
|
|
cardNumber: TEST_CARD_NUMBER,
|
|
direction: 'IN',
|
|
device: 'C'
|
|
});
|
|
try {
|
|
await client.move({
|
|
cardNumber: TEST_CARD_NUMBER,
|
|
direction: 'IN',
|
|
device: 'C'
|
|
});
|
|
// prev statement must fail
|
|
expect(true).toBe(false);
|
|
}catch (e){
|
|
expect(e).toBeDefined();
|
|
}
|
|
|
|
},10000);
|
|
|
|
test('Normal Ticket: can\'t move 2 times \'OUT\' without move in', async () => {
|
|
|
|
const client = new Client();
|
|
await client.reset(TEST_CARD_NUMBER);
|
|
await client.move({
|
|
cardNumber: TEST_CARD_NUMBER,
|
|
direction: 'OUT',
|
|
device: 'C'
|
|
});
|
|
try {
|
|
await client.move({
|
|
cardNumber: TEST_CARD_NUMBER,
|
|
direction: 'OUT',
|
|
device: 'C'
|
|
});
|
|
// prev statement must fail
|
|
expect(true).toBe(false);
|
|
}catch (e){
|
|
expect(e).toBeDefined();
|
|
}
|
|
|
|
},10000);
|
|
|
|
test('Normal Ticket: move in, move out, move in, move out', async () => {
|
|
|
|
const client = new Client();
|
|
await client.reset(TEST_CARD_NUMBER);
|
|
await client.checkoutKey(TEST_CARD_NUMBER,TEST_KEY);
|
|
await client.move({
|
|
cardNumber: TEST_CARD_NUMBER,
|
|
direction: 'IN',
|
|
device: 'C'
|
|
});
|
|
await client.revokeKey(TEST_CARD_NUMBER,TEST_KEY);
|
|
await client.move({
|
|
cardNumber: TEST_CARD_NUMBER,
|
|
direction: 'OUT',
|
|
device: 'C'
|
|
});
|
|
await client.checkoutKey(TEST_CARD_NUMBER,TEST_KEY);
|
|
await client.move({
|
|
cardNumber: TEST_CARD_NUMBER,
|
|
direction: 'IN',
|
|
device: 'C'
|
|
});
|
|
await client.revokeKey(TEST_CARD_NUMBER,TEST_KEY);
|
|
await client.move({
|
|
cardNumber: TEST_CARD_NUMBER,
|
|
direction: 'OUT',
|
|
device: 'C'
|
|
});
|
|
|
|
},10000);
|
|
|
|
|
|
test('Normal Ticket: can\'t move \'in\' without key', async () => {
|
|
|
|
try{
|
|
const client = new Client();
|
|
await client.reset(TEST_CARD_NUMBER);
|
|
await client.move({
|
|
cardNumber: TEST_CARD_NUMBER,
|
|
direction: 'IN',
|
|
device: 'C'
|
|
});
|
|
// should throw an exception, since no key is assigend
|
|
expect(true).toBe(false);
|
|
}catch (e){
|
|
expect(e).toBeDefined();
|
|
}
|
|
|
|
|
|
},10000);
|