Test cdn prefixes
diff --git a/xos/core/xoslib/spec/views/contentprovider.test.js b/xos/core/xoslib/spec/views/contentprovider.test.js
index ca9b727..55a78b6 100644
--- a/xos/core/xoslib/spec/views/contentprovider.test.js
+++ b/xos/core/xoslib/spec/views/contentprovider.test.js
@@ -12,6 +12,7 @@
 
   beforeEach(function() {
     module(function($provide) {
+      // mocking routeParams to pass 1 as id
       $provide.provider('$routeParams', function() {
         this.$get = function() {
           return {id: 1};
@@ -71,22 +72,33 @@
   });
 
   describe('the contentProviderDetail directive', () => {
+
+    beforeEach(inject(function($compile, $rootScope) {
+      scope = $rootScope.$new();
+      element = angular.element('<content-provider-detail></content-provider-detail>');
+      $compile(element)(scope);
+      httpBackend.expectGET('/hpcapi/contentproviders/1/').respond(CPmock.CPlist[0]);
+      scope.$digest();
+      httpBackend.flush();
+      isolatedScope = element.isolateScope().vm;
+    }));
+
+    it('should select the active service provider', () => {
+      var res = isolatedScope.activeServiceProvide(1, 'http://0.0.0.0:9000/hpcapi/serviceproviders/1/');
+      expect(res).toBe(true);
+    });
+
+    it('should not select a non active service provider', () => {
+      var res = isolatedScope.activeServiceProvide(1, 'http://0.0.0.0:9000/hpcapi/serviceproviders/3/');
+      expect(res).toBe(false);
+    });
+
     describe('when an id is set in the route', () => {
 
-      beforeEach(inject(function($compile, $rootScope, ContentProvider) {
-        scope = $rootScope.$new();
-
-        httpBackend.expectGET('/hpcapi/contentproviders/1/').respond(CPmock.CPlist[0]);
-        httpBackend.whenPUT('/hpcapi/contentproviders/1/').respond({name: 'done'});
-
-        spyOn(ContentProvider, 'save').and.callThrough();
-
-        element = angular.element('<content-provider-detail></content-provider-detail>');
-        $compile(element)(scope);
-        scope.$digest();
-        httpBackend.flush();
-        isolatedScope = element.isolateScope().vm;
-      }));
+      beforeEach(() => {
+        // spy the instance update method
+        spyOn(isolatedScope.cp, '$update').and.callThrough();
+      });
 
       it('should request the correct contentProvider', () => {
         expect(isolatedScope.cp.name).toEqual(CPmock.CPlist[0].name);
@@ -95,9 +107,41 @@
       it('should update a contentProvider', () => {
         isolatedScope.cp.name = 'new name';
         isolatedScope.saveContentProvider(isolatedScope.cp);
-        httpBackend.flush();
-        expect(isolatedScope.cp.name).toEqual('done');
+        expect(isolatedScope.cp.$update).toHaveBeenCalled();
       });
     });
   });
+
+  describe('the contentProviderCdn directive', () => {
+    beforeEach(inject(($compile, $rootScope) => {
+      scope = $rootScope.$new();
+      element = angular.element('<content-provider-cdn></content-provider-cdn>');
+      $compile(element)(scope);
+      httpBackend.expectGET('/hpcapi/contentproviders/1/').respond(CPmock.CPlist[0]);
+      httpBackend.expectGET('/hpcapi/cdnprefixs/?contentProvider=1').respond([CPmock.CDNlist[0]]);
+      httpBackend.expectGET('/hpcapi/cdnprefixs/').respond(CPmock.CDNlist);
+      httpBackend.whenPOST('/hpcapi/cdnprefixs/').respond(CPmock.CDNlist[0]);
+      httpBackend.whenDELETE('/hpcapi/cdnprefixs/5/').respond();
+      scope.$digest();
+      httpBackend.flush();
+      isolatedScope = element.isolateScope().vm;
+    }));
+
+    it('should load associated CDN prefix', () => {
+      expect(isolatedScope.cp_prf.length).toBe(1);
+      expect(isolatedScope.prf.length).toBe(2);
+    });
+
+    it('should add a CDN Prefix', () => {
+      isolatedScope.addPrefix({prefix: 'test.io', defaultOriginServer: '/hpcapi/originservers/2/'});
+      httpBackend.flush();
+      expect(isolatedScope.cp_prf.length).toBe(2);
+    });
+
+    it('should remove a CDN Prefix', () => {
+      isolatedScope.removePrefix(isolatedScope.cp_prf[0]);
+      httpBackend.flush();
+      expect(isolatedScope.cp_prf.length).toBe(0);
+    });
+  });
 });
diff --git a/xos/core/xoslib/spec/views/mocks/contentProvider.mock.js b/xos/core/xoslib/spec/views/mocks/contentProvider.mock.js
index 97ee31b..0bbd7ce 100644
--- a/xos/core/xoslib/spec/views/mocks/contentProvider.mock.js
+++ b/xos/core/xoslib/spec/views/mocks/contentProvider.mock.js
@@ -211,5 +211,153 @@
       'description':null,
       'enabled':true
     }
+  ],
+  CDNlist: [
+    {
+      'humanReadableName':'onlab.vicci.org',
+      'validators':{
+        'updated':[
+
+        ],
+        'contentProvider':[
+          'notBlank'
+        ],
+        'policed':[
+
+        ],
+        'created':[
+
+        ],
+        'deleted':[
+
+        ],
+        'description':[
+
+        ],
+        'enabled':[
+
+        ],
+        'cdn_prefix_id':[
+
+        ],
+        'lazy_blocked':[
+
+        ],
+        'backend_register':[
+          'notBlank'
+        ],
+        'write_protect':[
+
+        ],
+        'prefix':[
+          'notBlank'
+        ],
+        'defaultOriginServer':[
+
+        ],
+        'backend_status':[
+          'notBlank'
+        ],
+        'id':[
+
+        ],
+        'no_sync':[
+
+        ],
+        'enacted':[
+
+        ]
+      },
+      'id':5,
+      'created':'2015-10-26T13:09:44.343Z',
+      'updated':'2015-10-26T13:09:44.343Z',
+      'enacted':null,
+      'policed':null,
+      'backend_register':'{}',
+      'backend_status':'0 - Provisioning in progress',
+      'deleted':false,
+      'write_protect':false,
+      'lazy_blocked':false,
+      'no_sync':false,
+      'cdn_prefix_id':null,
+      'prefix':'onlab.vicci.org',
+      'contentProvider':'http://0.0.0.0:9000/hpcapi/contentproviders/1/',
+      'description':null,
+      'defaultOriginServer':'http://0.0.0.0:9000/hpcapi/originservers/2/',
+      'enabled':true
+    },
+    {
+      'humanReadableName':'downloads.onosproject.org',
+      'validators':{
+        'updated':[
+
+        ],
+        'contentProvider':[
+          'notBlank'
+        ],
+        'policed':[
+
+        ],
+        'created':[
+
+        ],
+        'deleted':[
+
+        ],
+        'description':[
+
+        ],
+        'enabled':[
+
+        ],
+        'cdn_prefix_id':[
+
+        ],
+        'lazy_blocked':[
+
+        ],
+        'backend_register':[
+          'notBlank'
+        ],
+        'write_protect':[
+
+        ],
+        'prefix':[
+          'notBlank'
+        ],
+        'defaultOriginServer':[
+
+        ],
+        'backend_status':[
+          'notBlank'
+        ],
+        'id':[
+
+        ],
+        'no_sync':[
+
+        ],
+        'enacted':[
+
+        ]
+      },
+      'id':1,
+      'created':'2015-10-26T13:09:44.196Z',
+      'updated':'2015-10-26T13:09:44.196Z',
+      'enacted':null,
+      'policed':null,
+      'backend_register':'{}',
+      'backend_status':'0 - Provisioning in progress',
+      'deleted':false,
+      'write_protect':false,
+      'lazy_blocked':false,
+      'no_sync':false,
+      'cdn_prefix_id':null,
+      'prefix':'downloads.onosproject.org',
+      'contentProvider':'http://0.0.0.0:9000/hpcapi/contentproviders/2/',
+      'description':null,
+      'defaultOriginServer':'http://0.0.0.0:9000/hpcapi/originservers/1/',
+      'enabled':true
+    }
   ]
 };
\ No newline at end of file
diff --git a/xos/core/xoslib/static/js/xosContentProvider.js b/xos/core/xoslib/static/js/xosContentProvider.js
index ff5bfe3..4b5677e 100644
--- a/xos/core/xoslib/static/js/xosContentProvider.js
+++ b/xos/core/xoslib/static/js/xosContentProvider.js
@@ -137,6 +137,10 @@
           };
         });
       }
+      else {
+        console.log('new');
+        _this.cp = new ContentProvider();
+      }
 
       ServiceProvider.query().$promise
       .then(function(sp) {
@@ -161,11 +165,11 @@
         else {
           isNew = true;
           cp.name = cp.humanReadableName;
-          p = new ContentProvider(cp).$save();
+          console.log('save');
+          p = cp.$save();
         }
 
         p.then(function(res) {
-          console.log('save done', res);
           _this.result = {
             status: 1,
             msg: 'Content Provider Saved'
@@ -188,6 +192,7 @@
   return{
     restrict: 'E',
     controllerAs: 'vm',
+    scope: {},
     templateUrl: '../../static/templates/contentProvider/cp_cdn_prefix.html',
     controller: function() {
       var _this = this;