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 { ScanningResultSummary, VulnerabilitySeverity, ScanningBaseResult } from '../service/index';

import { ResultBarChartComponent, ScanState } from './result-bar-chart.component';
import { ResultTipComponent } from './result-tip.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('ResultBarChartComponent (inline template)', () => {
  let component: ResultBarChartComponent;
  let fixture: ComponentFixture<ResultBarChartComponent>;
  let serviceConfig: IServiceConfig;
  let scanningService: ScanningResultService;
  let spy: jasmine.Spy;
  let testConfig: IServiceConfig = {
    vulnerabilityScanningBaseEndpoint: "/api/vulnerability/testing"
  };

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

  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(ResultBarChartComponent);
    component = fixture.componentInstance;
    component.tagId = "mockTag";
    component.state = ScanState.COMPLETED;

    serviceConfig = TestBed.get(SERVICE_CONFIG);
    scanningService = fixture.debugElement.injector.get(ScanningResultService);
    let mockData: ScanningResultSummary = {
      totalComponents: 21,
      noneComponents: 7,
      completeTimestamp: new Date(),
      high: [],
      medium: [],
      low: [],
      unknown: []
    };

    for (let i = 0; i < 14; i++) {
      let res: ScanningBaseResult = {
        id: "CVE-2016-" + (8859 + i),
        package: "package_" + i,
        version: '4.' + i + ".0",
        severity: VulnerabilitySeverity.UNKNOWN
      };

      switch (i % 4) {
        case 0:
          res.severity = VulnerabilitySeverity.HIGH;
          mockData.high.push(res);
          break;
        case 1:
          res.severity = VulnerabilitySeverity.MEDIUM;
          mockData.medium.push(res);
          break;
        case 2:
          res.severity = VulnerabilitySeverity.LOW;
          mockData.low.push(res);
          break;
        case 3:
          res.severity = VulnerabilitySeverity.UNKNOWN;
          mockData.unknown.push(res);
          break;
        default:
          break;
      }
    }

    spy = spyOn(scanningService, 'getScanningResultSummary')
      .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, 'getScanningResultSummary called');
  });

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

    fixture.whenStable().then(() => { // wait for async getRecentLogs
      fixture.detectChanges();
      expect(component.summary).toBeTruthy();
      expect(component.summary.totalComponents).toEqual(21);
      expect(component.summary.high.length).toEqual(4);
      expect(component.summary.medium.length).toEqual(4);
      expect(component.summary.low.length).toEqual(3);
      expect(component.summary.noneComponents).toEqual(7);
    });
  }));

});
