const {models} = require('vn-loopback/server/server');

describe('machineWorker updateInTime()', () => {
    const itBoss = 104;
    const davidCharles = 1106;

    beforeAll(async() => {
        ctx = {
            req: {
                accessToken: {},
                headers: {origin: 'http://localhost'},
                __: value => value
            }
        };
    });

    it('should throw an error if the plate does not exist', async() => {
        const tx = await models.MachineWorker.beginTransaction({});
        const options = {transaction: tx};
        const plate = 'RE-123';
        ctx.req.accessToken.userId = 1106;
        try {
            await models.MachineWorker.updateInTime(ctx, plate, options);
            await tx.rollback();
        } catch (e) {
            const error = e;

            expect(error.message).toContain('the plate does not exist');
            await tx.rollback();
        }
    });

    it('should grab a machine where is not in use', async() => {
        const tx = await models.MachineWorker.beginTransaction({});
        const options = {transaction: tx};
        const plate = 'RE-003';
        ctx.req.accessToken.userId = 1107;
        try {
            const totalBefore = await models.MachineWorker.find(null, options);
            await models.MachineWorker.updateInTime(ctx, plate, options);
            const totalAfter = await models.MachineWorker.find(null, options);

            expect(totalAfter.length).toEqual(totalBefore.length + 1);
            await tx.rollback();
        } catch (e) {
            await tx.rollback();
        }
    });

    describe('less than 12h', () => {
        const plate = 'RE-001';
        it('should trow an error if it is not himself', async() => {
            const tx = await models.MachineWorker.beginTransaction({});
            const options = {transaction: tx};
            ctx.req.accessToken.userId = davidCharles;

            try {
                await models.MachineWorker.updateInTime(ctx, plate, options);
                await tx.rollback();
            } catch (e) {
                const error = e;

                expect(error.message).toContain('This machine is already in use');
                await tx.rollback();
            }
        });

        it('should throw an error if it is himself with a different machine', async() => {
            const tx = await models.MachineWorker.beginTransaction({});
            const options = {transaction: tx};
            ctx.req.accessToken.userId = itBoss;
            const plate = 'RE-003';
            try {
                await models.MachineWorker.updateInTime(ctx, plate, options);
                await tx.rollback();
            } catch (e) {
                const error = e;

                expect(error.message).toEqual('You are already using a machine');
                await tx.rollback();
            }
        });

        it('should set the out time if it is himself', async() => {
            const tx = await models.MachineWorker.beginTransaction({});
            const options = {transaction: tx};
            ctx.req.accessToken.userId = itBoss;

            try {
                const isNotParked = await models.MachineWorker.findOne({
                    where: {workerFk: itBoss}
                }, options);
                await models.MachineWorker.updateInTime(ctx, plate, options);
                const isParked = await models.MachineWorker.findOne({
                    where: {workerFk: itBoss}
                }, options);

                expect(isNotParked.outTime).toBeNull();
                expect(isParked.outTime).toBeDefined();
                await tx.rollback();
            } catch (e) {
                await tx.rollback();
            }
        });
    });

    describe('equal or more than 12h', () => {
        const plate = 'RE-002';
        it('should set the out time and grab the machine', async() => {
            const tx = await models.MachineWorker.beginTransaction({});
            const options = {transaction: tx};
            ctx.req.accessToken.userId = davidCharles;
            const filter = {
                where: {workerFk: davidCharles, machineFk: 2}
            };
            try {
                const isNotParked = await models.MachineWorker.findOne(filter, options);
                const totalBefore = await models.MachineWorker.find(null, options);
                await models.MachineWorker.updateInTime(ctx, plate, options);
                const isParked = await models.MachineWorker.findOne(filter, options);
                const totalAfter = await models.MachineWorker.find(null, options);

                expect(isNotParked.outTime).toBeNull();
                expect(isParked.outTime).toBeDefined();
                expect(totalAfter.length).toEqual(totalBefore.length + 1);
                await tx.rollback();
            } catch (e) {
                await tx.rollback();
            }
        });
    });
});