beforeEach(() => {
   mock.module(HELP_FIELD_COMPONENT, ($provide: IProvideService) => {
     $provide.constant('helpContents', { 'aws.serverGroup.stack': 'expected stack help' });
   });
 });
describe("PageEditorService", () => {
    let service: PageEditorService, dataService: DataService;

    beforeEach(() => {
        angular.mock.module(PAGE_EDITOR_MODULE);
        angular.mock.module(DATA_MODULE);
    });

    beforeEach(angular.mock.inject($injector => {
        service = $injector.get("PageEditorService");
        dataService = $injector.get("DataService");

        spyOn(dataService, "getData");
    }));

    it("should get data when getPages is called for editor page", () => {
        service.getPages();

        expect(dataService.getData).toHaveBeenCalledWith({
            webservice: "api/pages?includeHtml=N",
            type: "GET"
        });
    });

    it("should get updatable pages when getUpdatablePages is called", () => {
        service.getUpdatablePages();

        expect(dataService.getData).toHaveBeenCalledWith({
            webservice: "api/pages?isUpdatable=true",
            type: "GET"
        });
    });

    it("should post all updatable pages when postAllPagesFromRepo is called", () => {
        service.postAllPagesFromRepo();

        expect(dataService.getData).toHaveBeenCalledWith({
            webservice: "api/pages",
            type: "POST"
        });
    });

    it("should post single page when postPageFromRepo is called", () => {
        service.postPageFromRepo("12steps");

        expect(dataService.getData).toHaveBeenCalledWith({
            webservice: "api/pages/12steps",
            type: "POST"
        });
    });

    it("should get data when getMeetings is called for editor page", () => {
        service.getPage("12steps", 2);

        expect(dataService.getData).toHaveBeenCalledWith({
            webservice: "api/pages?pageName=12steps&revision=2",
            type: "GET"
        });
    });

    it("should post single page when postPage is called", () => {
        service.postPage("read-andallo", 3, {
            PageTitle: "...And All Other Mind Altering Substances",
            PageContent: "<div>new content</div>",
            Status: "ACTIVE",
            ContentType: "R",
            ImageFilename: "PAMPHLETS_All_Other"
        });

        expect(dataService.getData).toHaveBeenCalledWith({
            webservice: "api/pages/read-andallo/3",
            type: "POST",
            payload: {
                PageTitle: "...And All Other Mind Altering Substances",
                PageContent: "<div>new content</div>",
                Status: "ACTIVE",
                ContentType: "R",
                ImageFilename: "PAMPHLETS_All_Other"
            }
        });
    });
});
describe('Controller: LoadBalancerDetailsCtrl', function() {
  let controller: AwsLoadBalancerDetailsController;
  let $scope;
  let $state;
  const loadBalancer = {
    name: 'foo',
    region: 'us-west-1',
    account: 'test',
    accountId: 'test',
    vpcId: '1',
  };

  beforeEach(mock.module(AWS_LOAD_BALANCER_DETAILS_CTRL));

  beforeEach(
    mock.inject(($controller: IControllerService, $rootScope: IRootScopeService, _$state_: StateService) => {
      $scope = $rootScope.$new();
      $state = _$state_;
      const app = ApplicationModelBuilder.createApplicationForTests('app', { key: 'loadBalancers', lazy: true });
      app.loadBalancers.data.push(loadBalancer);
      controller = $controller(AwsLoadBalancerDetailsController, {
        $scope,
        loadBalancer,
        app,
        $state,
      });
    }),
  );

  it('should have an instantiated controller', function() {
    expect(controller).toBeDefined();
  });

  describe('Get the first subnets purpose', function() {
    it('should return empty string if there are no subnets ', function() {
      const subnetDetails: ISubnet[] = [];
      const result = controller.getFirstSubnetPurpose(subnetDetails);
      expect(result).toEqual('');
    });

    it('should return empty string if no subnetDetail is submitted', function() {
      const result = controller.getFirstSubnetPurpose();
      expect(result).toEqual('');
    });

    it('should return empty string if undefined subnetDetail is submitted', function() {
      const result = controller.getFirstSubnetPurpose(undefined);
      expect(result).toEqual('');
    });

    it('should return the first purpose of subnetDetail if there is only one', function() {
      const subnetDetails = [{ purpose: 'internal(vpc0)' }] as ISubnet[];
      const result = controller.getFirstSubnetPurpose(subnetDetails);
      expect(result).toEqual('internal(vpc0)');
    });

    it('should return the first purpose of subnetDetail if there are multiple', function() {
      const subnetDetails = [{ purpose: 'internal(vpc0)' }, { purpose: 'internal(vpc1)' }] as ISubnet[];
      const result = controller.getFirstSubnetPurpose(subnetDetails);
      expect(result).toEqual('internal(vpc0)');
    });
  });
});
 beforeEach(() => {
   angular.mock.module('officeuifabric.core');
   angular.mock.module('officeuifabric.components.callout');
 });
 beforeEach(() => {
     angular.mock.module(PAGE_EDITOR_MODULE);
     angular.mock.module(DATA_MODULE);
 });
 beforeEach(() => angular.mock.module(CORE_MODULE));
  beforeEach(() => {
    angular.mock.inject(() => {
      dialogValidation = new DialogValidation();
    });

  });
 beforeEach(() => angular.mock.module(MEETINGS_MODULE));
