import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { VulnerabilityItem } from '../service/index';
import { NoopAnimationsModule } from "@angular/platform-browser/animations";
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';
import { FilterComponent } from '../filter/index';
import {ChannelService} from "../channel/channel.service";
import { UserPermissionService, UserPermissionDefaultService } from "../service/permission.service";
import { USERSTATICPERMISSION } from "../service/permission-static";
import { of } from "rxjs";
import { DEFAULT_SUPPORTED_MIME_TYPE, VULNERABILITY_SEVERITY } from "../utils";
describe('ResultGridComponent (inline template)', () => {
  let component: ResultGridComponent;
  let fixture: ComponentFixture<ResultGridComponent>;
  let serviceConfig: IServiceConfig;
  let scanningService: ScanningResultService;
  let userPermissionService: UserPermissionService;
  let spy: jasmine.Spy;
  let mockHasScanImagePermission: boolean = true;
  let testConfig: IServiceConfig = {
    vulnerabilityScanningBaseEndpoint: "/api/vulnerability/testing"
  };

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

  }));

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

    serviceConfig = TestBed.get(SERVICE_CONFIG);
    scanningService = fixture.debugElement.injector.get(ScanningResultService);
    let mockData: any = {};
    mockData[DEFAULT_SUPPORTED_MIME_TYPE] = {};
    mockData[DEFAULT_SUPPORTED_MIME_TYPE].vulnerabilities = [];
    for (let i = 0; i < 30; i++) {
      let res: VulnerabilityItem = {
        id: "CVE-2016-" + (8859 + i),
        severity: i % 2 === 0 ? VULNERABILITY_SEVERITY.HIGH : VULNERABILITY_SEVERITY.MEDIUM,
        package: "package_" + i,
        links: ["https://security-tracker.debian.org/tracker/CVE-2016-4484"],
        layer: "layer_" + i,
        version: '4.' + i + ".0",
        fix_version: '4.' + i + '.11',
        description: "Mock data"
      };
      mockData[DEFAULT_SUPPORTED_MIME_TYPE].vulnerabilities.push(res);
    }

    spy = spyOn(scanningService, 'getVulnerabilityScanningResults')
      .and.returnValue(of(mockData));


      userPermissionService = fixture.debugElement.injector.get(UserPermissionService);


    spyOn(userPermissionService, "getPermission")
    .withArgs(component.projectId, USERSTATICPERMISSION.REPOSITORY_TAG_SCAN_JOB.KEY,
      USERSTATICPERMISSION.REPOSITORY_TAG_SCAN_JOB.VALUE.CREATE )
    .and.returnValue(of(mockHasScanImagePermission));

    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 el: HTMLElement = fixture.nativeElement.querySelector('.datagrid-cell a');
      expect(el).toBeTruthy();
      expect(el.textContent.trim()).toEqual('CVE-2016-8859');
    });
  }));

});
