Skip to content

Commit

Permalink
fix: unregister a capability by its type and qualifier instead of its id
Browse files Browse the repository at this point in the history
fixes: #199
  • Loading branch information
mofogasy authored and danielwiehl committed Nov 11, 2019

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent 0996a22 commit 6044823
Showing 7 changed files with 57 additions and 67 deletions.
Original file line number Diff line number Diff line change
@@ -7,11 +7,6 @@ <h2>Properties</h2>
<sci-property [properties]="capability.properties"></sci-property>
</section>

<section class="metadata" *ngIf="capability.metadata">
<h2>Metadata</h2>
<sci-property [properties]="capability.metadata"></sci-property>
</section>

<section class="used-by">
<h2>Used by following applications</h2>
<ul>
Original file line number Diff line number Diff line change
@@ -36,7 +36,7 @@
}
}

&.has-properties {
&:not(.has-properties) {
> section.used-by {
grid-column: 1/-1;
}
Original file line number Diff line number Diff line change
@@ -105,15 +105,16 @@ export namespace ManifestRegistryIntentMessages {
}

/**
* Unregisters capability of given id.
* Unregisters capability of given type and qualifier.
*
* The requesting application can only unregister its own capabilities.
*/
export interface UnregisterCapability extends IntentMessage {
type: PlatformCapabilityTypes.ManifestRegistry;
payload: {
command: ManifestCommands.UnregisterCapability;
capabilityId: string;
type: string;
qualifier: Qualifier;
};
}
}
Original file line number Diff line number Diff line change
@@ -118,7 +118,7 @@ export class ManifestRegistry {
}

capabilities.forEach(it => {
if (it.hasOwnProperty('*')) {
if (it.qualifier && it.qualifier.hasOwnProperty('*')) {
throw Error(`[CapabilityRegistrationError] Capability qualifiers do not support \`*\` as key`);
}

@@ -141,25 +141,29 @@ export class ManifestRegistry {
}

/**
* Unregisters capability of the given application.
* Unregisters capabilities of given application which have the given type and qualifier.
*/
public unregisterCapability(symbolicName: string, capabilityId: string): void {
const capabilityToUnregister = this.getCapability(capabilityId);
public unregisterCapability(symbolicName: string, type: string, qualifier: Qualifier): void {
const capabilitiesToUnregister = this.getCapabilitiesByApplication(symbolicName)
.filter(it => it.type === type && isEqualQualifier(it.qualifier, qualifier));

if (!capabilityToUnregister) {
throw Error(`[CapabilityUnregistrationError] Capability does not exist [id=${capabilityId}]`);
}

if (capabilityToUnregister.metadata.symbolicAppName !== symbolicName) {
throw Error(`[CapabilityUnregistrationError] Capability cannot be unregistered by this application [id=${capabilityId}, appName=${symbolicName}]`);
if (!capabilitiesToUnregister.length) {
return;
}

const registeredCapabilities = this._capabilitiesByType.get(capabilityToUnregister.type);
this._capabilitiesById.delete(capabilityId);
this._capabilitiesByType.set(capabilityToUnregister.type, registeredCapabilities.filter(capability => capability.metadata.id !== capabilityId));
capabilitiesToUnregister.forEach(capabilityToUnregister => {
this._capabilitiesById.delete(capabilityToUnregister.metadata.id);
const capabilities = this._capabilitiesByType.get(capabilityToUnregister.type).filter(it => it.metadata.id !== capabilityToUnregister.metadata.id);
if (capabilities.length) {
this._capabilitiesByType.set(capabilityToUnregister.type, capabilities);
}
else {
this._capabilitiesByType.delete(capabilityToUnregister.type);
}
});

// Unregister implicit intent.
this.unregisterImplicitIntents(symbolicName, capabilityToUnregister.type, capabilityToUnregister.qualifier);
// Unregister implicit intents.
this.unregisterImplicitIntents(symbolicName, type, qualifier);
}

/**
Original file line number Diff line number Diff line change
@@ -175,14 +175,15 @@ export class ManifestRegistryIntentHandler implements IntentHandler {
}

/**
* Unregisters capability of given id.
* Unregisters capability of given type and qualifier.
*
* The requesting application can only unregister its own capabilities.
*/
private unregisterCapability(envelope: MessageEnvelope<ManifestRegistryIntentMessages.UnregisterCapability>): void {
const capabilityId: string = envelope.message.payload.capabilityId;
const type: string = envelope.message.payload.type;
const qualifier: Qualifier = envelope.message.payload.qualifier;
try {
this._manifestRegistry.unregisterCapability(envelope.sender, capabilityId);
this._manifestRegistry.unregisterCapability(envelope.sender, type, qualifier);
this._messageBus.publishReply({status: 'ok'}, envelope.sender, envelope.replyToUid);
}
catch (error) {
Original file line number Diff line number Diff line change
@@ -277,17 +277,16 @@ describe('ManifestRegistry', () => {

describe('function \'unregisterCapability(...)\'', () => {

it('should unregister capability of given id and its implicit intent', fakeAsync(inject([ManifestRegistry], (manifestRegistry: ManifestRegistry) => {
it('should unregister capability and its implicit intent', fakeAsync(inject([ManifestRegistry], (manifestRegistry: ManifestRegistry) => {
const type = PlatformCapabilityTypes.View;
const qualifier1: Qualifier = {entity: 'entity', qualifier: 1};
const qualifier2: Qualifier = {entity: 'entity', qualifier: 2};
const qualifier1: Qualifier = {entity: 'entity', id: 1};
const qualifier2: Qualifier = {entity: 'entity', id: 2};
const qualifier3: Qualifier = {entity: '?'};
manifestRegistry.registerCapability('app-1', [{type, qualifier: qualifier1, private: false}]);
manifestRegistry.registerCapability('app-1', [{type, qualifier: qualifier2, private: false}]);
manifestRegistry.registerCapability('app-1', [{type, qualifier: qualifier3, private: false}]);
const capability = manifestRegistry.getCapabilities(type, qualifier2)[0];

manifestRegistry.unregisterCapability('app-1', capability.metadata.id);
manifestRegistry.unregisterCapability('app-1', type, qualifier2);
expect(manifestRegistry.getCapabilitiesByApplication('app-1').length).toBe(2);
expect(manifestRegistry.getCapabilitiesByType(type).length).toBe(2);
expect(manifestRegistry.getCapabilities(type, qualifier1).length).toBe(1);
@@ -298,59 +297,48 @@ describe('ManifestRegistry', () => {
expect(manifestRegistry.hasIntent('app-1', type, qualifier3)).toBeTruthy();
})));

it('should unregister capability of given id and its implicit intent, but not the implicit intents of wildcard (*) capabilities', fakeAsync(inject([ManifestRegistry], (manifestRegistry: ManifestRegistry) => {
it('should unregister all capabilities and implicit intents for capabilities having equal qualifier', fakeAsync(inject([ManifestRegistry], (manifestRegistry: ManifestRegistry) => {
const type = PlatformCapabilityTypes.View;
const qualifier1: Qualifier = {entity: 'entity', qualifier: 1};
const qualifier2: Qualifier = {entity: '*', qualifier: '*'}; // implicit intent of this capability should not be unregistered
const qualifier1: Qualifier = {entity: 'entity', id: '*'};
const qualifier2: Qualifier = {entity: 'entity', id: '*'};
manifestRegistry.registerCapability('app-1', [{type, qualifier: qualifier1, private: false}]);
manifestRegistry.registerCapability('app-1', [{type, qualifier: qualifier2, private: false}]);
const capability = manifestRegistry.getCapabilities(type, qualifier1)[0];

manifestRegistry.unregisterCapability('app-1', capability.metadata.id);
expect(manifestRegistry.getCapabilitiesByApplication('app-1').length).toBe(1);
expect(manifestRegistry.getCapabilitiesByType(type).length).toBe(1);
expect(manifestRegistry.getIntentsByApplication('app-1').length).toBe(1);
expect(manifestRegistry.getIntentsByApplication('app-1')[0].qualifier).toEqual(qualifier2);
manifestRegistry.unregisterCapability('app-1', type, qualifier1);
expect(manifestRegistry.getCapabilitiesByApplication('app-1').length).toBe(0);
expect(manifestRegistry.getCapabilitiesByType(type).length).toBe(0);
expect(manifestRegistry.getCapabilities(type, qualifier1).length).toBe(0);
expect(manifestRegistry.getCapabilities(type, qualifier2).length).toBe(0);
expect(manifestRegistry.hasIntent('app-1', type, qualifier1)).toBeFalsy();
expect(manifestRegistry.hasIntent('app-1', type, qualifier2)).toBeFalsy();
})));

it('should unregister capability of given id and its implicit intent, but not the implicit intents of wildcard (?) capabilities', fakeAsync(inject([ManifestRegistry], (manifestRegistry: ManifestRegistry) => {
it('should unregister capability and its implicit intent, but not the implicit intents of wildcard (*) capabilities', fakeAsync(inject([ManifestRegistry], (manifestRegistry: ManifestRegistry) => {
const type = PlatformCapabilityTypes.View;
const qualifier1: Qualifier = {entity: 'entity', qualifier: 1};
const qualifier2: Qualifier = {entity: '?', qualifier: '?'}; // implicit intent of this capability should not be unregistered
const qualifier1: Qualifier = {entity: 'entity', id: 1};
const qualifier2: Qualifier = {entity: '*', id: '*'}; // implicit intent of this capability should not be unregistered
manifestRegistry.registerCapability('app-1', [{type, qualifier: qualifier1, private: false}]);
manifestRegistry.registerCapability('app-1', [{type, qualifier: qualifier2, private: false}]);
const capability = manifestRegistry.getCapabilities(type, qualifier1)[0];

manifestRegistry.unregisterCapability('app-1', capability.metadata.id);
manifestRegistry.unregisterCapability('app-1', type, qualifier1);
expect(manifestRegistry.getCapabilitiesByApplication('app-1').length).toBe(1);
expect(manifestRegistry.getCapabilitiesByType(type).length).toBe(1);
expect(manifestRegistry.getIntentsByApplication('app-1').length).toBe(1);
expect(manifestRegistry.getIntentsByApplication('app-1')[0].qualifier).toEqual(qualifier2);
})));

it('should throw exception for nonexistent capability', fakeAsync(inject([ManifestRegistry], (manifestRegistry: ManifestRegistry) => {
const type = PlatformCapabilityTypes.View;
const qualifier: Qualifier = {entity: 'entity'};
manifestRegistry.registerCapability('app-1', [{type, qualifier, private: false}]);

expect(() => manifestRegistry.unregisterCapability('app-1', 'nonexistent_id')).toThrowError(/CapabilityUnregistrationError/);
expect(manifestRegistry.getCapabilitiesByApplication('app-1').length).toBe(1);
expect(manifestRegistry.getCapabilitiesByType(type).length).toBe(1);
expect(manifestRegistry.getCapabilities(type, qualifier).length).toBe(1);
expect(manifestRegistry.hasIntent('app-1', type, qualifier)).toBeTruthy();
})));

it('should throw exception for capability of other application', fakeAsync(inject([ManifestRegistry], (manifestRegistry: ManifestRegistry) => {
it('should unregister capability and its implicit intent, but not the implicit intents of wildcard (?) capabilities', fakeAsync(inject([ManifestRegistry], (manifestRegistry: ManifestRegistry) => {
const type = PlatformCapabilityTypes.View;
const qualifier: Qualifier = {entity: 'entity'};
manifestRegistry.registerCapability('app-1', [{type, qualifier, private: false}]);
const capability = manifestRegistry.getCapabilities(type, qualifier)[0];
const qualifier1: Qualifier = {entity: 'entity', id: 1};
const qualifier2: Qualifier = {entity: '?', id: '?'}; // implicit intent of this capability should not be unregistered
manifestRegistry.registerCapability('app-1', [{type, qualifier: qualifier1, private: false}]);
manifestRegistry.registerCapability('app-1', [{type, qualifier: qualifier2, private: false}]);

expect(() => manifestRegistry.unregisterCapability('app-2', capability.metadata.id)).toThrowError(/CapabilityUnregistrationError/);
manifestRegistry.unregisterCapability('app-1', type, qualifier1);
expect(manifestRegistry.getCapabilitiesByApplication('app-1').length).toBe(1);
expect(manifestRegistry.getCapabilitiesByType(type).length).toBe(1);
expect(manifestRegistry.getCapabilities(type, qualifier).length).toBe(1);
expect(manifestRegistry.hasIntent('app-1', type, qualifier)).toBeTruthy();
expect(manifestRegistry.getIntentsByApplication('app-1').length).toBe(1);
expect(manifestRegistry.getIntentsByApplication('app-1')[0].qualifier).toEqual(qualifier2);
})));
});
});
Original file line number Diff line number Diff line change
@@ -147,17 +147,18 @@ export class ManifestRegistryService implements Service {
}

/**
* Unregisters capability of given id.
* Unregisters capability of given type and qualifier.
*
* The requesting application can only unregister its own capabilities.
*/
public unregisterCapability$(capabilityId: string): Observable<void> {
public unregisterCapability$(type: string, qualifier: Qualifier): Observable<void> {
const intentMessage: ManifestRegistryIntentMessages.UnregisterCapability = {
type: PlatformCapabilityTypes.ManifestRegistry,
qualifier: NilQualifier,
payload: {
command: ManifestCommands.UnregisterCapability,
capabilityId: capabilityId,
type: type,
qualifier: qualifier,
},
};

0 comments on commit 6044823

Please sign in to comment.