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

describe('VnUser privileges()', () => {
    const employeeId = 1;
    const developerId = 9;
    const sysadminId = 66;
    const itBossId = 104;
    const rootId = 100;
    const clarkKent = 1103;

    it('should throw an error when user not has privileges', async() => {
        const ctx = {req: {accessToken: {userId: developerId}}};
        const tx = await models.VnUser.beginTransaction({});

        let error;
        try {
            const options = {transaction: tx};

            await models.VnUser.privileges(ctx, employeeId, null, true, options);

            await tx.rollback();
        } catch (e) {
            error = e;
            await tx.rollback();
        }

        expect(error.message).toContain(`You don't have grant privilege`);
    });

    it('should throw an error when user has privileges but not has the role', async() => {
        const ctx = {req: {accessToken: {userId: sysadminId}}};
        const tx = await models.VnUser.beginTransaction({});

        let error;
        try {
            const options = {transaction: tx};

            await models.VnUser.privileges(ctx, employeeId, rootId, null, options);

            await tx.rollback();
        } catch (e) {
            error = e;
            await tx.rollback();
        }

        expect(error.message).toContain(`You don't own the role and you can't assign it to another user`);
    });

    it('should throw an error when user has privileges but not has the role from user', async() => {
        const ctx = {req: {accessToken: {userId: sysadminId}}};
        const tx = await models.VnUser.beginTransaction({});

        let error;
        try {
            const options = {transaction: tx};

            await models.VnUser.privileges(ctx, itBossId, developerId, null, options);

            await tx.rollback();
        } catch (e) {
            error = e;
            await tx.rollback();
        }

        expect(error.message).toContain(`You don't own the role and you can't assign it to another user`);
    });

    it('should change role', async() => {
        const ctx = {req: {accessToken: {userId: sysadminId}}};
        const tx = await models.VnUser.beginTransaction({});

        const options = {transaction: tx};
        const agency = await models.Role.findOne({
            where: {
                name: 'agency'
            }
        }, options);

        let error;
        let result;
        try {
            await models.VnUser.privileges(ctx, clarkKent, agency.id, null, options);
            result = await models.VnUser.findById(clarkKent, null, options);

            await tx.rollback();
        } catch (e) {
            error = e;
            await tx.rollback();
        }

        expect(error).not.toBeDefined();
        expect(result.roleFk).toEqual(agency.id);
    });

    it('should change hasGrant', async() => {
        const ctx = {req: {accessToken: {userId: sysadminId}}};
        const tx = await models.VnUser.beginTransaction({});

        let error;
        let result;
        try {
            const options = {transaction: tx};
            await models.VnUser.privileges(ctx, clarkKent, null, true, options);
            result = await models.VnUser.findById(clarkKent, null, options);

            await tx.rollback();
        } catch (e) {
            error = e;
            await tx.rollback();
        }

        expect(error).not.toBeDefined();
        expect(result.hasGrant).toBeTruthy();
    });
});