Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Uniqueness of key for RelationshipAttributes #319

Merged
merged 110 commits into from
Dec 17, 2024
Merged
Show file tree
Hide file tree
Changes from 101 commits
Commits
Show all changes
110 commits
Select commit Hold shift + click to select a range
d08c7dd
refactor: preapare CreateAttributeRequestItemProcessor to add more va…
britsta Nov 4, 2024
7874cfd
feat: add validation for CreateAttributeRequestItemProcessor
britsta Nov 4, 2024
d907ad3
test: CreateAttributeRequestItemProcessor key validation
britsta Nov 4, 2024
a8e8540
fix: uniqueness for key only instead of pair of owner and key
britsta Nov 4, 2024
2a6a745
fix: failing test
britsta Nov 4, 2024
e149cad
test: ensure key uniqueness in attributes.test
britsta Nov 4, 2024
6238152
test: ensure key uniqueness in CreateRelationshipAttributeRequestItem…
britsta Nov 4, 2024
34923c7
feat: use database language every database understands
britsta Nov 5, 2024
72099fd
test: ensure key uniqueness only for constant ownership
britsta Nov 5, 2024
3b06f91
fix: too late clean up of Attributes
britsta Nov 5, 2024
220234c
Merge branch 'main' into feature/uniqueness-of-key-for-relationshipat…
britsta Nov 5, 2024
61e36cf
feat: ensure key uniqueness only for RelationshipAttributes that are …
britsta Nov 5, 2024
fade54a
refactor: extract function call as auxiliary function
britsta Nov 5, 2024
8cb471c
refactor: put afterEach block inside describe block
britsta Nov 5, 2024
a758774
feat: ensure key uniqueness for Recipient within CreateAttributeReque…
britsta Nov 5, 2024
69b38ee
refactor: auxiliary function can be applied to queries as well
britsta Nov 5, 2024
1724a43
feat: ensure key uniqueness for Sender within ReadAttributeRequestIte…
britsta Nov 5, 2024
dd692ac
feat: ensure key uniqueness only for constant value type
britsta Nov 5, 2024
5ed3477
fix: failing tests with async canCreateOutgoingRequestItem method
britsta Nov 5, 2024
3281167
feat: key uniqueness for Recipient within ReadAttributeRequestItemPro…
britsta Nov 5, 2024
93c4e51
Merge branch 'main' into feature/uniqueness-of-key-for-relationshipat…
britsta Nov 7, 2024
2a137af
Merge branch 'main' into feature/uniqueness-of-key-for-relationshipat…
britsta Nov 8, 2024
511364a
feat: ensure key uniquess for empty owner as placeholder as well
britsta Nov 8, 2024
c7faa77
refactor: simplify error message
britsta Nov 8, 2024
4d512ab
refactor: move validation to canAccept method
britsta Nov 8, 2024
cdd7639
refactor: standardize error messages
britsta Nov 8, 2024
890a4ef
test: ensure key uniqueness with empty owner
britsta Nov 8, 2024
e1fabf6
test: move tests to canAccept block
britsta Nov 8, 2024
c0ca07c
fix: call accept instead of canAccept
britsta Nov 8, 2024
1ab707c
test: refactor canAccept test with SuccessfulValidationResult
britsta Nov 8, 2024
57306d4
test: make tests independent of each other
britsta Nov 8, 2024
ee19aef
feat: ensure key uniqueness for empty owner queried with ReadAttribut…
britsta Nov 8, 2024
54d8df0
feat: ensure key uniqueness on Sender site of ProposeAttributeRequest…
britsta Nov 8, 2024
34df52a
feat: ensure key uniqueness on Recipient site of ProposeAttributeRequ…
britsta Nov 8, 2024
4625a4c
refactor: standardize error messages
britsta Nov 11, 2024
05b0039
feat: prohibit Requests that create more than one RelationshipAttribu…
britsta Nov 12, 2024
418e4c9
Merge branch 'main' into feature/uniqueness-of-key-for-relationshipat…
britsta Nov 12, 2024
5b80233
Merge branch 'main' into feature/uniqueness-of-key-for-relationshipat…
britsta Nov 12, 2024
9b87f1e
fix: title type
britsta Nov 12, 2024
9708eae
test: key uniqueness of incomingRequestsController
britsta Nov 12, 2024
98e2d77
Merge branch 'main' into feature/uniqueness-of-key-for-relationshipat…
britsta Nov 12, 2024
e4289a4
Merge branch 'feature/uniqueness-of-key-for-relationshipattributes' o…
britsta Nov 12, 2024
f16cdf7
test: key uniqueness of OutgoingRequestsController
britsta Nov 12, 2024
4cd7902
refactor: remove recursion of IncomingRequestsController
britsta Nov 12, 2024
b43e8b6
refactor: keep RequestItemGroup in mind
britsta Nov 12, 2024
7c31e1a
Merge branch 'main' into feature/uniqueness-of-key-for-relationshipat…
britsta Nov 13, 2024
023a7e7
refactor: use auxiliary method for clearness
britsta Nov 13, 2024
2c81c18
feat: handle empty owner in IncomingRequestsController and OutgoingRe…
britsta Nov 13, 2024
a513af6
test: ensure key uniqueness for empty owner
britsta Nov 13, 2024
6d1aec8
refactor: move validation from canDecide to canAccept
britsta Nov 13, 2024
f5d43e4
fix: failing IncomingRequestsController test
britsta Nov 13, 2024
d95ac55
test: ensure key uniqueness with RequestItemGroups
britsta Nov 13, 2024
1377b89
fix: wrong DecideRequestParameters for RequestItemGroups
britsta Nov 13, 2024
7cca039
feat: use already known separation sequence
britsta Nov 13, 2024
4061e7f
feat: give better validation function name
britsta Nov 13, 2024
4b417ea
refactor: do not break existing code blocks anymore
britsta Nov 13, 2024
5c7c459
fix: error due to incorrect merging
britsta Nov 13, 2024
0307d56
test: ensure key uniqueness with ProposeAttributeRequestItem
britsta Nov 13, 2024
b7ccf7e
chore: descriptive values should not start with capital letter
britsta Nov 13, 2024
0a32bb9
refactor: rename error code
britsta Nov 13, 2024
ca33cd3
feat: distinguish between user mistake and deformed Request
britsta Nov 13, 2024
5b2ce6e
feat: throwing instead of returning error if Request is deformed
britsta Nov 13, 2024
44bd001
feat: reuse key uniqueness error
britsta Nov 13, 2024
cbeeaa6
feat: distinguish between deformed Requests and wrong accept parameters
britsta Nov 13, 2024
27e55a0
test: RequestItem cannot be accepted due to incorrect params of User
britsta Nov 14, 2024
9d23aa1
fix: failing test due to void return
britsta Nov 14, 2024
a1143c8
feat: self-explanatory variable names
britsta Nov 14, 2024
c7c63a9
refactor: more renaming of variables
britsta Nov 14, 2024
d01feb9
refactor: unify renaming
britsta Nov 14, 2024
b2f7097
Merge branch 'main' into feature/uniqueness-of-key-for-relationshipat…
britsta Nov 15, 2024
b6bb2f2
Merge branch 'main' into feature/uniqueness-of-key-for-relationshipat…
britsta Dec 2, 2024
42042b6
feat: simplify error message for unknown recipient of Request
britsta Dec 4, 2024
74d8dc2
Merge branch 'main' into feature/uniqueness-of-key-for-relationshipat…
britsta Dec 4, 2024
b7e8f91
feat: incorporate some review comments
britsta Dec 4, 2024
feead9b
fix: failing test due to wrong error format
britsta Dec 4, 2024
4763175
feat: incorporate review comment
britsta Dec 5, 2024
e4fa4a7
refactor: prepare reusability of code
britsta Dec 5, 2024
f60506e
Merge branch 'main' into feature/uniqueness-of-key-for-relationshipat…
britsta Dec 5, 2024
22fac71
Merge branch 'feature/uniqueness-of-key-for-relationshipattributes' o…
britsta Dec 5, 2024
6360712
fix: error due to merge
britsta Dec 5, 2024
c9c4dd4
Merge branch 'main' into feature/uniqueness-of-key-for-relationshipat…
mergify[bot] Dec 9, 2024
d71f587
Merge branch 'main' into feature/uniqueness-of-key-for-relationshipat…
mergify[bot] Dec 9, 2024
d7df45a
Merge branch 'main' into feature/uniqueness-of-key-for-relationshipat…
mergify[bot] Dec 10, 2024
23747b3
Merge branch 'main' into feature/uniqueness-of-key-for-relationshipat…
mergify[bot] Dec 10, 2024
d17cdba
Merge branch 'main' into feature/uniqueness-of-key-for-relationshipat…
mergify[bot] Dec 10, 2024
1d561da
Merge branch 'main' into feature/uniqueness-of-key-for-relationshipat…
mergify[bot] Dec 10, 2024
326d967
feat: use JSON.stringify() instead of own method for extracting ident…
britsta Dec 11, 2024
5dd7910
refactor: reduce redundancy by move auxiliary functions to different …
britsta Dec 11, 2024
99e2ad7
feat: inform user what key would be redundantly in use
britsta Dec 11, 2024
9ed1c84
Merge branch 'main' into feature/uniqueness-of-key-for-relationshipat…
mergify[bot] Dec 11, 2024
92342b5
Merge branch 'main' into feature/uniqueness-of-key-for-relationshipat…
mergify[bot] Dec 12, 2024
c6014e5
Merge branch 'main' into feature/uniqueness-of-key-for-relationshipat…
mergify[bot] Dec 12, 2024
f3a786e
Merge branch 'main' into feature/uniqueness-of-key-for-relationshipat…
mergify[bot] Dec 13, 2024
ff41a74
feat: incorporate some review comments
britsta Dec 13, 2024
90b0192
Merge branch 'main' into feature/uniqueness-of-key-for-relationshipat…
mergify[bot] Dec 13, 2024
6c2917a
Merge branch 'main' into feature/uniqueness-of-key-for-relationshipat…
mergify[bot] Dec 16, 2024
374ac86
feat: incoporate review comments
britsta Dec 16, 2024
16ef18a
Merge branch 'feature/uniqueness-of-key-for-relationshipattributes' o…
britsta Dec 16, 2024
367342f
refactor: change order of thrown errors
britsta Dec 16, 2024
ccb0e17
test: can propose and query RelationshipAttribute with same key but d…
britsta Dec 16, 2024
05d8ca0
Merge branch 'main' into feature/uniqueness-of-key-for-relationshipat…
mergify[bot] Dec 16, 2024
a9cc5ef
Merge branch 'main' into feature/uniqueness-of-key-for-relationshipat…
mergify[bot] Dec 16, 2024
eeec2b9
feat: incorporate review comments
britsta Dec 17, 2024
0887e49
Merge branch 'feature/uniqueness-of-key-for-relationshipattributes' o…
britsta Dec 17, 2024
2415d79
refactor: simplify extraction of fragments of mustBeAcceptedItems
Milena-Czierlinski Dec 17, 2024
e1e242b
refactor: further simplification of extraction of fragments of mustBe…
Milena-Czierlinski Dec 17, 2024
5d7a12e
refactor: simplify extraction of fragments of accepte items
Milena-Czierlinski Dec 17, 2024
5b65b17
fix: returned instead of continued
britsta Dec 17, 2024
a665282
test: RequestItem cannot be accepted if key uniqueness is violated re…
britsta Dec 17, 2024
03901ce
fix: forgotten change in error messages
britsta Dec 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/consumption/src/consumption/ConsumptionCoreErrors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,10 @@ class Requests {
return new CoreError("error.consumption.requests.peerIsInDeletion", message);
}

