From d2de563c139655c9301fe7f45be1448d83576de1 Mon Sep 17 00:00:00 2001 From: Milena Czierlinski <146972016+Milena-Czierlinski@users.noreply.github.com> Date: Wed, 23 Oct 2024 16:34:26 +0200 Subject: [PATCH] Update ThirdPartyRelationshipAttribute nomenclature (#304) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: remove ThirdPartyOwnedRelationship and add ThirdPartyRelationshipAttribute to LocalAttribute * feat: replace ThirdPartyOwnedRA deletion by ThirdPartyRA deletion * feat: replace third party owned succession by ThirdPartyRA succession * feat: adjust tests * refactor: use wording emitted instead of own shared * fix: rebasing * feat: clean up PR * feat: re-add deprecated ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItem for backwards-campatibility * feat: re-add runtime ThirdPartyOwnedRelationshipAttributeDeletedByPeerEvent for backwards-compatibility * feat: simplify deprecation of ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItem * feat: re-add deprecated deleteThirdPartyOwnedRelationshipAttributeAndNotifyPeer for backwards-compatibility * feat: integrate comments * refactor: ThirdPartyRelationshipAttributeDeletedByPeerNotificationItem test --------- Co-authored-by: Julian König <33655937+jkoenig134@users.noreply.github.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- .../src/consumption/ConsumptionController.ts | 6 +- .../src/consumption/ConsumptionCoreErrors.ts | 27 +++-- .../attributes/AttributesController.ts | 22 ++-- ...RelationshipAttributeDeletedByPeerEvent.ts | 10 -- ...wnedRelationshipAttributeSucceededEvent.ts | 11 -- ...RelationshipAttributeDeletedByPeerEvent.ts | 10 ++ ...artyRelationshipAttributeSucceededEvent.ts | 11 ++ .../src/modules/attributes/events/index.ts | 4 +- .../attributes/local/LocalAttribute.ts | 59 +++------- .../src/modules/notifications/index.ts | 2 +- ...DeletedByPeerNotificationItemProcessor.ts} | 22 ++-- .../ReadAttributeRequestItemProcessor.ts | 26 +---- .../attributes/AttributesController.test.ts | 4 +- .../LocalAttributeDeletionInfo.test.ts | 49 ++++---- ...edByPeerNotificationItemProcessor.test.ts} | 40 +++---- .../ReadAttributeRequestItemProcessor.test.ts | 2 +- ...pAttributeDeletedByPeerNotificationItem.ts | 28 ----- ...pAttributeDeletedByPeerNotificationItem.ts | 27 +++++ .../content/src/notifications/items/index.ts | 2 +- ...ibuteDeletedByPeerNotificationItem.test.ts | 14 +++ packages/runtime/src/events/EventProxy.ts | 15 ++- ...RelationshipAttributeDeletedByPeerEvent.ts | 3 + ...RelationshipAttributeDeletedByPeerEvent.ts | 10 ++ ...artyRelationshipAttributeSucceededEvent.ts | 10 ++ .../runtime/src/events/consumption/index.ts | 2 + .../facades/consumption/AttributesFacade.ts | 23 ++-- .../src/useCases/common/RuntimeErrors.ts | 6 +- .../runtime/src/useCases/common/Schemas.ts | 104 ++++++++--------- ...artyRelationshipAttributeAndNotifyPeer.ts} | 38 +++---- .../useCases/consumption/attributes/index.ts | 4 +- .../test/consumption/attributes.test.ts | 106 ++++++++++-------- 31 files changed, 365 insertions(+), 332 deletions(-) delete mode 100644 packages/consumption/src/modules/attributes/events/ThirdPartyOwnedRelationshipAttributeDeletedByPeerEvent.ts delete mode 100644 packages/consumption/src/modules/attributes/events/ThirdPartyOwnedRelationshipAttributeSucceededEvent.ts create mode 100644 packages/consumption/src/modules/attributes/events/ThirdPartyRelationshipAttributeDeletedByPeerEvent.ts create mode 100644 packages/consumption/src/modules/attributes/events/ThirdPartyRelationshipAttributeSucceededEvent.ts rename packages/consumption/src/modules/notifications/itemProcessors/attributeDeleted/{ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItemProcessor.ts => ThirdPartyRelationshipAttributeDeletedByPeerNotificationItemProcessor.ts} (71%) rename packages/consumption/test/modules/notifications/itemProcessors/attributeDeleted/{ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItemProcessor.test.ts => ThirdPartyRelationshipAttributeDeletedByPeerNotificationItemProcessor.test.ts} (78%) delete mode 100644 packages/content/src/notifications/items/ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItem.ts create mode 100644 packages/content/src/notifications/items/ThirdPartyRelationshipAttributeDeletedByPeerNotificationItem.ts create mode 100644 packages/content/test/notifications/ThirdPartyRelationshipAttributeDeletedByPeerNotificationItem.test.ts create mode 100644 packages/runtime/src/events/consumption/ThirdPartyRelationshipAttributeDeletedByPeerEvent.ts create mode 100644 packages/runtime/src/events/consumption/ThirdPartyRelationshipAttributeSucceededEvent.ts rename packages/runtime/src/useCases/consumption/attributes/{DeleteThirdPartyOwnedRelationshipAttributeAndNotifyPeer.ts => DeleteThirdPartyRelationshipAttributeAndNotifyPeer.ts} (50%) diff --git a/packages/consumption/src/consumption/ConsumptionController.ts b/packages/consumption/src/consumption/ConsumptionController.ts index c215914d7..56e94ce7e 100644 --- a/packages/consumption/src/consumption/ConsumptionController.ts +++ b/packages/consumption/src/consumption/ConsumptionController.ts @@ -11,7 +11,7 @@ import { ReadAttributeRequestItem, RegisterAttributeListenerRequestItem, ShareAttributeRequestItem, - ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItem + ThirdPartyRelationshipAttributeDeletedByPeerNotificationItem } from "@nmshd/content"; import { CoreAddress, CoreId } from "@nmshd/core-types"; import { AccountController, Transport } from "@nmshd/transport"; @@ -41,7 +41,7 @@ import { RequestItemProcessorRegistry, SettingsController, ShareAttributeRequestItemProcessor, - ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItemProcessor + ThirdPartyRelationshipAttributeDeletedByPeerNotificationItemProcessor } from "../modules"; import { ConsumptionConfig } from "./ConsumptionConfig"; @@ -168,7 +168,7 @@ export class ConsumptionController { [PeerSharedAttributeSucceededNotificationItem, PeerSharedAttributeSucceededNotificationItemProcessor], [OwnSharedAttributeDeletedByOwnerNotificationItem, OwnSharedAttributeDeletedByOwnerNotificationItemProcessor], [PeerSharedAttributeDeletedByPeerNotificationItem, PeerSharedAttributeDeletedByPeerNotificationItemProcessor], - [ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItem, ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItemProcessor] + [ThirdPartyRelationshipAttributeDeletedByPeerNotificationItem, ThirdPartyRelationshipAttributeDeletedByPeerNotificationItemProcessor] ]); } diff --git a/packages/consumption/src/consumption/ConsumptionCoreErrors.ts b/packages/consumption/src/consumption/ConsumptionCoreErrors.ts index 87582bba6..68737cab4 100644 --- a/packages/consumption/src/consumption/ConsumptionCoreErrors.ts +++ b/packages/consumption/src/consumption/ConsumptionCoreErrors.ts @@ -92,8 +92,8 @@ class Attributes { return new CoreError("error.consumption.attributes.predecessorIsNotPeerSharedRelationshipAttribute", "Predecessor is not a peer shared RelationshipAttribute."); } - public predecessorIsNotThirdPartyOwnedRelationshipAttribute() { - return new CoreError("error.consumption.attributes.predecessorIsNotThirdPartyOwnedRelationshipAttribute", "Predecessor is not a third party owned RelationshipAttribute."); + public predecessorIsNotThirdPartyRelationshipAttribute() { + return new CoreError("error.consumption.attributes.predecessorIsNotThirdPartyRelationshipAttribute", "Predecessor is not a ThirdPartyRelationshipAttribute."); } public successorIsNotRepositoryAttribute() { @@ -116,8 +116,8 @@ class Attributes { return new CoreError("error.consumption.attributes.successorIsNotPeerSharedRelationshipAttribute", "Successor is not a peer shared RelationshipAttribute."); } - public successorIsNotThirdPartyOwnedRelationshipAttribute() { - return new CoreError("error.consumption.attributes.successorIsNotThirdPartyOwnedRelationshipAttribute", "Successor is not a third party owned RelationshipAttribute."); + public successorIsNotThirdPartyRelationshipAttribute() { + return new CoreError("error.consumption.attributes.successorIsNotThirdPartyRelationshipAttribute", "Successor is not a ThirdPartyRelationshipAttribute."); } public setPredecessorIdDoesNotMatchActualPredecessorId() { @@ -170,6 +170,12 @@ class Attributes { return new CoreError("error.consumption.attributes.successionMustNotChangePeer", errorMessage); } + public successionMustNotChangeThirdParty(comment?: string) { + let errorMessage = "The thirdPartyAddress of the shared Attribute must not change."; + if (comment) errorMessage += ` ${comment}`; + return new CoreError("error.consumption.attributes.successionMustNotChangeThirdParty", errorMessage); + } + public cannotSucceedAttributesWithASuccessor(successorId: string | CoreId) { return new CoreError( "error.consumption.attributes.cannotSucceedAttributesWithASuccessor", @@ -209,10 +215,10 @@ class Attributes { ); } - public invalidDeletionInfoOfThirdPartyOwnedRelationshipAttribute() { + public invalidDeletionInfoOfThirdPartyRelationshipAttribute() { return new CoreError( - "error.consumption.attributes.invalidDeletionInfoOfThirdPartyOwnedRelationshipAttribute", - "The only valid deletionStatus for third party owned RelationshipAttributes is 'DeletedByPeer'." + "error.consumption.attributes.invalidDeletionInfoOfThirdPartyRelationshipAttribute", + "The only valid deletionStatus for ThirdPartyRelationshipAttributes is 'DeletedByPeer'." ); } @@ -239,11 +245,8 @@ class Attributes { return new CoreError("error.consumption.attributes.isNotPeerSharedAttribute", `The Attribute (id: '${attributeId}') is not a peer shared Attribute.`); } - public isNotThirdPartyOwnedRelationshipAttribute(attributeId: string | CoreId) { - return new CoreError( - "error.consumption.attributes.isNotThirdPartyOwnedRelationshipAttribute", - `The Attribute (id: '${attributeId}') is not a third party owned RelationshipAttribute.` - ); + public isNotThirdPartyRelationshipAttribute(attributeId: string | CoreId) { + return new CoreError("error.consumption.attributes.isNotThirdPartyRelationshipAttribute", `The Attribute (id: '${attributeId}') is not a ThirdPartyRelationshipAttribute.`); } public senderIsNotPeerOfSharedAttribute(senderId: string | CoreAddress, attributeId: string | CoreId) { diff --git a/packages/consumption/src/modules/attributes/AttributesController.ts b/packages/consumption/src/modules/attributes/AttributesController.ts index 27e4dd2b4..356f24d48 100644 --- a/packages/consumption/src/modules/attributes/AttributesController.ts +++ b/packages/consumption/src/modules/attributes/AttributesController.ts @@ -32,7 +32,7 @@ import { OwnSharedAttributeSucceededEvent, RepositoryAttributeSucceededEvent, SharedAttributeCopyCreatedEvent, - ThirdPartyOwnedRelationshipAttributeSucceededEvent + ThirdPartyRelationshipAttributeSucceededEvent } from "./events"; import { AttributeSuccessorParams, AttributeSuccessorParamsJSON, IAttributeSuccessorParams } from "./local/AttributeSuccessorParams"; import { CreateRepositoryAttributeParams, ICreateRepositoryAttributeParams } from "./local/CreateRepositoryAttributeParams"; @@ -535,7 +535,7 @@ export class AttributesController extends ConsumptionBaseController { return { predecessor, successor }; } - public async succeedThirdPartyOwnedRelationshipAttribute( + public async succeedThirdPartyRelationshipAttribute( predecessorId: CoreId, successorParams: IAttributeSuccessorParams | AttributeSuccessorParamsJSON, validate = true @@ -543,7 +543,7 @@ export class AttributesController extends ConsumptionBaseController { const parsedSuccessorParams = AttributeSuccessorParams.from(successorParams); if (validate) { - const validationResult = await this.validateThirdPartyOwnedRelationshipAttributeSuccession(predecessorId, parsedSuccessorParams); + const validationResult = await this.validateThirdPartyRelationshipAttributeSuccession(predecessorId, parsedSuccessorParams); if (validationResult.isError()) { throw validationResult.error; } @@ -559,7 +559,7 @@ export class AttributesController extends ConsumptionBaseController { succeededBy: parsedSuccessorParams.succeededBy }); - this.eventBus.publish(new ThirdPartyOwnedRelationshipAttributeSucceededEvent(this.identity.address.toString(), predecessor, successor)); + this.eventBus.publish(new ThirdPartyRelationshipAttributeSucceededEvent(this.identity.address.toString(), predecessor, successor)); return { predecessor, successor }; } @@ -887,7 +887,7 @@ export class AttributesController extends ConsumptionBaseController { return ValidationResult.success(); } - public async validateThirdPartyOwnedRelationshipAttributeSuccession( + public async validateThirdPartyRelationshipAttributeSuccession( predecessorId: CoreId, successorParams: IAttributeSuccessorParams | AttributeSuccessorParamsJSON ): Promise { @@ -912,12 +912,12 @@ export class AttributesController extends ConsumptionBaseController { parentId: parsedSuccessorParams.parentId }); - if (!predecessor.isThirdPartyOwnedRelationshipAttribute(this.identity.address)) { - return ValidationResult.error(ConsumptionCoreErrors.attributes.predecessorIsNotThirdPartyOwnedRelationshipAttribute()); + if (!predecessor.isThirdPartyRelationshipAttribute()) { + return ValidationResult.error(ConsumptionCoreErrors.attributes.predecessorIsNotThirdPartyRelationshipAttribute()); } - if (!successor.isThirdPartyOwnedRelationshipAttribute(this.identity.address)) { - return ValidationResult.error(ConsumptionCoreErrors.attributes.successorIsNotThirdPartyOwnedRelationshipAttribute()); + if (!successor.isThirdPartyRelationshipAttribute()) { + return ValidationResult.error(ConsumptionCoreErrors.attributes.successorIsNotThirdPartyRelationshipAttribute()); } if (successor.content.key !== predecessor.content.key) { @@ -928,6 +928,10 @@ export class AttributesController extends ConsumptionBaseController { return ValidationResult.error(ConsumptionCoreErrors.attributes.successionMustNotChangePeer()); } + if (!predecessor.shareInfo.thirdPartyAddress.equals(successor.shareInfo.thirdPartyAddress)) { + return ValidationResult.error(ConsumptionCoreErrors.attributes.successionMustNotChangeThirdParty()); + } + return ValidationResult.success(); } diff --git a/packages/consumption/src/modules/attributes/events/ThirdPartyOwnedRelationshipAttributeDeletedByPeerEvent.ts b/packages/consumption/src/modules/attributes/events/ThirdPartyOwnedRelationshipAttributeDeletedByPeerEvent.ts deleted file mode 100644 index af14ad658..000000000 --- a/packages/consumption/src/modules/attributes/events/ThirdPartyOwnedRelationshipAttributeDeletedByPeerEvent.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { TransportDataEvent } from "@nmshd/transport"; -import { LocalAttribute } from "../local/LocalAttribute"; - -export class ThirdPartyOwnedRelationshipAttributeDeletedByPeerEvent extends TransportDataEvent { - public static readonly namespace = "consumption.thirdPartyOwnedRelationshipAttributeDeletedByPeer"; - - public constructor(eventTargetAddress: string, data: LocalAttribute) { - super(ThirdPartyOwnedRelationshipAttributeDeletedByPeerEvent.namespace, eventTargetAddress, data); - } -} diff --git a/packages/consumption/src/modules/attributes/events/ThirdPartyOwnedRelationshipAttributeSucceededEvent.ts b/packages/consumption/src/modules/attributes/events/ThirdPartyOwnedRelationshipAttributeSucceededEvent.ts deleted file mode 100644 index fe5fe03f3..000000000 --- a/packages/consumption/src/modules/attributes/events/ThirdPartyOwnedRelationshipAttributeSucceededEvent.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { TransportDataEvent } from "@nmshd/transport"; -import { LocalAttribute } from "../local/LocalAttribute"; -import { AttributeSucceededEventData } from "./AttributeSucceededEventData"; - -export class ThirdPartyOwnedRelationshipAttributeSucceededEvent extends TransportDataEvent { - public static readonly namespace = "consumption.thirdPartyOwnedRelationshipAttributeSucceded"; - - public constructor(eventTargetAddress: string, predecessor: LocalAttribute, successor: LocalAttribute) { - super(ThirdPartyOwnedRelationshipAttributeSucceededEvent.namespace, eventTargetAddress, { predecessor, successor }); - } -} diff --git a/packages/consumption/src/modules/attributes/events/ThirdPartyRelationshipAttributeDeletedByPeerEvent.ts b/packages/consumption/src/modules/attributes/events/ThirdPartyRelationshipAttributeDeletedByPeerEvent.ts new file mode 100644 index 000000000..aa8416c93 --- /dev/null +++ b/packages/consumption/src/modules/attributes/events/ThirdPartyRelationshipAttributeDeletedByPeerEvent.ts @@ -0,0 +1,10 @@ +import { TransportDataEvent } from "@nmshd/transport"; +import { LocalAttribute } from "../local/LocalAttribute"; + +export class ThirdPartyRelationshipAttributeDeletedByPeerEvent extends TransportDataEvent { + public static readonly namespace = "consumption.thirdPartyRelationshipAttributeDeletedByPeer"; + + public constructor(eventTargetAddress: string, data: LocalAttribute) { + super(ThirdPartyRelationshipAttributeDeletedByPeerEvent.namespace, eventTargetAddress, data); + } +} diff --git a/packages/consumption/src/modules/attributes/events/ThirdPartyRelationshipAttributeSucceededEvent.ts b/packages/consumption/src/modules/attributes/events/ThirdPartyRelationshipAttributeSucceededEvent.ts new file mode 100644 index 000000000..70d0de965 --- /dev/null +++ b/packages/consumption/src/modules/attributes/events/ThirdPartyRelationshipAttributeSucceededEvent.ts @@ -0,0 +1,11 @@ +import { TransportDataEvent } from "@nmshd/transport"; +import { LocalAttribute } from "../local/LocalAttribute"; +import { AttributeSucceededEventData } from "./AttributeSucceededEventData"; + +export class ThirdPartyRelationshipAttributeSucceededEvent extends TransportDataEvent { + public static readonly namespace = "consumption.thirdPartyRelationshipAttributeSucceeded"; + + public constructor(eventTargetAddress: string, predecessor: LocalAttribute, successor: LocalAttribute) { + super(ThirdPartyRelationshipAttributeSucceededEvent.namespace, eventTargetAddress, { predecessor, successor }); + } +} diff --git a/packages/consumption/src/modules/attributes/events/index.ts b/packages/consumption/src/modules/attributes/events/index.ts index 1a477153e..94100392a 100644 --- a/packages/consumption/src/modules/attributes/events/index.ts +++ b/packages/consumption/src/modules/attributes/events/index.ts @@ -7,5 +7,5 @@ export * from "./PeerSharedAttributeDeletedByPeerEvent"; export * from "./PeerSharedAttributeSucceededEvent"; export * from "./RepositoryAttributeSucceededEvent"; export * from "./SharedAttributeCopyCreatedEvent"; -export * from "./ThirdPartyOwnedRelationshipAttributeDeletedByPeerEvent"; -export * from "./ThirdPartyOwnedRelationshipAttributeSucceededEvent"; +export * from "./ThirdPartyRelationshipAttributeDeletedByPeerEvent"; +export * from "./ThirdPartyRelationshipAttributeSucceededEvent"; diff --git a/packages/consumption/src/modules/attributes/local/LocalAttribute.ts b/packages/consumption/src/modules/attributes/local/LocalAttribute.ts index 7e318660c..5ed4b19cf 100644 --- a/packages/consumption/src/modules/attributes/local/LocalAttribute.ts +++ b/packages/consumption/src/modules/attributes/local/LocalAttribute.ts @@ -52,12 +52,6 @@ export type OwnSharedRelationshipAttribute = LocalAttribute & { isDefault: undefined; }; -export type OwnSharedThirdPartyRelationshipAttribute = OwnSharedRelationshipAttribute & { - shareInfo: OwnSharedRelationshipAttribute["shareInfo"] & { - thirdPartyAddress: CoreAddress; - }; -}; - export type PeerSharedIdentityAttribute = LocalAttribute & { content: IdentityAttribute; shareInfo: LocalAttributeShareInfo & { sourceAttribute: undefined }; @@ -72,15 +66,9 @@ export type PeerSharedRelationshipAttribute = LocalAttribute & { isDefault: undefined; }; -export type PeerSharedThirdPartyRelationshipAttribute = PeerSharedRelationshipAttribute & { - shareInfo: PeerSharedRelationshipAttribute["shareInfo"] & { - thirdPartyAddress: CoreAddress; - }; -}; - -export type ThirdPartyOwnedRelationshipAttribute = LocalAttribute & { +export type ThirdPartyRelationshipAttribute = LocalAttribute & { content: RelationshipAttribute; - shareInfo: LocalAttribute["shareInfo"] & { + shareInfo: LocalAttributeShareInfo & { thirdPartyAddress: CoreAddress; }; parentId: undefined; @@ -157,8 +145,8 @@ export class LocalAttribute extends CoreSynchronizable implements ILocalAttribut return this.isRelationshipAttribute() && this.isPeerSharedAttribute(peerAddress); } - public isThirdPartyOwnedRelationshipAttribute(ownAddress: CoreAddress, thirdPartyAddress?: CoreAddress): this is ThirdPartyOwnedRelationshipAttribute { - return this.isRelationshipAttribute() && this.isThirdPartyOwnedAttribute(ownAddress, thirdPartyAddress); + public isThirdPartyRelationshipAttribute(): this is ThirdPartyRelationshipAttribute { + return this.isRelationshipAttribute() && !!this.shareInfo.thirdPartyAddress; } public isRepositoryAttribute(ownAddress: CoreAddress): this is RepositoryAttribute { @@ -187,36 +175,17 @@ export class LocalAttribute extends CoreSynchronizable implements ILocalAttribut return isPeerSharedAttribute; } - public isOwnSharedThirdPartyRelationshipAttribute(ownAddress: CoreAddress): this is OwnSharedThirdPartyRelationshipAttribute { - const isThirdPartyAttribute = !!this.shareInfo?.thirdPartyAddress; - const isOwnShared = this.isOwnedBy(ownAddress); - return isThirdPartyAttribute && isOwnShared; - } - - public isPeerSharedThirdPartyRelationshipAttribute(peerAddress: CoreAddress): this is PeerSharedThirdPartyRelationshipAttribute { - const isThirdPartyAttribute = !!this.shareInfo?.thirdPartyAddress; - const isPeerShared = this.isOwnedBy(peerAddress); - return isThirdPartyAttribute && isPeerShared; - } - - public isThirdPartyOwnedAttribute(ownAddress: CoreAddress, thirdPartyAddress?: CoreAddress): this is ThirdPartyOwnedRelationshipAttribute { - let isThirdPartyOwnedAttribute = this.isShared() && !this.isOwnedBy(ownAddress) && !this.isOwnedBy(this.shareInfo.peer); - - isThirdPartyOwnedAttribute &&= !this.parentId; - isThirdPartyOwnedAttribute &&= !this.isDefault; - - if (thirdPartyAddress) isThirdPartyOwnedAttribute &&= this.isOwnedBy(thirdPartyAddress); - return isThirdPartyOwnedAttribute; - } - public isIdentityAttribute(): this is LocalAttribute & { content: IdentityAttribute } { return this.content instanceof IdentityAttribute; } - public isRelationshipAttribute(): this is LocalAttribute & { content: RelationshipAttribute } & { - shareInfo: LocalAttributeShareInfo; - } { - return this.content instanceof RelationshipAttribute && this.isShared(); + public isRelationshipAttribute(): this is LocalAttribute & { content: RelationshipAttribute; shareInfo: LocalAttributeShareInfo } { + let isRelationshipAttribute = this.content instanceof RelationshipAttribute && this.isShared(); + + isRelationshipAttribute &&= !this.parentId; + isRelationshipAttribute &&= !this.isDefault; + + return isRelationshipAttribute; } public isComplexAttribute(): boolean { @@ -244,8 +213,8 @@ export class LocalAttribute extends CoreSynchronizable implements ILocalAttribut throw ConsumptionCoreErrors.attributes.invalidDeletionInfoOfPeerSharedAttribute(); } - if (this.isThirdPartyOwnedRelationshipAttribute(ownAddress) && !this.isThirdPartyOwnedRelationshipAttributeDeletionInfo(deletionInfo)) { - throw ConsumptionCoreErrors.attributes.invalidDeletionInfoOfThirdPartyOwnedRelationshipAttribute(); + if (this.isThirdPartyRelationshipAttribute() && !this.isThirdPartyRelationshipAttributeDeletionInfo(deletionInfo)) { + throw ConsumptionCoreErrors.attributes.invalidDeletionInfoOfThirdPartyRelationshipAttribute(); } this.deletionInfo = deletionInfo; @@ -265,7 +234,7 @@ export class LocalAttribute extends CoreSynchronizable implements ILocalAttribut ); } - private isThirdPartyOwnedRelationshipAttributeDeletionInfo(deletionInfo: LocalAttributeDeletionInfo): boolean { + private isThirdPartyRelationshipAttributeDeletionInfo(deletionInfo: LocalAttributeDeletionInfo): boolean { return deletionInfo.deletionStatus === LocalAttributeDeletionStatus.DeletedByPeer; } diff --git a/packages/consumption/src/modules/notifications/index.ts b/packages/consumption/src/modules/notifications/index.ts index a39789cef..be0c32fef 100644 --- a/packages/consumption/src/modules/notifications/index.ts +++ b/packages/consumption/src/modules/notifications/index.ts @@ -1,7 +1,7 @@ export * from "./itemProcessors/AbstractNotificationItemProcessor"; export * from "./itemProcessors/attributeDeleted/OwnSharedAttributeDeletedByOwnerNotificationItemProcessor"; export * from "./itemProcessors/attributeDeleted/PeerSharedAttributeDeletedByPeerNotificationItemProcessor"; -export * from "./itemProcessors/attributeDeleted/ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItemProcessor"; +export * from "./itemProcessors/attributeDeleted/ThirdPartyRelationshipAttributeDeletedByPeerNotificationItemProcessor"; export * from "./itemProcessors/attributeSucceeded/PeerSharedAttributeSucceededNotificationItemProcessor"; export * from "./itemProcessors/NotificationItemConstructor"; export * from "./itemProcessors/NotificationItemProcessorConstructor"; diff --git a/packages/consumption/src/modules/notifications/itemProcessors/attributeDeleted/ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItemProcessor.ts b/packages/consumption/src/modules/notifications/itemProcessors/attributeDeleted/ThirdPartyRelationshipAttributeDeletedByPeerNotificationItemProcessor.ts similarity index 71% rename from packages/consumption/src/modules/notifications/itemProcessors/attributeDeleted/ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItemProcessor.ts rename to packages/consumption/src/modules/notifications/itemProcessors/attributeDeleted/ThirdPartyRelationshipAttributeDeletedByPeerNotificationItemProcessor.ts index 3eddc64f2..5cea6e611 100644 --- a/packages/consumption/src/modules/notifications/itemProcessors/attributeDeleted/ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItemProcessor.ts +++ b/packages/consumption/src/modules/notifications/itemProcessors/attributeDeleted/ThirdPartyRelationshipAttributeDeletedByPeerNotificationItemProcessor.ts @@ -1,33 +1,33 @@ import { ILogger } from "@js-soft/logging-abstractions"; -import { ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItem } from "@nmshd/content"; +import { ThirdPartyRelationshipAttributeDeletedByPeerNotificationItem } from "@nmshd/content"; import { CoreDate } from "@nmshd/core-types"; import { TransportLoggerFactory } from "@nmshd/transport"; import { ConsumptionController } from "../../../../consumption/ConsumptionController"; import { ConsumptionCoreErrors } from "../../../../consumption/ConsumptionCoreErrors"; -import { ThirdPartyOwnedRelationshipAttributeDeletedByPeerEvent } from "../../../attributes"; +import { ThirdPartyRelationshipAttributeDeletedByPeerEvent } from "../../../attributes"; import { LocalAttributeDeletionInfo, LocalAttributeDeletionStatus } from "../../../attributes/local/LocalAttributeDeletionInfo"; import { ValidationResult } from "../../../common"; import { LocalNotification } from "../../local/LocalNotification"; import { AbstractNotificationItemProcessor } from "../AbstractNotificationItemProcessor"; -export class ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItemProcessor extends AbstractNotificationItemProcessor { +export class ThirdPartyRelationshipAttributeDeletedByPeerNotificationItemProcessor extends AbstractNotificationItemProcessor { private readonly _logger: ILogger; public constructor(consumptionController: ConsumptionController) { super(consumptionController); - this._logger = TransportLoggerFactory.getLogger(ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItemProcessor); + this._logger = TransportLoggerFactory.getLogger(ThirdPartyRelationshipAttributeDeletedByPeerNotificationItemProcessor); } public override async checkPrerequisitesOfIncomingNotificationItem( - notificationItem: ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItem, + notificationItem: ThirdPartyRelationshipAttributeDeletedByPeerNotificationItem, notification: LocalNotification ): Promise { const attribute = await this.consumptionController.attributes.getLocalAttribute(notificationItem.attributeId); if (!attribute) return ValidationResult.success(); - if (!attribute.isThirdPartyOwnedRelationshipAttribute(this.currentIdentityAddress)) { - return ValidationResult.error(ConsumptionCoreErrors.attributes.isNotThirdPartyOwnedRelationshipAttribute(notificationItem.attributeId)); + if (!attribute.isThirdPartyRelationshipAttribute()) { + return ValidationResult.error(ConsumptionCoreErrors.attributes.isNotThirdPartyRelationshipAttribute(notificationItem.attributeId)); } if (!notification.peer.equals(attribute.shareInfo.peer)) { @@ -38,9 +38,9 @@ export class ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItemPr } public override async process( - notificationItem: ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItem, + notificationItem: ThirdPartyRelationshipAttributeDeletedByPeerNotificationItem, _notification: LocalNotification - ): Promise { + ): Promise { const attribute = await this.consumptionController.attributes.getLocalAttribute(notificationItem.attributeId); if (!attribute) return; @@ -57,10 +57,10 @@ export class ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItemPr await this.consumptionController.attributes.updateAttributeUnsafe(attr); } - return new ThirdPartyOwnedRelationshipAttributeDeletedByPeerEvent(this.currentIdentityAddress.toString(), attribute); + return new ThirdPartyRelationshipAttributeDeletedByPeerEvent(this.currentIdentityAddress.toString(), attribute); } - public override async rollback(notificationItem: ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItem, _notification: LocalNotification): Promise { + public override async rollback(notificationItem: ThirdPartyRelationshipAttributeDeletedByPeerNotificationItem, _notification: LocalNotification): Promise { const attribute = await this.consumptionController.attributes.getLocalAttribute(notificationItem.attributeId); if (!attribute) return; diff --git a/packages/consumption/src/modules/requests/itemProcessors/readAttribute/ReadAttributeRequestItemProcessor.ts b/packages/consumption/src/modules/requests/itemProcessors/readAttribute/ReadAttributeRequestItemProcessor.ts index f7e02e875..ecc2c0c0e 100644 --- a/packages/consumption/src/modules/requests/itemProcessors/readAttribute/ReadAttributeRequestItemProcessor.ts +++ b/packages/consumption/src/modules/requests/itemProcessors/readAttribute/ReadAttributeRequestItemProcessor.ts @@ -257,10 +257,8 @@ export class ReadAttributeRequestItemProcessor extends GenericRequestItemProcess let successorSharedAttribute: LocalAttribute; if (existingSourceAttribute.isRepositoryAttribute(this.currentIdentityAddress)) { successorSharedAttribute = await this.performOwnSharedIdentityAttributeSuccession(sharedPredecessor.id, existingSourceAttribute, requestInfo); - } else if (existingSourceAttribute.isOwnedBy(this.accountController.identity.address)) { - successorSharedAttribute = await this.performOwnSharedThirdPartyRelationshipAttributeSuccession(sharedPredecessor.id, existingSourceAttribute, requestInfo); } else { - successorSharedAttribute = await this.performThirdPartyOwnedRelationshipAttributeSuccession(sharedPredecessor.id, existingSourceAttribute, requestInfo); + successorSharedAttribute = await this.performThirdPartyRelationshipAttributeSuccession(sharedPredecessor.id, existingSourceAttribute, requestInfo); } return AttributeSuccessionAcceptResponseItem.from({ @@ -306,7 +304,7 @@ export class ReadAttributeRequestItemProcessor extends GenericRequestItemProcess return successor; } - private async performOwnSharedThirdPartyRelationshipAttributeSuccession(sharedPredecessorId: CoreId, sourceSuccessor: LocalAttribute, requestInfo: LocalRequestInfo) { + private async performThirdPartyRelationshipAttributeSuccession(sharedPredecessorId: CoreId, sourceSuccessor: LocalAttribute, requestInfo: LocalRequestInfo) { const predecessor = await this.consumptionController.attributes.getLocalAttribute(sharedPredecessorId); const successorParams = { @@ -318,23 +316,7 @@ export class ReadAttributeRequestItemProcessor extends GenericRequestItemProcess thirdPartyAddress: predecessor?.shareInfo?.thirdPartyAddress }) }; - const { successor } = await this.consumptionController.attributes.succeedOwnSharedRelationshipAttribute(sharedPredecessorId, successorParams); - return successor; - } - - private async performThirdPartyOwnedRelationshipAttributeSuccession(sharedPredecessorId: CoreId, sourceSuccessor: LocalAttribute, requestInfo: LocalRequestInfo) { - const predecessor = await this.consumptionController.attributes.getLocalAttribute(sharedPredecessorId); - - const successorParams = { - content: sourceSuccessor.content, - shareInfo: LocalAttributeShareInfo.from({ - peer: requestInfo.peer, - requestReference: requestInfo.id, - sourceAttribute: sourceSuccessor.id, - thirdPartyAddress: predecessor?.shareInfo?.thirdPartyAddress - }) - }; - const { successor } = await this.consumptionController.attributes.succeedThirdPartyOwnedRelationshipAttribute(sharedPredecessorId, successorParams); + const { successor } = await this.consumptionController.attributes.succeedThirdPartyRelationshipAttribute(sharedPredecessorId, successorParams); return successor; } @@ -397,7 +379,7 @@ export class ReadAttributeRequestItemProcessor extends GenericRequestItemProcess if (responseItem.successorContent.owner === requestInfo.peer) { await this.consumptionController.attributes.succeedPeerSharedRelationshipAttribute(responseItem.predecessorId, successorParams); } else { - await this.consumptionController.attributes.succeedThirdPartyOwnedRelationshipAttribute(responseItem.predecessorId, successorParams); + await this.consumptionController.attributes.succeedThirdPartyRelationshipAttribute(responseItem.predecessorId, successorParams); } } diff --git a/packages/consumption/test/modules/attributes/AttributesController.test.ts b/packages/consumption/test/modules/attributes/AttributesController.test.ts index 548df3116..15d2c49c1 100644 --- a/packages/consumption/test/modules/attributes/AttributesController.test.ts +++ b/packages/consumption/test/modules/attributes/AttributesController.test.ts @@ -2376,7 +2376,7 @@ describe("AttributesController", function () { expect((successor.content.value.toJSON() as any).value).toBe("1337"); }); - test("should succeed a third party owned relationship attribute", async function () { + test("should succeed a ThirdPartyRelationshipAttribute", async function () { const predecessor = await consumptionController.attributes.createAttributeUnsafe({ content: RelationshipAttribute.from({ key: "customerId", @@ -2414,7 +2414,7 @@ describe("AttributesController", function () { } }; - const { predecessor: updatedPredecessor, successor } = await consumptionController.attributes.succeedThirdPartyOwnedRelationshipAttribute( + const { predecessor: updatedPredecessor, successor } = await consumptionController.attributes.succeedThirdPartyRelationshipAttribute( predecessor.id, successorParams ); diff --git a/packages/consumption/test/modules/attributes/LocalAttributeDeletionInfo.test.ts b/packages/consumption/test/modules/attributes/LocalAttributeDeletionInfo.test.ts index f097364c6..e94358acd 100644 --- a/packages/consumption/test/modules/attributes/LocalAttributeDeletionInfo.test.ts +++ b/packages/consumption/test/modules/attributes/LocalAttributeDeletionInfo.test.ts @@ -16,7 +16,7 @@ describe("LocalAttributeDeletionInfo", function () { let repositoryAttribute: LocalAttribute; let ownSharedIdentityAttribute: LocalAttribute; let peerSharedIdentityAttribute: LocalAttribute; - let thirdPartyOwnedRelationshipAttribute: LocalAttribute; + let thirdPartyRelationshipAttribute: LocalAttribute; beforeAll(async function () { connection = await TestUtil.createConnection(); @@ -59,7 +59,7 @@ describe("LocalAttributeDeletionInfo", function () { requestReference: CoreId.from("request") }); - thirdPartyOwnedRelationshipAttribute = await consumptionController.attributes.createSharedLocalAttribute({ + thirdPartyRelationshipAttribute = await consumptionController.attributes.createSharedLocalAttribute({ content: RelationshipAttribute.from({ value: ProprietaryEMailAddress.from({ value: "thirdParty@email.com", @@ -70,7 +70,8 @@ describe("LocalAttributeDeletionInfo", function () { owner: CoreAddress.from("thirdParty") }), peer: CoreAddress.from("peer"), - requestReference: CoreId.from("request") + requestReference: CoreId.from("request"), + thirdPartyAddress: CoreAddress.from("thirdPartyAddress") }); }); @@ -194,55 +195,55 @@ describe("LocalAttributeDeletionInfo", function () { }); }); - describe("DeletionInfo of third party owned RelationshipAttributes", function () { - test("should set the deletionInfo of a third party owned RelationshipAttribute to DeletedByPeer", async function () { + describe("DeletionInfo of ThirdPartyRelationshipAttributes", function () { + test("should set the deletionInfo of a ThirdPartyRelationshipAttribute to DeletedByPeer", async function () { const deletionInfo = LocalAttributeDeletionInfo.from({ deletionStatus: LocalAttributeDeletionStatus.DeletedByPeer, deletionDate: CoreDate.utc() }); - thirdPartyOwnedRelationshipAttribute.setDeletionInfo(deletionInfo, testAccount.identity.address); - await consumptionController.attributes.updateAttributeUnsafe(thirdPartyOwnedRelationshipAttribute); + thirdPartyRelationshipAttribute.setDeletionInfo(deletionInfo, testAccount.identity.address); + await consumptionController.attributes.updateAttributeUnsafe(thirdPartyRelationshipAttribute); - const updatedThirdPartyOwnedRelationshipAttribute = await consumptionController.attributes.getLocalAttribute(thirdPartyOwnedRelationshipAttribute.id); - expect(updatedThirdPartyOwnedRelationshipAttribute!.deletionInfo!.deletionStatus).toBe(LocalAttributeDeletionStatus.DeletedByPeer); + const updatedThirdPartyRelationshipAttribute = await consumptionController.attributes.getLocalAttribute(thirdPartyRelationshipAttribute.id); + expect(updatedThirdPartyRelationshipAttribute!.deletionInfo!.deletionStatus).toBe(LocalAttributeDeletionStatus.DeletedByPeer); }); - test("should throw trying to set the deletionInfo of a third party owned RelationshipAttribute to DeletedByOwner", function () { + test("should throw trying to set the deletionInfo of a ThirdPartyRelationshipAttribute to DeletedByOwner", function () { const deletionInfo = LocalAttributeDeletionInfo.from({ deletionStatus: LocalAttributeDeletionStatus.DeletedByOwner, deletionDate: CoreDate.utc() }); expect(() => { - thirdPartyOwnedRelationshipAttribute.setDeletionInfo(deletionInfo, testAccount.identity.address); - }).toThrow("The only valid deletionStatus for third party owned RelationshipAttributes is 'DeletedByPeer'."); + thirdPartyRelationshipAttribute.setDeletionInfo(deletionInfo, testAccount.identity.address); + }).toThrow("The only valid deletionStatus for ThirdPartyRelationshipAttributes is 'DeletedByPeer'."); }); - test("should throw trying to set the deletionInfo of a third party owned RelationshipAttribute to DeletionRequestSent", function () { + test("should throw trying to set the deletionInfo of a ThirdPartyRelationshipAttribute to DeletionRequestSent", function () { const deletionInfo = LocalAttributeDeletionInfo.from({ deletionStatus: LocalAttributeDeletionStatus.DeletionRequestSent, deletionDate: CoreDate.utc() }); expect(() => { - thirdPartyOwnedRelationshipAttribute.setDeletionInfo(deletionInfo, testAccount.identity.address); - }).toThrow("The only valid deletionStatus for third party owned RelationshipAttributes is 'DeletedByPeer'."); + thirdPartyRelationshipAttribute.setDeletionInfo(deletionInfo, testAccount.identity.address); + }).toThrow("The only valid deletionStatus for ThirdPartyRelationshipAttributes is 'DeletedByPeer'."); }); - test("should throw trying to set the deletionInfo of a third party owned RelationshipAttribute to DeletionRequestRejected", function () { + test("should throw trying to set the deletionInfo of a ThirdPartyRelationshipAttribute to DeletionRequestRejected", function () { const deletionInfo = LocalAttributeDeletionInfo.from({ deletionStatus: LocalAttributeDeletionStatus.DeletionRequestRejected, deletionDate: CoreDate.utc() }); expect(() => { - thirdPartyOwnedRelationshipAttribute.setDeletionInfo(deletionInfo, testAccount.identity.address); - }).toThrow("The only valid deletionStatus for third party owned RelationshipAttributes is 'DeletedByPeer'."); + thirdPartyRelationshipAttribute.setDeletionInfo(deletionInfo, testAccount.identity.address); + }).toThrow("The only valid deletionStatus for ThirdPartyRelationshipAttributes is 'DeletedByPeer'."); }); - test("should throw trying to set the deletionInfo of a third party owned RelationshipAttribute to ToBeDeletedByPeer", function () { + test("should throw trying to set the deletionInfo of a ThirdPartyRelationshipAttribute to ToBeDeletedByPeer", function () { const deletionInfo = LocalAttributeDeletionInfo.from({ deletionStatus: LocalAttributeDeletionStatus.ToBeDeletedByPeer, deletionDate: CoreDate.utc() }); expect(() => { - thirdPartyOwnedRelationshipAttribute.setDeletionInfo(deletionInfo, testAccount.identity.address); - }).toThrow("The only valid deletionStatus for third party owned RelationshipAttributes is 'DeletedByPeer'."); + thirdPartyRelationshipAttribute.setDeletionInfo(deletionInfo, testAccount.identity.address); + }).toThrow("The only valid deletionStatus for ThirdPartyRelationshipAttributes is 'DeletedByPeer'."); }); - test("should throw trying to set the deletionInfo of a third party owned RelationshipAttribute to ToBeDeleted", function () { + test("should throw trying to set the deletionInfo of a ThirdPartyRelationshipAttribute to ToBeDeleted", function () { const deletionInfo = LocalAttributeDeletionInfo.from({ deletionStatus: LocalAttributeDeletionStatus.ToBeDeleted, deletionDate: CoreDate.utc() }); expect(() => { - thirdPartyOwnedRelationshipAttribute.setDeletionInfo(deletionInfo, testAccount.identity.address); - }).toThrow("The only valid deletionStatus for third party owned RelationshipAttributes is 'DeletedByPeer'."); + thirdPartyRelationshipAttribute.setDeletionInfo(deletionInfo, testAccount.identity.address); + }).toThrow("The only valid deletionStatus for ThirdPartyRelationshipAttributes is 'DeletedByPeer'."); }); }); diff --git a/packages/consumption/test/modules/notifications/itemProcessors/attributeDeleted/ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItemProcessor.test.ts b/packages/consumption/test/modules/notifications/itemProcessors/attributeDeleted/ThirdPartyRelationshipAttributeDeletedByPeerNotificationItemProcessor.test.ts similarity index 78% rename from packages/consumption/test/modules/notifications/itemProcessors/attributeDeleted/ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItemProcessor.test.ts rename to packages/consumption/test/modules/notifications/itemProcessors/attributeDeleted/ThirdPartyRelationshipAttributeDeletedByPeerNotificationItemProcessor.test.ts index 757b2eb4b..6cbaaadef 100644 --- a/packages/consumption/test/modules/notifications/itemProcessors/attributeDeleted/ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItemProcessor.test.ts +++ b/packages/consumption/test/modules/notifications/itemProcessors/attributeDeleted/ThirdPartyRelationshipAttributeDeletedByPeerNotificationItemProcessor.test.ts @@ -1,5 +1,5 @@ import { IDatabaseConnection } from "@js-soft/docdb-access-abstractions"; -import { Notification, RelationshipAttribute, RelationshipAttributeConfidentiality, ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItem } from "@nmshd/content"; +import { Notification, RelationshipAttribute, RelationshipAttributeConfidentiality, ThirdPartyRelationshipAttributeDeletedByPeerNotificationItem } from "@nmshd/content"; import { CoreAddress, CoreDate, CoreId } from "@nmshd/core-types"; import { AccountController, Transport } from "@nmshd/transport"; import { @@ -8,15 +8,15 @@ import { LocalNotification, LocalNotificationSource, LocalNotificationStatus, - ThirdPartyOwnedRelationshipAttributeDeletedByPeerEvent, - ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItemProcessor + ThirdPartyRelationshipAttributeDeletedByPeerEvent, + ThirdPartyRelationshipAttributeDeletedByPeerNotificationItemProcessor } from "../../../../../src"; import { TestUtil } from "../../../../core/TestUtil"; import { MockEventBus } from "../../../MockEventBus"; const mockEventBus = new MockEventBus(); -describe("ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItemProcessor", function () { +describe("ThirdPartyRelationshipAttributeDeletedByPeerNotificationItemProcessor", function () { let connection: IDatabaseConnection; let transport: Transport; @@ -53,8 +53,8 @@ describe("ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItemProce } }); - test("runs all processor methods for a third party owned relationship attribute", async function () { - const thirdPartyOwnedRelationshipAttribute = await consumptionController.attributes.createAttributeUnsafe({ + test("runs all processor methods for a ThirdPartyRelationshipAttribute", async function () { + const thirdPartyRelationshipAttribute = await consumptionController.attributes.createAttributeUnsafe({ content: RelationshipAttribute.from({ key: "customerId", value: { @@ -67,12 +67,13 @@ describe("ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItemProce }), shareInfo: { peer: CoreAddress.from("peer"), - requestReference: CoreId.from("reqRef") + requestReference: CoreId.from("reqRef"), + thirdPartyAddress: CoreAddress.from("thirdPartyAddress") } }); - const notificationItem = ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItem.from({ - attributeId: thirdPartyOwnedRelationshipAttribute.id + const notificationItem = ThirdPartyRelationshipAttributeDeletedByPeerNotificationItem.from({ + attributeId: thirdPartyRelationshipAttribute.id }); const notification = LocalNotification.from({ id: CoreId.from("notificationRef"), @@ -90,7 +91,7 @@ describe("ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItemProce }), receivedByDevice: CoreId.from("deviceId") }); - const processor = new ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItemProcessor(consumptionController); + const processor = new ThirdPartyRelationshipAttributeDeletedByPeerNotificationItemProcessor(consumptionController); /* Run and check validation. */ const checkResult = await processor.checkPrerequisitesOfIncomingNotificationItem(notificationItem, notification); @@ -98,8 +99,8 @@ describe("ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItemProce /* Run process() and validate its results. */ const event = await processor.process(notificationItem, notification); - expect(event).toBeInstanceOf(ThirdPartyOwnedRelationshipAttributeDeletedByPeerEvent); - const updatedAttribute = (event as ThirdPartyOwnedRelationshipAttributeDeletedByPeerEvent).data; + expect(event).toBeInstanceOf(ThirdPartyRelationshipAttributeDeletedByPeerEvent); + const updatedAttribute = (event as ThirdPartyRelationshipAttributeDeletedByPeerEvent).data; expect(notificationItem.attributeId.equals(updatedAttribute.id)).toBe(true); expect(updatedAttribute.deletionInfo!.deletionStatus).toStrictEqual(LocalAttributeDeletionStatus.DeletedByPeer); @@ -115,7 +116,7 @@ describe("ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItemProce test("runs all processor methods for an unknown attribute", async function () { const unknownAttributeId = CoreId.from("ATT"); - const notificationItem = ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItem.from({ + const notificationItem = ThirdPartyRelationshipAttributeDeletedByPeerNotificationItem.from({ attributeId: unknownAttributeId }); const notification = LocalNotification.from({ @@ -134,7 +135,7 @@ describe("ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItemProce }), receivedByDevice: CoreId.from("deviceId") }); - const processor = new ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItemProcessor(consumptionController); + const processor = new ThirdPartyRelationshipAttributeDeletedByPeerNotificationItemProcessor(consumptionController); /* Run and check validation. */ const checkResult = await processor.checkPrerequisitesOfIncomingNotificationItem(notificationItem, notification); @@ -153,7 +154,7 @@ describe("ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItemProce /* A naughty peer is trying to delete attributes shared * not with them, but with another peer. This must be * caught by the validation. */ - const thirdPartyOwnedRelationshipAttributeSharedWithOtherPeer = await consumptionController.attributes.createAttributeUnsafe({ + const thirdPartyRelationshipAttributeSharedWithOtherPeer = await consumptionController.attributes.createAttributeUnsafe({ content: RelationshipAttribute.from({ key: "customerId", value: { @@ -166,12 +167,13 @@ describe("ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItemProce }), shareInfo: { peer: CoreAddress.from("otherPeer"), - requestReference: CoreId.from("reqRef") + requestReference: CoreId.from("reqRef"), + thirdPartyAddress: CoreAddress.from("thirdPartyAddress") } }); - const notificationItem = ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItem.from({ - attributeId: thirdPartyOwnedRelationshipAttributeSharedWithOtherPeer.id + const notificationItem = ThirdPartyRelationshipAttributeDeletedByPeerNotificationItem.from({ + attributeId: thirdPartyRelationshipAttributeSharedWithOtherPeer.id }); const notification = LocalNotification.from({ @@ -190,7 +192,7 @@ describe("ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItemProce }), receivedByDevice: CoreId.from("deviceId") }); - const processor = new ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItemProcessor(consumptionController); + const processor = new ThirdPartyRelationshipAttributeDeletedByPeerNotificationItemProcessor(consumptionController); const checkResult = await processor.checkPrerequisitesOfIncomingNotificationItem(notificationItem, notification); expect(checkResult).errorValidationResult({ diff --git a/packages/consumption/test/modules/requests/itemProcessors/readAttribute/ReadAttributeRequestItemProcessor.test.ts b/packages/consumption/test/modules/requests/itemProcessors/readAttribute/ReadAttributeRequestItemProcessor.test.ts index 289fe08d3..1e21229f9 100644 --- a/packages/consumption/test/modules/requests/itemProcessors/readAttribute/ReadAttributeRequestItemProcessor.test.ts +++ b/packages/consumption/test/modules/requests/itemProcessors/readAttribute/ReadAttributeRequestItemProcessor.test.ts @@ -1916,7 +1916,7 @@ describe("ReadAttributeRequestItemProcessor", function () { expect(updatedPredecessorPeerSharedIdentityAttribute!.succeededBy).toStrictEqual(successorPeerSharedIdentityAttribute!.id); }); - test("succeeds an existing third party owned RelationshipAttribute with the Attribute received in the ResponseItem", async function () { + test("succeeds an existing ThirdPartyRelationshipAttribute with the Attribute received in the ResponseItem", async function () { const thirdPartyAddress = CoreAddress.from("thirdPartyAddress"); const recipient = CoreAddress.from("Recipient"); diff --git a/packages/content/src/notifications/items/ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItem.ts b/packages/content/src/notifications/items/ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItem.ts deleted file mode 100644 index b6cb287c7..000000000 --- a/packages/content/src/notifications/items/ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItem.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { serialize, type, validate } from "@js-soft/ts-serval"; -import { CoreId, ICoreId } from "@nmshd/core-types"; -import { INotificationItem, NotificationItem, NotificationItemJSON } from "../NotificationItem"; - -export interface ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItemJSON extends NotificationItemJSON { - "@type": "ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItem"; - attributeId: string; -} - -export interface IThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItem extends INotificationItem { - attributeId: ICoreId; -} - -@type("ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItem") -export class ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItem - extends NotificationItem - implements IThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItem -{ - @validate() - @serialize() - public attributeId: CoreId; - - public static from( - value: IThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItem | Omit - ): ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItem { - return this.fromAny(value); - } -} diff --git a/packages/content/src/notifications/items/ThirdPartyRelationshipAttributeDeletedByPeerNotificationItem.ts b/packages/content/src/notifications/items/ThirdPartyRelationshipAttributeDeletedByPeerNotificationItem.ts new file mode 100644 index 000000000..9dc1505da --- /dev/null +++ b/packages/content/src/notifications/items/ThirdPartyRelationshipAttributeDeletedByPeerNotificationItem.ts @@ -0,0 +1,27 @@ +import { serialize, type, validate } from "@js-soft/ts-serval"; +import { CoreId, ICoreId } from "@nmshd/core-types"; +import { INotificationItem, NotificationItem, NotificationItemJSON } from "../NotificationItem"; + +export interface ThirdPartyRelationshipAttributeDeletedByPeerNotificationItemJSON extends NotificationItemJSON { + "@type": "ThirdPartyRelationshipAttributeDeletedByPeerNotificationItem"; + attributeId: string; +} + +export interface IThirdPartyRelationshipAttributeDeletedByPeerNotificationItem extends INotificationItem { + attributeId: ICoreId; +} + +// deprecated +@type("ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItem") +@type("ThirdPartyRelationshipAttributeDeletedByPeerNotificationItem") +export class ThirdPartyRelationshipAttributeDeletedByPeerNotificationItem extends NotificationItem implements IThirdPartyRelationshipAttributeDeletedByPeerNotificationItem { + @validate() + @serialize() + public attributeId: CoreId; + + public static from( + value: IThirdPartyRelationshipAttributeDeletedByPeerNotificationItem | Omit + ): ThirdPartyRelationshipAttributeDeletedByPeerNotificationItem { + return this.fromAny(value); + } +} diff --git a/packages/content/src/notifications/items/index.ts b/packages/content/src/notifications/items/index.ts index f443effb9..699791f03 100644 --- a/packages/content/src/notifications/items/index.ts +++ b/packages/content/src/notifications/items/index.ts @@ -1,4 +1,4 @@ export * from "./OwnSharedAttributeDeletedByOwnerNotificationItem"; export * from "./PeerSharedAttributeDeletedByPeerNotificationItem"; export * from "./PeerSharedAttributeSucceededNotificationItem"; -export * from "./ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItem"; +export * from "./ThirdPartyRelationshipAttributeDeletedByPeerNotificationItem"; diff --git a/packages/content/test/notifications/ThirdPartyRelationshipAttributeDeletedByPeerNotificationItem.test.ts b/packages/content/test/notifications/ThirdPartyRelationshipAttributeDeletedByPeerNotificationItem.test.ts new file mode 100644 index 000000000..e27f467b9 --- /dev/null +++ b/packages/content/test/notifications/ThirdPartyRelationshipAttributeDeletedByPeerNotificationItem.test.ts @@ -0,0 +1,14 @@ +import { Serializable } from "@js-soft/ts-serval"; +import { ThirdPartyRelationshipAttributeDeletedByPeerNotificationItem } from "../../src"; + +describe("ThirdPartyRelationshipAttributeDeletedByPeerNotificationItem", () => { + test("can create a ThirdPartyRelationshipAttributeDeletedByPeerNotificationItem with @type ThirdPartyRelationshipAttributeDeletedByPeerNotificationItem", () => { + const notificationItem = Serializable.fromUnknown({ "@type": "ThirdPartyRelationshipAttributeDeletedByPeerNotificationItem", attributeId: "anAttributeId" }); + expect(notificationItem instanceof ThirdPartyRelationshipAttributeDeletedByPeerNotificationItem).toBe(true); + }); + + test("can create a ThirdPartyRelationshipAttributeDeletedByPeerNotificationItem with deprecated @type ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItem", () => { + const notificationItem = Serializable.fromUnknown({ "@type": "ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItem", attributeId: "anAttributeId" }); + expect(notificationItem instanceof ThirdPartyRelationshipAttributeDeletedByPeerNotificationItem).toBe(true); + }); +}); diff --git a/packages/runtime/src/events/EventProxy.ts b/packages/runtime/src/events/EventProxy.ts index 65e0641a6..fdbf0f1eb 100644 --- a/packages/runtime/src/events/EventProxy.ts +++ b/packages/runtime/src/events/EventProxy.ts @@ -18,7 +18,9 @@ import { PeerSharedAttributeSucceededEvent, RepositoryAttributeSucceededEvent, ThirdPartyOwnedRelationshipAttributeDeletedByPeerEvent, - ThirdPartyOwnedRelationshipAttributeSucceededEvent + ThirdPartyOwnedRelationshipAttributeSucceededEvent, + ThirdPartyRelationshipAttributeDeletedByPeerEvent, + ThirdPartyRelationshipAttributeSucceededEvent } from "./consumption"; import { IdentityDeletionProcessStatusChangedEvent, @@ -125,7 +127,8 @@ export class EventProxy { this.targetEventBus.publish(new PeerSharedAttributeDeletedByPeerEvent(event.eventTargetAddress, AttributeMapper.toAttributeDTO(event.data))); }); - this.subscribeToSourceEvent(consumption.ThirdPartyOwnedRelationshipAttributeDeletedByPeerEvent, (event) => { + this.subscribeToSourceEvent(consumption.ThirdPartyRelationshipAttributeDeletedByPeerEvent, (event) => { + this.targetEventBus.publish(new ThirdPartyRelationshipAttributeDeletedByPeerEvent(event.eventTargetAddress, AttributeMapper.toAttributeDTO(event.data))); this.targetEventBus.publish(new ThirdPartyOwnedRelationshipAttributeDeletedByPeerEvent(event.eventTargetAddress, AttributeMapper.toAttributeDTO(event.data))); }); @@ -147,7 +150,13 @@ export class EventProxy { ); }); - this.subscribeToSourceEvent(consumption.ThirdPartyOwnedRelationshipAttributeSucceededEvent, (event) => { + this.subscribeToSourceEvent(consumption.ThirdPartyRelationshipAttributeSucceededEvent, (event) => { + this.targetEventBus.publish( + new ThirdPartyRelationshipAttributeSucceededEvent(event.eventTargetAddress, { + predecessor: AttributeMapper.toAttributeDTO(event.data.predecessor), + successor: AttributeMapper.toAttributeDTO(event.data.successor) + }) + ); this.targetEventBus.publish( new ThirdPartyOwnedRelationshipAttributeSucceededEvent(event.eventTargetAddress, { predecessor: AttributeMapper.toAttributeDTO(event.data.predecessor), diff --git a/packages/runtime/src/events/consumption/ThirdPartyOwnedRelationshipAttributeDeletedByPeerEvent.ts b/packages/runtime/src/events/consumption/ThirdPartyOwnedRelationshipAttributeDeletedByPeerEvent.ts index a8eb63a10..85bcc499a 100644 --- a/packages/runtime/src/events/consumption/ThirdPartyOwnedRelationshipAttributeDeletedByPeerEvent.ts +++ b/packages/runtime/src/events/consumption/ThirdPartyOwnedRelationshipAttributeDeletedByPeerEvent.ts @@ -1,6 +1,9 @@ import { LocalAttributeDTO } from "../../types"; import { DataEvent } from "../DataEvent"; +/** + * @deprecated Use ThirdPartyRelationshipAttributeDeletedByPeerEvent instead. + */ export class ThirdPartyOwnedRelationshipAttributeDeletedByPeerEvent extends DataEvent { public static readonly namespace = "consumption.thirdPartyOwnedRelationshipAttributeDeletedByPeer"; diff --git a/packages/runtime/src/events/consumption/ThirdPartyRelationshipAttributeDeletedByPeerEvent.ts b/packages/runtime/src/events/consumption/ThirdPartyRelationshipAttributeDeletedByPeerEvent.ts new file mode 100644 index 000000000..ab4da8fc7 --- /dev/null +++ b/packages/runtime/src/events/consumption/ThirdPartyRelationshipAttributeDeletedByPeerEvent.ts @@ -0,0 +1,10 @@ +import { LocalAttributeDTO } from "../../types"; +import { DataEvent } from "../DataEvent"; + +export class ThirdPartyRelationshipAttributeDeletedByPeerEvent extends DataEvent { + public static readonly namespace = "consumption.thirdPartyRelationshipAttributeDeletedByPeer"; + + public constructor(eventTargetAddress: string, data: LocalAttributeDTO) { + super(ThirdPartyRelationshipAttributeDeletedByPeerEvent.namespace, eventTargetAddress, data); + } +} diff --git a/packages/runtime/src/events/consumption/ThirdPartyRelationshipAttributeSucceededEvent.ts b/packages/runtime/src/events/consumption/ThirdPartyRelationshipAttributeSucceededEvent.ts new file mode 100644 index 000000000..2351ef27c --- /dev/null +++ b/packages/runtime/src/events/consumption/ThirdPartyRelationshipAttributeSucceededEvent.ts @@ -0,0 +1,10 @@ +import { DataEvent } from "../DataEvent"; +import { SuccessionEventData } from "./SuccessionEventData"; + +export class ThirdPartyRelationshipAttributeSucceededEvent extends DataEvent { + public static readonly namespace = "consumption.thirdPartyRelationshipAttributeSucceeded"; + + public constructor(eventTargetAddress: string, data: SuccessionEventData) { + super(ThirdPartyRelationshipAttributeSucceededEvent.namespace, eventTargetAddress, data); + } +} diff --git a/packages/runtime/src/events/consumption/index.ts b/packages/runtime/src/events/consumption/index.ts index 17aca274c..1adcee952 100644 --- a/packages/runtime/src/events/consumption/index.ts +++ b/packages/runtime/src/events/consumption/index.ts @@ -20,3 +20,5 @@ export * from "./RepositoryAttributeSucceededEvent"; export * from "./SuccessionEventData"; export * from "./ThirdPartyOwnedRelationshipAttributeDeletedByPeerEvent"; export * from "./ThirdPartyOwnedRelationshipAttributeSucceededEvent"; +export * from "./ThirdPartyRelationshipAttributeDeletedByPeerEvent"; +export * from "./ThirdPartyRelationshipAttributeSucceededEvent"; diff --git a/packages/runtime/src/extensibility/facades/consumption/AttributesFacade.ts b/packages/runtime/src/extensibility/facades/consumption/AttributesFacade.ts index 7ca3b2dde..ef3a92d4e 100644 --- a/packages/runtime/src/extensibility/facades/consumption/AttributesFacade.ts +++ b/packages/runtime/src/extensibility/facades/consumption/AttributesFacade.ts @@ -18,9 +18,9 @@ import { DeleteRepositoryAttributeUseCase, DeleteSharedAttributesForRejectedOrRevokedRelationshipRequest, DeleteSharedAttributesForRejectedOrRevokedRelationshipUseCase, - DeleteThirdPartyOwnedRelationshipAttributeAndNotifyPeerRequest, - DeleteThirdPartyOwnedRelationshipAttributeAndNotifyPeerResponse, - DeleteThirdPartyOwnedRelationshipAttributeAndNotifyPeerUseCase, + DeleteThirdPartyRelationshipAttributeAndNotifyPeerRequest, + DeleteThirdPartyRelationshipAttributeAndNotifyPeerResponse, + DeleteThirdPartyRelationshipAttributeAndNotifyPeerUseCase, ExecuteIQLQueryRequest, ExecuteIQLQueryUseCase, ExecuteIdentityAttributeQueryRequest, @@ -82,7 +82,7 @@ export class AttributesFacade { @Inject private readonly changeDefaultRepositoryAttributeUseCase: ChangeDefaultRepositoryAttributeUseCase, @Inject private readonly deleteOwnSharedAttributeAndNotifyPeerUseCase: DeleteOwnSharedAttributeAndNotifyPeerUseCase, @Inject private readonly deletePeerSharedAttributeAndNotifyOwnerUseCase: DeletePeerSharedAttributeAndNotifyOwnerUseCase, - @Inject private readonly deleteThirdPartyOwnedRelationshipAttributeAndNotifyPeerUseCase: DeleteThirdPartyOwnedRelationshipAttributeAndNotifyPeerUseCase, + @Inject private readonly deleteThirdPartyRelationshipAttributeAndNotifyPeerUseCase: DeleteThirdPartyRelationshipAttributeAndNotifyPeerUseCase, @Inject private readonly deleteRepositoryAttributeUseCase: DeleteRepositoryAttributeUseCase, @Inject private readonly deleteSharedAttributesForRejectedOrRevokedRelationshipUseCase: DeleteSharedAttributesForRejectedOrRevokedRelationshipUseCase ) {} @@ -177,10 +177,19 @@ export class AttributesFacade { return await this.deletePeerSharedAttributeAndNotifyOwnerUseCase.execute(request); } + public async deleteThirdPartyRelationshipAttributeAndNotifyPeer( + request: DeleteThirdPartyRelationshipAttributeAndNotifyPeerRequest + ): Promise> { + return await this.deleteThirdPartyRelationshipAttributeAndNotifyPeerUseCase.execute(request); + } + + /** + * @deprecated use deleteThirdPartyRelationshipAttributeAndNotifyPeer instead + */ public async deleteThirdPartyOwnedRelationshipAttributeAndNotifyPeer( - request: DeleteThirdPartyOwnedRelationshipAttributeAndNotifyPeerRequest - ): Promise> { - return await this.deleteThirdPartyOwnedRelationshipAttributeAndNotifyPeerUseCase.execute(request); + request: DeleteThirdPartyRelationshipAttributeAndNotifyPeerRequest + ): Promise> { + return await this.deleteThirdPartyRelationshipAttributeAndNotifyPeer(request); } public async deleteRepositoryAttribute(request: DeleteRepositoryAttributeRequest): Promise> { diff --git a/packages/runtime/src/useCases/common/RuntimeErrors.ts b/packages/runtime/src/useCases/common/RuntimeErrors.ts index 3c7de7745..ba6d19e27 100644 --- a/packages/runtime/src/useCases/common/RuntimeErrors.ts +++ b/packages/runtime/src/useCases/common/RuntimeErrors.ts @@ -194,10 +194,10 @@ class Attributes { return new ApplicationError("error.runtime.attributes.isNotPeerSharedAttribute", `Attribute '${attributeId.toString()}' is not a peer shared Attribute.`); } - public isNotThirdPartyOwnedRelationshipAttribute(attributeId: CoreId | string): ApplicationError { + public isNotThirdPartyRelationshipAttribute(attributeId: CoreId | string): ApplicationError { return new ApplicationError( - "error.runtime.attributes.isNotThirdPartyOwnedRelationshipAttribute", - `Attribute '${attributeId.toString()}' is not a third party owned RelationshipAttribute.` + "error.runtime.attributes.isNotThirdPartyRelationshipAttribute", + `Attribute '${attributeId.toString()}' is not a ThirdPartyRelationshipAttribute.` ); } diff --git a/packages/runtime/src/useCases/common/Schemas.ts b/packages/runtime/src/useCases/common/Schemas.ts index 1269dc45a..962021e1c 100644 --- a/packages/runtime/src/useCases/common/Schemas.ts +++ b/packages/runtime/src/useCases/common/Schemas.ts @@ -16265,11 +16265,11 @@ export const DeleteSharedAttributesForRejectedOrRevokedRelationshipRequest: any } } -export const DeleteThirdPartyOwnedRelationshipAttributeAndNotifyPeerRequest: any = { +export const DeleteThirdPartyRelationshipAttributeAndNotifyPeerRequest: any = { "$schema": "http://json-schema.org/draft-07/schema#", - "$ref": "#/definitions/DeleteThirdPartyOwnedRelationshipAttributeAndNotifyPeerRequest", + "$ref": "#/definitions/DeleteThirdPartyRelationshipAttributeAndNotifyPeerRequest", "definitions": { - "DeleteThirdPartyOwnedRelationshipAttributeAndNotifyPeerRequest": { + "DeleteThirdPartyRelationshipAttributeAndNotifyPeerRequest": { "type": "object", "properties": { "attributeId": { @@ -16288,37 +16288,15 @@ export const DeleteThirdPartyOwnedRelationshipAttributeAndNotifyPeerRequest: any } } -export const ExecuteIQLQueryRequest: any = { +export const ExecuteIdentityAttributeQueryRequest: any = { "$schema": "http://json-schema.org/draft-07/schema#", - "$ref": "#/definitions/ExecuteIQLQueryRequest", + "$ref": "#/definitions/ExecuteIdentityAttributeQueryRequest", "definitions": { - "ExecuteIQLQueryRequest": { + "ExecuteIdentityAttributeQueryRequest": { "type": "object", "properties": { "query": { - "type": "object", - "additionalProperties": false, - "properties": { - "@type": { - "type": "string", - "const": "IQLQuery" - }, - "queryString": { - "type": "string" - }, - "attributeCreationHints": { - "$ref": "#/definitions/IQLQueryCreationHintsJSON" - }, - "@context": { - "type": "string" - }, - "@version": { - "type": "string" - } - }, - "required": [ - "queryString" - ] + "$ref": "#/definitions/IdentityAttributeQueryJSON" } }, "required": [ @@ -16326,9 +16304,19 @@ export const ExecuteIQLQueryRequest: any = { ], "additionalProperties": false }, - "IQLQueryCreationHintsJSON": { + "IdentityAttributeQueryJSON": { "type": "object", "properties": { + "@type": { + "type": "string", + "const": "IdentityAttributeQuery" + }, + "@context": { + "type": "string" + }, + "@version": { + "type": "string" + }, "valueType": { "$ref": "#/definitions/AttributeValues.Identity.TypeName" }, @@ -16337,9 +16325,16 @@ export const ExecuteIQLQueryRequest: any = { "items": { "type": "string" } + }, + "validFrom": { + "type": "string" + }, + "validTo": { + "type": "string" } }, "required": [ + "@type", "valueType" ], "additionalProperties": false @@ -16409,15 +16404,37 @@ export const ExecuteIQLQueryRequest: any = { } } -export const ExecuteIdentityAttributeQueryRequest: any = { +export const ExecuteIQLQueryRequest: any = { "$schema": "http://json-schema.org/draft-07/schema#", - "$ref": "#/definitions/ExecuteIdentityAttributeQueryRequest", + "$ref": "#/definitions/ExecuteIQLQueryRequest", "definitions": { - "ExecuteIdentityAttributeQueryRequest": { + "ExecuteIQLQueryRequest": { "type": "object", "properties": { "query": { - "$ref": "#/definitions/IdentityAttributeQueryJSON" + "type": "object", + "additionalProperties": false, + "properties": { + "@type": { + "type": "string", + "const": "IQLQuery" + }, + "queryString": { + "type": "string" + }, + "attributeCreationHints": { + "$ref": "#/definitions/IQLQueryCreationHintsJSON" + }, + "@context": { + "type": "string" + }, + "@version": { + "type": "string" + } + }, + "required": [ + "queryString" + ] } }, "required": [ @@ -16425,19 +16442,9 @@ export const ExecuteIdentityAttributeQueryRequest: any = { ], "additionalProperties": false }, - "IdentityAttributeQueryJSON": { + "IQLQueryCreationHintsJSON": { "type": "object", "properties": { - "@type": { - "type": "string", - "const": "IdentityAttributeQuery" - }, - "@context": { - "type": "string" - }, - "@version": { - "type": "string" - }, "valueType": { "$ref": "#/definitions/AttributeValues.Identity.TypeName" }, @@ -16446,16 +16453,9 @@ export const ExecuteIdentityAttributeQueryRequest: any = { "items": { "type": "string" } - }, - "validFrom": { - "type": "string" - }, - "validTo": { - "type": "string" } }, "required": [ - "@type", "valueType" ], "additionalProperties": false diff --git a/packages/runtime/src/useCases/consumption/attributes/DeleteThirdPartyOwnedRelationshipAttributeAndNotifyPeer.ts b/packages/runtime/src/useCases/consumption/attributes/DeleteThirdPartyRelationshipAttributeAndNotifyPeer.ts similarity index 50% rename from packages/runtime/src/useCases/consumption/attributes/DeleteThirdPartyOwnedRelationshipAttributeAndNotifyPeer.ts rename to packages/runtime/src/useCases/consumption/attributes/DeleteThirdPartyRelationshipAttributeAndNotifyPeer.ts index 3ba86d04b..fec3a2149 100644 --- a/packages/runtime/src/useCases/consumption/attributes/DeleteThirdPartyOwnedRelationshipAttributeAndNotifyPeer.ts +++ b/packages/runtime/src/useCases/consumption/attributes/DeleteThirdPartyRelationshipAttributeAndNotifyPeer.ts @@ -1,28 +1,28 @@ import { Result } from "@js-soft/ts-utils"; import { AttributesController, ConsumptionIds, LocalAttribute } from "@nmshd/consumption"; -import { Notification, ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItem } from "@nmshd/content"; +import { Notification, ThirdPartyRelationshipAttributeDeletedByPeerNotificationItem } from "@nmshd/content"; import { CoreId } from "@nmshd/core-types"; import { AccountController, MessageController } from "@nmshd/transport"; import { Inject } from "@nmshd/typescript-ioc"; import { AttributeIdString, NotificationIdString, RuntimeErrors, SchemaRepository, SchemaValidator, UseCase } from "../../common"; -export interface DeleteThirdPartyOwnedRelationshipAttributeAndNotifyPeerRequest { +export interface DeleteThirdPartyRelationshipAttributeAndNotifyPeerRequest { attributeId: AttributeIdString; } -export interface DeleteThirdPartyOwnedRelationshipAttributeAndNotifyPeerResponse { +export interface DeleteThirdPartyRelationshipAttributeAndNotifyPeerResponse { notificationId: NotificationIdString; } -class Validator extends SchemaValidator { +class Validator extends SchemaValidator { public constructor(@Inject schemaRepository: SchemaRepository) { - super(schemaRepository.getSchema("DeleteThirdPartyOwnedRelationshipAttributeAndNotifyPeerRequest")); + super(schemaRepository.getSchema("DeleteThirdPartyRelationshipAttributeAndNotifyPeerRequest")); } } -export class DeleteThirdPartyOwnedRelationshipAttributeAndNotifyPeerUseCase extends UseCase< - DeleteThirdPartyOwnedRelationshipAttributeAndNotifyPeerRequest, - DeleteThirdPartyOwnedRelationshipAttributeAndNotifyPeerResponse +export class DeleteThirdPartyRelationshipAttributeAndNotifyPeerUseCase extends UseCase< + DeleteThirdPartyRelationshipAttributeAndNotifyPeerRequest, + DeleteThirdPartyRelationshipAttributeAndNotifyPeerResponse > { public constructor( @Inject private readonly attributesController: AttributesController, @@ -34,29 +34,29 @@ export class DeleteThirdPartyOwnedRelationshipAttributeAndNotifyPeerUseCase exte } protected async executeInternal( - request: DeleteThirdPartyOwnedRelationshipAttributeAndNotifyPeerRequest - ): Promise> { - const thirdPartyOwnedRelationshipAttributeId = CoreId.from(request.attributeId); - const thirdPartyOwnedRelationshipAttribute = await this.attributesController.getLocalAttribute(thirdPartyOwnedRelationshipAttributeId); - if (!thirdPartyOwnedRelationshipAttribute) return Result.fail(RuntimeErrors.general.recordNotFound(LocalAttribute)); + request: DeleteThirdPartyRelationshipAttributeAndNotifyPeerRequest + ): Promise> { + const thirdPartyRelationshipAttributeId = CoreId.from(request.attributeId); + const thirdPartyRelationshipAttribute = await this.attributesController.getLocalAttribute(thirdPartyRelationshipAttributeId); + if (!thirdPartyRelationshipAttribute) return Result.fail(RuntimeErrors.general.recordNotFound(LocalAttribute)); - if (!thirdPartyOwnedRelationshipAttribute.isThirdPartyOwnedAttribute(this.accountController.identity.address)) { - return Result.fail(RuntimeErrors.attributes.isNotThirdPartyOwnedRelationshipAttribute(thirdPartyOwnedRelationshipAttributeId)); + if (!thirdPartyRelationshipAttribute.isThirdPartyRelationshipAttribute()) { + return Result.fail(RuntimeErrors.attributes.isNotThirdPartyRelationshipAttribute(thirdPartyRelationshipAttributeId)); } - const validationResult = await this.attributesController.validateFullAttributeDeletionProcess(thirdPartyOwnedRelationshipAttribute); + const validationResult = await this.attributesController.validateFullAttributeDeletionProcess(thirdPartyRelationshipAttribute); if (validationResult.isError()) return Result.fail(validationResult.error); - await this.attributesController.executeFullAttributeDeletionProcess(thirdPartyOwnedRelationshipAttribute); + await this.attributesController.executeFullAttributeDeletionProcess(thirdPartyRelationshipAttribute); const notificationId = await ConsumptionIds.notification.generate(); - const notificationItem = ThirdPartyOwnedRelationshipAttributeDeletedByPeerNotificationItem.from({ attributeId: thirdPartyOwnedRelationshipAttributeId }); + const notificationItem = ThirdPartyRelationshipAttributeDeletedByPeerNotificationItem.from({ attributeId: thirdPartyRelationshipAttributeId }); const notification = Notification.from({ id: notificationId, items: [notificationItem] }); await this.messageController.sendMessage({ - recipients: [thirdPartyOwnedRelationshipAttribute.shareInfo.peer], + recipients: [thirdPartyRelationshipAttribute.shareInfo.peer], content: notification }); diff --git a/packages/runtime/src/useCases/consumption/attributes/index.ts b/packages/runtime/src/useCases/consumption/attributes/index.ts index f670d5d7f..2c86ebc51 100644 --- a/packages/runtime/src/useCases/consumption/attributes/index.ts +++ b/packages/runtime/src/useCases/consumption/attributes/index.ts @@ -6,9 +6,9 @@ export * from "./DeleteOwnSharedAttributeAndNotifyPeer"; export * from "./DeletePeerSharedAttributeAndNotifyOwner"; export * from "./DeleteRepositoryAttribute"; export * from "./DeleteSharedAttributesForRejectedOrRevokedRelationship"; -export * from "./DeleteThirdPartyOwnedRelationshipAttributeAndNotifyPeer"; -export * from "./ExecuteIQLQuery"; +export * from "./DeleteThirdPartyRelationshipAttributeAndNotifyPeer"; export * from "./ExecuteIdentityAttributeQuery"; +export * from "./ExecuteIQLQuery"; export * from "./ExecuteRelationshipAttributeQuery"; export * from "./ExecuteThirdPartyRelationshipAttributeQuery"; export * from "./GetAttribute"; diff --git a/packages/runtime/test/consumption/attributes.test.ts b/packages/runtime/test/consumption/attributes.test.ts index 218ea304a..b88d1d691 100644 --- a/packages/runtime/test/consumption/attributes.test.ts +++ b/packages/runtime/test/consumption/attributes.test.ts @@ -24,7 +24,7 @@ import { DeleteOwnSharedAttributeAndNotifyPeerUseCase, DeletePeerSharedAttributeAndNotifyOwnerUseCase, DeleteRepositoryAttributeUseCase, - DeleteThirdPartyOwnedRelationshipAttributeAndNotifyPeerUseCase, + DeleteThirdPartyRelationshipAttributeAndNotifyPeerUseCase, ExecuteIdentityAttributeQueryUseCase, ExecuteRelationshipAttributeQueryUseCase, ExecuteThirdPartyRelationshipAttributeQueryUseCase, @@ -46,7 +46,7 @@ import { SucceedRelationshipAttributeAndNotifyPeerUseCase, SucceedRepositoryAttributeRequest, SucceedRepositoryAttributeUseCase, - ThirdPartyOwnedRelationshipAttributeDeletedByPeerEvent + ThirdPartyRelationshipAttributeDeletedByPeerEvent } from "../../src"; import { RuntimeServiceProvider, @@ -1826,7 +1826,7 @@ describe("Get (shared) versions of attribute", () => { } }); - test("should return all shared third party relationship attributes of a source relationship attribute", async () => { + test("should return all emitted ThirdPartyRelationshipAttributes of a source RelationshipAttribute", async () => { await createAndShareRelationshipAttributeVersion0(); const requestParams = { peer: services1.address, @@ -1843,7 +1843,7 @@ describe("Get (shared) versions of attribute", () => { ] } }; - const ownSharedThirdPartyRelationshipAttribute = await executeFullRequestAndAcceptExistingAttributeFlow( + const emittedThirdPartyRelationshipAttribute = await executeFullRequestAndAcceptExistingAttributeFlow( services1, services3, requestParams, @@ -1853,7 +1853,7 @@ describe("Get (shared) versions of attribute", () => { const result = await services1.consumption.attributes.getSharedVersionsOfAttribute({ attributeId: sOwnSharedRelationshipAttributeVersion0.id }); expect(result.isSuccess).toBe(true); const returnedVersions = result.value; - expect(returnedVersions).toStrictEqual([ownSharedThirdPartyRelationshipAttribute]); + expect(returnedVersions).toStrictEqual([emittedThirdPartyRelationshipAttribute]); }); test("should return an empty list if a relationship attribute without associated third party relationship attributes is queried", async () => { @@ -2039,7 +2039,7 @@ describe("DeleteAttributeUseCases", () => { expect(getDeletedPredecessorResult).toBeAnError(/.*/, "error.runtime.recordNotFound"); }); - test("should remove 'shareInfo.sourceAttribute' from own shared third party relationship attribute copies of a deleted repository attribute", async () => { + test("should remove 'shareInfo.sourceAttribute' from emitted ThirdPartyRelationshipAttribute copies of a deleted RepositoryAttribute", async () => { const ownSharedRelationshipAttribute = await executeFullCreateAndShareRelationshipAttributeFlow(services1, services3, { content: { value: { @@ -2068,7 +2068,7 @@ describe("DeleteAttributeUseCases", () => { } }; - const ownSharedThirdPartyRelationshipAttribute = await executeFullRequestAndAcceptExistingAttributeFlow( + const emittedThirdPartyRelationshipAttribute = await executeFullRequestAndAcceptExistingAttributeFlow( services1, services2, requestParams, @@ -2077,11 +2077,11 @@ describe("DeleteAttributeUseCases", () => { await services1.consumption.attributes.deleteOwnSharedAttributeAndNotifyPeer({ attributeId: ownSharedRelationshipAttribute.id }); - const updatedOwnSharedThirdPartyRelationshipAttributeResult = await services1.consumption.attributes.getAttribute({ id: ownSharedThirdPartyRelationshipAttribute.id }); - expect(updatedOwnSharedThirdPartyRelationshipAttributeResult.isSuccess).toBe(true); - const updatedOwnSharedThirdPartyRelationshipAttribute = updatedOwnSharedThirdPartyRelationshipAttributeResult.value; - expect(updatedOwnSharedThirdPartyRelationshipAttribute.shareInfo).toBeDefined(); - expect(updatedOwnSharedThirdPartyRelationshipAttribute.shareInfo!.sourceAttribute).toBeUndefined(); + const updatedEmittedThirdPartyRelationshipAttributeResult = await services1.consumption.attributes.getAttribute({ id: emittedThirdPartyRelationshipAttribute.id }); + expect(updatedEmittedThirdPartyRelationshipAttributeResult.isSuccess).toBe(true); + const updatedEmittedThirdPartyRelationshipAttribute = updatedEmittedThirdPartyRelationshipAttributeResult.value; + expect(updatedEmittedThirdPartyRelationshipAttribute.shareInfo).toBeDefined(); + expect(updatedEmittedThirdPartyRelationshipAttribute.shareInfo!.sourceAttribute).toBeUndefined(); }); test("should set the 'succeeds' property of the own shared identity attribute successor to undefined", async () => { @@ -2147,7 +2147,7 @@ describe("DeleteAttributeUseCases", () => { expect(getDeletedPredecessorResult).toBeAnError(/.*/, "error.runtime.recordNotFound"); }); - test("should remove 'shareInfo.sourceAttribute' from third party relationship attribute copies of a deleted relationship attribute", async () => { + test("should remove 'shareInfo.sourceAttribute' from emitted ThirdPartyRelationshipAttribute copies of a deleted peer shared RelationshipAttribute", async () => { const peerSharedRelationshipAttribute = await executeFullCreateAndShareRelationshipAttributeFlow(services3, services1, { content: { value: { @@ -2176,7 +2176,7 @@ describe("DeleteAttributeUseCases", () => { } }; - const thirdPartyOwnedRelationshipAttribute = await executeFullRequestAndAcceptExistingAttributeFlow( + const emittedThirdPartyRelationshipAttribute = await executeFullRequestAndAcceptExistingAttributeFlow( services1, services2, requestParams, @@ -2185,13 +2185,13 @@ describe("DeleteAttributeUseCases", () => { await services1.consumption.attributes.deletePeerSharedAttributeAndNotifyOwner({ attributeId: peerSharedRelationshipAttribute.id }); - const updatedThirdPartyOwnedRelationshipAttributeResult = await services1.consumption.attributes.getAttribute({ - id: thirdPartyOwnedRelationshipAttribute.id + const updatedEmittedThirdPartyRelationshipAttributeResult = await services1.consumption.attributes.getAttribute({ + id: emittedThirdPartyRelationshipAttribute.id }); - expect(updatedThirdPartyOwnedRelationshipAttributeResult.isSuccess).toBe(true); - const updatedThirdPartyOwnedRelationshipAttribute = updatedThirdPartyOwnedRelationshipAttributeResult.value; - expect(updatedThirdPartyOwnedRelationshipAttribute.shareInfo).toBeDefined(); - expect(updatedThirdPartyOwnedRelationshipAttribute.shareInfo!.sourceAttribute).toBeUndefined(); + expect(updatedEmittedThirdPartyRelationshipAttributeResult.isSuccess).toBe(true); + const updatedEmittedThirdPartyRelationshipAttribute = updatedEmittedThirdPartyRelationshipAttributeResult.value; + expect(updatedEmittedThirdPartyRelationshipAttribute.shareInfo).toBeDefined(); + expect(updatedEmittedThirdPartyRelationshipAttribute.shareInfo!.sourceAttribute).toBeUndefined(); }); test("should set the 'succeeds' property of the peer shared identity attribute successor to undefined", async () => { @@ -2239,9 +2239,9 @@ describe("DeleteAttributeUseCases", () => { }); }); - describe(DeleteThirdPartyOwnedRelationshipAttributeAndNotifyPeerUseCase.name, () => { + describe(DeleteThirdPartyRelationshipAttributeAndNotifyPeerUseCase.name, () => { let peerSharedRelationshipAttribute: LocalAttributeDTO; - let thirdPartyOwnedRelationshipAttribute: LocalAttributeDTO; + let emittedThirdPartyRelationshipAttribute: LocalAttributeDTO; beforeEach(async () => { peerSharedRelationshipAttribute = await executeFullCreateAndShareRelationshipAttributeFlow(services3, services1, { content: { @@ -2271,72 +2271,88 @@ describe("DeleteAttributeUseCases", () => { } }; - thirdPartyOwnedRelationshipAttribute = await executeFullRequestAndAcceptExistingAttributeFlow(services1, services2, requestParams, peerSharedRelationshipAttribute.id); + emittedThirdPartyRelationshipAttribute = await executeFullRequestAndAcceptExistingAttributeFlow( + services1, + services2, + requestParams, + peerSharedRelationshipAttribute.id + ); }); - test("should delete a third party owned RelationshipAttribute as the sender of it", async () => { - const senderThirdPartyOwnedRelationshipAttribute = (await services1.consumption.attributes.getAttribute({ id: thirdPartyOwnedRelationshipAttribute.id })).value; - expect(senderThirdPartyOwnedRelationshipAttribute).toBeDefined(); + test("should delete a ThirdPartyRelationshipAttribute as the emitter of it", async () => { + expect(emittedThirdPartyRelationshipAttribute).toBeDefined(); - const deletionResult = await services1.consumption.attributes.deleteThirdPartyOwnedRelationshipAttributeAndNotifyPeer({ - attributeId: senderThirdPartyOwnedRelationshipAttribute.id + const deletionResult = await services1.consumption.attributes.deleteThirdPartyRelationshipAttributeAndNotifyPeer({ + attributeId: emittedThirdPartyRelationshipAttribute.id }); expect(deletionResult.isSuccess).toBe(true); - const getDeletedAttributeResult = await services1.consumption.attributes.getAttribute({ id: senderThirdPartyOwnedRelationshipAttribute.id }); + const getDeletedAttributeResult = await services1.consumption.attributes.getAttribute({ id: emittedThirdPartyRelationshipAttribute.id }); expect(getDeletedAttributeResult).toBeAnError(/.*/, "error.runtime.recordNotFound"); }); - test("should delete a third party owned RelationshipAttribute as the recipient of it", async () => { - const recipientThirdPartyOwnedRelationshipAttribute = (await services2.consumption.attributes.getAttribute({ id: thirdPartyOwnedRelationshipAttribute.id })).value; - expect(recipientThirdPartyOwnedRelationshipAttribute).toBeDefined(); + test("should delete a ThirdPartyRelationshipAttribute as the recipient of it", async () => { + const receivedThirdPartyRelationshipAttribute = (await services2.consumption.attributes.getAttribute({ id: emittedThirdPartyRelationshipAttribute.id })).value; + expect(receivedThirdPartyRelationshipAttribute).toBeDefined(); - const deletionResult = await services2.consumption.attributes.deleteThirdPartyOwnedRelationshipAttributeAndNotifyPeer({ - attributeId: recipientThirdPartyOwnedRelationshipAttribute.id + const deletionResult = await services2.consumption.attributes.deleteThirdPartyRelationshipAttributeAndNotifyPeer({ + attributeId: receivedThirdPartyRelationshipAttribute.id }); expect(deletionResult.isSuccess).toBe(true); - const getDeletedAttributeResult = await services2.consumption.attributes.getAttribute({ id: recipientThirdPartyOwnedRelationshipAttribute.id }); + const getDeletedAttributeResult = await services2.consumption.attributes.getAttribute({ id: receivedThirdPartyRelationshipAttribute.id }); expect(getDeletedAttributeResult).toBeAnError(/.*/, "error.runtime.recordNotFound"); }); - test("should notify about third party owned RelationshipAttribute as the sender of it", async () => { + test("should notify about ThirdPartyRelationshipAttribute as the emitter of it", async () => { const notificationId = ( - await services1.consumption.attributes.deleteThirdPartyOwnedRelationshipAttributeAndNotifyPeer({ attributeId: thirdPartyOwnedRelationshipAttribute.id }) + await services1.consumption.attributes.deleteThirdPartyRelationshipAttributeAndNotifyPeer({ attributeId: emittedThirdPartyRelationshipAttribute.id }) ).value.notificationId; const timeBeforeUpdate = CoreDate.utc(); await syncUntilHasMessageWithNotification(services2.transport, notificationId); - await services2.eventBus.waitForEvent(ThirdPartyOwnedRelationshipAttributeDeletedByPeerEvent, (e) => { - return e.data.id.toString() === thirdPartyOwnedRelationshipAttribute.id; + await services2.eventBus.waitForEvent(ThirdPartyRelationshipAttributeDeletedByPeerEvent, (e) => { + return e.data.id.toString() === emittedThirdPartyRelationshipAttribute.id; }); const timeAfterUpdate = CoreDate.utc(); - const result = await services2.consumption.attributes.getAttribute({ id: thirdPartyOwnedRelationshipAttribute.id }); + const result = await services2.consumption.attributes.getAttribute({ id: emittedThirdPartyRelationshipAttribute.id }); expect(result.isSuccess).toBe(true); const updatedAttribute = result.value; expect(updatedAttribute.deletionInfo?.deletionStatus).toStrictEqual(LocalAttributeDeletionStatus.DeletedByPeer); expect(CoreDate.from(updatedAttribute.deletionInfo!.deletionDate).isBetween(timeBeforeUpdate, timeAfterUpdate.add(1))).toBe(true); }); - test("should notify about third party owned RelationshipAttribute as the recipient of it", async () => { + test("should notify about ThirdPartyRelationshipAttribute as the recipient of it", async () => { const notificationId = ( - await services2.consumption.attributes.deleteThirdPartyOwnedRelationshipAttributeAndNotifyPeer({ attributeId: thirdPartyOwnedRelationshipAttribute.id }) + await services2.consumption.attributes.deleteThirdPartyRelationshipAttributeAndNotifyPeer({ attributeId: emittedThirdPartyRelationshipAttribute.id }) ).value.notificationId; const timeBeforeUpdate = CoreDate.utc(); await syncUntilHasMessageWithNotification(services1.transport, notificationId); - await services1.eventBus.waitForEvent(ThirdPartyOwnedRelationshipAttributeDeletedByPeerEvent, (e) => { - return e.data.id.toString() === thirdPartyOwnedRelationshipAttribute.id; + await services1.eventBus.waitForEvent(ThirdPartyRelationshipAttributeDeletedByPeerEvent, (e) => { + return e.data.id.toString() === emittedThirdPartyRelationshipAttribute.id; }); const timeAfterUpdate = CoreDate.utc(); - const result = await services1.consumption.attributes.getAttribute({ id: thirdPartyOwnedRelationshipAttribute.id }); + const result = await services1.consumption.attributes.getAttribute({ id: emittedThirdPartyRelationshipAttribute.id }); expect(result.isSuccess).toBe(true); const updatedAttribute = result.value; expect(updatedAttribute.deletionInfo?.deletionStatus).toStrictEqual(LocalAttributeDeletionStatus.DeletedByPeer); expect(CoreDate.from(updatedAttribute.deletionInfo!.deletionDate).isBetween(timeBeforeUpdate, timeAfterUpdate.add(1))).toBe(true); }); + + test("should delete a ThirdPartyRelationshipAttribute as the emitter of it using the deprecated function deleteThirdPartyOwnedRelationshipAttributeAndNotifyPeer", async () => { + expect(emittedThirdPartyRelationshipAttribute).toBeDefined(); + + const deletionResult = await services1.consumption.attributes.deleteThirdPartyOwnedRelationshipAttributeAndNotifyPeer({ + attributeId: emittedThirdPartyRelationshipAttribute.id + }); + expect(deletionResult.isSuccess).toBe(true); + + const getDeletedAttributeResult = await services1.consumption.attributes.getAttribute({ id: emittedThirdPartyRelationshipAttribute.id }); + expect(getDeletedAttributeResult).toBeAnError(/.*/, "error.runtime.recordNotFound"); + }); }); });