// 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);