import { ManageTriggerGithostComponent } from './manage-trigger-githost.component';
import { Local, Trigger, Repository } from '../../../types/common.types';
import { Mock } from 'ts-mocks';
import Spy = jasmine.Spy;


describe("ManageTriggerGithostComponent", () => {
  var component: ManageTriggerGithostComponent;
  var apiServiceMock: Mock<any>;
  var tableServiceMock: Mock<any>;
  var triggerServiceMock: Mock<any>;
  var rolesServiceMock: Mock<any>;
  var repository: any;
  var trigger: Trigger;
  var $scopeMock: Mock<ng.IScope>;

  beforeEach(inject(($injector: ng.auto.IInjectorService) => {
    apiServiceMock = new Mock<any>();
    tableServiceMock = new Mock<any>();
    triggerServiceMock = new Mock<any>();
    rolesServiceMock = new Mock<any>();
    $scopeMock = new Mock<ng.IScope>();
    component = new ManageTriggerGithostComponent(apiServiceMock.Object,
                                                  tableServiceMock.Object,
                                                  triggerServiceMock.Object,
                                                  rolesServiceMock.Object,
                                                  $scopeMock.Object);
    trigger = {service: "serviceMock", id: 1};
    component.trigger = trigger;
  }));

  describe("constructor", () => {
    // TODO
  });

  describe("$onInit", () => {
    // TODO
  });

  describe("getTriggerIcon", () => {

    beforeEach(() => {
      triggerServiceMock.setup(mock => mock.getIcon).is((service: any) => null);
    });

    it("calls trigger service to get icon", () => {
      const icon: any = component.getTriggerIcon();

      expect((<Spy>triggerServiceMock.Object.getIcon).calls.argsFor(0)[0]).toEqual(component.trigger.service);
    });
  });

  describe("createTrigger", () => {

    beforeEach(() => {
      component.local.selectedRepository = new Mock<Repository>().Object;
      component.local.selectedRepository.full_name = "someorg/some-repository";
      component.local.dockerfilePath = "/Dockerfile";
      component.local.dockerContext = "/";
      component.local.triggerOptions = {};
      component.local.triggerAnalysis = {};
      rolesServiceMock.setup(mock => mock.setRepositoryRole).is((repo, role, entityKind, entityName, callback) => {
        callback();
      });
    });

    it("calls roles service to grant read access to selected robot if robot is required and cannot read", (done) => {
      component.local.triggerAnalysis = {status: 'requiresrobot', name: 'privatebase', namespace: 'someorg'};
      component.local.robotAccount = {can_read: false, is_robot: true, kind: 'user', name: 'test-robot'};
      component.activateTrigger.subscribe((event: {config: any, pull_robot: any}) => {
        expect((<Spy>rolesServiceMock.Object.setRepositoryRole).calls.argsFor(0)[0]).toEqual({
          name: component.local.triggerAnalysis.name,
          namespace: component.local.triggerAnalysis.namespace,
        });
        expect((<Spy>rolesServiceMock.Object.setRepositoryRole).calls.argsFor(0)[1]).toEqual('read');
        expect((<Spy>rolesServiceMock.Object.setRepositoryRole).calls.argsFor(0)[2]).toEqual('robot');
        done();
      });

      component.createTrigger();
    });

    it("does not call roles service if robot is required but already has read access", (done) => {
      component.local.robotAccount = {can_read: true, is_robot: true, kind: 'user', name: 'test-robot'};
      component.activateTrigger.subscribe((event: {config: any, pull_robot: any}) => {
        expect((<Spy>rolesServiceMock.Object.setRepositoryRole)).not.toHaveBeenCalled();
        done();
      });

      component.createTrigger();
    });

    it("does not call roles service if robot is not required", (done) => {
      component.activateTrigger.subscribe((event: {config: any, pull_robot: any}) => {
        expect((<Spy>rolesServiceMock.Object.setRepositoryRole)).not.toHaveBeenCalled();
        done();
      });

      component.createTrigger();
    });

    it("emits output event with config and pull robot", (done) => {
      component.activateTrigger.subscribe((event: {config: any, pull_robot: any}) => {
        expect(event.config.build_source).toEqual(component.local.selectedRepository.full_name);
        expect(event.config.dockerfile_path).toEqual(component.local.dockerfilePath);
        expect(event.config.context).toEqual(component.local.dockerContext);
        done();
      });

      component.createTrigger();
    });
  });
});