Skip to content

Commit

Permalink
Make relationship setting usable (#274)
Browse files Browse the repository at this point in the history
* refactor: add reference and scope to GetSettingByKey

* refactor: add reference and scope to UpsertSettingByKey

* feat: add originalName to IdentityDVO and RelationshipDVO

* refactor: query relationship setting correctly

* feat: add originalName to IdentityDVO and RelationshipDVO

* test: update tests for new settings utilities

* fix: update schemas

* fix: use correct value

* test: add test for updated RelationshipDVO

* fix: handle hardcoded settingsScope

* fix: typo

* chore: check more stuff
  • Loading branch information
jkoenig134 authored Sep 19, 2024
1 parent b71ea61 commit 929c99f
Show file tree
Hide file tree
Showing 8 changed files with 126 additions and 33 deletions.
32 changes: 23 additions & 9 deletions packages/runtime/src/dataViews/DataViewExpander.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1698,15 +1698,7 @@ export class DataViewExpander {
}

private async createRelationshipDVO(relationship: RelationshipDTO): Promise<RelationshipDVO> {
let relationshipSetting: RelationshipSettingDVO;
const settingResult = await this.consumption.settings.getSettings({ query: { reference: relationship.id } });
if (settingResult.value.length > 0) {
relationshipSetting = settingResult.value[0].value;
} else {
relationshipSetting = {
isPinned: false
};
}
const relationshipSetting = await this.getRelationshipSettingDVO(relationship);

const stringByType: Record<string, undefined | string> = {};
const relationshipAttributesResult = await this.consumption.attributes.getPeerSharedAttributes({ onlyValid: true, peer: relationship.peer });
Expand Down Expand Up @@ -1781,6 +1773,7 @@ export class DataViewExpander {
return {
id: relationship.id,
name: relationshipSetting.userTitle ?? name,
originalName: relationshipSetting.userTitle ? name : undefined,
description: relationshipSetting.userDescription ?? statusText,
date: creationDate,
image: "",
Expand All @@ -1799,6 +1792,26 @@ export class DataViewExpander {
};
}

private async getRelationshipSettingDVO(relationship: RelationshipDTO): Promise<RelationshipSettingDVO> {
const settingResult = await this.consumption.settings.getSettings({
query: {
scope: "Relationship",
reference: relationship.id
}
});

const defaultSetting = { isPinned: false };

if (settingResult.value.length === 0) return defaultSetting;

const latestSetting = settingResult.value.reduce((prev, current) => (prev.createdAt > current.createdAt ? prev : current));
const value = latestSetting.value;

if (typeof value !== "object") return defaultSetting;

return { ...defaultSetting, ...value };
}

public async expandRelationshipDTO(relationship: RelationshipDTO): Promise<IdentityDVO> {
const relationshipDVO = await this.createRelationshipDVO(relationship);
const initials = (relationshipDVO.name.match(/\b\w/g) ?? []).join("");
Expand All @@ -1807,6 +1820,7 @@ export class DataViewExpander {
type: "IdentityDVO",
id: relationship.peer,
name: relationshipDVO.name,
originalName: relationshipDVO.originalName,
date: relationshipDVO.date,
description: relationshipDVO.description,
publicKey: relationship.peerIdentity.publicKey,
Expand Down
1 change: 1 addition & 0 deletions packages/runtime/src/dataViews/transport/IdentityDVO.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ export interface IdentityDVO extends DataViewObject {
isSelf: boolean;
hasRelationship: boolean;
relationship?: RelationshipDVO;
originalName?: string;
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export interface RelationshipDVO extends DataViewObject {
attributeMap: Record<string, undefined | LocalAttributeDVO[]>;
nameMap: Record<string, undefined | string>;
templateId: string;
originalName?: string;
}

export interface RelationshipTheme {
Expand Down
28 changes: 27 additions & 1 deletion packages/runtime/src/useCases/common/Schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20302,6 +20302,17 @@ export const GetSettingByKeyRequest: any = {
"properties": {
"key": {
"type": "string"
},
"reference": {
"type": "string"
},
"scope": {
"type": "string",
"enum": [
"Identity",
"Device",
"Relationship"
]
}
},
"required": [
Expand Down Expand Up @@ -20447,13 +20458,28 @@ export const UpsertSettingByKeyRequest: any = {
"key": {
"type": "string"
},
"value": {}
"value": {},
"reference": {
"$ref": "#/definitions/GenericIdString"
},
"scope": {
"type": "string",
"enum": [
"Identity",
"Device",
"Relationship"
]
}
},
"required": [
"key",
"value"
],
"additionalProperties": false
},
"GenericIdString": {
"type": "string",
"pattern": "[A-Za-z0-9]{20}"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { Result } from "@js-soft/ts-utils";
import { Setting, SettingsController } from "@nmshd/consumption";
import { Setting, SettingsController, SettingScope } from "@nmshd/consumption";
import { Inject } from "typescript-ioc";
import { SettingDTO } from "../../../types";
import { RuntimeErrors, SchemaRepository, SchemaValidator, UseCase } from "../../common";
import { SettingMapper } from "./SettingMapper";

export interface GetSettingByKeyRequest {
key: string;
reference?: string;
scope?: "Identity" | "Device" | "Relationship";
}

class Validator extends SchemaValidator<GetSettingByKeyRequest> {
Expand All @@ -24,7 +26,13 @@ export class GetSettingByKeyUseCase extends UseCase<GetSettingByKeyRequest, Sett
}

protected async executeInternal(request: GetSettingByKeyRequest): Promise<Result<SettingDTO>> {
const settings = await this.settingController.getSettings({ key: request.key });
const query = {
key: request.key,
reference: request.reference ?? { $exists: false },
scope: request.scope ?? SettingScope.Identity
};

const settings = await this.settingController.getSettings(query);
if (settings.length === 0) {
return Result.fail(RuntimeErrors.general.recordNotFound(Setting));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
import { Serializable } from "@js-soft/ts-serval";
import { Result } from "@js-soft/ts-utils";
import { SettingsController } from "@nmshd/consumption";
import { SettingsController, SettingScope } from "@nmshd/consumption";
import { CoreId } from "@nmshd/core-types";
import { AccountController } from "@nmshd/transport";
import { Inject } from "typescript-ioc";
import { SettingDTO } from "../../../types";
import { SchemaRepository, SchemaValidator, UseCase } from "../../common";
import { GenericIdString, SchemaRepository, SchemaValidator, UseCase } from "../../common";
import { SettingMapper } from "./SettingMapper";

export interface UpsertSettingByKeyRequest {
key: string;
value: any;
reference?: GenericIdString;
scope?: "Identity" | "Device" | "Relationship";
}

class Validator extends SchemaValidator<UpsertSettingByKeyRequest> {
Expand All @@ -28,12 +31,21 @@ export class UpsertSettingByKeyUseCase extends UseCase<UpsertSettingByKeyRequest
}

protected async executeInternal(request: UpsertSettingByKeyRequest): Promise<Result<SettingDTO>> {
const settings = await this.settingController.getSettings({ key: request.key });
const settings = await this.settingController.getSettings({
key: request.key,
reference: request.reference ?? { $exists: false },
scope: request.scope ?? SettingScope.Identity
});

const newValue = Serializable.fromUnknown(request.value);

if (settings.length === 0) {
const setting = await this.settingController.createSetting({ key: request.key, value: newValue });
const setting = await this.settingController.createSetting({
key: request.key,
value: newValue,
reference: request.reference ? CoreId.from(request.reference) : undefined,
scope: request.scope as SettingScope | undefined
});
await this.accountController.syncDatawallet();
return Result.ok(SettingMapper.toSettingDTO(setting));
}
Expand Down
14 changes: 14 additions & 0 deletions packages/runtime/test/consumption/settings.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,20 @@ describe("Settings", () => {
const setting = await consumptionServices.settings.getSettingByKey({ key: "a-key" });
expect(setting.value.value).toStrictEqual({ aKey: "aNewValue" });
});

test("should get the settings by key including a reference and type", async () => {
const key = "a-key";
const value = { aKey: "a-value" };
const reference = (await TransportIds.generic.generate()).toString();
const scope = "Identity";

const upsertSettingResult = await consumptionServices.settings.upsertSettingByKey({ key, reference, scope, value });
expect(upsertSettingResult).toBeSuccessful();

const result = await consumptionServices.settings.getSettingByKey({ key, reference, scope });
expect(result).toBeSuccessful();
expect(result.value.value).toStrictEqual(value);
});
});

describe("Settings query", () => {
Expand Down
51 changes: 34 additions & 17 deletions packages/runtime/test/dataViews/RelationshipDVO.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,21 @@ import {
} from "@nmshd/content";
import { CoreAddress } from "@nmshd/core-types";
import { CoreIdHelper } from "@nmshd/transport";
import { DataViewExpander, TransportServices } from "../../src";
import { establishRelationshipWithContents, RuntimeServiceProvider } from "../lib";
import { establishRelationshipWithContents, RuntimeServiceProvider, TestRuntimeServices } from "../lib";

const serviceProvider = new RuntimeServiceProvider();
let transportServices1: TransportServices;
let transportServices2: TransportServices;
let expander1: DataViewExpander;
let expander2: DataViewExpander;

let runtimeServices1: TestRuntimeServices;
let runtimeServices2: TestRuntimeServices;

beforeAll(async () => {
const runtimeServices = await serviceProvider.launch(2);
transportServices1 = runtimeServices[0].transport;
transportServices2 = runtimeServices[1].transport;
expander1 = runtimeServices[0].expander;
expander2 = runtimeServices[1].expander;
runtimeServices1 = runtimeServices[0];
runtimeServices2 = runtimeServices[1];

await establishRelationshipWithContents(
transportServices1,
transportServices2,
runtimeServices1.transport,
runtimeServices2.transport,

RelationshipTemplateContent.from({
onNewRelationship: {
Expand All @@ -53,7 +50,7 @@ beforeAll(async () => {
result: ResponseItemResult.Accepted,
attributeId: await CoreIdHelper.notPrefixed.generate(),
attribute: IdentityAttribute.from({
owner: CoreAddress.from((await transportServices1.account.getIdentityInfo()).value.address),
owner: CoreAddress.from((await runtimeServices1.transport.account.getIdentityInfo()).value.address),
value: GivenName.from("AGivenName")
})
}).toJSON()
Expand All @@ -67,8 +64,8 @@ afterAll(() => serviceProvider.stop());

describe("RelationshipDVO", () => {
test("check the relationship dvo for the templator", async () => {
const dtos = (await transportServices1.relationships.getRelationships({})).value;
const dvos = await expander1.expandRelationshipDTOs(dtos);
const dtos = (await runtimeServices1.transport.relationships.getRelationships({})).value;
const dvos = await runtimeServices1.expander.expandRelationshipDTOs(dtos);
const dto = dtos[0];
const dvo = dvos[0];
expect(dvo).toBeDefined();
Expand All @@ -87,8 +84,8 @@ describe("RelationshipDVO", () => {
});

test("check the relationship dvo for the requestor", async () => {
const dtos = (await transportServices2.relationships.getRelationships({})).value;
const dvos = await expander2.expandRelationshipDTOs(dtos);
const dtos = (await runtimeServices2.transport.relationships.getRelationships({})).value;
const dvos = await runtimeServices2.expander.expandRelationshipDTOs(dtos);
const dto = dtos[0];
const dvo = dvos[0];
expect(dvo).toBeDefined();
Expand All @@ -105,4 +102,24 @@ describe("RelationshipDVO", () => {

expect(dvo.relationship!.templateId).toBe(dto.template.id);
});

test("check the relationship dvo for the templator with active relationshipSetting", async () => {
const dtos = (await runtimeServices1.transport.relationships.getRelationships({})).value;
const dto = dtos[0];

await runtimeServices1.consumption.settings.upsertSettingByKey({
key: "relationshipSetting",
value: { userTitle: "aTitle", userDescription: "aDescription" },
scope: "Relationship",
reference: dto.id
});

const dvos = await runtimeServices1.expander.expandRelationshipDTOs(dtos);
const dvo = dvos[0];

expect(dvo).toBeDefined();
expect(dvo.name).toBe("aTitle");
expect(dvo.originalName).toBe("i18n://dvo.identity.unknown");
expect(dvo.description).toBe("aDescription");
});
});

0 comments on commit 929c99f

Please sign in to comment.