Moved modelHelpers service in the DataSources module

Change-Id: Ife4239d8f0ca0ec12ed7db17c337deb6e06e80fe
diff --git a/src/app/config/.gitignore b/src/app/config/.gitignore
new file mode 100644
index 0000000..d6b7ef3
--- /dev/null
+++ b/src/app/config/.gitignore
@@ -0,0 +1,2 @@
+*
+!.gitignore
diff --git a/src/app/config/app.config.ts b/src/app/config/app.config.ts
deleted file mode 100644
index 50570d7..0000000
--- a/src/app/config/app.config.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-import {IAppConfig} from './interfaces';
-export const AppConfig: IAppConfig = {
-    apiEndpoint: 'http://xos.dev:3000/api',
-    websocketClient: 'http://xos.dev:3000'
-};
diff --git a/src/app/config/interfaces.ts b/src/app/config/interfaces.ts
deleted file mode 100644
index ddf3126..0000000
--- a/src/app/config/interfaces.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import {IXosNavigationRoute} from '../core/services/navigation';
-export interface IStyleConfig {
-  projectName: string;
-  payoff: string;
-  favicon: string;
-  background: string;
-  logo: string;
-  routes: IXosNavigationRoute[];
-}
-
-export interface IAppConfig {
-  apiEndpoint: string;
-  websocketClient: string;
-}
diff --git a/src/app/config/style.config.ts b/src/app/config/style.config.ts
deleted file mode 100644
index c43cac8..0000000
--- a/src/app/config/style.config.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import {IStyleConfig} from './interfaces';
-export const StyleConfig: IStyleConfig = {
-    projectName: 'CORD',
-    favicon: 'cord-favicon.png',
-    background: 'cord-bg.jpg',
-    payoff: 'Your VNF orchestrator',
-    logo: 'cord-logo.png',
-    routes: [
-        {
-            label: 'Slices',
-            state: 'xos.core.slices'
-        },
-        {
-            label: 'Instances',
-            state: 'xos.core.instances'
-        },
-        {
-            label: 'Nodes',
-            state: 'xos.core.nodes'
-        }
-    ]
-};
diff --git a/src/app/core/index.ts b/src/app/core/index.ts
index fd87e38..a9aa9a6 100644
--- a/src/app/core/index.ts
+++ b/src/app/core/index.ts
@@ -13,7 +13,6 @@
 import {xosForm} from './form/form';
 import {xosField} from './field/field';
 import 'angular-toastr';
-import {ModelHelpers} from './services/helpers/model.helper';
 
 export const xosCore = 'xosCore';
 
@@ -25,7 +24,6 @@
   .service('PageTitle', PageTitle)
   .service('XosFormHelpers', XosFormHelpers)
   .service('ConfigHelpers', ConfigHelpers)
-  .service('ModelHelpers', ModelHelpers)
   .directive('xosLinkWrapper', xosLinkWrapper)
   .component('xosHeader', xosHeader)
   .component('xosFooter', xosFooter)
diff --git a/src/app/core/services/helpers/model.helpers.spec.ts b/src/app/datasources/helpers/model.helpers.spec.ts
similarity index 91%
rename from src/app/core/services/helpers/model.helpers.spec.ts
rename to src/app/datasources/helpers/model.helpers.spec.ts
index 8456738..ee23b28 100644
--- a/src/app/core/services/helpers/model.helpers.spec.ts
+++ b/src/app/datasources/helpers/model.helpers.spec.ts
@@ -2,10 +2,10 @@
 import 'angular-mocks';
 import 'angular-ui-router';
 
-import {IXosModelHelpersService, ModelHelpers} from './model.helper';
+import {IXosModelHelpersService, ModelHelpers} from './model.helpers';
 
 let service: IXosModelHelpersService;
