import { HttpHandler, HttpParams } from '@angular/common/http';
import { TestBed } from '@angular/core/testing';
import { ApiService } from '@shared/services/api/api.service';
import { CacheService } from '@shared/services/cache.service';

describe('ApiService', () => {
    let service: ApiService;
    const getCacheMock = jasmine.createSpy('getCache');
    const setCacheMock = jasmine.createSpy('setCache');
    const httpGetMock = jasmine.createSpy('httpGet');

    beforeEach(() => {
        TestBed.configureTestingModule({
            providers: [
                ApiService,
                {
                    provide: HttpHandler,
                    useValue: {},
                },
                {
                    provide: CacheService,
                    useValue: {
                        get: getCacheMock,
                        set: setCacheMock,
                    },
                },
            ],
        });

        getCacheMock.calls.reset();
        setCacheMock.calls.reset();
        httpGetMock.calls.reset();

        service = TestBed.inject(ApiService);
        (service.get as any) = httpGetMock;
    });

    it('should cache result', async () => {
        const expectedResult = 'expected-result';
        const url = 'schedule';
        const params = new HttpParams({
            fromObject: {
                request: 'request',
            },
        });
        const options = params.toString();

        getCacheMock.withArgs(url, options).and.returnValue(undefined);
        httpGetMock.withArgs(url, { params }).and.returnValue({
            toPromise: () => Promise.resolve(expectedResult),
        });

        const result = await service.cacheFirst(url, params);
        expect(result).toBe(expectedResult);
        expect(setCacheMock).toHaveBeenCalledWith(url, options, expectedResult);
    });

    it('should return cached value', async () => {
        const expectedResult = 'expected-result';
        const url = 'onlineboard';
        const params = new HttpParams({
            fromObject: {
                request: 'board-request',
            },
        });
        const options = params.toString();

        getCacheMock.withArgs(url, options).and.returnValue(expectedResult);

        const result = await service.cacheFirst(url, params);
        expect(result).toBe(expectedResult);
        expect(httpGetMock).not.toHaveBeenCalled();
        expect(setCacheMock).not.toHaveBeenCalled();
    });
});
