This repository has been archived on 2020-03-24. You can view files and clone it, but cannot push or open issues or pull requests.
quay/static/js/directives/ui/manage-trigger/manage-trigger.component.spec.ts
2019-11-12 11:09:47 -05:00

286 lines
12 KiB
TypeScript

import { ManageTriggerComponent } from './manage-trigger.component';
import { Local, Trigger, Repository } from '../../../types/common.types';
import { ViewArray } from '../../../services/view-array/view-array';
import { ContextChangeEvent } from '../context-path-select/context-path-select.component';
import { PathChangeEvent } from '../dockerfile-path-select/dockerfile-path-select.component';
import { Mock } from 'ts-mocks';
import Spy = jasmine.Spy;
describe("ManageTriggerComponent", () => {
var component: ManageTriggerComponent;
var apiServiceMock: Mock<any>;
var tableServiceMock: Mock<any>;
var triggerServiceMock: Mock<any>;
var rolesServiceMock: Mock<any>;
var keyServiceMock: Mock<any>;
var repository: any;
var $scopeMock: Mock<ng.IScope>;
beforeEach(() => {
apiServiceMock = new Mock<any>();
tableServiceMock = new Mock<any>();
triggerServiceMock = new Mock<any>();
rolesServiceMock = new Mock<any>();
keyServiceMock = new Mock<any>();
$scopeMock = new Mock<ng.IScope>();
component = new ManageTriggerComponent(apiServiceMock.Object,
tableServiceMock.Object,
triggerServiceMock.Object,
rolesServiceMock.Object,
keyServiceMock.Object,
$scopeMock.Object);
component.repository = {namespace: "someuser", name: "somerepo"};
component.trigger = {id: "2cac6317-754e-47d4-88d3-2a50b3f09ee3", service: "github"};
});
describe("ngOnChanges", () => {
beforeEach(() => {
apiServiceMock.setup(mock => mock.listTriggerBuildSourceNamespaces).is(() => Promise.resolve({}));
apiServiceMock.setup(mock => mock.errorDisplay).is((message) => null);
$scopeMock.setup(mock => mock.$watch).is((val, callback) => null);
});
it("sets default values for config and selected namespace", () => {
component.ngOnChanges({});
expect(component.config).toEqual({});
expect(component.local.selectedNamespace).toBe(null);
});
});
describe("checkBuildSource", () => {
it("sets selected repository full name if given build source matches regex pattern", () => {
const buildSource: string = "git@somegithost.net:user/repo.git";
component.checkBuildSource(buildSource);
expect(component.local.selectedRepository.full_name).toEqual(buildSource);
});
it("sets selected repository full name to null if given build source does not match regex pattern", () => {
const buildSource: string = "a_randomstring";
component.checkBuildSource(buildSource);
expect(component.local.selectedRepository.full_name).toBe(null);
});
});
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("checkDockerfilePath", () => {
var event: PathChangeEvent;
beforeEach(() => {
event = {path: '/Dockerfile', isValid: true};
component.local.selectedRepository = {name: "", full_name: "someorg/somerepo"};
component.local.dockerContext = '/';
component.local.dockerfileLocations = {contextMap: {}};
spyOn(component, "analyzeDockerfilePath").and.returnValue(null);
});
it("sets local Dockerfile path and validity to given event values", () => {
component.checkDockerfilePath(event);
expect(component.local.hasValidDockerfilePath).toEqual(event.isValid);
expect(component.local.dockerfilePath).toEqual(event.path);
});
it("sets local Dockerfile contexts if present in local Dockerfile locations", () => {
component.local.dockerfileLocations.contextMap[event.path] = ['/', '/dir'];
component.checkDockerfilePath(event);
expect(component.local.contexts).toEqual(component.local.dockerfileLocations.contextMap[event.path]);
});
it("sets local Dockerfile contexts to empty array if given path not present in local Dockerfile locations", () => {
component.checkDockerfilePath(event);
expect(component.local.contexts).toEqual([]);
});
it("calls component method to analyze new Dockerfile path", () => {
component.checkDockerfilePath(event);
expect((<Spy>component.analyzeDockerfilePath).calls.argsFor(0)[0]).toEqual(component.local.selectedRepository);
expect((<Spy>component.analyzeDockerfilePath).calls.argsFor(0)[1]).toEqual(event.path);
expect((<Spy>component.analyzeDockerfilePath).calls.argsFor(0)[2]).toEqual(component.local.dockerContext);
});
});
describe("checkBuildContext", () => {
var event: ContextChangeEvent;
beforeEach(() => {
event = {contextDir: '/', isValid: true};
});
});
describe("analyzeDockerfilePath", () => {
var selectedRepository: Repository;
var path: string;
var context: string;
var robots: {robots: {[key: string]: any}[]};
var analysis: {[key: string]: any};
var orderedRobots: Mock<ViewArray>;
beforeEach(() => {
selectedRepository = {name: "", full_name: "someorg/somerepo"};
path = "/Dockerfile";
context = "/";
robots = {robots: [{name: 'robot'}]};
analysis = {'publicbase': true, robots: robots.robots};
orderedRobots = new Mock<ViewArray>();
apiServiceMock.setup(mock => mock.analyzeBuildTrigger).is((data, params) => Promise.resolve(analysis));
apiServiceMock.setup(mock => mock.getRobots).is((user, arg, params) => Promise.resolve(robots));
apiServiceMock.setup(mock => mock.errorDisplay).is((message) => null);
tableServiceMock.setup(mock => mock.buildOrderedItems).is((items, options, filterFields, numericFields) => orderedRobots.Object);
});
it("does nothing if given invalid Git repository", (done) => {
const invalidRepositories: Repository[] = [null];
invalidRepositories.forEach((repo, index) => {
component.analyzeDockerfilePath(repo, path, context);
expect((<Spy>apiServiceMock.Object.analyzeBuildTrigger)).not.toHaveBeenCalled();
if (index == invalidRepositories.length - 1) {
done();
}
});
});
it("uses default values for Dockerfile path and context if not given", (done) => {
const spy: Spy = <Spy>apiServiceMock.Object.analyzeBuildTrigger;
component.analyzeDockerfilePath(selectedRepository);
setTimeout(() => {
expect(spy.calls.argsFor(0)[0]['config']['build_source']).toEqual(selectedRepository.full_name);
expect(spy.calls.argsFor(0)[0]['config']['dockerfile_path']).toEqual('Dockerfile');
expect(spy.calls.argsFor(0)[0]['config']['context']).toEqual('/');
expect(spy.calls.argsFor(0)[1]['repository']).toEqual(`${component.repository.namespace}/${component.repository.name}`);
expect(spy.calls.argsFor(0)[1]['trigger_uuid']).toEqual(component.trigger.id);
done();
}, 10);
});
it("calls API service to analyze build trigger config with given values", (done) => {
const spy: Spy = <Spy>apiServiceMock.Object.analyzeBuildTrigger;
component.analyzeDockerfilePath(selectedRepository, path, context);
setTimeout(() => {
expect(spy.calls.argsFor(0)[0]['config']['build_source']).toEqual(selectedRepository.full_name);
expect(spy.calls.argsFor(0)[0]['config']['dockerfile_path']).toEqual(path.substr(1));
expect(spy.calls.argsFor(0)[0]['config']['context']).toEqual(context);
expect(spy.calls.argsFor(0)[1]['repository']).toEqual(`${component.repository.namespace}/${component.repository.name}`);
expect(spy.calls.argsFor(0)[1]['trigger_uuid']).toEqual(component.trigger.id);
done();
}, 10);
});
it("calls API service to display error if API service's trigger analysis fails", (done) => {
apiServiceMock.setup(mock => mock.analyzeBuildTrigger).is((data, params) => Promise.reject("Error"));
component.analyzeDockerfilePath(selectedRepository, path, context);
setTimeout(() => {
expect((<Spy>apiServiceMock.Object.errorDisplay).calls.argsFor(0)[0]).toEqual('Could not analyze trigger');
done();
}, 10);
});
it("updates component trigger analysis with successful trigger analysis response", (done) => {
component.analyzeDockerfilePath(selectedRepository, path, context);
setTimeout(() => {
expect(component.local.triggerAnalysis).toEqual(analysis);
done();
}, 10);
});
});
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("does not call roles service if robot is required but robot is not selected", (done) => {
component.local.triggerAnalysis = {status: 'requiresrobot', name: 'privatebase', namespace: 'someorg'};
component.local.robotAccount = null;
component.activateTrigger.subscribe((event: {config: any, pull_robot: any}) => {
expect((<Spy>rolesServiceMock.Object.setRepositoryRole)).not.toHaveBeenCalled();
done();
});
component.createTrigger();
});
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.triggerAnalysis = {status: 'requiresrobot', name: 'privatebase', namespace: 'someorg'};
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.local.triggerAnalysis = {status: 'publicbase', name: 'publicrepo', namespace: 'someorg'};
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();
});
});
});