Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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/content/src/attributes/IdentityAttribute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ export class IdentityAttribute<TValueClass extends AttributeValues.Identity.Clas
}

public static validateTags(tags: string[]): string | undefined {
if (new Set(tags).size !== tags.length) {
return "The tags are not unique.";
}

if (tags.length > 20) {
return "The maximum number of tags is 20.";
}
Expand Down
15 changes: 2 additions & 13 deletions packages/content/src/attributes/IdentityAttributeQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { serialize, type, validate } from "@js-soft/ts-serval";
import { CoreDate, ICoreDate } from "@nmshd/core-types";
import { AbstractAttributeQuery, AbstractAttributeQueryJSON, IAbstractAttributeQuery } from "./AbstractAttributeQuery";
import { AttributeValues } from "./AttributeValueTypes";
import { IdentityAttribute } from "./IdentityAttribute";

export interface IdentityAttributeQueryJSON extends AbstractAttributeQueryJSON {
"@type": "IdentityAttributeQuery";
Expand All @@ -27,7 +28,7 @@ export class IdentityAttributeQuery extends AbstractAttributeQuery implements II
public valueType: AttributeValues.Identity.TypeName;

@serialize({ type: String })
@validate({ nullable: true, customValidator: IdentityAttributeQuery.validateTags })
@validate({ nullable: true, customValidator: IdentityAttribute.validateTags })
public tags?: string[];

@serialize()
Expand All @@ -45,16 +46,4 @@ export class IdentityAttributeQuery extends AbstractAttributeQuery implements II
public override toJSON(verbose?: boolean | undefined, serializeAsString?: boolean | undefined): IdentityAttributeQueryJSON {
return super.toJSON(verbose, serializeAsString) as IdentityAttributeQueryJSON;
}

private static validateTags(tags: string[]) {
if (tags.length > 20) {
return "The maximum number of tags is 20.";
}

if (tags.some((tag) => tag.length > 250)) {
return "The maximum length of a tag is 250 characters.";
}

return undefined;
}
}
13 changes: 13 additions & 0 deletions packages/content/test/attributes/IdentityAttribute.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -259,4 +259,17 @@ describe("IdentityAttribute", function () {
expect(affiliationAttribute.value.role).toBeInstanceOf(AffiliationRole);
expect(affiliationAttribute.value.unit).toBeInstanceOf(AffiliationUnit);
});

test("should validate uniqueness of tags", function () {
expect(() =>
IdentityAttribute.from({
value: {
"@type": "Nationality",
value: "DE"
},
owner: CoreAddress.from("address"),
tags: ["tag1", "tag1"]
})
).toThrow("IdentityAttribute.tags:Array :: The tags are not unique");
});
});
12 changes: 8 additions & 4 deletions packages/runtime/src/useCases/common/Schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21800,7 +21800,8 @@ export const UploadOwnFileRequest: any = {
"type": "array",
"items": {
"type": "string"
}
},
"uniqueItems": true
}
},
"required": [
Expand Down Expand Up @@ -21844,7 +21845,8 @@ export const UploadOwnFileValidatableRequest: any = {
"type": "array",
"items": {
"type": "string"
}
},
"uniqueItems": true
},
"content": {
"type": "object"
Expand Down Expand Up @@ -22179,14 +22181,16 @@ export const SendMessageRequest: any = {
"items": {
"$ref": "#/definitions/AddressString"
},
"minItems": 1
"minItems": 1,
"uniqueItems": true
},
"content": {},
"attachments": {
"type": "array",
"items": {
"$ref": "#/definitions/FileIdString"
}
},
"uniqueItems": true
}
},
"required": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ export interface UploadOwnFileRequest {
expiresAt?: ISO8601DateTimeString;
title?: string;
description?: string;
/**
* @uniqueItems true
*/
tags?: string[];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,13 @@ import { MessageMapper } from "./MessageMapper";
export interface SendMessageRequest {
/**
* @minItems 1
* @uniqueItems true
*/
recipients: AddressString[];
content: any;

/**
* @uniqueItems true
*/
attachments?: FileIdString[];
}

Expand Down
5 changes: 5 additions & 0 deletions packages/runtime/test/transport/files.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,11 @@ describe("File upload", () => {
const response = await transportServices1.files.uploadOwnFile(await makeUploadRequest({ expiresAt: "" }));
expect(response).toBeAnError("expiresAt must match ISO8601 datetime format", "error.runtime.validation.invalidPropertyValue");
});

test("cannot upload a file with a duplicate tag", async () => {
const response = await transportServices1.files.uploadOwnFile(await makeUploadRequest({ tags: ["tag1", "tag1"] }));
expect(response).toBeAnError("tags must NOT have duplicate items", "error.runtime.validation.invalidPropertyValue");
});
});

describe("Get file", () => {
Expand Down
27 changes: 27 additions & 0 deletions packages/runtime/test/transport/messages.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,33 @@ describe("Message errors", () => {
requestId = createRequestResult.id;
});

test("should throw correct error for duplicate recipient in the Message", async () => {
const result = await client1.transport.messages.sendMessage({
recipients: [client2.address, client2.address],
content: {
"@type": "Mail",
to: [],
subject: "A Subject",
body: "A Body"
}
});
expect(result).toBeAnError("recipients must NOT have duplicate items", "error.runtime.validation.invalidPropertyValue");
});

test("should throw correct error for duplicate attachment in the Message", async () => {
const result = await client1.transport.messages.sendMessage({
recipients: [client2.address],
content: {
"@type": "Mail",
to: [],
subject: "A Subject",
body: "A Body"
},
attachments: ["FIL12345678901234567", "FIL12345678901234567"]
});
expect(result).toBeAnError("attachments must NOT have duplicate items", "error.runtime.validation.invalidPropertyValue");
});

test("should throw correct error for empty 'to' in the Message", async () => {
const result = await client1.transport.messages.sendMessage({
recipients: [client2.address],
Expand Down