blob: ce3e2cd4a5145bef14754324ce312452e6c5c897 [file] [log] [blame]
/*
* 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 'angular-resource';
import {IXosModelStoreService, XosModelStore} from './model.store';
import {Subject} from 'rxjs';
import {IWSEvent} from '../websocket/global';
import {StoreHelpers} from '../helpers/store.helpers';
import {ModelRest} from '../rest/model.rest';
import {ConfigHelpers} from '../../core/services/helpers/config.helpers';
import {AuthService} from '../rest/auth.rest';
import {XosDebouncer} from '../../core/services/helpers/debounce.helper';
import {IXosModeldefsCache} from '../helpers/modeldefs.service';
import {XosFormHelpers} from '../../core/form/form-helpers';
let service: IXosModelStoreService;
let httpBackend: ng.IHttpBackendService;
let $scope;
let WebSocket;
let XosModeldefsCache;
class MockWs {
private _list;
constructor() {
this._list = new Subject<IWSEvent>();
}
list() {
return this._list.asObservable();
}
next(event: IWSEvent) {
this._list.next(event);
}
}
const queryData = [
{id: 1, name: 'foo'},
{id: 2, name: 'bar'}
];
const MockAppCfg = {
apiEndpoint: 'http://xos-test:3000/api',
websocketClient: 'http://xos-test:3000'
};
describe('The ModelStore service', () => {
beforeEach(() => {
angular
.module('ModelStore', ['ngResource', 'toastr', 'ngCookies'])
.service('WebSocket', MockWs)
.service('StoreHelpers', StoreHelpers) // TODO mock
.service('ModelRest', ModelRest) // TODO mock
.service('XosModelStore', XosModelStore)
.service('ConfigHelpers', ConfigHelpers) // TODO mock
.service('AuthService', AuthService)
.service('XosFormHelpers', XosFormHelpers)
.constant('AppConfig', MockAppCfg)
.value('XosModeldefsCache', {
get: jasmine.createSpy('XosModeldefsCache.get').and.returnValue({}),
getApiUrlFromModel: jasmine.createSpy('XosModeldefsCache.getApiUrlFromModel')
})
.service('XosDebouncer', XosDebouncer);
angular.mock.module('ModelStore');
});
beforeEach(angular.mock.inject((
XosModelStore: IXosModelStoreService,
$httpBackend: ng.IHttpBackendService,
_$rootScope_: ng.IRootScopeService,
_WebSocket_: any,
_XosModeldefsCache_: IXosModeldefsCache
) => {
service = XosModelStore;
httpBackend = $httpBackend;
$scope = _$rootScope_;
WebSocket = _WebSocket_;
XosModeldefsCache = _XosModeldefsCache_;
// ModelRest will call the backend
httpBackend.whenGET(`${MockAppCfg.apiEndpoint}/core/samples`)
.respond(queryData);
}));
describe('the QUERY method', () => {
it('should return an Observable', () => {
expect(typeof service.query('test').subscribe).toBe('function');
});
it('the first event should be the resource response', (done) => {
XosModeldefsCache.getApiUrlFromModel.and.returnValue(`/core/samples`);
let event = 0;
service.query('sample')
.subscribe(collection => {
event++;
if (event === 2) {
expect(collection[0].id).toEqual(queryData[0].id);
expect(collection[1].id).toEqual(queryData[1].id);
done();
}
});
$scope.$apply();
httpBackend.flush();
});
});
describe('the GET method', () => {
it('should return an observable containing a single model', (done) => {
let event = 0;
XosModeldefsCache.getApiUrlFromModel.and.returnValue(`/core/samples`);
service.get('sample', queryData[1].id)
.subscribe((model) => {
event++;
if (event === 2) {
expect(model.id).toEqual(queryData[1].id);
expect(model.name).toEqual(queryData[1].name);
done();
}
});
httpBackend.flush();
$scope.$apply();
});
});
describe('when a web-socket event is received for that model', () => {
it('should update the collection', (done) => {
let event = 0;
service.query('sample')
.subscribe(
collection => {
event++;
if (event === 3) {
expect(collection[0].id).toEqual(queryData[0].id);
expect(collection[1].id).toEqual(queryData[1].id);
expect(collection[2].id).toEqual(3);
expect(collection[2].name).toEqual('baz');
done();
}
},
err => {
done(err);
}
);
window.setTimeout(() => {
WebSocket.next({
model: 'sample',
msg: {
changed_fields: ['id'],
object: {id: 3, name: 'baz'},
pk: 3
}
});
}, 1);
$scope.$apply();
httpBackend.flush();
});
});
describe('when multiple stores are requested', () => {
beforeEach(() => {
httpBackend.expectGET(`${MockAppCfg.apiEndpoint}/core/firsts`)
.respond([
{first: 'foo'}
]);
httpBackend.expectGET(`${MockAppCfg.apiEndpoint}/core/seconds`)
.respond([
{second: 'foo'}
]);
});
it('should create different Subject', (done) => {
let fevent = 0;
let sevent = 0;
XosModeldefsCache.get.and.callFake(v => v);
XosModeldefsCache.getApiUrlFromModel.and.callFake(v => `/core/${v}s`);
service.query('first')
.subscribe(first => {
fevent++;
if (fevent >= 2) {
service.query('second')
.subscribe(second => {
sevent++;
if (sevent === 2) {
expect(first).not.toEqual(second);
done();
}
});
}
});
$scope.$apply();
httpBackend.flush();
});
});
});