[CORD-2647] Handling deletion for _decl model
Change-Id: Iedbf09a59907ed85009e1e9946e6994a34ab6adf
diff --git a/src/app/datasources/websocket/global.spec.ts b/src/app/datasources/websocket/global.spec.ts
new file mode 100644
index 0000000..7adaf07
--- /dev/null
+++ b/src/app/datasources/websocket/global.spec.ts
@@ -0,0 +1,184 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import * as angular from 'angular';
+import 'angular-mocks';
+import {IWSEvent, IWSEventService, WebSocketEvent} from './global';
+
+const MockAppCfg = {
+ apiEndpoint: 'http://xos-test:3000/api',
+ websocketClient: 'http://xos-test:3000'
+};
+
+class MockSocket {
+ private cbs = {};
+
+ public on(event: string, cb: any) {
+ this.cbs[event] = cb;
+ }
+
+ public send(evt: string, data: any) {
+ const cb = this.cbs[evt];
+ cb(data);
+ }
+
+ public clean() {
+ this.cbs = {};
+ }
+}
+
+describe('The WebSocket service', () => {
+
+ let service, observable, mockWS;
+
+ beforeEach(() => {
+
+ mockWS = new MockSocket();
+
+ angular
+ .module('WebSocketEvent', [])
+ .service('WebSocket', WebSocketEvent)
+ .constant('AppConfig', MockAppCfg)
+ .value('SocketIo', {socket: mockWS});
+
+ angular.mock.module('WebSocketEvent');
+ });
+
+ beforeEach(angular.mock.inject((
+ WebSocket: IWSEventService
+ ) => {
+ service = WebSocket;
+ observable = service['_events'];
+
+ spyOn(observable, 'next');
+ }));
+
+ afterEach(() => {
+ mockWS.clean();
+ observable.next.calls.reset();
+ });
+
+ it('should have a list method', () => {
+ expect(service.list).toBeDefined();
+ });
+
+ describe('the update event', () => {
+ it('should update the base class', () => {
+ const data: IWSEvent = {
+ model: 'Test',
+ msg: {
+ pk: 1,
+ changed_fields: ['name'],
+ object: {}
+ }
+ };
+ mockWS.send('update', data);
+ expect(observable.next).toHaveBeenCalledWith(data);
+ expect(observable.next.calls.count()).toBe(1);
+ });
+
+ it('should not update the class if the changed_fields are not useful to the UI', () => {
+ const data: IWSEvent = {
+ model: 'Test',
+ msg: {
+ pk: 1,
+ changed_fields: ['created', 'updated', 'backend_register', 'backend_status', 'policy_status'],
+ object: {}
+ }
+ };
+ mockWS.send('update', data);
+ expect(observable.next).not.toHaveBeenCalled();
+ });
+
+ it('should update parent classes (if any)', () => {
+ const data: IWSEvent = {
+ model: 'ONOSApp',
+ msg: {
+ pk: 1,
+ changed_fields: ['name'],
+ object: {
+ class_names: 'ONOSApp,ONOSApp_decl,ServiceInstance,XOSBase,Model,PlModelMixIn,AttributeMixin,object'
+ }
+ }
+ };
+ mockWS.send('update', data);
+ expect(observable.next).toHaveBeenCalledWith(data);
+ const siEvent = data;
+ siEvent.model = 'ServiceInstance';
+ siEvent.skip_notification = true;
+ expect(observable.next).toHaveBeenCalledWith(siEvent);
+ expect(observable.next.calls.count()).toBe(2);
+ });
+ });
+
+ describe('the remove event', () => {
+ it('should trigger the remove event', () => {
+ const data: IWSEvent = {
+ model: 'Test',
+ msg: {
+ pk: 1,
+ changed_fields: [],
+ object: {}
+ },
+ };
+ mockWS.send('remove', data);
+ expect(observable.next).toHaveBeenCalledWith(data);
+ });
+
+ it('should update parent classes (if any)', () => {
+ const data: IWSEvent = {
+ model: 'ONOSApp',
+ msg: {
+ pk: 1,
+ changed_fields: ['name'],
+ object: {
+ class_names: 'ONOSApp,ONOSApp_decl,ServiceInstance,XOSBase,Model,PlModelMixIn,AttributeMixin,object'
+ }
+ }
+ };
+ mockWS.send('remove', data);
+ expect(observable.next).toHaveBeenCalledWith(data);
+ const siEvent = data;
+ siEvent.model = 'ServiceInstance';
+ siEvent.skip_notification = true;
+ expect(observable.next).toHaveBeenCalledWith(siEvent);
+ expect(observable.next.calls.count()).toBe(2);
+ });
+
+ it('should update derived class if the original is _decl', () => {
+ const data: IWSEvent = {
+ model: 'ONOSApp_decl',
+ msg: {
+ pk: 1,
+ changed_fields: ['name'],
+ object: {
+ class_names: 'ONOSApp_decl,ServiceInstance,XOSBase,Model,PlModelMixIn,AttributeMixin,object'
+ }
+ }
+ };
+ mockWS.send('remove', data);
+
+ const nextData = angular.copy(data);
+ nextData.model = 'ONOSApp';
+ expect(observable.next).toHaveBeenCalledWith(nextData);
+ const declEvent = nextData;
+ declEvent.model = 'ServiceInstance';
+ declEvent.skip_notification = true;
+ expect(observable.next).toHaveBeenCalledWith(declEvent);
+ expect(observable.next.calls.count()).toBe(2);
+ });
+ });
+});