blob: 023bb7d3970be1d513190b8d58ae33f61dc3728e [file] [log] [blame]
Matteo Scandolofb46ae62017-08-08 09:10:50 -07001
2/*
3 * Copyright 2017-present Open Networking Foundation
4
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8
9 * http://www.apache.org/licenses/LICENSE-2.0
10
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18
Matteo Scandolof6acdbe2016-12-13 10:29:37 -080019/// <reference path="../../../../typings/index.d.ts" />
20
Matteo Scandolo52fa5cb2016-12-16 10:06:13 -080021import * as $ from 'jquery';
22import 'jasmine-jquery';
Matteo Scandolof6acdbe2016-12-13 10:29:37 -080023import * as angular from 'angular';
24import 'angular-mocks';
Matteo Scandolo52fa5cb2016-12-16 10:06:13 -080025import {xosHeader, INotification} from './header';
Matteo Scandolo63e43eb2016-12-14 14:18:53 -080026import {Subject} from 'rxjs';
Matteo Scandolof3717252017-10-11 15:38:54 -070027import {IXosDebugService} from '../debug/debug.service';
Matteo Scandoloe9cdf9a2017-11-21 10:41:28 -080028import {IWSEvent} from '../../datasources/websocket/global';
Matteo Scandolof6acdbe2016-12-13 10:29:37 -080029
Matteo Scandolo52fa5cb2016-12-16 10:06:13 -080030let element, scope: angular.IRootScopeService, compile: ng.ICompileService, isolatedScope;
31const events = new Subject();
32const sendEvent = (event: INotification): void => {
33 events.next(event);
34};
35const MockStore = function() {
36 this.query = () => {
37 return events.asObservable();
38 };
39};
Matteo Scandolo266907e2016-12-20 13:41:42 -080040
Matteo Scandoloa8a6fbb2016-12-21 16:59:08 -080041const MockToastr = {
Matteo Scandoloe9cdf9a2017-11-21 10:41:28 -080042 info: jasmine.createSpy('info'),
43 success: jasmine.createSpy('success'),
44 error: jasmine.createSpy('error')
Matteo Scandolo266907e2016-12-20 13:41:42 -080045};
46
Matteo Scandoloa8a6fbb2016-12-21 16:59:08 -080047const MockAuth = {
48 getUser: () => {
49 return {email: 'test@xos.us'};
50 }
51};
52
Matteo Scandolo266907e2016-12-20 13:41:42 -080053const MockToastrConfig = {};
54
55const infoNotification = {
Matteo Scandolo52fa5cb2016-12-16 10:06:13 -080056 model: 'TestModel',
57 msg: {
Matteo Scandolo31daa802017-09-01 12:19:56 -070058 changed_fields: ['backend_status', 'backend_code'],
Matteo Scandolo52fa5cb2016-12-16 10:06:13 -080059 pk: 1,
60 object: {
61 name: 'TestName',
Matteo Scandolo31daa802017-09-01 12:19:56 -070062 backend_status: 'In Progress',
63 backend_code: 0
64 }
65 }
66};
67
68const noNotification = {
69 model: 'TestModel',
70 skip_notification: true,
71 msg: {
72 changed_fields: ['backend_status', 'backend_code'],
73 pk: 1,
74 object: {
75 name: 'TestName',
76 backend_status: 'In Progress',
77 backend_code: 0
Matteo Scandolo52fa5cb2016-12-16 10:06:13 -080078 }
79 }
80};
81
Matteo Scandolo5053cbe2017-01-31 17:37:56 -080082const MockXosKeyboardShortcut = {
83 registerKeyBinding: jasmine.createSpy('registerKeyBinding')
84};
85
Matteo Scandolof3717252017-10-11 15:38:54 -070086const MockXosDebug: IXosDebugService = {
87 status: {
88 global: false,
89 events: false,
90 modelsTab: false,
91 notifications: true
92 },
93 setupShortcuts: jasmine.createSpy('debug.createShortcuts'),
94 toggleDebug: jasmine.createSpy('debug.toggleDebug')
95};
96
Matteo Scandolof6acdbe2016-12-13 10:29:37 -080097describe('header component', () => {
98 beforeEach(() => {
99 angular
Matteo Scandolo67c105f2017-01-09 09:30:52 -0800100 .module('xosHeader', ['app/core/header/header.html', 'ui.router'])
Matteo Scandolo63e43eb2016-12-14 14:18:53 -0800101 .component('xosHeader', xosHeader)
Matteo Scandolo266907e2016-12-20 13:41:42 -0800102 .service('SynchronizerStore', MockStore)
103 .value('toastr', MockToastr)
Matteo Scandoloa8a6fbb2016-12-21 16:59:08 -0800104 .value('toastrConfig', MockToastrConfig)
Matteo Scandolo67c105f2017-01-09 09:30:52 -0800105 .value('AuthService', MockAuth)
Matteo Scandolo1aee1982017-02-17 08:33:23 -0800106 .value('XosNavigationService', {})
Matteo Scandolo31daa802017-09-01 12:19:56 -0700107 .value('ConfigHelpers', {
108 stateWithParamsForJs: () => null
109 })
Matteo Scandolo5053cbe2017-01-31 17:37:56 -0800110 .value('XosKeyboardShortcut', MockXosKeyboardShortcut)
Matteo Scandolo828d1e82017-01-17 14:49:38 -0800111 .value('StyleConfig', {
112 logo: 'cord-logo.png',
Matteo Scandolo86bc26a2017-01-18 11:06:47 -0800113 })
Matteo Scandolof3717252017-10-11 15:38:54 -0700114 .value('SearchService', {})
115 .value('XosDebug', MockXosDebug);
Matteo Scandolo828d1e82017-01-17 14:49:38 -0800116
Matteo Scandolof6acdbe2016-12-13 10:29:37 -0800117 angular.mock.module('xosHeader');
118 });
119
Matteo Scandolo52fa5cb2016-12-16 10:06:13 -0800120 beforeEach(angular.mock.inject(($rootScope: ng.IRootScopeService, $compile: ng.ICompileService) => {
121 scope = $rootScope;
122 compile = $compile;
123 element = $compile('<xos-header></xos-header>')($rootScope);
Matteo Scandolof6acdbe2016-12-13 10:29:37 -0800124 $rootScope.$digest();
Matteo Scandolo52fa5cb2016-12-16 10:06:13 -0800125 isolatedScope = element.isolateScope();
126
127 // clear notifications
128 isolatedScope.notifications = [];
Matteo Scandolo31daa802017-09-01 12:19:56 -0700129 MockToastr.info.calls.reset();
Matteo Scandolo52fa5cb2016-12-16 10:06:13 -0800130 }));
131
Matteo Scandoloa8a6fbb2016-12-21 16:59:08 -0800132 it('should render the appropriate logo', () => {
133 const header = $('a.navbar-brand img', element).attr('src');
134 // webpack convert img to base64, how to test?
135 expect(header.trim()).not.toBeNull();
Matteo Scandolo52fa5cb2016-12-16 10:06:13 -0800136 });
137
Matteo Scandolo5053cbe2017-01-31 17:37:56 -0800138 it('should register a keyboard shortcut', () => {
139 expect(MockXosKeyboardShortcut.registerKeyBinding).toHaveBeenCalled();
140 // expect(MockXosKeyboardShortcut.registerKeyBinding).toHaveBeenCalledWith({
141 // key: 'f',
142 // description: 'Select search box',
143 // cb: () => {
144 // $('.navbar-form input').focus();
145 // },
146 // }, 'global');
147 });
148
Matteo Scandolo266907e2016-12-20 13:41:42 -0800149 it('should configure toastr', () => {
Matteo Scandolo31daa802017-09-01 12:19:56 -0700150 delete MockToastrConfig['onTap'];
151
Matteo Scandolo266907e2016-12-20 13:41:42 -0800152 expect(MockToastrConfig).toEqual({
153 newestOnTop: false,
154 positionClass: 'toast-top-right',
155 preventDuplicates: false,
156 preventOpenDuplicates: false,
157 progressBar: true,
158 });
Matteo Scandolo52fa5cb2016-12-16 10:06:13 -0800159 });
160
Matteo Scandolof3717252017-10-11 15:38:54 -0700161 it('should not display a toastr for a new notification (if notifications are disabled)', () => {
162 MockXosDebug.status.notifications = false;
163 sendEvent(infoNotification);
164 scope.$digest();
165
166 expect(MockToastr.info).not.toHaveBeenCalled();
167 });
168
169 it('should display a toastr for a new notification (if notifications are enabled)', () => {
170 MockXosDebug.status.notifications = true;
Matteo Scandolo266907e2016-12-20 13:41:42 -0800171 sendEvent(infoNotification);
Matteo Scandolo52fa5cb2016-12-16 10:06:13 -0800172 scope.$digest();
173
Matteo Scandoloe9cdf9a2017-11-21 10:41:28 -0800174 expect(MockToastr.info).toHaveBeenCalledWith('Synchronization in progress for: TestName', 'TestModel', {extraData: {dest: null}});
Matteo Scandolo31daa802017-09-01 12:19:56 -0700175 });
176
177 it('should not display a toastr for a new event that use skip_notification', () => {
178 sendEvent(noNotification);
179 scope.$digest();
180
181 expect(MockToastr.info).not.toHaveBeenCalled();
Matteo Scandolo52fa5cb2016-12-16 10:06:13 -0800182 });
183
Matteo Scandoloe9cdf9a2017-11-21 10:41:28 -0800184 it('should send a synchronization success notification', () => {
185 const event: IWSEvent = {
186 model: 'TestModel',
187 msg: {
188 changed_fields: ['backend_status', 'backend_code'],
189 pk: 1,
190 object: {
191 name: 'TestName',
192 backend_status: 'OK',
193 backend_code: 1
194 }
195 }
196 };
197 sendEvent(event);
198 scope.$digest();
199
200 expect(MockToastr.success).toHaveBeenCalledWith('Synchronization succedeed for: TestName', 'TestModel', {extraData: {dest: null}});
201 });
202
203 it('should send a synchronization error notification', () => {
204 const event: IWSEvent = {
205 model: 'TestModel',
206 msg: {
207 changed_fields: ['backend_status', 'backend_code'],
208 pk: 1,
209 object: {
210 name: 'TestName',
211 backend_status: 'Failed',
212 backend_code: 2
213 }
214 }
215 };
216 sendEvent(event);
217 scope.$digest();
218
219 expect(MockToastr.error).toHaveBeenCalledWith('Synchronization failed for: TestName', 'TestModel', {extraData: {dest: null}});
220 });
221
222 it('should send a removal success notification', () => {
223 const event: IWSEvent = {
224 model: 'TestModel',
225 deleted: true,
226 msg: {
227 changed_fields: ['backend_status', 'backend_code'],
228 pk: 1,
229 object: {
230 name: 'TestName'
231 }
232 }
233 };
234 sendEvent(event);
235 scope.$digest();
236
237 expect(MockToastr.info).toHaveBeenCalledWith('Deleted object: TestName', 'TestModel', {extraData: {dest: null}});
238 });
239
Matteo Scandolo266907e2016-12-20 13:41:42 -0800240 // TODO test error and success toaster call
Matteo Scandolof6acdbe2016-12-13 10:29:37 -0800241});