describe("PageRouterCtrl", () => {
    let ctrl: PageRouterCtrl, pageRouterService: PageRouterService, caLondonAppConfig: ICALondonAppConfig;
    let $controller: IControllerService, $rootScope: IRootScopeService, $scope: IScope, $q: IQService,
        $templateCache: ITemplateCacheService, $timeout: ITimeoutService, $httpBackend: IHttpBackendService,
        $window: IWindowService, $routeParams;

    beforeEach(() => angular.mock.module(CORE_MODULE));

    beforeEach(angular.mock.inject($injector => {
        $controller = $injector.get("$controller");
        $rootScope = $injector.get("$rootScope");
        $window = $injector.get("$window");
        $q = $injector.get("$q");
        $routeParams = $injector.get("$routeParams");
        $templateCache = $injector.get("$templateCache");
        $timeout = $injector.get("$timeout");
        $httpBackend = $injector.get("$httpBackend");
        $scope = $rootScope.$new(true);

        caLondonAppConfig = $injector.get("caLondonAppConfig");
        pageRouterService = $injector.get("PageRouterService");

        caLondonAppConfig.API_URL = "https://myurl.com/";

        $routeParams.pageName = "testpage";

        $httpBackend.whenGET("https://myurl.com/api/pages?contentType")
            .respond([]);
    }));

    function initController(): void {
        ctrl = $controller("PageRouterCtrl", {
            $scope: $scope
        });
    }

    describe("initialising controller", () => {
        it("should exist", () => {
            initController();
            expect(ctrl).toBeDefined();
        });

        it("should initialise and load loading page when template cache is not ready", () => {
            pageRouterService.templateLoadingState = TemplateState.NotReady;
            spyOn(pageRouterService, "getPageTitle").and.returnValue("Test Page");
            spyOn($templateCache, "get").and.callFake(page => {
                if (page === "page/testpage.html") {
                    return "<div>some template</div>";
                } else if (page === "page/disclaimmain.html") {
                    return "<div>disclaimer</div>";
                }
            });

            initController();

            expect(ctrl.pageData).toEqual([
                {PageContent: `<div id="loader"></div>`, PageTitle: "CA London"}
            ]);
            expect(ctrl.pageName).toEqual("testpage");
            expect($window.document.title).toEqual("Cocaine Anonymous London");

            pageRouterService.templateLoadingState = TemplateState.Ready;
            $timeout.flush();

            expect(ctrl.pageData).toEqual([
                {PageContent: "<div>some template</div>"},
                {PageContent: "<div>disclaimer</div>"}
            ]);
            expect(ctrl.pageName).toEqual("testpage");
            expect($window.document.title).toEqual("Test Page | Cocaine Anonymous London");
        });

        it("should load page if cache is not populated", () => {
            pageRouterService.templateLoadingState = TemplateState.Ready;
            spyOn(pageRouterService, "getPageTitle").and.returnValue("Test Page");
            spyOn($templateCache, "get").and.callFake(page => {
                if (page === "page/testpage.html") {
                    return "<div>some template</div>";
                } else if (page === "page/disclaimmain.html") {
                    return "<div>disclaimer</div>";
                }
            });

            initController();

            expect(ctrl.pageData).toEqual([
                {PageContent: "<div>some template</div>"},
                {PageContent: "<div>disclaimer</div>"}
            ]);
            expect(ctrl.pageName).toEqual("testpage");
            expect($window.document.title).toEqual("Test Page | Cocaine Anonymous London");
        });

        it("should load error page if cache has errored", () => {
            pageRouterService.templateLoadingState = TemplateState.Errored;
            spyOn(pageRouterService, "getPageTitle").and.returnValue("Error");
            spyOn($templateCache, "get").and.callFake(page => {
                if (page === "page/error.html") {
                    return "<div>error template</div>";
                }
            });

            initController();

            expect(ctrl).toBeDefined();
            expect(ctrl.pageData).toEqual([
                {PageContent: "<div>error template</div>"}
            ]);
            expect($window.document.title).toEqual("Error | Cocaine Anonymous London");
        });
    });
});
describe("MeetingDistrictCtrl", () => {
    let ctrl: MeetingDistrictCtrl, meetingService: MeetingService;
    let $controller: IControllerService, $rootScope: IRootScopeService, $scope: IScope, $q: IQService;
    let fakeDistrictForm;

    beforeEach(() => angular.mock.module(MEETINGS_MODULE));

    beforeEach(angular.mock.inject($injector => {
        $controller = $injector.get("$controller");
        $rootScope = $injector.get("$rootScope");
        $q = $injector.get("$q");
        meetingService = $injector.get("MeetingService");

        $scope = $rootScope.$new(true);

        spyOn(meetingService, "getDistricts").and.callFake(() => {
            const deferred: IDeferred<Array<IDistrict>> = $q.defer();
            deferred.resolve(TestDistricts);
            return deferred.promise;
        });

        fakeDistrictForm = {$setPristine: () => {}};

        ctrl = $controller("MeetingDistrictCtrl", {
            $scope: $scope
        });
    }));

    it("should initialise", () => {
        expect(ctrl).toBeDefined();
        expect(ctrl.districts).toEqual([]);
        expect(ctrl.areaEditor).toEqual({
            areaStatus: ctrl.NOT_STARTED,
            editingArea: undefined,
            newAreaDescription: undefined
        });
        expect(ctrl.districtEditor.districtStatus).toEqual(ctrl.NOT_STARTED);
        expect(ctrl.districtEditor.newDistrictDescription).toBeUndefined();
        expect(ctrl.districtEditor.editingDistrict).toBeUndefined();
        expect(ctrl.isLoading).toEqual(true);

        $scope.$digest();

        expect(meetingService.getDistricts).toHaveBeenCalled();
        expect(ctrl.districts).toEqual(TestDistricts);
        expect(ctrl.areas).toEqual([
            {Area: "CENTRAL", AreaDescription: "Central"},
            {Area: "LONDON", AreaDescription: "London"},
            {Area: "UK", AreaDescription: "UK"}
        ]);
        expect(ctrl.isLoading).toEqual(false);
    });

    describe("#calculateId", () => {
        it("should calculate correct Id", () => {
            expect(ctrl.calculateId("Some area name")).toEqual("SOMEAREANA");
        });
    });

    describe("Area Form", () => {
        describe("#editArea", () => {
            it("should edit existing area", () => {
                ctrl.editArea({Area: "LONDON", AreaDescription: "London"});

                expect(ctrl.areaEditor).toEqual({
                    areaStatus: ctrl.STARTED,
                    editingArea: {Area: "LONDON", AreaDescription: "London"},
                    newAreaDescription: "London"
                });
            });

            it("should add new area", () => {
                ctrl.editArea();

                expect(ctrl.areaEditor).toEqual({
                    areaStatus: ctrl.STARTED,
                    editingArea: undefined,
                    newAreaDescription: undefined
                });
            });
        });

        describe("#cancelAddArea", () => {
            it("should cancel", () => {
                ctrl.areaEditor = {
                    areaStatus: ctrl.SUCCESS,
                    editingArea: {Area: "LONDON", AreaDescription: "London"},
                    newAreaDescription: "something"
                };

                ctrl.cancelAddArea();

                expect(ctrl.areaEditor).toEqual({
                    areaStatus: ctrl.NOT_STARTED,
                    editingArea: undefined,
                    newAreaDescription: undefined
                });
            });
        });

        describe("#saveNewArea", () => {
            beforeEach(() => {
                spyOn(ctrl, "loadDistricts");

                ctrl.areaEditor = {
                    areaStatus: ctrl.STARTED,
                    editingArea: undefined,
                    newAreaDescription: "A New Area"
                };
            });

            it("should submit new area and change status for success", () => {
                spyOn(meetingService, "postMeetingDistrict").and.callFake(() => {
                    const deferred: IDeferred<any> = $q.defer();
                    deferred.resolve();
                    return deferred.promise;
                });

                ctrl.saveNewArea();

                expect(meetingService.postMeetingDistrict).toHaveBeenCalledWith({
                    Area: "ANEWAREA",
                    District: "NONE",
                    AreaDescription: "A New Area",
                    DistrictDescription: "None",
                    Icon: "red_MarkerA"
                });
                expect(ctrl.loadDistricts).not.toHaveBeenCalled();

                $scope.$digest();

                expect(ctrl.areaEditor.areaStatus).toEqual(ctrl.SUCCESS);
                expect(ctrl.loadDistricts).toHaveBeenCalled();
            });

            it("should submit new area and change status for failure", () => {
                spyOn(meetingService, "postMeetingDistrict").and.callFake(() => {
                    const deferred: IDeferred<any> = $q.defer();
                    deferred.reject();
                    return deferred.promise;
                });

                ctrl.saveNewArea();

                expect(meetingService.postMeetingDistrict).toHaveBeenCalledWith({
                    Area: "ANEWAREA",
                    District: "NONE",
                    AreaDescription: "A New Area",
                    DistrictDescription: "None",
                    Icon: "red_MarkerA"
                });
                expect(ctrl.loadDistricts).not.toHaveBeenCalled();

                $scope.$digest();

                expect(ctrl.areaEditor.areaStatus).toEqual(ctrl.FAILURE);
                expect(ctrl.loadDistricts).not.toHaveBeenCalled();
            });
        });

        describe("#updateArea", () => {
            beforeEach(() => {
                spyOn(ctrl, "loadDistricts");

                ctrl.areaEditor = {
                    areaStatus: ctrl.STARTED,
                    editingArea: {
                        Area: "LONDON",
                        AreaDescription: "A New Area"
                    },
                    newAreaDescription: "New Description"
                };
            });

            it("should update existing area and change status for success", () => {
                spyOn(meetingService, "putMeetingDistrict").and.callFake(() => {
                    const deferred: IDeferred<any> = $q.defer();
                    deferred.resolve();
                    return deferred.promise;
                });

                ctrl.updateArea({
                    Area: "LONDON",
                    AreaDescription: "A New Area"
                });

                expect(meetingService.putMeetingDistrict).toHaveBeenCalledWith({
                    Area: "LONDON",
                    AreaDescription: "New Description"
                });
                expect(ctrl.loadDistricts).not.toHaveBeenCalled();

                $scope.$digest();

                expect(ctrl.areaEditor.areaStatus).toEqual(ctrl.SUCCESS);
                expect(ctrl.loadDistricts).toHaveBeenCalled();
            });

            it("should update existing area and change status for failure", () => {
                spyOn(meetingService, "putMeetingDistrict").and.callFake(() => {
                    const deferred: IDeferred<any> = $q.defer();
                    deferred.reject();
                    return deferred.promise;
                });

                ctrl.updateArea({
                    Area: "LONDON",
                    AreaDescription: "A New Area"
                });

                expect(meetingService.putMeetingDistrict).toHaveBeenCalledWith({
                    Area: "LONDON",
                    AreaDescription: "New Description"
                });
                expect(ctrl.loadDistricts).not.toHaveBeenCalled();

                $scope.$digest();

                expect(ctrl.areaEditor.areaStatus).toEqual(ctrl.FAILURE);
                expect(ctrl.loadDistricts).not.toHaveBeenCalled();
            });
        });
    });


    describe("District Form", () => {
        const district: IDistrict = {
            Area: "CENTRAL",
            District: "HERTS",
            Icon: "red_MarkerY",
            MeetingDistrictsID: 1,
            AreaDescription: "Central",
            DistrictDescription: "Hertfordshire",
            Count: 1
        };

        describe("#editDistrict", () => {
            it("should edit existing district", () => {
                ctrl.editDistrict(district);

                expect(ctrl.districtEditor).toEqual({
                    districtStatus: ctrl.STARTED,
                    editingDistrict: district,
                    newIconColour: "red",
                    newIconLetter: "Y",
                    newDistrictAreaDescription: {Area: "CENTRAL", AreaDescription: "Central"},
                    newDistrictDescription: "Hertfordshire"
                });
            });

            it("should add new district", () => {
                ctrl.editDistrict();

                expect(ctrl.districtEditor).toEqual({
                    districtStatus: ctrl.STARTED,
                    editingDistrict: undefined,
                    newIconColour: undefined,
                    newIconLetter: undefined,
                    newDistrictAreaDescription: undefined,
                    newDistrictDescription: undefined
                });
            });
        });

        describe("#cancelAddDistrict", () => {
            it("should cancel", () => {
                ctrl.districtForm = fakeDistrictForm;
                spyOn(fakeDistrictForm, "$setPristine");

                const editingDistrict: IDistrict = {
                    Area: "CENTRAL", District: "HERTS", Icon: "red_MarkerY", MeetingDistrictsID: 1,
                    AreaDescription: "Central", DistrictDescription: "Hertfordshire", Count: 1
                };

                ctrl.districtEditor = {
                    districtStatus: ctrl.SUCCESS,
                    newDistrictDescription: "something",
                    editingDistrict: editingDistrict,
                    newIconLetter: "Y",
                    newIconColour: "red",
                    newDistrictAreaDescription: {Area: "CENTRAL", AreaDescription: "Central"}
                };

                ctrl.cancelAddDistrict();

                expect(ctrl.districtEditor).toEqual({
                    districtStatus: ctrl.NOT_STARTED,
                    newDistrictDescription: undefined,
                    editingDistrict: undefined,
                    newIconLetter: undefined,
                    newIconColour: undefined,
                    newDistrictAreaDescription: undefined
                });

                expect(fakeDistrictForm.$setPristine).toHaveBeenCalled();
            });
        });

        describe("#saveNewDistrict", () => {
            beforeEach(() => {
                spyOn(ctrl, "loadDistricts");

                ctrl.districtEditor = {
                    districtStatus: ctrl.STARTED,
                    editingDistrict: undefined,
                    newIconColour: "purple",
                    newIconLetter: "R",
                    newDistrictAreaDescription: {Area: "CENTRAL", AreaDescription: "Central"},
                    newDistrictDescription: "New District"
                };
                ctrl.areas = [
                    {Area: "CENTRAL", AreaDescription: "Central"},
                    {Area: "LONDON", AreaDescription: "London"},
                    {Area: "UK", AreaDescription: "UK"}
                ];
            });

            it("should submit new district and change status for success", () => {
                spyOn(meetingService, "postMeetingDistrict").and.callFake(() => {
                    const deferred: IDeferred<any> = $q.defer();
                    deferred.resolve();
                    return deferred.promise;
                });

                ctrl.saveNewDistrict();

                expect(meetingService.postMeetingDistrict).toHaveBeenCalledWith({
                    Area: "CENTRAL",
                    District: "NEWDISTRIC",
                    AreaDescription: "Central",
                    DistrictDescription: "New District",
                    Icon: "purple_MarkerR"
                });
                expect(ctrl.loadDistricts).not.toHaveBeenCalled();

                $scope.$digest();

                expect(ctrl.districtEditor.districtStatus).toEqual(ctrl.SUCCESS);
                expect(ctrl.loadDistricts).toHaveBeenCalled();
            });

            it("should submit new district and change status for failure", () => {
                spyOn(meetingService, "postMeetingDistrict").and.callFake(() => {
                    const deferred: IDeferred<any> = $q.defer();
                    deferred.reject();
                    return deferred.promise;
                });

                ctrl.saveNewDistrict();

                expect(meetingService.postMeetingDistrict).toHaveBeenCalledWith({
                    Area: "CENTRAL",
                    District: "NEWDISTRIC",
                    AreaDescription: "Central",
                    DistrictDescription: "New District",
                    Icon: "purple_MarkerR"
                });
                expect(ctrl.loadDistricts).not.toHaveBeenCalled();

                $scope.$digest();

                expect(ctrl.districtEditor.districtStatus).toEqual(ctrl.FAILURE);
                expect(ctrl.loadDistricts).not.toHaveBeenCalled();
            });
        });

        describe("#updateDistrict", () => {
            beforeEach(() => {
                spyOn(ctrl, "loadDistricts");

                ctrl.districtEditor = {
                    districtStatus: ctrl.STARTED,
                    editingDistrict: district,
                    newDistrictAreaDescription: {Area: "CENTRAL", AreaDescription: "Central"},
                    newDistrictDescription: "New Description",
                    newIconColour: "pink",
                    newIconLetter: "Q"
                };
            });

            it("should update existing district and change status for success", () => {
                spyOn(meetingService, "putMeetingDistrict").and.callFake(() => {
                    const deferred: IDeferred<any> = $q.defer();
                    deferred.resolve();
                    return deferred.promise;
                });

                ctrl.updateDistrict({
                    Area: "CENTRAL",
                    AreaDescription: "Central",
                    MeetingDistrictsID: 1,
                    District: "HERTS",
                    Icon: "red_MarkerK",
                    DistrictDescription: "Hertfordshire",
                    Count: 1
                });

                expect(meetingService.putMeetingDistrict).toHaveBeenCalledWith({
                    Area: "CENTRAL",
                    AreaDescription: "Central",
                    District: "HERTS",
                    DistrictDescription: "New Description",
                    Icon: "pink_MarkerQ"
                });
                expect(ctrl.loadDistricts).not.toHaveBeenCalled();

                $scope.$digest();

                expect(ctrl.districtEditor.districtStatus).toEqual(ctrl.SUCCESS);
                expect(ctrl.loadDistricts).toHaveBeenCalled();
            });

            it("should update existing district and change status for failure", () => {
                spyOn(meetingService, "putMeetingDistrict").and.callFake(() => {
                    const deferred: IDeferred<any> = $q.defer();
                    deferred.reject();
                    return deferred.promise;
                });

                ctrl.updateDistrict({
                    Area: "CENTRAL",
                    AreaDescription: "Central",
                    MeetingDistrictsID: 1,
                    District: "HERTS",
                    Icon: "red_MarkerK",
                    DistrictDescription: "Hertfordshire",
                    Count: 1
                });

                expect(meetingService.putMeetingDistrict).toHaveBeenCalledWith({
                    Area: "CENTRAL",
                    AreaDescription: "Central",
                    District: "HERTS",
                    DistrictDescription: "New Description",
                    Icon: "pink_MarkerQ"
                });
                expect(ctrl.loadDistricts).not.toHaveBeenCalled();

                $scope.$digest();

                expect(ctrl.districtEditor.districtStatus).toEqual(ctrl.FAILURE);
                expect(ctrl.loadDistricts).not.toHaveBeenCalled();
            });
        });
    });
});
describe('dateParser directive', function() {
    var $scope, $compile;

    beforeEach(angular.mock.module('dateParser'));

    beforeEach(inject(function(_$rootScope_, _$compile_) {
        $scope = _$rootScope_;
        $compile = _$compile_;
    }));

    describe('UI', function() {
        var inputEl, changeInputValueTo;

        function assignElements(wrapElement) {
            inputEl = wrapElement.find('input');
        }

        beforeEach(inject(function($sniffer) {
            $scope.datetime = new Date(2013, 11, 22, 13, 45, 0);
            $scope.dateFormat = 'dd.MM.yyyy';

            var wrapElement = $compile(angular.element('<div ng-form name="testForm"><input type="text" ng-model="datetime" date-parser="{{dateFormat}}" /></div>'))($scope);
            $scope.$digest();

            assignElements(wrapElement);

            changeInputValueTo = function (el, value) {
                el.val(value);
                el.triggerHandler($sniffer.hasEvent('input') ? 'input' : 'change');
                $scope.$digest();
            };
        }));

        it('should have an initial value that uses the given format', function() {
            expect(inputEl.val()).toEqual('22.12.2013');
            expect($scope.testForm.$valid).toEqual(true);
        });

        it('should change model value when input value is changed', function() {
            changeInputValueTo(inputEl, '23.12.2013');

            expect($scope.datetime).toEqual(new Date(2013, 11, 23, 0, 0, 0));
            expect($scope.testForm.$valid).toEqual(true);
        });

        it('should change the view value when model value is changed', function() {
            $scope.datetime = new Date(2014, 11, 23, 21, 50, 0);
            $scope.$digest();

            expect(inputEl.val()).toEqual('23.12.2014');
            expect($scope.testForm.$valid).toEqual(true);
        });

        it('should reset the view value when model value is changed to null', function() {
            $scope.datetime = new Date(2014, 11, 23, 21, 50, 0);
            $scope.$digest();

            expect(inputEl.val()).toEqual('23.12.2014');
            expect($scope.testForm.$valid).toEqual(true);

            $scope.datetime = null;
            $scope.$digest();

            expect(inputEl.val()).toEqual('');
            expect($scope.testForm.$valid).toEqual(true);
        });

        it('should reset the view value when model value is changed to empty', function() {
            $scope.datetime = new Date(2014, 11, 23, 21, 50, 0);
            $scope.$digest();

            expect(inputEl.val()).toEqual('23.12.2014');
            expect($scope.testForm.$valid).toEqual(true);

            $scope.datetime = '';
            $scope.$digest();

            expect(inputEl.val()).toEqual('');
            expect($scope.testForm.$valid).toEqual(true);
        });

        it('should set validity as invalid when an invalid value is entered', function() {
            changeInputValueTo(inputEl, 'something completely invalid');

            expect($scope.testForm.$valid).toEqual(false);
        });

        it('should set validity when ng-required is present', function() {
            var wrapElement = $compile(angular.element('<div ng-form name="testForm"><input type="text" ng-model="datetime" date-parser="{{dateFormat}}" ng-required="true" /></div>'))($scope);
            $scope.$digest();

            assignElements(wrapElement);

            changeInputValueTo(inputEl, '');

            expect($scope.testForm.$valid).toBeFalsy();
            expect($scope.testForm.$error.date).toBeFalsy();

            changeInputValueTo(inputEl, 'something invalid');

            expect($scope.testForm.$valid).toBeFalsy();
            expect($scope.testForm.$error.date).toBeTruthy();

            changeInputValueTo(inputEl, '23.12.2013');

            expect($scope.testForm.$valid).toBeTruthy();
            expect($scope.testForm.$error.date).toBeFalsy();

            $scope.datetime = null;
            $scope.$digest();

            expect($scope.testForm.$valid).toBeFalsy();
            expect($scope.testForm.$error.date).toBeFalsy();
        });
    });
});
Example #12
0
describe('Application Model', function() {
  let application: Application,
    securityGroupReader: SecurityGroupReader,
    loadBalancerReader: any,
    clusterService: any,
    $q: ng.IQService,
    $scope: ng.IScope;

  beforeEach(() => ApplicationDataSourceRegistry.clearDataSources());

  beforeEach(mock.module(SECURITY_GROUP_DATA_SOURCE, SERVER_GROUP_DATA_SOURCE, LOAD_BALANCER_DATA_SOURCE));

  beforeEach(
    mock.inject(function(
      _securityGroupReader_: SecurityGroupReader,
      _clusterService_: any,
      _$q_: ng.IQService,
      _loadBalancerReader_: any,
      $rootScope: any,
    ) {
      securityGroupReader = _securityGroupReader_;
      clusterService = _clusterService_;
      loadBalancerReader = _loadBalancerReader_;
      $q = _$q_;
      $scope = $rootScope.$new();
    }),
  );

  function configureApplication(serverGroups: any[], loadBalancers: any[], securityGroupsByApplicationName: any[]) {
    spyOn(securityGroupReader, 'loadSecurityGroupsByApplicationName').and.returnValue(
      $q.when(securityGroupsByApplicationName),
    );
    spyOn(loadBalancerReader, 'loadLoadBalancers').and.returnValue($q.when(loadBalancers));
    spyOn(clusterService, 'loadServerGroups').and.returnValue($q.when(serverGroups));
    spyOn(securityGroupReader, 'loadSecurityGroups').and.returnValue($q.when([]));
    spyOn(securityGroupReader, 'getApplicationSecurityGroups').and.callFake(function(
      _app: Application,
      groupsByName: any[],
    ) {
      return $q.when(groupsByName || []);
    });
    application = ApplicationModelBuilder.createApplicationForTests(
      'app',
      ...ApplicationDataSourceRegistry.getDataSources(),
    );
    application.refresh();
    $scope.$digest();
  }

  describe('lazy dataSources', function() {
    beforeEach(function() {
      ApplicationDataSourceRegistry.registerDataSource({
        key: 'lazySource',
        lazy: true,
        loader: () => $q.resolve(['a']),
        onLoad: (_app, data) => $q.resolve(data),
      });
    });

    describe('activate', function() {
      it('refreshes section if not already active and not already loaded', function() {
        configureApplication([], [], []);
        spyOn(application.getDataSource('lazySource'), 'refresh').and.callThrough();

        application.getDataSource('lazySource').activate();
        $scope.$digest();
        expect((application.getDataSource('lazySource').refresh as any).calls.count()).toBe(1);
        expect(application.getDataSource('lazySource').active).toBe(true);
        expect(application.getDataSource('lazySource').loaded).toBe(true);

        application.getDataSource('lazySource').deactivate();
        expect(application.getDataSource('lazySource').active).toBe(false);
        application.getDataSource('lazySource').activate();
        // not refreshed since still loaded
        expect(application.getDataSource('lazySource').active).toBe(true);
        expect((application.getDataSource('lazySource').refresh as any).calls.count()).toBe(1);

        application.getDataSource('lazySource').deactivate();
        application.getDataSource('lazySource').loaded = false;
        application.getDataSource('lazySource').activate();
        expect((application.getDataSource('lazySource').refresh as any).calls.count()).toBe(2);
      });
    });

    describe('refresh behavior', function() {
      it('clears data on inactive lazy dataSources and sets loaded flag to false', function() {
        configureApplication([], [], []);

        expect(application.getDataSource('lazySource').active).toBeFalsy();

        application.getDataSource('lazySource').activate();
        $scope.$digest();
        expect(application.getDataSource('lazySource').active).toBe(true);
        expect(application.getDataSource('lazySource').loaded).toBe(true);
        expect(application.getDataSource('lazySource').data.length).toBe(1);

        application.getDataSource('lazySource').deactivate();
        application.refresh();
        $scope.$digest();

        expect(application.getDataSource('lazySource').data).toEqual([]);
        expect(application.getDataSource('lazySource').loaded).toBe(false);
      });

      it('adds entityTags that contain alerts if found on data', function() {
        const alertTag: IEntityTag = { name: 'spinnaker_ui_alert:alert1', value: { message: 'an alert' } };
        const tags: IEntityTags = {
          id: 'zzzz',
          tags: [alertTag],
          tagsMetadata: null,
          entityRef: null,
          alerts: [alertTag],
          notices: [],
        };
        const nonAlertTags: IEntityTags = {
          id: 'zzzz',
          tags: [{ name: 'spinnaker_ui_notice:notice1', value: { message: 'a notice' } }],
          tagsMetadata: null,
          entityRef: null,
          alerts: [],
          notices: [{ name: 'spinnaker_ui_notice:notice1', value: { message: 'a notice' } }],
        };
        const serverGroups: IServerGroup[] = [
          {
            account: 'test',
            cloudProvider: 'aws',
            cluster: 'myapp',
            instanceCounts: null,
            instances: [],
            name: 'myapp-v001',
            region: 'us-east-1',
            type: 'aws',
            entityTags: tags,
          },
          {
            account: 'test',
            cloudProvider: 'aws',
            cluster: 'myapp',
            instanceCounts: null,
            instances: [],
            name: 'myapp-v001',
            region: 'us-east-1',
            type: 'aws',
            entityTags: nonAlertTags,
          },
          {
            account: 'test',
            cloudProvider: 'aws',
            cluster: 'myapp',
            instanceCounts: null,
            instances: [],
            name: 'myapp-no-alerts-v002',
            region: 'us-east-1',
            type: 'aws',
          },
        ];
        configureApplication(serverGroups, [], []);
        expect(application.getDataSource('serverGroups').alerts).toEqual([tags]);
      });
    });

    describe('application ready', function() {
      it('ignores lazy dataSources when determining if application is ready', function() {
        let isReady = false;
        configureApplication([], [], []);

        application.ready().then(() => (isReady = true));
        $scope.$digest();
        expect(isReady).toBe(true);
      });
    });
  });

  describe('setting default credentials and regions', function() {
    it('sets default credentials and region from server group when only one account/region found', function() {
      const serverGroups: IServerGroup[] = [
          {
            name: 'deck-test-v001',
            cluster: 'deck-test',
            account: 'test',
            region: 'us-west-2',
            type: 'aws',
            cloudProvider: 'aws',
            instances: [],
            instanceCounts: {} as IInstanceCounts,
          },
        ],
        loadBalancers: ILoadBalancer[] = [],
        securityGroupsByApplicationName: any[] = [];

      configureApplication(serverGroups, loadBalancers, securityGroupsByApplicationName);
      expect(application.defaultCredentials.aws).toBe('test');
      expect(application.defaultRegions.aws).toBe('us-west-2');
    });

    it('sets default credentials and region from load balancer when only one account/region found', function() {
      const serverGroups: IServerGroup[] = [],
        loadBalancers: ILoadBalancer[] = [
          { name: 'deck-frontend', cloudProvider: 'gce', vpcId: 'vpc0', region: 'us-central-1', account: 'prod' },
        ],
        securityGroupsByApplicationName: any[] = [];

      configureApplication(serverGroups, loadBalancers, securityGroupsByApplicationName);
      expect(application.defaultCredentials.gce).toBe('prod');
      expect(application.defaultRegions.gce).toBe('us-central-1');
    });

    it('sets default credentials and region from firewall', function() {
      const serverGroups: any[] = [],
        loadBalancers: ILoadBalancer[] = [],
        securityGroupsByApplicationName: any[] = [
          { name: 'deck-test', provider: 'cf', accountName: 'test', region: 'us-south-7' },
        ];

      configureApplication(serverGroups, loadBalancers, securityGroupsByApplicationName);
      expect(application.defaultCredentials.cf).toBe('test');
      expect(application.defaultRegions.cf).toBe('us-south-7');
    });

    it('does not set defaults when multiple values found for the same provider', function() {
      const serverGroups: IServerGroup[] = [],
        loadBalancers: ILoadBalancer[] = [
          { name: 'deck-frontend', cloudProvider: 'aws', vpcId: 'vpcId', region: 'us-west-1', account: 'prod' },
        ],
        securityGroupsByApplicationName: any[] = [
          { name: 'deck-test', provider: 'aws', accountName: 'test', region: 'us-east-1' },
        ];

      configureApplication(serverGroups, loadBalancers, securityGroupsByApplicationName);
      expect(application.defaultCredentials.aws).toBeUndefined();
      expect(application.defaultRegions.aws).toBeUndefined();
    });

    it('sets default region or default credentials if possible', function() {
      const serverGroups: IServerGroup[] = [],
        loadBalancers: ILoadBalancer[] = [
          { name: 'deck-frontend', cloudProvider: 'aws', vpcId: 'vpcId', region: 'us-east-1', account: 'prod' },
        ],
        securityGroupsByApplicationName: any[] = [
          { name: 'deck-test', provider: 'aws', accountName: 'test', region: 'us-east-1' },
        ];

      configureApplication(serverGroups, loadBalancers, securityGroupsByApplicationName);
      expect(application.defaultCredentials.aws).toBeUndefined();
      expect(application.defaultRegions.aws).toBe('us-east-1');
    });

    it('sets default credentials, even if region cannot be set', function() {
      const serverGroups: IServerGroup[] = [],
        loadBalancers: ILoadBalancer[] = [
          { name: 'deck-frontend', cloudProvider: 'aws', vpcId: 'vpc0', region: 'us-east-1', account: 'test' },
        ],
        securityGroupsByApplicationName: any[] = [
          { name: 'deck-test', provider: 'aws', accountName: 'test', region: 'us-west-1' },
        ];

      configureApplication(serverGroups, loadBalancers, securityGroupsByApplicationName);
      expect(application.defaultCredentials.aws).toBe('test');
      expect(application.defaultRegions.aws).toBeUndefined();
    });

    it('should set defaults for multiple providers', function() {
      const serverGroups: any[] = [
          {
            name: 'deck-test-v001',
            account: 'test',
            region: 'us-west-2',
            provider: 'aws',
            instances: [],
            instanceCounts: { up: 0, down: 0, starting: 0, unknown: 0, outOfService: 0 },
          },
          {
            name: 'deck-gce-v001',
            account: 'gce-test',
            region: 'us-central-1',
            provider: 'gce',
            instances: [],
            instanceCounts: { up: 0, down: 0, starting: 0, unknown: 0, outOfService: 0 },
          },
        ],
        loadBalancers: ILoadBalancer[] = [
          {
            name: 'deck-frontend',
            account: 'gce-test',
            cloudProvider: 'gce',
            region: 'us-central-1',
            serverGroups: [],
          },
        ],
        securityGroupsByApplicationName: any[] = [
          { name: 'deck-test', provider: 'aws', accountName: 'test', region: 'us-west-2' },
        ];

      configureApplication(serverGroups, loadBalancers, securityGroupsByApplicationName);
      expect(application.defaultCredentials.aws).toBe('test');
      expect(application.defaultRegions.aws).toBe('us-west-2');
      expect(application.defaultCredentials.gce).toBe('gce-test');
      expect(application.defaultRegions.gce).toBe('us-central-1');
    });
  });
});
describe('serverGroupWarningMessageService', () => {
  let service: ServerGroupWarningMessageService,
      applicationModelBuilder: ApplicationModelBuilder,
      app: Application,
      serverGroup: ServerGroup;

  beforeEach(mock.module(SERVER_GROUP_WARNING_MESSAGE_SERVICE, APPLICATION_MODEL_BUILDER));

  beforeEach(mock.inject((serverGroupWarningMessageService: ServerGroupWarningMessageService,
                          _applicationModelBuilder_: ApplicationModelBuilder) => {
    service = serverGroupWarningMessageService;
    applicationModelBuilder = _applicationModelBuilder_;
    app = applicationModelBuilder.createApplication();
  }));

  describe('addDestroyWarningMessage', () => {
    it('leaves parameters unchanged when additional server groups exist in cluster', () => {
      serverGroup = {
        account: 'test',
        cloudProvider: 'aws',
        cluster: 'foo',
        instanceCounts: { up: 0, down: 0, succeeded: 0, failed: 0, unknown: 0, outOfService: 0 },
        instances: [],
        name: 'foo-v000',
        region: 'us-east-1',
        type: 'a'
      };

        app.clusters = [
        {
          name: 'foo',
          account: 'test',
          cloudProvider: '',
          category: '',
          serverGroups: [
            serverGroup,
            { account: 'test', cloudProvider: 'aws', cluster: 'foo', instanceCounts: { up: 0, down: 0, succeeded: 0, failed: 0, unknown: 0, outOfService: 0 }, instances: [], name: 'foo-v001', region: 'us-east-1', type: 'a' },
          ]
        }
      ];
      const params: IConfirmationModalParams = {};
      service.addDestroyWarningMessage(app, serverGroup, params);
      expect(params.body).toBeUndefined();
    });

    it('adds a body to the parameters with cluster name, region, account when this is the last server group', () => {
      serverGroup = {
        account: 'test',
        cloudProvider: 'aws',
        cluster: 'foo',
        instanceCounts: { up: 0, down: 0, succeeded: 0, failed: 0, unknown: 0, outOfService: 0 },
        instances: [],
        name: 'foo-v000',
        region: 'us-east-1',
        type: 'a'
      };

      app.clusters = [
        {
          name: 'foo',
          account: 'test',
          cloudProvider: '',
          category: '',
          serverGroups: [serverGroup]
        }
      ];
      const params: IConfirmationModalParams = {};
      service.addDestroyWarningMessage(app, serverGroup, params);
      expect(params.body).toBeDefined();
      expect(params.body.includes('You are destroying the last Server Group in the Cluster')).toBe(true);
      expect(params.body.includes('test')).toBe(true);
      expect(params.body.includes('foo')).toBe(true);
      expect(params.body.includes('us-east-1')).toBe(true);
    });
  });

  describe('addDisableWarningMessage', () => {
    it('leaves parameters unchanged when server group has no instances', () => {
      serverGroup = {
        account: 'test',
        cloudProvider: 'aws',
        cluster: 'foo',
        instanceCounts: { up: 0, down: 0, succeeded: 0, failed: 0, unknown: 0, outOfService: 0 },
        instances: [],
        name: 'foo-v000',
        region: 'us-east-1',
        type: 'a'
      };

      app.clusters = [
        {
          name: 'foo',
          account: 'test',
          cloudProvider: '',
          category: '',
          serverGroups: [serverGroup]
        }
      ];
      const params: IConfirmationModalParams = {};
      service.addDisableWarningMessage(app, serverGroup, params);
      expect(params.body).toBeUndefined();
    });

    it('adds warning if there are any other instances, even if they are disabled', () => {
      serverGroup = {
        account: 'test',
        cloudProvider: 'aws',
        cluster: 'foo',
        instanceCounts: { up: 1, down: 0, succeeded: 0, failed: 0, unknown: 0, outOfService: 0 },
        instances: [{id: 'a', launchTime: 1, zone: 'b', health: null}],
        name: 'foo-v000',
        region: 'us-east-1',
        type: 'a'
      };
      const down: ServerGroup = {
        account: 'test',
        cloudProvider: 'aws',
        cluster: 'foo',
        instanceCounts: { up: 0, down: 1, succeeded: 0, failed: 0, unknown: 0, outOfService: 0 },
        instances: [{id: 'a', launchTime: 1, zone: 'b', health: null}],
        name: 'foo-v001',
        region: 'us-east-1',
        type: 'a'
      };

      app.clusters = [
        {
          name: 'foo',
          account: 'test',
          cloudProvider: '',
          category: '',
          serverGroups: [serverGroup, down]
        }
      ];
      const params: IConfirmationModalParams = {account: 'prod'};
      service.addDisableWarningMessage(app, serverGroup, params);
      expect(params.body).toBeDefined();
      expect(params.body.includes('<li>')).toBe(false);
      expect(params.textToVerify).toBe('0');
      expect(params.account).toBeUndefined();
    });

    it('adds remaining server groups to the body if they have up instances, removes account from params', () => {
      serverGroup = {
        account: 'test',
        cloudProvider: 'aws',
        cluster: 'foo',
        instanceCounts: { up: 1, down: 0, succeeded: 0, failed: 0, unknown: 0, outOfService: 0 },
        instances: [{id: 'a', launchTime: 1, zone: 'b', health: null}],
        name: 'foo-v000',
        region: 'us-east-1',
        type: 'a'
      };
      const omitted: ServerGroup = {
        account: 'test',
        cloudProvider: 'aws',
        cluster: 'foo',
        instanceCounts: { up: 0, down: 0, succeeded: 0, failed: 0, unknown: 0, outOfService: 0 },
        instances: [],
        name: 'foo-v001',
        region: 'us-east-1',
        type: 'a'
      };

      const included: ServerGroup = {
        account: 'test',
        cloudProvider: 'aws',
        cluster: 'foo',
        instanceCounts: { up: 1, down: 0, succeeded: 0, failed: 0, unknown: 0, outOfService: 0 },
        instances: [{id: 'b', launchTime: 1, zone: 'b', health: null}],
        name: 'foo-v002',
        region: 'us-east-1',
        type: 'a'
      };

      app.clusters = [
        {
          name: 'foo',
          account: 'test',
          cloudProvider: '',
          category: '',
          serverGroups: [serverGroup, omitted, included]
        }
      ];
      const params: IConfirmationModalParams = {account: 'prod'};
      service.addDisableWarningMessage(app, serverGroup, params);
      expect(params.body).toBeDefined();
      expect(params.body.includes('foo-v000')).toBe(false); // this is the target, so should not be included
      expect(params.body.includes('foo-v001')).toBe(false);
      expect(params.body.includes('foo-v002')).toBe(true);
      expect(params.account).toBeUndefined();
    });
  });
});
 beforeEach(() => angular.mock.module(USERS_MODULE));