import { async, ComponentFixture, TestBed, fakeAsync, tick } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { HttpModule } from '@angular/http';
import { DebugElement } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { ScanningDetailResult, VulnerabilitySeverity, RequestQueryParams } from '../service/index';

import { ResultGridComponent } from './result-grid.component';
import { ScanningResultService, ScanningResultDefaultService } from '../service/scanning.service';
import { SERVICE_CONFIG, IServiceConfig } from '../service.config';
import { ErrorHandler } from '../error-handler/index';
import { SharedModule } from '../shared/shared.module';

describe('ResultGridComponent (inline template)', () => {
  let component: ResultGridComponent;
  let fixture: ComponentFixture<ResultGridComponent>;
  let serviceConfig: IServiceConfig;
  let scanningService: ScanningResultService;
  let spy: jasmine.Spy;
  let testConfig: IServiceConfig = {
    vulnerabilityScanningBaseEndpoint: "/api/vulnerability/testing"
  };

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [
        SharedModule
      ],
      declarations: [ResultGridComponent],
      providers: [
        ErrorHandler,
        { provide: SERVICE_CONFIG, useValue: testConfig },
        { provide: ScanningResultService, useClass: ScanningResultDefaultService }
      ]
    });

  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(ResultGridComponent);
    component = fixture.componentInstance;
    component.tagId = "mockTag";

    serviceConfig = TestBed.get(SERVICE_CONFIG);
    scanningService = fixture.debugElement.injector.get(ScanningResultService);
    let mockData: ScanningDetailResult[] = [];
    for (let i = 0; i < 30; i++) {
      let res: ScanningDetailResult = {
        id: "CVE-2016-" + (8859 + i),
        severity: i % 2 === 0 ? VulnerabilitySeverity.HIGH : VulnerabilitySeverity.MEDIUM,
        package: "package_" + i,
        layer: "layer_" + i,
        version: '4.' + i + ".0",
        fixedVersion: '4.' + i + '.11',
        description: "Mock data"
      };
      mockData.push(res);
    }

    spy = spyOn(scanningService, 'getScanningResults')
      .and.returnValue(Promise.resolve(mockData));

    fixture.detectChanges();
  });

  it('should be created', () => {
    expect(component).toBeTruthy();
  });

  it('should inject the SERVICE_CONFIG', () => {
    expect(serviceConfig).toBeTruthy();
    expect(serviceConfig.vulnerabilityScanningBaseEndpoint).toEqual("/api/vulnerability/testing");
  });

  it('should inject and call the ScanningResultService', () => {
    expect(scanningService).toBeTruthy();
    expect(spy.calls.any()).toBe(true, 'getScanningResults called');
  });

  it('should get data from ScanningResultService', async(() => {
    fixture.detectChanges();

    fixture.whenStable().then(() => { // wait for async getRecentLogs
      fixture.detectChanges();
      expect(component.scanningResults).toBeTruthy();
      expect(component.scanningResults.length).toEqual(30);
    });
  }));

  it('should render data to view', async(() => {
    fixture.detectChanges();
    fixture.whenStable().then(() => {
      fixture.detectChanges();

      let de: DebugElement = fixture.debugElement.query(del => del.classes['datagrid-cell']);
      expect(de).toBeTruthy();
      let el: HTMLElement = de.nativeElement;
      expect(el).toBeTruthy();
      expect(el.textContent.trim()).toEqual('CVE-2016-8859');
    });
  }));

});
