import { TestBed } from '@angular/core/testing';
import { IBreadCrumbItem } from '@components/page/breadcrumds/page-breadcrumbs.component';
import { OnlineBoardDetailsBreadCrumbsResolver } from '@online-board/resolvers/bread-crumbs/details-bread-crumbs.resolver';
import { OnlineBoardRequestDataResolver } from '@online-board/resolvers/request-data.resolver';
import { OnlineBoardBreadCrumbService } from '@online-board/services/bread-crumb.service';

describe('OnlineBoardDetailsBreadCrumbsResolver', () => {
    let service: OnlineBoardDetailsBreadCrumbsResolver;
    const getRootBreadCrumbMock = jasmine.createSpy('getRootBreadCrumb');
    const getFlightNumberSearchBreadCrumbMock = jasmine.createSpy(
        'getFlightNumberSearchBreadCrumb',
    );
    const getRouteSearchBreadCrumbMock = jasmine.createSpy(
        'getRouteSearchBreadCrumb',
    );
    const resolveMock = jasmine.createSpy('resolve');

    const rootBreadCrumb: IBreadCrumbItem = {
        url: 'onlineboard',
        label: 'root breadcrumb',
    };

    beforeEach(() => {
        TestBed.configureTestingModule({
            providers: [
                OnlineBoardDetailsBreadCrumbsResolver,
                {
                    provide: OnlineBoardBreadCrumbService,
                    useValue: {
                        getRootBreadCrumb: getRootBreadCrumbMock,
                        getFlightNumberSearchBreadCrumb:
                            getFlightNumberSearchBreadCrumbMock,
                        getRouteSearchBreadCrumb: getRouteSearchBreadCrumbMock,
                    },
                },
                {
                    provide: OnlineBoardRequestDataResolver,
                    useValue: {
                        resolve: resolveMock,
                    },
                },
            ],
        });

        service = TestBed.inject(OnlineBoardDetailsBreadCrumbsResolver);
        getRootBreadCrumbMock.calls.reset();
        getRootBreadCrumbMock.withArgs().and.returnValue(rootBreadCrumb);
        getFlightNumberSearchBreadCrumbMock.calls.reset();
        getRouteSearchBreadCrumbMock.calls.reset();
        resolveMock.calls.reset();
    });

    it('should return root bread crumb', async () => {
        resolveMock.withArgs({}).and.returnValue(undefined);

        const result = await service.resolve({} as any);
        expect(result).toEqual([rootBreadCrumb]);
    });

    it('should return array of two bread crumbs items for flight number request', async () => {
        const requestData = {
            parsed: {
                type: 'flight-number',
                params: {},
            },
        };
        const mockedBreadCrumbItem: IBreadCrumbItem = {
            url: 'flight-number-url',
            label: 'flight-number-label',
        };
        const expectedResult = [rootBreadCrumb, mockedBreadCrumbItem];

        resolveMock.withArgs({}).and.returnValue(requestData);
        getFlightNumberSearchBreadCrumbMock
            .withArgs({})
            .and.returnValue(mockedBreadCrumbItem);

        const result = await service.resolve({} as any);
        expect(result).toEqual(expectedResult);
    });

    it('should return array of two bread crumbs items for route request', async () => {
        const requestData = {
            parsed: {
                type: 'route',
                params: {},
            },
        };
        const mockedBreadCrumbItem: IBreadCrumbItem = {
            url: 'route-url',
            label: 'route-label',
        };
        const expectedResult = [rootBreadCrumb, mockedBreadCrumbItem];

        resolveMock.withArgs({}).and.returnValue(requestData);
        getRouteSearchBreadCrumbMock
            .withArgs({})
            .and.returnValue(mockedBreadCrumbItem);

        const result = await service.resolve({} as any);
        expect(result).toEqual(expectedResult);
    });
});
