import { TestBed } from '@angular/core/testing';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { AccessControlAuthorizationService, AUTH_OPTIONS, AuthenticationService, IAuthModuleConfig } from '../../';
import { Provider } from '@angular/core';
import { of } from 'rxjs';

const resourceSetRequestUrl = 'http://test/api/v1/ResourceSets/test';

describe('AccessControlAuthorizationService - with deprecated accessControlEndpoint parameter', () => {
  let service: AccessControlAuthorizationService;
  let httpTestingController: HttpTestingController;
  beforeEach(() => {
    const authenticationServiceStub = {
      getRoles: () => of('test1', 'test2'),
      isAuthenticated: () => of(true),
    };

    TestBed.configureTestingModule({
      providers: <Provider[]>[
        {
          provide: AUTH_OPTIONS,
          useValue: <IAuthModuleConfig>{
            accessControlEndpoint: 'http://test',
            resourceSetName: 'test',
          },
        },
        {
          provide: AuthenticationService,
          useValue: authenticationServiceStub,
        },
        {
          provide: AccessControlAuthorizationService,
          useClass: AccessControlAuthorizationService,
        },
      ],
      imports: [HttpClientTestingModule],
    });
    service = TestBed.inject(AccessControlAuthorizationService);
    httpTestingController = TestBed.inject(HttpTestingController);
  });

  it('should load resource set', () => {
    expect(service).toBeTruthy();
    const request = httpTestingController.expectOne(resourceSetRequestUrl);
    expect(request.request.method).toBe('GET');
    request.flush({});
    httpTestingController.verify();
  });
});

describe('AccessControlAuthorizationService', () => {
  let service: AccessControlAuthorizationService;
  let httpTestingController: HttpTestingController;
  beforeEach(() => {
    const authenticationServiceStub = {
      getRoles: () => of('test1', 'test2'),
      isAuthenticated: () => of(true),
    };

    TestBed.configureTestingModule({
      providers: <Provider[]>[
        {
          provide: AUTH_OPTIONS,
          useValue: <IAuthModuleConfig>{
            authServerBaseUrl: 'http://test',
            resourceSetName: 'test',
          },
        },
        {
          provide: AuthenticationService,
          useValue: authenticationServiceStub,
        },
        {
          provide: AccessControlAuthorizationService,
          useClass: AccessControlAuthorizationService,
        },
      ],
      imports: [HttpClientTestingModule],
    });
    service = TestBed.inject(AccessControlAuthorizationService);
    httpTestingController = TestBed.inject(HttpTestingController);
  });

  it('should load resource set', () => {
    expect(service).toBeTruthy();
    const request = httpTestingController.expectOne(resourceSetRequestUrl);
    expect(request.request.method).toBe('GET');
    request.flush({});
    httpTestingController.verify();
  });
});

describe('AccessControlAuthorizationService with observable resource set - with deprecated accessControlEndpoint parameter', () => {
  let service: AccessControlAuthorizationService;
  let httpTestingController: HttpTestingController;
  beforeEach(() => {
    const authenticationServiceStub = {
      getRoles: () => of('test1', 'test2'),
      isAuthenticated: () => of(true),
    };

    TestBed.configureTestingModule({
      providers: <Provider[]>[
        {
          provide: AUTH_OPTIONS,
          useValue: <IAuthModuleConfig>{
            accessControlEndpoint: 'http://test',
            resourceSetName: of('test'),
          },
        },
        {
          provide: AuthenticationService,
          useValue: authenticationServiceStub,
        },
        {
          provide: AccessControlAuthorizationService,
          useClass: AccessControlAuthorizationService,
        },
      ],
      imports: [HttpClientTestingModule],
    });
    service = TestBed.inject(AccessControlAuthorizationService);
    httpTestingController = TestBed.inject(HttpTestingController);
  });

  it('should load resource set', () => {
    expect(service).toBeTruthy();
    const request = httpTestingController.expectOne(resourceSetRequestUrl);
    expect(request.request.method).toBe('GET');
    request.flush({});
    httpTestingController.verify();
  });
});

describe('AccessControlAuthorizationService with observable resource set', () => {
  let service: AccessControlAuthorizationService;
  let httpTestingController: HttpTestingController;
  beforeEach(() => {
    const authenticationServiceStub = {
      getRoles: () => of('test1', 'test2'),
      isAuthenticated: () => of(true),
    };

    TestBed.configureTestingModule({
      providers: <Provider[]>[
        {
          provide: AUTH_OPTIONS,
          useValue: <IAuthModuleConfig>{
            authServerBaseUrl: 'http://test',
            resourceSetName: of('test'),
          },
        },
        {
          provide: AuthenticationService,
          useValue: authenticationServiceStub,
        },
        {
          provide: AccessControlAuthorizationService,
          useClass: AccessControlAuthorizationService,
        },
      ],
      imports: [HttpClientTestingModule],
    });
    service = TestBed.inject(AccessControlAuthorizationService);
    httpTestingController = TestBed.inject(HttpTestingController);
  });

  it('should load resource set', () => {
    expect(service).toBeTruthy();
    const request = httpTestingController.expectOne(resourceSetRequestUrl);
    expect(request.request.method).toBe('GET');
    request.flush({});
    httpTestingController.verify();
  });
});
