From a4c6626e83d5a0192a57e439babe78e816e34a11 Mon Sep 17 00:00:00 2001 From: Shobit Beltangdy Date: Fri, 6 Oct 2023 18:26:22 -0700 Subject: [PATCH] Add Dwn.handleRecordsDelete function This commit introduces a handleRecordsDelete function meant to be used in place of the existing processMessage (which is eventually meant to be replaced, as described in issue #289). This commit also updates the relevant tests in records-(write|delete|read).ts files, which were using processMessage and replaces its usage with the new handleRecordsDelete. It also introduces a test in dwn.spec.ts, enough to bring uncovered lines of this new function to 0 (more specifically, the new test is meant to cover the exception path). --- src/dwn.ts | 18 +++++++++++++++++- src/types/records-types.ts | 2 ++ tests/dwn.spec.ts | 16 ++++++++++++++++ tests/handlers/records-delete.spec.ts | 18 +++++++++--------- tests/handlers/records-read.spec.ts | 2 +- tests/handlers/records-write.spec.ts | 8 ++++---- 6 files changed, 49 insertions(+), 15 deletions(-) diff --git a/src/dwn.ts b/src/dwn.ts index 7d783218f..fe8e8a37d 100644 --- a/src/dwn.ts +++ b/src/dwn.ts @@ -8,7 +8,8 @@ import type { RecordsWriteHandlerOptions } from './handlers/records-write.js'; import type { TenantGate } from './core/tenant-gate.js'; import type { GenericMessageReply, UnionMessageReply } from './core/message-reply.js'; import type { MessagesGetMessage, MessagesGetReply } from './types/messages-types.js'; -import type { RecordsQueryMessage, RecordsQueryReply, RecordsReadMessage, RecordsReadReply, RecordsWriteMessage, RecordsWriteReply } from './types/records-types.js'; +import type { RecordsDeleteMessage, RecordsDeleteReply, RecordsQueryMessage, RecordsQueryReply, + RecordsReadMessage, RecordsReadReply, RecordsWriteMessage, RecordsWriteReply } from './types/records-types.js'; import { AllowAllTenantGate } from './core/tenant-gate.js'; import { DidResolver } from './did/did-resolver.js'; @@ -155,6 +156,21 @@ export class Dwn { return handler.handle({ tenant, message }); } + /** + * Handles a `RecordsDelete` message. + */ + public async handleRecordsDelete(tenant: string, message: RecordsDeleteMessage): Promise { + const errorMessageReply = + await this.validateTenant(tenant) ?? + await this.validateMessageIntegrity(message, DwnInterfaceName.Records, DwnMethodName.Delete); + if (errorMessageReply !== undefined) { + return errorMessageReply; + } + + const handler = new RecordsDeleteHandler(this.didResolver, this.messageStore, this.dataStore, this.eventLog); + return handler.handle({ tenant, message }); + } + /** * Handles a `MessagesGet` message. */ diff --git a/src/types/records-types.ts b/src/types/records-types.ts index 32c810e9d..0d7abdd2b 100644 --- a/src/types/records-types.ts +++ b/src/types/records-types.ts @@ -27,6 +27,8 @@ export type RecordsWriteDescriptor = { export type RecordsWriteReply = GenericMessageReply; +export type RecordsDeleteReply = GenericMessageReply; + /** * Internal RecordsWrite message representation that can be in an incomplete state. */ diff --git a/tests/dwn.spec.ts b/tests/dwn.spec.ts index 6ff1e0488..d3ddd392b 100644 --- a/tests/dwn.spec.ts +++ b/tests/dwn.spec.ts @@ -365,5 +365,21 @@ export function testDwnClass(): void { }); + describe('handleRecordsDelete', () => { + it('should return 400 error for bad message (invalid method)', async () => { + const alice = await DidKeyResolver.generate(); + + const { message } = await TestDataGenerator.generateRecordsDelete(); + + ( message as any).descriptor.method = 'Foo'; + + const reply = await dwn.handleRecordsDelete(alice.did, message); + + expect(reply.status.code).to.equal(400); + expect(reply.status.detail).to.equal('Expected method RecordsDelete, received RecordsFoo'); + }); + + }); + }); } diff --git a/tests/handlers/records-delete.spec.ts b/tests/handlers/records-delete.spec.ts index 527e72a2b..253ac7659 100644 --- a/tests/handlers/records-delete.spec.ts +++ b/tests/handlers/records-delete.spec.ts @@ -81,7 +81,7 @@ export function testRecordsDeleteHandler(): void { authorizationSigner : Jws.createSigner(alice) }); - const deleteReply = await dwn.processMessage(alice.did, recordsDelete.message); + const deleteReply = await dwn.handleRecordsDelete(alice.did, recordsDelete.message); expect(deleteReply.status.code).to.equal(202); // ensure a query will no longer find the deleted record @@ -95,7 +95,7 @@ export function testRecordsDeleteHandler(): void { authorizationSigner : Jws.createSigner(alice) }); - const recordsDelete2Reply = await dwn.processMessage(alice.did, recordsDelete2.message); + const recordsDelete2Reply = await dwn.handleRecordsDelete(alice.did, recordsDelete2.message); expect(recordsDelete2Reply.status.code).to.equal(404); }); @@ -129,7 +129,7 @@ export function testRecordsDeleteHandler(): void { author : alice, recordId : aliceWriteData.message.recordId }); - const aliceDeleteWriteReply = await dwn.processMessage(alice.did, aliceDeleteWriteData.message); + const aliceDeleteWriteReply = await dwn.handleRecordsDelete(alice.did, aliceDeleteWriteData.message); expect(aliceDeleteWriteReply.status.code).to.equal(202); // verify the other record with the same data is unaffected @@ -151,7 +151,7 @@ export function testRecordsDeleteHandler(): void { author : alice, recordId : aliceAssociateData.message.recordId }); - const aliceDeleteAssociateReply = await dwn.processMessage(alice.did, aliceDeleteAssociateData.message); + const aliceDeleteAssociateReply = await dwn.handleRecordsDelete(alice.did, aliceDeleteAssociateData.message); expect(aliceDeleteAssociateReply.status.code).to.equal(202); // verify that alice can no longer fetch the 2nd record @@ -182,7 +182,7 @@ export function testRecordsDeleteHandler(): void { authorizationSigner : Jws.createSigner(alice) }); - const deleteReply = await dwn.processMessage(alice.did, recordsDelete.message); + const deleteReply = await dwn.handleRecordsDelete(alice.did, recordsDelete.message); expect(deleteReply.status.code).to.equal(404); }); @@ -211,7 +211,7 @@ export function testRecordsDeleteHandler(): void { expect(subsequentWriteReply.status.code).to.equal(202); // test that a delete with an earlier `messageTimestamp` results in a 409 - const deleteReply = await dwn.processMessage(alice.did, recordsDelete.message); + const deleteReply = await dwn.handleRecordsDelete(alice.did, recordsDelete.message); expect(deleteReply.status.code).to.equal(409); // ensure data still exists @@ -253,7 +253,7 @@ export function testRecordsDeleteHandler(): void { author : alice, recordId : aliceWriteData.message.recordId }); - const aliceDeleteWriteReply = await dwn.processMessage(alice.did, aliceDeleteWriteData.message); + const aliceDeleteWriteReply = await dwn.handleRecordsDelete(alice.did, aliceDeleteWriteData.message); expect(aliceDeleteWriteReply.status.code).to.equal(202); const aliceQueryWriteAfterAliceDeleteData = await TestDataGenerator.generateRecordsQuery({ @@ -295,7 +295,7 @@ export function testRecordsDeleteHandler(): void { authorizationSigner : Jws.createSigner(alice) }); - const deleteReply = await dwn.processMessage(alice.did, recordsDelete.message); + const deleteReply = await dwn.handleRecordsDelete(alice.did, recordsDelete.message); expect(deleteReply.status.code).to.equal(202); const events = await eventLog.getEvents(alice.did); @@ -333,7 +333,7 @@ export function testRecordsDeleteHandler(): void { authorizationSigner : Jws.createSigner(author) }); - const deleteReply = await dwn.processMessage(author.did, recordsDelete.message); + const deleteReply = await dwn.handleRecordsDelete(author.did, recordsDelete.message); expect(deleteReply.status.code).to.equal(202); const events = await eventLog.getEvents(author.did); diff --git a/tests/handlers/records-read.spec.ts b/tests/handlers/records-read.spec.ts index 1f0c008d9..e128ba597 100644 --- a/tests/handlers/records-read.spec.ts +++ b/tests/handlers/records-read.spec.ts @@ -1428,7 +1428,7 @@ export function testRecordsReadHandler(): void { authorizationSigner : Jws.createSigner(alice) }); - const deleteReply = await dwn.processMessage(alice.did, recordsDelete.message); + const deleteReply = await dwn.handleRecordsDelete(alice.did, recordsDelete.message); expect(deleteReply.status.code).to.equal(202); // RecordsRead diff --git a/tests/handlers/records-write.spec.ts b/tests/handlers/records-write.spec.ts index f5abc68e1..b8244965a 100644 --- a/tests/handlers/records-write.spec.ts +++ b/tests/handlers/records-write.spec.ts @@ -644,7 +644,7 @@ export function testRecordsWriteHandler(): void { recordId : message.recordId, authorizationSigner : Jws.createSigner(author), }); - const deleteReply = await dwn.processMessage(tenant, recordsDelete.message); + const deleteReply = await dwn.handleRecordsDelete(tenant, recordsDelete.message); expect(deleteReply.status.code).to.equal(202); const write = await RecordsWrite.createFrom({ @@ -676,7 +676,7 @@ export function testRecordsWriteHandler(): void { recordId : message.recordId, authorizationSigner : Jws.createSigner(author), }); - const deleteReply = await dwn.processMessage(tenant, recordsDelete.message); + const deleteReply = await dwn.handleRecordsDelete(tenant, recordsDelete.message); expect(deleteReply.status.code).to.equal(202); const write = await RecordsWrite.createFrom({ @@ -1336,7 +1336,7 @@ export function testRecordsWriteHandler(): void { author : alice, recordId : friendRoleRecord.message.recordId, }); - const deleteFriendReply = await dwn.processMessage(alice.did, deleteFriend.message); + const deleteFriendReply = await dwn.handleRecordsDelete(alice.did, deleteFriend.message); expect(deleteFriendReply.status.code).to.equal(202); // Alice writes a new record adding Bob as a 'friend' again @@ -1553,7 +1553,7 @@ export function testRecordsWriteHandler(): void { author : alice, recordId : participantRecord1.message.recordId, }); - const participantDeleteReply = await dwn.processMessage(alice.did, partipantDelete.message); + const participantDeleteReply = await dwn.handleRecordsDelete(alice.did, partipantDelete.message); expect(participantDeleteReply.status.code).to.equal(202); // Alice creates a new 'thread/participant' record