public violatedKeyUniquenessOfRelationshipAttributes(message: string) {
return new CoreError("error.consumption.requests.violatedKeyUniquenessOfRelationshipAttributes", message);
}

public inheritedFromItem(message: string) {
return new ApplicationError("error.consumption.requests.validation.inheritedFromItem", message);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1294,6 +1294,25 @@ export class AttributesController extends ConsumptionBaseController {
return ownSharedAttributeSuccessors;
}

public async getRelationshipAttributesOfValueTypeToPeerWithGivenKeyAndOwner(key: string, owner: CoreAddress, valueType: string, peer: CoreAddress): Promise<LocalAttribute[]> {
return await this.getLocalAttributes({
"content.@type": "RelationshipAttribute",
"content.owner": owner.toString(),
"content.key": key,
"content.value.@type": valueType,
"shareInfo.peer": peer.toString(),
"shareInfo.thirdPartyAddress": { $exists: false },
"deletionInfo.deletionStatus": {
$nin: [
LocalAttributeDeletionStatus.ToBeDeleted,
britsta marked this conversation as resolved.
Show resolved Hide resolved
LocalAttributeDeletionStatus.ToBeDeletedByPeer,
LocalAttributeDeletionStatus.DeletedByPeer,
LocalAttributeDeletionStatus.DeletedByOwner
]
}
});
}

public async getAttributeTagCollection(): Promise<AttributeTagCollection> {
const backboneTagCollection = (await this.attributeTagClient.getTagCollection()).value;
return AttributeTagCollection.from(backboneTagCollection);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { RequestItemProcessorRegistry } from "../itemProcessors/RequestItemProce
import { ILocalRequestSource, LocalRequest } from "../local/LocalRequest";
import { LocalRequestStatus } from "../local/LocalRequestStatus";
import { LocalResponse, LocalResponseSource } from "../local/LocalResponse";
import { validateKeyUniquenessOfRelationshipAttributesWithinIncomingRequest } from "../utility/validateRelationshipAttributesWithinRequest";
import { DecideRequestParametersValidator } from "./DecideRequestParametersValidator";
import { CheckPrerequisitesOfIncomingRequestParameters, ICheckPrerequisitesOfIncomingRequestParameters } from "./checkPrerequisites/CheckPrerequisitesOfIncomingRequestParameters";
import { CompleteIncomingRequestParameters, ICompleteIncomingRequestParameters } from "./complete/CompleteIncomingRequestParameters";
Expand Down Expand Up @@ -166,7 +167,15 @@ export class IncomingRequestsController extends ConsumptionBaseController {
}

public async canAccept(params: DecideRequestParametersJSON): Promise<ValidationResult> {
return await this.canDecide({ ...params, accept: true });
const canDecideResult = await this.canDecide({ ...params, accept: true });

if (canDecideResult.isError()) return canDecideResult;

const request = await this.getOrThrow(params.requestId);
const keyUniquenessValidationResult = validateKeyUniquenessOfRelationshipAttributesWithinIncomingRequest(request.content.items, params.items, this.identity.address);
if (keyUniquenessValidationResult.isError()) return keyUniquenessValidationResult;

return canDecideResult;
}

public async canReject(params: DecideRequestParametersJSON): Promise<ValidationResult> {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
import { CreateAttributeAcceptResponseItem, CreateAttributeRequestItem, IdentityAttribute, RejectResponseItem, Request, ResponseItemResult } from "@nmshd/content";
import {
CreateAttributeAcceptResponseItem,
CreateAttributeRequestItem,
IdentityAttribute,
RejectResponseItem,
RelationshipAttribute,
Request,
ResponseItemResult
} from "@nmshd/content";
import { CoreAddress } from "@nmshd/core-types";
import { ConsumptionCoreErrors } from "../../../../consumption/ConsumptionCoreErrors";
import { LocalAttribute } from "../../../attributes";
Expand All @@ -8,11 +16,7 @@ import { GenericRequestItemProcessor } from "../GenericRequestItemProcessor";
import { LocalRequestInfo } from "../IRequestItemProcessor";

export class CreateAttributeRequestItemProcessor extends GenericRequestItemProcessor<CreateAttributeRequestItem> {
public override canCreateOutgoingRequestItem(
requestItem: CreateAttributeRequestItem,
_request?: Request,
recipient?: CoreAddress
): ValidationResult | Promise<ValidationResult> {
public override async canCreateOutgoingRequestItem(requestItem: CreateAttributeRequestItem, _request?: Request, recipient?: CoreAddress): Promise<ValidationResult> {
const recipientIsAttributeOwner = requestItem.attribute.owner.equals(recipient);
const senderIsAttributeOwner = requestItem.attribute.owner.equals(this.currentIdentityAddress);
const ownerIsEmptyString = requestItem.attribute.owner.toString() === "";
Expand All @@ -30,30 +34,66 @@ export class CreateAttributeRequestItemProcessor extends GenericRequestItemProce
);
}

if (typeof recipient !== "undefined") {
return ValidationResult.error(
ConsumptionCoreErrors.requests.invalidRequestItem(
"The owner of the provided IdentityAttribute for the `attribute` property can only be the address of the recipient or an empty string. The latter will default to the address of the recipient."
)
);
}

if (!(recipientIsAttributeOwner || senderIsAttributeOwner || ownerIsEmptyString)) {
return ValidationResult.error(
ConsumptionCoreErrors.requests.invalidRequestItem(
"The owner of the provided RelationshipAttribute for the `attribute` property can only be the address of the sender, the address of the recipient or an empty string. The latter will default to the address of the recipient."
)
);
}

if (typeof recipient !== "undefined") {
const relationshipAttributesWithSameKey = await this.consumptionController.attributes.getRelationshipAttributesOfValueTypeToPeerWithGivenKeyAndOwner(
britsta marked this conversation as resolved.
Show resolved Hide resolved
requestItem.attribute.key,
ownerIsEmptyString ? recipient : requestItem.attribute.owner,
requestItem.attribute.value.toJSON()["@type"],
recipient
);

if (relationshipAttributesWithSameKey.length !== 0) {
return ValidationResult.error(
ConsumptionCoreErrors.requests.invalidRequestItem(
"The owner of the provided IdentityAttribute for the `attribute` property can only be the Recipient's Address or an empty string. The latter will default to the Recipient's Address."
`The creation of the provided RelationshipAttribute cannot be requested because there is already a RelationshipAttribute in the context of this Relationship with the same key '${requestItem.attribute.key}', owner and value type.`
)
);
}
}

return ValidationResult.error(
ConsumptionCoreErrors.requests.invalidRequestItem(
"The owner of the provided IdentityAttribute for the `attribute` property can only be an empty string. It will default to the Recipient's Address."
)
return ValidationResult.success();
}

public override async canAccept(requestItem: CreateAttributeRequestItem, _params: AcceptRequestItemParametersJSON, requestInfo: LocalRequestInfo): Promise<ValidationResult> {
if (requestItem.attribute instanceof RelationshipAttribute) {
const ownerIsEmptyString = requestItem.attribute.owner.toString() === "";

const relationshipAttributesWithSameKey = await this.consumptionController.attributes.getRelationshipAttributesOfValueTypeToPeerWithGivenKeyAndOwner(
requestItem.attribute.key,
ownerIsEmptyString ? this.currentIdentityAddress : requestItem.attribute.owner,
requestItem.attribute.value.toJSON()["@type"],
requestInfo.peer
);
}

if (recipientIsAttributeOwner || senderIsAttributeOwner || ownerIsEmptyString) {
return ValidationResult.success();
if (relationshipAttributesWithSameKey.length !== 0 && requestItem.mustBeAccepted) {
throw ConsumptionCoreErrors.requests.violatedKeyUniquenessOfRelationshipAttributes(
`The provided RelationshipAttribute cannot be created because there is already a RelationshipAttribute in the context of this Relationship with the same key '${requestItem.attribute.key}', owner and value type.`
);
britsta marked this conversation as resolved.
Show resolved Hide resolved
britsta marked this conversation as resolved.
Show resolved Hide resolved
} else if (relationshipAttributesWithSameKey.length !== 0) {
return ValidationResult.error(
ConsumptionCoreErrors.requests.invalidAcceptParameters(
`This CreateAttributeRequestItem cannot be accepted as the provided RelationshipAttribute cannot be created because there is already a RelationshipAttribute in the context of this Relationship with the same key '${requestItem.attribute.key}', owner and value type.`
)
);
}
}
britsta marked this conversation as resolved.
Show resolved Hide resolved

return ValidationResult.error(
ConsumptionCoreErrors.requests.invalidRequestItem(
"The owner of the provided RelationshipAttribute for the `attribute` property can only be the address of the sender, recipient or an empty string. The latter will default to the address of the recipient."
)
);
return ValidationResult.success();
}

public override async accept(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import validateQuery from "../utility/validateQuery";
import { AcceptProposeAttributeRequestItemParameters, AcceptProposeAttributeRequestItemParametersJSON } from "./AcceptProposeAttributeRequestItemParameters";

export class ProposeAttributeRequestItemProcessor extends GenericRequestItemProcessor<ProposeAttributeRequestItem, AcceptProposeAttributeRequestItemParametersJSON> {
public override canCreateOutgoingRequestItem(requestItem: ProposeAttributeRequestItem, _request: Request, recipient?: CoreAddress): ValidationResult {
public override async canCreateOutgoingRequestItem(requestItem: ProposeAttributeRequestItem, _request: Request, recipient?: CoreAddress): Promise<ValidationResult> {
const queryValidationResult = this.validateQuery(requestItem, recipient);
if (queryValidationResult.isError()) {
return queryValidationResult;
Expand All @@ -46,6 +46,23 @@ export class ProposeAttributeRequestItemProcessor extends GenericRequestItemProc
return proposedAttributeMatchesWithQueryValidationResult;
}

if (requestItem.query instanceof RelationshipAttributeQuery && typeof recipient !== "undefined") {
const relationshipAttributesWithSameKey = await this.consumptionController.attributes.getRelationshipAttributesOfValueTypeToPeerWithGivenKeyAndOwner(
requestItem.query.key,
recipient,
requestItem.query.attributeCreationHints.valueType,
recipient
);

if (relationshipAttributesWithSameKey.length !== 0) {
return ValidationResult.error(
ConsumptionCoreErrors.requests.invalidRequestItem(
`The creation of the proposed RelationshipAttribute cannot be requested because there is already a RelationshipAttribute in the context of this Relationship with the same key '${requestItem.query.key}', owner and value type.`
)
);
}
}

return ValidationResult.success();
}

Expand All @@ -67,12 +84,14 @@ export class ProposeAttributeRequestItemProcessor extends GenericRequestItemProc
return commonQueryValidationResult;
}

if (requestItem.query instanceof RelationshipAttributeQuery && requestItem.query.owner.toString() !== "") {
return ValidationResult.error(
ConsumptionCoreErrors.requests.invalidRequestItem(
"The owner of the given `query` can only be an empty string. This is because you can only propose Attributes where the Recipient of the Request is the owner anyway. And in order to avoid mistakes, the owner will be automatically filled for you."
)
);
if (requestItem.query instanceof RelationshipAttributeQuery) {
if (requestItem.query.owner.toString() !== "") {
return ValidationResult.error(
ConsumptionCoreErrors.requests.invalidRequestItem(
"The owner of the given `query` can only be an empty string. This is because you can only propose Attributes where the Recipient of the Request is the owner anyway. And in order to avoid mistakes, the owner will be automatically filled for you."
)
);
}
britsta marked this conversation as resolved.
Show resolved Hide resolved
}

return ValidationResult.success();
Expand Down Expand Up @@ -157,6 +176,27 @@ export class ProposeAttributeRequestItemProcessor extends GenericRequestItemProc
const answerToQueryValidationResult = validateAttributeMatchesWithQuery(requestItem.query, attribute, this.currentIdentityAddress, requestInfo.peer);
if (answerToQueryValidationResult.isError()) return answerToQueryValidationResult;

if (requestItem.query instanceof RelationshipAttributeQuery) {
const relationshipAttributesWithSameKey = await this.consumptionController.attributes.getRelationshipAttributesOfValueTypeToPeerWithGivenKeyAndOwner(
requestItem.query.key,
this.currentIdentityAddress,
requestItem.query.attributeCreationHints.valueType,
requestInfo.peer
);

if (relationshipAttributesWithSameKey.length !== 0 && requestItem.mustBeAccepted) {
throw ConsumptionCoreErrors.requests.violatedKeyUniquenessOfRelationshipAttributes(
`The queried RelationshipAttribute cannot be created because there is already a RelationshipAttribute in the context of this Relationship with the same key '${requestItem.query.key}', owner and value type.`
);
} else if (relationshipAttributesWithSameKey.length !== 0) {
return ValidationResult.error(
ConsumptionCoreErrors.requests.invalidAcceptParameters(
`This ProposeAttributeRequestItem cannot be accepted as the queried RelationshipAttribute cannot be created because there is already a RelationshipAttribute in the context of this Relationship with the same key '${requestItem.query.key}', owner and value type.`
)
);
}
britsta marked this conversation as resolved.
Show resolved Hide resolved
}

return ValidationResult.success();
}

Expand Down
Loading
Loading