Skip to content

Commit

Permalink
feat(core): Peer connection storage (#453)
Browse files Browse the repository at this point in the history
* feat: add peer connection metadata

* feat: create peer connection storage

* feat: remove isPending in peerConnection metadata

* feat: remove peerConnectionService

* feat: remove peerConnectionStorage in AgentServicesProps

* feat: remove storages in AgentServicesProps

* feat: remove storages in AgentServicesProps

* feat: remove storages in AgentServicesProps in tests

* revert: revert changes in services unit tests
  • Loading branch information
Sotatek-HocNguyena committed May 8, 2024
1 parent 63d0aa5 commit 3b0a775
Show file tree
Hide file tree
Showing 10 changed files with 247 additions and 23 deletions.
12 changes: 12 additions & 0 deletions src/core/agent/agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import {
CredentialStorage,
IdentifierMetadataRecord,
IdentifierStorage,
PeerConnectionMetadataRecord,
PeerConnectionStorage,
NotificationRecord,
NotificationStorage,
} from "./records";
Expand Down Expand Up @@ -55,6 +57,7 @@ class Agent {
private connectionStorage!: ConnectionStorage;
private connectionNoteStorage!: ConnectionNoteStorage;
private notificationStorage!: NotificationStorage;
private peerConnectionStorage!: PeerConnectionStorage;

private signifyClient!: SignifyClient;
static ready = false;
Expand Down Expand Up @@ -124,6 +127,10 @@ class Agent {
return this.credentialService;
}

get peerConnectionMetadataStorage() {
return this.peerConnectionStorage;
}

get basicStorage() {
return this.basicStorageService;
}
Expand Down Expand Up @@ -194,6 +201,11 @@ class Agent {
eventService: new EventService(),
};

this.peerConnectionStorage = new PeerConnectionStorage(
this.getStorageService<PeerConnectionMetadataRecord>(
this.storageSession
)
);
Agent.ready = true;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/core/agent/agent.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import {
import { EventService } from "./services/eventService";
import { IdentifierStorage } from "./records/identifierStorage";
import { CredentialStorage } from "./records/credentialStorage";
import { BasicStorage } from "./records/basicStorage";
import { ConnectionHistoryType } from "./services/connection.types";
import { PeerConnectionStorage } from "./records";

enum ConnectionStatus {
CONFIRMED = "confirmed",
Expand Down
2 changes: 2 additions & 0 deletions src/core/agent/records/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
export * from "./credentialMetadataRecord";
export * from "./identifierMetadataRecord";
export * from "./peerConnectionMetadataRecord";
export * from "./basicRecord";
export * from "./connectionRecord";
export * from "./connectionNoteRecord";
export * from "./notificationRecord";
export * from "./credentialStorage";
export * from "./identifierStorage";
export * from "./peerConnectionStorage";
export * from "./basicStorage";
export * from "./connectionStorage";
export * from "./connectionNoteStorage";
Expand Down
30 changes: 30 additions & 0 deletions src/core/agent/records/peerConnectionMetadataRecord.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import {
PeerConnectionMetadataRecord,
PeerConnectionMetadataRecordProps,
} from "./peerConnectionMetadataRecord";

const mockData: PeerConnectionMetadataRecordProps = {
id: "id",
name: "name",
url: "url",
iconB64: "icon",
selectedAid: "aid",
};

describe("Peer Connection Record", () => {
test("should fill the record based on supplied props", () => {
const createdAt = new Date();
const settingsRecord = new PeerConnectionMetadataRecord({
...mockData,
createdAt: createdAt,
});
settingsRecord.getTags();
expect(settingsRecord.type).toBe(PeerConnectionMetadataRecord.type);
expect(settingsRecord.id).toBe(mockData.id);
expect(settingsRecord.name).toBe(mockData.name);
expect(settingsRecord.url).toBe(mockData.url);
expect(settingsRecord.selectedAid).toBe(mockData.selectedAid);
expect(settingsRecord.iconB64).toBe(mockData.iconB64);
expect(settingsRecord.createdAt).toBe(createdAt);
});
});
42 changes: 42 additions & 0 deletions src/core/agent/records/peerConnectionMetadataRecord.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { BaseRecord } from "../../storage/storage.types";

interface PeerConnectionMetadataRecordProps {
id: string;
name?: string;
url?: string;
createdAt?: Date;
iconB64?: string;
selectedAid?: string;
}

class PeerConnectionMetadataRecord extends BaseRecord {
name?: string;
url?: string;
iconB64?: string;
selectedAid?: string;

static readonly type = "PeerConnectionMetadataRecord";
readonly type = PeerConnectionMetadataRecord.type;

constructor(props: PeerConnectionMetadataRecordProps) {
super();

if (props) {
this.id = props.id;
this.name = props.name ?? "";
this.url = props.url ?? "";
this.selectedAid = props.selectedAid ?? "";
this.createdAt = props.createdAt ?? new Date();
this.iconB64 = props.iconB64 ?? "";
}
}

getTags() {
return {
...this._tags,
};
}
}

export type { PeerConnectionMetadataRecordProps };
export { PeerConnectionMetadataRecord };
87 changes: 87 additions & 0 deletions src/core/agent/records/peerConnectionStorage.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { PeerConnectionMetadataRecord } from "./peerConnectionMetadataRecord";
import { PeerConnectionStorage } from "./peerConnectionStorage";

const storageService = jest.mocked({
save: jest.fn(),
delete: jest.fn(),
deleteById: jest.fn(),
update: jest.fn(),
findById: jest.fn(),
findAllByQuery: jest.fn(),
getAll: jest.fn(),
});

const peerConnectionStorage = new PeerConnectionStorage(storageService as any);

const peerConnectionMetadataRecordProps = {
id: "id",
name: "name",
url: "url",
iconB64: "icon",
selectedAid: "aid",
createdAt: new Date(),
};

const peerConnectionMetadataRecord = new PeerConnectionMetadataRecord({
...peerConnectionMetadataRecordProps,
});

const peerConnectionMetadataRecord2 = new PeerConnectionMetadataRecord({
...peerConnectionMetadataRecordProps,
id: "id2",
});

describe("Connection service of agent", () => {
beforeEach(() => {
jest.resetAllMocks();
});

test("Should get all credentials", async () => {
storageService.getAll.mockResolvedValue([
peerConnectionMetadataRecord,
peerConnectionMetadataRecord2,
]);
expect(await peerConnectionStorage.getAllPeerConnectionMetadata()).toEqual([
peerConnectionMetadataRecord,
peerConnectionMetadataRecord2,
]);
});

test("Should get credential metadata", async () => {
storageService.findById.mockResolvedValue(peerConnectionMetadataRecord);
expect(
await peerConnectionStorage.getPeerConnectionMetadata(
peerConnectionMetadataRecord.id
)
).toEqual(peerConnectionMetadataRecord);
});

test("Should throw if peerConnection metadata record is missing", async () => {
storageService.findById.mockResolvedValue(null);
await expect(
peerConnectionStorage.getPeerConnectionMetadata(
peerConnectionMetadataRecord.id
)
).rejects.toThrowError(
PeerConnectionStorage.PEER_CONNECTION_METADATA_RECORD_MISSING
);
});

test("Should save peerConnection metadata record", async () => {
await peerConnectionStorage.createPeerConnectionMetadataRecord(
peerConnectionMetadataRecordProps
);
expect(storageService.save).toBeCalledWith(peerConnectionMetadataRecord);
});

test("Should update credential metadata record", async () => {
storageService.findById.mockResolvedValue(peerConnectionMetadataRecord);
await peerConnectionStorage.updatePeerConnectionMetadata(
peerConnectionMetadataRecord.id,
{
name: "update name",
}
);
expect(storageService.update).toBeCalled();
});
});
73 changes: 73 additions & 0 deletions src/core/agent/records/peerConnectionStorage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { StorageService } from "../../storage/storage.types";
import {
PeerConnectionMetadataRecord,
PeerConnectionMetadataRecordProps,
} from "./peerConnectionMetadataRecord";

class PeerConnectionStorage {
static readonly PEER_CONNECTION_METADATA_RECORD_MISSING =
"Peer connection metadata record does not exist";
private storageService: StorageService<PeerConnectionMetadataRecord>;

constructor(storageService: StorageService<PeerConnectionMetadataRecord>) {
this.storageService = storageService;
}

async getPeerConnectionMetadata(
id: string
): Promise<PeerConnectionMetadataRecord> {
const metadata = await this.storageService.findById(
id,
PeerConnectionMetadataRecord
);
if (!metadata) {
throw new Error(
PeerConnectionStorage.PEER_CONNECTION_METADATA_RECORD_MISSING
);
}
return metadata;
}

async getAllPeerConnectionMetadata(): Promise<
PeerConnectionMetadataRecord[]
> {
const records = await this.storageService.getAll(
PeerConnectionMetadataRecord
);
return records;
}

async updatePeerConnectionMetadata(
id: string,
metadata: Partial<
Pick<
PeerConnectionMetadataRecord,
"name" | "url" | "iconB64" | "selectedAid"
>
>
): Promise<void> {
const identifierMetadataRecord = await this.getPeerConnectionMetadata(id);
if (metadata.name !== undefined)
identifierMetadataRecord.name = metadata.name;
if (metadata.url !== undefined) identifierMetadataRecord.url = metadata.url;
if (metadata.iconB64 !== undefined)
identifierMetadataRecord.iconB64 = metadata.iconB64;
if (metadata.selectedAid !== undefined)
identifierMetadataRecord.selectedAid = metadata.selectedAid;
await this.storageService.update(identifierMetadataRecord);
}

async createPeerConnectionMetadataRecord(
data: PeerConnectionMetadataRecordProps
): Promise<void> {
const record = new PeerConnectionMetadataRecord(data);
await this.storageService.save(record);
}

async deletePeerConnectionMetadataRecord(id: string): Promise<void> {
const record = await this.getPeerConnectionMetadata(id);
await this.storageService.delete(record);
}
}

export { PeerConnectionStorage };
3 changes: 0 additions & 3 deletions src/core/agent/services/agentService.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import { SignifyClient } from "signify-ts";
import { StorageApi } from "../../storage/storage.types";
import { EventService } from "./eventService";
import { IdentifierStorage } from "../records/identifierStorage";
import { CredentialStorage } from "../records/credentialStorage";
import { AgentServicesProps } from "../agent.types";

abstract class AgentService {
Expand Down
9 changes: 0 additions & 9 deletions src/core/agent/services/identifierService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,15 +93,6 @@ const identifierStorage = jest.mocked({
createIdentifierMetadataRecord: jest.fn(),
});

const credentialStorage = jest.mocked({
getAllCredentialMetadata: jest.fn(),
deleteCredentialMetadata: jest.fn(),
getCredentialMetadata: jest.fn(),
getCredentialMetadataByConnectionId: jest.fn(),
saveCredentialMetadataRecord: jest.fn(),
updateCredentialMetadata: jest.fn(),
});

const agentServicesProps = {
signifyClient: signifyClient as any,
eventService: new EventService(),
Expand Down
10 changes: 0 additions & 10 deletions src/core/agent/services/signifyNotificationService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,20 +85,10 @@ const signifyClient = jest.mocked({

groups: () => ({ getRequest: groupGetRequestMock }),
});
const identifierStorage = jest.mocked({
getIdentifierMetadata: jest.fn(),
getAllIdentifierMetadata: jest.fn(),
getKeriIdentifiersMetadata: jest.fn(),
updateIdentifierMetadata: jest.fn(),
createIdentifierMetadataRecord: jest.fn(),
});

const agentServicesProps = {
basicStorage: basicStorage as any,
signifyClient: signifyClient as any,
eventService: new EventService(),
identifierStorage: identifierStorage as any,
credentialStorage: {} as any,
};

const notificationStorage = jest.mocked({
Expand Down

0 comments on commit 3b0a775

Please sign in to comment.