import { faker } from '@faker-js/faker/locale/en_US';
import { PerformanceReviewCycleParticipantType } from '../../../../src/api/modules/performanceReviews/business/types/performanceReviewCycleRole';
import { ListPerformanceReviewUsersByParticipantTypeAndResponsibleVC } from '../../../../src/api/modules/performanceReviews/presentation/validationClasses/listPerformanceReviewUsersByParticipantTypeAndResponsibleVC';
import { fakePositiveInteger } from '../../../common/common';
import { getValidationClass } from '../../../common/serializationClasses/serializationClassesHelper';

describe('ListPerformanceReviewUsersByParticipantTypeAndResponsibleVC', () => {
    it('should pass validation if the user sends correct values', () => {
        const responsibleId = fakePositiveInteger();
        const { errors } = getValidationClass(
            {
                q: faker.word.words(),
                responsibleId: faker.helpers.arrayElement([responsibleId, responsibleId.toString()]),
                role: PerformanceReviewCycleParticipantType.REVIEWED,
            },
            ListPerformanceReviewUsersByParticipantTypeAndResponsibleVC,
        );

        expect(errors).toHaveLength(0);
    });

    it('should pass validation if the user sends only responsibleId and role', () => {
        const { errors } = getValidationClass(
            {
                responsibleId: fakePositiveInteger(),
                role: PerformanceReviewCycleParticipantType.REVIEWED,
            },
            ListPerformanceReviewUsersByParticipantTypeAndResponsibleVC,
        );

        expect(errors).toHaveLength(0);
    });

    it('should validate correctly if the user sends an empty object', () => {
        const { errors } = getValidationClass({}, ListPerformanceReviewUsersByParticipantTypeAndResponsibleVC);

        ['responsibleId', 'role'].forEach((property) => {
            expect(errors).toPartiallyContain({ property });
        });
    });

    it('should validate correctly if the user sends incorrect types', () => {
        const { errors } = getValidationClass(
            {
                q: faker.datatype.boolean(),
                responsibleId: faker.word.words(),
                role: faker.datatype.boolean(),
            },
            ListPerformanceReviewUsersByParticipantTypeAndResponsibleVC,
        );

        ['q', 'responsibleId', 'role'].forEach((property) => {
            expect(errors).toPartiallyContain({ property });
        });
    });

    it('should validate correctly if the user sends an invalid role', () => {
        const { errors } = getValidationClass(
            {
                responsibleId: fakePositiveInteger(),
                role: faker.word.words(),
            },
            ListPerformanceReviewUsersByParticipantTypeAndResponsibleVC,
        );

        expect(errors).toPartiallyContain({ property: 'role' });
    });

    it('should validate correctly if the user sends a reviewer role', () => {
        const { errors } = getValidationClass(
            {
                responsibleId: fakePositiveInteger(),
                role: PerformanceReviewCycleParticipantType.REVIEWER,
            },
            ListPerformanceReviewUsersByParticipantTypeAndResponsibleVC,
        );

        expect(errors).toPartiallyContain({ property: 'role' });
    });

    it('should accept valid pendingActionFilter PENDING_SELECTION', () => {
        const { errors } = getValidationClass(
            {
                responsibleId: fakePositiveInteger(),
                role: PerformanceReviewCycleParticipantType.REVIEWED,
                pendingActionFilter: 'PENDING_SELECTION',
            },
            ListPerformanceReviewUsersByParticipantTypeAndResponsibleVC,
        );

        expect(errors.filter((e) => e.property === 'pendingActionFilter')).toHaveLength(0);
    });

    it('should accept valid pendingActionFilter PENDING_EVALUATION', () => {
        const { errors } = getValidationClass(
            {
                responsibleId: fakePositiveInteger(),
                role: PerformanceReviewCycleParticipantType.REVIEWED,
                pendingActionFilter: 'PENDING_EVALUATION',
            },
            ListPerformanceReviewUsersByParticipantTypeAndResponsibleVC,
        );

        expect(errors.filter((e) => e.property === 'pendingActionFilter')).toHaveLength(0);
    });

    it('should accept valid pendingActionFilter PENDING_DELIVERY', () => {
        const { errors } = getValidationClass(
            {
                responsibleId: fakePositiveInteger(),
                role: PerformanceReviewCycleParticipantType.REVIEWED,
                pendingActionFilter: 'PENDING_DELIVERY',
            },
            ListPerformanceReviewUsersByParticipantTypeAndResponsibleVC,
        );

        expect(errors.filter((e) => e.property === 'pendingActionFilter')).toHaveLength(0);
    });

    it('should reject invalid pendingActionFilter value', () => {
        const { errors } = getValidationClass(
            {
                responsibleId: fakePositiveInteger(),
                role: PerformanceReviewCycleParticipantType.REVIEWED,
                pendingActionFilter: 'INVALID_FILTER',
            },
            ListPerformanceReviewUsersByParticipantTypeAndResponsibleVC,
        );

        expect(errors).toPartiallyContain({ property: 'pendingActionFilter' });
    });

    it('should accept request without pendingActionFilter (optional)', () => {
        const { errors } = getValidationClass(
            {
                responsibleId: fakePositiveInteger(),
                role: PerformanceReviewCycleParticipantType.REVIEWED,
            },
            ListPerformanceReviewUsersByParticipantTypeAndResponsibleVC,
        );

        expect(errors.filter((e) => e.property === 'pendingActionFilter')).toHaveLength(0);
    });
});