-describe('The ConfigHelpers service', () => {
+describe('The ModelHelpers service', () => {
 
   beforeEach(() => {
     angular
diff --git a/src/app/core/services/helpers/model.helper.ts b/src/app/datasources/helpers/model.helpers.ts
similarity index 100%
rename from src/app/core/services/helpers/model.helper.ts
rename to src/app/datasources/helpers/model.helpers.ts
diff --git a/src/app/datasources/helpers/store.helpers.spec.ts b/src/app/datasources/helpers/store.helpers.spec.ts
new file mode 100644
index 0000000..b2085e3
--- /dev/null
+++ b/src/app/datasources/helpers/store.helpers.spec.ts
@@ -0,0 +1,124 @@
+import * as angular from 'angular';
+import 'angular-mocks';
+import 'angular-ui-router';
+import {StoreHelpers, IStoreHelpersService} from './store.helpers';
+import {ModelHelpers} from './model.helpers';
+import {ModelRest} from '../rest/model.rest';
+import {BehaviorSubject} from 'rxjs';
+import {IWSEvent} from '../websocket/global';
+
+let service: IStoreHelpersService;
+let subject: BehaviorSubject<any>;
+let resource: ng.resource.IResourceClass<any>;
+let $resource: ng.resource.IResourceService;
+
+describe('The StoreHelpers service', () => {
+
+  beforeEach(() => {
+    angular
+      .module('test', ['ngResource'])
+      .service('ModelHelpers', ModelHelpers) // NOTE evaluate mock
+      .service('ModelRest', ModelRest) // NOTE evaluate mock
+      .service('StoreHelpers', StoreHelpers);
+
+    angular.mock.module('test');
+  });
+
+  beforeEach(angular.mock.inject((
+    StoreHelpers: IStoreHelpersService,
+    _$resource_: ng.resource.IResourceService
+  ) => {
+    $resource = _$resource_;
+    resource = $resource('/test');
+    service = StoreHelpers;
+  }));
+
+  it('should have an update collection method', () => {
+    expect(service.updateCollection).toBeDefined();
+  });
+
+  describe('when updating a collection', () => {
+
+    beforeEach(() => {
+      subject = new BehaviorSubject([
+        new resource({id: 1, name: 'test'})
+      ]);
+    });
+
+    it('should remove a model if it has been deleted', () => {
+      const event: IWSEvent = {
+        model: 'Test',
+        msg: {
+          object: {
+            id: 1,
+            name: 'test'
+          },
+          changed_fields: ['deleted']
+        }
+      };
+      service.updateCollection(event, subject);
+      expect(subject.value.length).toBe(0);
+    });
+
+    it('should update a model if it has been updated', () => {
+      const event: IWSEvent = {
+        model: 'Test',
+        msg: {
+          object: {
+            id: 1,
+            name: 'test-updated'
+          },
+          changed_fields: ['name']
+        }
+      };
+      service.updateCollection(event, subject);
+      expect(subject.value.length).toBe(1);
+      expect(subject.value[0].name).toBe('test-updated');
+    });
+
+    it('should add a model if it has been created', () => {
+      const event: IWSEvent = {
+        model: 'Test',
+        msg: {
+          object: {
+            id: 2,
+            name: 'another-test'
+          },
+          changed_fields: ['created']
+        }
+      };
+      service.updateCollection(event, subject);
+      expect(subject.value.length).toBe(2);
+      expect(subject.value[0].name).toBe('test');
+      expect(subject.value[1].name).toBe('another-test');
+    });
+
+    describe('when adding a model', () => {
+
+      beforeEach(() => {
+        const event: IWSEvent = {
+          model: 'Test',
+          msg: {
+            object: {
+              id: 2,
+              name: 'another-test'
+            },
+            changed_fields: ['created']
+          }
+        };
+        service.updateCollection(event, subject);
+      });
+
+      it('should create a resource', () => {
+        expect(subject.value[1].$save).toBeDefined();
+        expect(subject.value[1].$delete).toBeDefined();
+      });
+
+      xit('should automatically create the appropriate resource', () => {
+        // TODO test that the url of the resource is the correct one,
+        // use httpbackend and mock a call?? any faster way??
+      });
+    });
+  });
+
+});
diff --git a/src/app/datasources/helpers/store.helpers.ts b/src/app/datasources/helpers/store.helpers.ts
index 1a2b0ab..99662da 100644
--- a/src/app/datasources/helpers/store.helpers.ts
+++ b/src/app/datasources/helpers/store.helpers.ts
@@ -1,12 +1,22 @@
 import {BehaviorSubject} from 'rxjs';
 import * as _ from 'lodash';
 import {IWSEvent} from '../websocket/global';
+import {IXosModelHelpersService} from './model.helpers';
+import {IXosResourceService} from '../rest/model.rest';
 
 export interface IStoreHelpersService {
   updateCollection(event: IWSEvent, subject: BehaviorSubject<any>): BehaviorSubject<any>;
 }
 
 export class StoreHelpers {
+  static $inject = ['ModelHelpers', 'ModelRest'];
+
+  constructor (
+    private modelHelpers: IXosModelHelpersService,
+    private modelRest: IXosResourceService
+  ) {
+  }
+
   public updateCollection(event: IWSEvent, subject: BehaviorSubject<any>): BehaviorSubject<any> {
     const collection: any[] = subject.value;
     const index: number = _.findIndex(collection, (i) => {
@@ -15,17 +25,23 @@
     });
     const exist: boolean = index > -1;
     const isDeleted: boolean = _.includes(event.msg.changed_fields, 'deleted');
-       // remove
+
+    // generate a resource for the model
+    const endpoint = this.modelHelpers.urlFromCoreModel(event.model);
+    const resource = this.modelRest.getResource(endpoint);
+    const model = new resource(event.msg.object);
+
+    // remove
     if (exist && isDeleted) {
        _.remove(collection, {id: event.msg.object.id});
      }
     // Replace item at index using native splice
     else if (exist && !isDeleted) {
-       collection.splice(index, 1, event.msg.object);
+       collection.splice(index, 1, model);
      }
     // if the element is not deleted add it
     else if (!exist && !isDeleted) {
-      collection.push(event.msg.object);
+      collection.push(model);
      }
 
     subject.next(collection);
diff --git a/src/app/datasources/index.ts b/src/app/datasources/index.ts
index 7a14a9a..b6897ed 100644
--- a/src/app/datasources/index.ts
+++ b/src/app/datasources/index.ts
@@ -5,12 +5,12 @@
 import {StoreHelpers} from './helpers/store.helpers';
 import {SynchronizerStore} from './stores/synchronizer.store';
 import {ModeldefsService} from './rest/modeldefs.rest';
-import {xosCore} from '../core/index';
+import {ModelHelpers} from './helpers/model.helpers';
 
 export const xosDataSources = 'xosDataSources';
 
 angular
-  .module('xosDataSources', ['ngCookies', 'ngResource', xosCore])
+  .module('xosDataSources', ['ngCookies', 'ngResource'])
   .service('ModelRest', ModelRest)
   .service('AuthService', AuthService)
   .service('WebSocket', WebSocketEvent);
@@ -18,6 +18,7 @@
 angular
   .module('xosDataSources')
   .service('StoreHelpers', StoreHelpers)
+  .service('ModelHelpers', ModelHelpers)
   .service('SynchronizerStore', SynchronizerStore)
   .service('ModelStore', ModelStore)
   .service('ModelDefs', ModeldefsService);
diff --git a/src/app/datasources/stores/model.store.spec.ts b/src/app/datasources/stores/model.store.spec.ts
index a6edcb9..49b9338 100644
--- a/src/app/datasources/stores/model.store.spec.ts
+++ b/src/app/datasources/stores/model.store.spec.ts
@@ -7,7 +7,7 @@
 import {StoreHelpers} from '../helpers/store.helpers';
 import {ModelRest} from '../rest/model.rest';
 import {AppConfig} from '../../config/app.config';
-import {ModelHelpers} from '../../core/services/helpers/model.helper';
+import {ModelHelpers} from '../helpers/model.helpers';
 
 let service: IModelStoreService;
 let httpBackend: ng.IHttpBackendService;
diff --git a/src/app/datasources/stores/model.store.ts b/src/app/datasources/stores/model.store.ts
index 015d729..91cdf24 100644
--- a/src/app/datasources/stores/model.store.ts
+++ b/src/app/datasources/stores/model.store.ts
@@ -4,7 +4,7 @@
 import {IWSEvent, IWSEventService} from '../websocket/global';
 import {IXosResourceService} from '../rest/model.rest';
 import {IStoreHelpersService} from '../helpers/store.helpers';
-import {IXosModelHelpersService} from '../../core/services/helpers/model.helper';
+import {IXosModelHelpersService} from '../helpers/model.helpers';
 
 export interface  IModelStoreService {
   query(model: string): Observable<any>;
diff --git a/src/index.ts b/src/index.ts
index 88c2250..07cdead 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -29,7 +29,6 @@
 import {IXosConfigHelpersService} from './app/core/services/helpers/config.helpers';
 import {StyleConfig} from './app/config/style.config';
 import {IXosResourceService} from './app/datasources/rest/model.rest';
-import {IXosModelHelpersService} from './app/core/services/helpers/model.helper';
 
 export interface IXosState extends angular.ui.IState {
   data: IXosCrudData;
@@ -69,7 +68,6 @@
     RuntimeStates: IRuntimeStatesService,
     NavigationService: IXosNavigationService,
     ConfigHelpers: IXosConfigHelpersService,
-    ModelHelpers: IXosModelHelpersService,
     toastr: ng.toastr.IToastrService,
     PageTitle: IXosPageTitleService
   ) => {
@@ -105,15 +103,7 @@
                     color: 'red',
                     cb: (item) => {
                       let obj = angular.copy(item);
-                      // check that item in an angular resource
-                      if (!item.$delete) {
-                        const endpoint = ModelHelpers.urlFromCoreModel(m.name);
-                        const resource = ModelRest.getResource(endpoint);
-                        // create a resource with that item
-                        item = new resource(item);
 
-                      }
-                      console.log(item);
                       item.$delete()
                         .then((res) => {
                           if (res.status === 404) {