UNPKG

@eclipse-emfcloud/model-service-theia

Version:
303 lines 13.1 kB
"use strict"; // ***************************************************************************** // Copyright (C) 2023-2024 STMicroelectronics. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at // http://www.eclipse.org/legal/epl-2.0. // // This Source Code may also be made available under the following Secondary // Licenses when the conditions for such availability set forth in the Eclipse // Public License v. 2.0 are satisfied: MIT License which is // available at https://opensource.org/licenses/MIT. // // SPDX-License-Identifier: EPL-2.0 OR MIT // ***************************************************************************** var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.MockProvider = void 0; const model_manager_1 = require("@eclipse-emfcloud/model-manager"); const model_service_1 = require("@eclipse-emfcloud/model-service"); const inversify_1 = require("@theia/core/shared/inversify"); const chai_1 = require("chai"); const sinon_1 = __importDefault(require("sinon")); const common_1 = require("../../common"); const backend_module_1 = __importDefault(require("../backend-module")); const model_hub_provider_1 = require("../model-hub-provider"); const model_service_contribution_1 = require("../model-service-contribution"); const fake_json_rpc_1 = require("./fake-json-rpc"); const FAKE_MODEL_ID = 'test.fake-model'; function createTestContainer(contrib) { const container = new inversify_1.Container(); container.load(backend_module_1.default); container.bind(model_service_contribution_1.ModelServiceContribution).toConstantValue(contrib); (0, fake_json_rpc_1.bindFakeRpcConnectionFactory)(container); return container; } describe('Model Accessor Bus Server', () => { const appContext = 'test-app'; let sandbox; let modelAccessorBusServer; let fakeContribution; let clientProxy; beforeEach(async () => { sandbox = sinon_1.default.createSandbox(); fakeContribution = new FakeContribution(); const container = createTestContainer(fakeContribution); const factory = container.get(fake_json_rpc_1.RpcConnectionFactory); clientProxy = { onAccessorChanged: sandbox.stub(), closeSubscription: sandbox.stub(), }; modelAccessorBusServer = await factory.getServer(common_1.ModelAccessorBusProtocolServicePath, clientProxy); // Some tests need to start interacting with the model service // right away, so initialize the context's provided hub await container.get(model_hub_provider_1.ModelHubProvider)(appContext); }); afterEach(() => { sandbox.restore(); }); describe('getClient', async () => { beforeEach(() => { sandbox = sinon_1.default.createSandbox(); }); afterEach(() => { sandbox.restore(); }); it('expect not undefined', async () => { (0, chai_1.expect)(modelAccessorBusServer.getClient()).not.to.be.undefined; }); it('expect undefined', async () => { modelAccessorBusServer.setClient(undefined); (0, chai_1.expect)(modelAccessorBusServer.getClient()).to.be.undefined; }); it('expect specific client', async () => { const alternateProxy = { onAccessorChanged: sandbox.stub(), closeSubscription: sandbox.stub(), }; modelAccessorBusServer.setClient(alternateProxy); (0, chai_1.expect)(modelAccessorBusServer.getClient()).to.be.equal(alternateProxy); }); }); describe('setClient', async () => { beforeEach(() => { sandbox = sinon_1.default.createSandbox(); }); afterEach(() => { sandbox.restore(); }); it('expect undefined', async () => { modelAccessorBusServer.setClient(undefined); (0, chai_1.expect)(modelAccessorBusServer.getClient()).to.be.undefined; }); it('expect same client', async () => { modelAccessorBusServer.setClient(clientProxy); (0, chai_1.expect)(modelAccessorBusServer.getClient()).to.be.equal(clientProxy); }); it('expect client change with disposeSubscriptions', async () => { const alternateProxy = { onAccessorChanged: sandbox.stub(), closeSubscription: sandbox.stub(), }; (0, chai_1.expect)(await modelAccessorBusServer.subscribe(appContext, 'test')).to.be.eql({ id: 1, accessorId: 'test', }, 'Subscribe did not provide the expected result.'); modelAccessorBusServer.setClient(alternateProxy); (0, chai_1.expect)(modelAccessorBusServer.getClient()).to.be.equal(alternateProxy, 'Client does not match expected result'); }); }); describe('subscribe', async () => { beforeEach(() => { sandbox = sinon_1.default.createSandbox(); }); afterEach(() => { sandbox.restore(); }); it('no client', async () => { modelAccessorBusServer.setClient(undefined); (0, chai_1.expect)(await modelAccessorBusServer.subscribe(appContext, 'test')).to.be.eql({ id: 1, accessorId: 'test', }); }); it('expect subscription token', async () => { (0, chai_1.expect)(await modelAccessorBusServer.subscribe(appContext, 'test')).to.be.eql({ id: 1, accessorId: 'test', }); }); it('expect 2 different subscription token', async () => { (0, chai_1.expect)(await modelAccessorBusServer.subscribe(appContext, 'test1')).to.be.eql({ id: 1, accessorId: 'test1', }); (0, chai_1.expect)(await modelAccessorBusServer.subscribe(appContext, 'test2')).to.be.eql({ id: 2, accessorId: 'test2', }); }); }); describe('closeSubscription', async () => { beforeEach(() => { sandbox = sinon_1.default.createSandbox(); }); afterEach(() => { sandbox.restore(); }); it('execute closeSubscription with no subscription', async () => { (0, chai_1.expect)(() => modelAccessorBusServer.closeSubscription({ id: 1, accessorId: 'test', })).not.to.throw(); }); it('execute closeSubscription', async () => { const token = await modelAccessorBusServer.subscribe(appContext, 'test'); (0, chai_1.expect)(token).to.be.eql({ id: 1, accessorId: 'test', }, 'Subscribe did not provide the expected result.'); (0, chai_1.expect)(() => modelAccessorBusServer.closeSubscription(token)).not.to.throw(); }); it('execute dispose', async () => { const token = await modelAccessorBusServer.subscribe(appContext, 'test'); (0, chai_1.expect)(token).to.be.eql({ id: 1, accessorId: 'test', }, 'Subscribe did not provide the expected result.'); modelAccessorBusServer.dispose(); }); }); describe('get', async () => { it('expect undefined : existing context, not existing accessor', async () => { (0, chai_1.expect)(await modelAccessorBusServer.get(appContext, 'empty')).to.be .undefined; }); }); describe('trigger subscription', () => { it('expect subscription token', async () => { const providerChangeSubToken = await modelAccessorBusServer.subscribe(appContext, 'fake-provider.get'); const fakeService = fakeContribution.getModelService(); (0, chai_1.expect)(providerChangeSubToken).to.be.eql({ id: 1, accessorId: 'fake-provider.get', }, 'Subscription did not provide the expected result.'); await fakeService.setName('Fake Model 2'); (0, chai_1.expect)(clientProxy.onAccessorChanged.calledOnceWith(1)).to.be.true; }); }); describe('getModelAccessorBus', async () => { it('expect to be different on different contexts', async () => { const spiedAccessorBusAccess = sandbox.spy(modelAccessorBusServer); await Promise.all([ modelAccessorBusServer.get(appContext, 'empty'), modelAccessorBusServer.get(`${appContext}-2`, 'empty'), ]); (0, chai_1.expect)(spiedAccessorBusAccess.getModelAccessorBus.calledTwice).to.be.true; const bus_0 = await spiedAccessorBusAccess.getModelAccessorBus .returnValues[0]; const bus_1 = await spiedAccessorBusAccess.getModelAccessorBus .returnValues[1]; (0, chai_1.expect)(bus_0 !== bus_1).to.be.true; }); it('expect to be same for same contexts', async () => { const spiedAccessorBusAccess = sandbox.spy(modelAccessorBusServer); await Promise.all([ modelAccessorBusServer.get(appContext, 'empty'), modelAccessorBusServer.get(appContext, 'empty'), ]); (0, chai_1.expect)(spiedAccessorBusAccess.getModelAccessorBus.calledTwice).to.be.true; const bus_0 = await spiedAccessorBusAccess.getModelAccessorBus .returnValues[0]; const bus_1 = await spiedAccessorBusAccess.getModelAccessorBus .returnValues[1]; (0, chai_1.expect)(bus_0 === bus_1).to.be.true; }); }); }); class MockProvider extends model_service_1.HubAwareProvider { constructor() { super('fake-provider'); this.getId = this.getId.bind(this); this.accessors.set('get', this.getId); } setModelHub(modelHub) { super.setModelHub(modelHub); const subscription = modelHub.subscribe(FAKE_MODEL_ID); subscription.onModelChanged = (_modelId, _model, delta) => { if (delta?.some((op) => op.path === '/name')) { this.notify('get'); } }; } getId() { return this.id; } } exports.MockProvider = MockProvider; const mockProvider = new MockProvider(); class FakeContribution extends model_service_1.AbstractModelServiceContribution { getModelService() { return this.modelService; } setModelManager(modelManager) { super.setModelManager(modelManager); this.commandStack = modelManager.getCommandStack(FAKE_MODEL_ID); } constructor() { super(); this.model = { name: 'Fake Model 1', }; this.modelService = { getModel: () => { let model = this.modelManager.getModel(FAKE_MODEL_ID); if (!model) { this.modelManager.setModel(FAKE_MODEL_ID, this.model); model = this.modelManager.getModel(FAKE_MODEL_ID); } if (!model) { throw new Error('No model to edit'); } return model; }, setName: async (newName) => { this.modelService.getModel(); // Ensure the model is loaded const command = createSetNameCommand(FAKE_MODEL_ID, newName); await this.commandStack.execute(command); }, }; this.initialize({ id: 'test.contrib1', persistenceContribution: { canHandle: (modelId) => Promise.resolve(modelId === FAKE_MODEL_ID), loadModel: (modelId) => modelId === FAKE_MODEL_ID ? Promise.resolve(this.model) : Promise.reject(new Error(`No such model: ${modelId}`)), saveModel: async (modelId, model) => { if (modelId !== FAKE_MODEL_ID) { throw new Error(`Unsupported model ${modelId}`); } const newImage = { ...model }; Array.from(Object.keys(this.model)).forEach((key) => delete this.model[key]); Object.assign(this.model, newImage); return true; }, }, modelAccessorContribution: { getProviders() { return [mockProvider]; }, }, }); } } function createSetNameCommand(modelId, newName) { return (0, model_manager_1.createModelUpdaterCommand)('Set Name', modelId, (model) => { model.name = newName; }); } //# sourceMappingURL=model-accessor-bus-server.spec.js.map