import { faker } from '@faker-js/faker/locale/en_US';
import { FillPerformanceReviewFormReviewVC } from '../../../../src/api/modules/performanceReviews/presentation/validationClasses/fillPerformanceReviewFormReviewVC';
import { fakePositiveInteger } from '../../../common/common';
import { getValidationClass } from '../../../common/serializationClasses/serializationClassesHelper';

describe('FillPerformanceReviewFormReviewVC', () => {
    it(`should pass validation if the user sends correct parameters`, () => {
        const { errors } = getValidationClass(
            {
                fillingTime: fakePositiveInteger(),
                questionAnswers: [],
            },
            FillPerformanceReviewFormReviewVC,
        );

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

    it(`should pass validation if the user sends correct parameters with one question answer`, () => {
        const { errors } = getValidationClass(
            {
                fillingTime: fakePositiveInteger(),
                questionAnswers: [
                    {
                        answer: faker.word.words(),
                        comment: faker.word.words(),
                        questionId: faker.string.uuid(),
                    },
                ],
            },
            FillPerformanceReviewFormReviewVC,
        );

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

    it(`should pass validation if the user sends correct parameters with multiple question answers, each of a different question`, () => {
        const questionIds = Array.from(new Set(faker.helpers.multiple(faker.string.uuid, { count: { max: 10, min: 2 } })));
        const questionAnswers = questionIds.map((questionId) => ({
            answer: faker.word.words(),
            comment: faker.word.words(),
            questionId,
        }));
        const { errors } = getValidationClass(
            {
                fillingTime: fakePositiveInteger(),
                questionAnswers,
            },
            FillPerformanceReviewFormReviewVC,
        );

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

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

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

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

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

    it(`should validate correctly if the user sends incorrect question answers`, () => {
        const { errors } = getValidationClass(
            {
                fillingTime: fakePositiveInteger(),
                questionAnswers: [
                    {
                        property: faker.word.words(),
                        secondProperty: fakePositiveInteger(),
                    },
                ],
            },
            FillPerformanceReviewFormReviewVC,
        );

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

    it(`should validate correctly if the user sends duplicate question ids in question answers`, () => {
        const questionId = faker.string.uuid();
        const { errors } = getValidationClass(
            {
                fillingTime: fakePositiveInteger(),
                questionAnswers: [
                    {
                        answer: faker.word.words(),
                        comment: faker.word.words(),
                        questionId,
                    },
                    {
                        answer: faker.word.words(),
                        comment: faker.word.words(),
                        questionId,
                    },
                ],
            },
            FillPerformanceReviewFormReviewVC,
        );

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