blob: 720392aab0dd4bb480570d1eb72158d62eac03c4 [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 Scandolo57aee472018-06-28 15:24:42 -0700107 .value('XosVersionReaderService', {
108 getVersion: () => {
109 return {
110 then: (cb) => cb('version')
111 };
112 }
113 })
Matteo Scandolo31daa802017-09-01 12:19:56 -0700114 .value('ConfigHelpers', {
115 stateWithParamsForJs: () => null
116 })
Matteo Scandolo5053cbe2017-01-31 17:37:56 -0800117 .value('XosKeyboardShortcut', MockXosKeyboardShortcut)
Matteo Scandolo828d1e82017-01-17 14:49:38 -0800118 .value('StyleConfig', {
119 logo: 'cord-logo.png',
Matteo Scandolo86bc26a2017-01-18 11:06:47 -0800120 })
Matteo Scandolof3717252017-10-11 15:38:54 -0700121 .value('SearchService', {})
122 .value('XosDebug', MockXosDebug);
Matteo Scandolo828d1e82017-01-17 14:49:38 -0800123
Matteo Scandolof6acdbe2016-12-13 10:29:37 -0800124 angular.mock.module('xosHeader');
125 });
126
Matteo Scandolo52fa5cb2016-12-16 10:06:13 -0800127 beforeEach(angular.mock.inject(($rootScope: ng.IRootScopeService, $compile: ng.ICompileService) => {
128 scope = $rootScope;
129 compile = $compile;
130 element = $compile('<xos-header></xos-header>')($rootScope);
Matteo Scandolof6acdbe2016-12-13 10:29:37 -0800131 $rootScope.$digest();
Matteo Scandolo52fa5cb2016-12-16 10:06:13 -0800132 isolatedScope = element.isolateScope();
133
134 // clear notifications
135 isolatedScope.notifications = [];
Matteo Scandolo31daa802017-09-01 12:19:56 -0700136 MockToastr.info.calls.reset();
Matteo Scandolo52fa5cb2016-12-16 10:06:13 -0800137 }));
138
Matteo Scandoloa8a6fbb2016-12-21 16:59:08 -0800139 it('should render the appropriate logo', () => {
140 const header = $('a.navbar-brand img', element).attr('src');
141 // webpack convert img to base64, how to test?
142 expect(header.trim()).not.toBeNull();
Matteo Scandolo52fa5cb2016-12-16 10:06:13 -0800143 });
144
Matteo Scandolo5053cbe2017-01-31 17:37:56 -0800145 it('should register a keyboard shortcut', () => {
146 expect(MockXosKeyboardShortcut.registerKeyBinding).toHaveBeenCalled();
147 // expect(MockXosKeyboardShortcut.registerKeyBinding).toHaveBeenCalledWith({
148 // key: 'f',
149 // description: 'Select search box',
150 // cb: () => {
151 // $('.navbar-form input').focus();
152 // },
153 // }, 'global');
154 });
155
Matteo Scandolo266907e2016-12-20 13:41:42 -0800156 it('should configure toastr', () => {
Matteo Scandolo31daa802017-09-01 12:19:56 -0700157 delete MockToastrConfig['onTap'];
158
Matteo Scandolo266907e2016-12-20 13:41:42 -0800159 expect(MockToastrConfig).toEqual({
160 newestOnTop: false,
161 positionClass: 'toast-top-right',
162 preventDuplicates: false,
163 preventOpenDuplicates: false,
164 progressBar: true,
165 });
Matteo Scandolo52fa5cb2016-12-16 10:06:13 -0800166 });
167
Matteo Scandolof3717252017-10-11 15:38:54 -0700168 it('should not display a toastr for a new notification (if notifications are disabled)', () => {
169 MockXosDebug.status.notifications = false;
170 sendEvent(infoNotification);
171 scope.$digest();
172
173 expect(MockToastr.info).not.toHaveBeenCalled();
174 });
175
176 it('should display a toastr for a new notification (if notifications are enabled)', () => {
177 MockXosDebug.status.notifications = true;
Matteo Scandolo266907e2016-12-20 13:41:42 -0800178 sendEvent(infoNotification);
Matteo Scandolo52fa5cb2016-12-16 10:06:13 -0800179 scope.$digest();
180
Matteo Scandoloe9cdf9a2017-11-21 10:41:28 -0800181 expect(MockToastr.info).toHaveBeenCalledWith('Synchronization in progress for: TestName', 'TestModel', {extraData: {dest: null}});
Matteo Scandolo31daa802017-09-01 12:19:56 -0700182 });
183
184 it('should not display a toastr for a new event that use skip_notification', () => {
185 sendEvent(noNotification);
186 scope.$digest();
187
188 expect(MockToastr.info).not.toHaveBeenCalled();
Matteo Scandolo52fa5cb2016-12-16 10:06:13 -0800189 });
190
Matteo Scandoloe9cdf9a2017-11-21 10:41:28 -0800191 it('should send a synchronization success notification', () => {
192 const event: IWSEvent = {
193 model: 'TestModel',
194 msg: {
195 changed_fields: ['backend_status', 'backend_code'],
196 pk: 1,
197 object: {
198 name: 'TestName',
199 backend_status: 'OK',
200 backend_code: 1
201 }
202 }
203 };
204 sendEvent(event);
205 scope.$digest();
206
207 expect(MockToastr.success).toHaveBeenCalledWith('Synchronization succedeed for: TestName', 'TestModel', {extraData: {dest: null}});
208 });
209
210 it('should send a synchronization error notification', () => {
211 const event: IWSEvent = {
212 model: 'TestModel',
213 msg: {
214 changed_fields: ['backend_status', 'backend_code'],
215 pk: 1,
216 object: {
217 name: 'TestName',
218 backend_status: 'Failed',
219 backend_code: 2
220 }
221 }
222 };
223 sendEvent(event);
224 scope.$digest();
225
226 expect(MockToastr.error).toHaveBeenCalledWith('Synchronization failed for: TestName', 'TestModel', {extraData: {dest: null}});
227 });
228
229 it('should send a removal success notification', () => {
230 const event: IWSEvent = {
231 model: 'TestModel',
232 deleted: true,
233 msg: {
234 changed_fields: ['backend_status', 'backend_code'],
235 pk: 1,
236 object: {
237 name: 'TestName'
238 }
239 }
240 };
241 sendEvent(event);
242 scope.$digest();
243
244 expect(MockToastr.info).toHaveBeenCalledWith('Deleted object: TestName', 'TestModel', {extraData: {dest: null}});
245 });
246
Matteo Scandolo266907e2016-12-20 13:41:42 -0800247 // TODO test error and success toaster call
Matteo Scandolof6acdbe2016-12-13 10:29:37 -0800248});