import { TestBed } from '@angular/core/testing';
import { ScheduleDateValidationService } from '@schedule/services/date-validation.service';
import { AppSettingsService } from '@shared/services';

describe('ScheduleDateValidationService', () => {
    let service: ScheduleDateValidationService;
    const scheduleMinDate = new Date(2022, 4, 23);
    const scheduleMaxDate = new Date(2022, 4, 29);

    beforeEach(() => {
        TestBed.configureTestingModule({
            providers: [
                ScheduleDateValidationService,
                {
                    provide: AppSettingsService,
                    useValue: {
                        getSettings: () => {
                            return Promise.resolve({
                                scheduleMinDate,
                                scheduleMaxDate,
                            });
                        },
                    },
                },
            ],
        });

        service = TestBed.inject(ScheduleDateValidationService);
    });

    it('should validate date', async () => {
        const validDates = [
            new Date(2022, 4, 23),
            new Date(2022, 4, 25),
            new Date(2022, 4, 29),
        ];
        const invalidDates = [new Date(2022, 4, 21), new Date(2022, 4, 30)];

        const truthyResult = await Promise.all(
            validDates.map((date) => service.isDateValid(date)),
        );
        const falsyResult = await Promise.all(
            invalidDates.map((date) => service.isDateValid(date)),
        );

        expect(truthyResult.every(Boolean)).toBe(true);
        expect(falsyResult.every((res) => !res)).toBe(true);
    });

    it('should return date if it is valid or scheduleMinDate', async () => {
        const validDate = new Date(2022, 4, 25);
        const invalidDate = new Date(2022, 4, 21);

        const firstResult = await service.getMinValidDate(validDate);
        expect(firstResult).toEqual(validDate);

        const secondResult = await service.getMinValidDate(invalidDate);
        expect(secondResult).toEqual(scheduleMinDate);
    });

    it('should resolve with undefined as minDate if date was not provided', async () => {
        const result = await service.getMinValidDate();
        expect(result).toBe(undefined);
    });

    it('should return date if it is valid or scheduleMaxDate', async () => {
        const validDate = new Date(2022, 4, 25);
        const invalidDate = new Date(2022, 4, 29);

        const firstResult = await service.getMaxValidDate(validDate);
        expect(firstResult).toEqual(validDate);

        const secondResult = await service.getMaxValidDate(invalidDate);
        expect(secondResult).toEqual(scheduleMaxDate);
    });

    it('should resolve with undefined as maxDate if date was not provided', async () => {
        const result = await service.getMaxValidDate();
        expect(result).toBe(undefined);
    });
});
