Skip to content

Commit

Permalink
Merge branch 'main' into compressed_pubkey_v2
Browse files Browse the repository at this point in the history
* main:
  Replace `handle<Xyz>` methods in `Dwn` class with overloaded `process… (decentralized-identity#566)
  • Loading branch information
Diane Huxley committed Oct 18, 2023
2 parents f70b19b + f23bf02 commit 3049d40
Show file tree
Hide file tree
Showing 7 changed files with 233 additions and 407 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ Here's to a thrilling Hacktoberfest voyage with us! 🎉
# Decentralized Web Node (DWN) SDK <!-- omit in toc -->

Code Coverage
![Statements](https://img.shields.io/badge/statements-98.46%25-brightgreen.svg?style=flat) ![Branches](https://img.shields.io/badge/branches-95.23%25-brightgreen.svg?style=flat) ![Functions](https://img.shields.io/badge/functions-95.75%25-brightgreen.svg?style=flat) ![Lines](https://img.shields.io/badge/lines-98.46%25-brightgreen.svg?style=flat)
![Statements](https://img.shields.io/badge/statements-98.47%25-brightgreen.svg?style=flat) ![Branches](https://img.shields.io/badge/branches-95.55%25-brightgreen.svg?style=flat) ![Functions](https://img.shields.io/badge/functions-95.7%25-brightgreen.svg?style=flat) ![Lines](https://img.shields.io/badge/lines-98.47%25-brightgreen.svg?style=flat)

- [Introduction](#introduction)
- [Installation](#installation)
Expand Down
66 changes: 1 addition & 65 deletions src/dwn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import type { TenantGate } from './core/tenant-gate.js';
import type { EventsGetMessage, EventsGetReply, PermissionsGrantMessage, PermissionsRequestMessage, PermissionsRevokeMessage, ProtocolsConfigureMessage, ProtocolsQueryMessage, ProtocolsQueryReply } from './index.js';
import type { GenericMessageReply, UnionMessageReply } from './core/message-reply.js';
import type { MessagesGetMessage, MessagesGetReply } from './types/messages-types.js';
import type { RecordsDeleteMessage, RecordsQueryMessage, RecordsQueryReply, RecordsReadMessage, RecordsReadReply, RecordsWriteMessage, RecordsWriteReply } from './types/records-types.js';
import type { RecordsDeleteMessage, RecordsQueryMessage, RecordsQueryReply, RecordsReadMessage, RecordsReadReply, RecordsWriteMessage } from './types/records-types.js';

import { AllowAllTenantGate } from './core/tenant-gate.js';
import { DidResolver } from './did/did-resolver.js';
Expand Down Expand Up @@ -119,70 +119,6 @@ export class Dwn {
return methodHandlerReply;
}

/**
* Handles a `RecordsWrite` message.
*/
public async handleRecordsWrite(
tenant: string,
message: RecordsWriteMessage,
dataStream?: Readable,
options?: RecordsWriteHandlerOptions): Promise<RecordsWriteReply> {
const errorMessageReply =
await this.validateTenant(tenant) ??
await this.validateMessageIntegrity(message, DwnInterfaceName.Records, DwnMethodName.Write);
if (errorMessageReply !== undefined) {
return errorMessageReply;
}

const handler = new RecordsWriteHandler(this.didResolver, this.messageStore, this.dataStore, this.eventLog);
return handler.handle({ tenant, message, options, dataStream });
}

/**
* Handles a `RecordsQuery` message.
*/
public async handleRecordsQuery(tenant: string, message: RecordsQueryMessage): Promise<RecordsQueryReply> {
const errorMessageReply =
await this.validateTenant(tenant) ??
await this.validateMessageIntegrity(message, DwnInterfaceName.Records, DwnMethodName.Query);
if (errorMessageReply !== undefined) {
return errorMessageReply;
}

const handler = new RecordsQueryHandler(this.didResolver, this.messageStore, this.dataStore);
return handler.handle({ tenant, message });
}

/**
* Handles a `RecordsRead` message.
*/
public async handleRecordsRead(tenant: string, message: RecordsReadMessage): Promise<RecordsReadReply> {
const errorMessageReply =
await this.validateTenant(tenant) ??
await this.validateMessageIntegrity(message, DwnInterfaceName.Records, DwnMethodName.Read);
if (errorMessageReply !== undefined) {
return errorMessageReply;
}

const handler = new RecordsReadHandler(this.didResolver, this.messageStore, this.dataStore);
return handler.handle({ tenant, message });
}

/**
* Handles a `MessagesGet` message.
*/
public async handleMessagesGet(tenant: string, message: MessagesGetMessage): Promise<MessagesGetReply> {
const errorMessageReply =
await this.validateTenant(tenant) ??
await this.validateMessageIntegrity(message, DwnInterfaceName.Messages, DwnMethodName.Get);
if (errorMessageReply !== undefined) {
return errorMessageReply;
}

const handler = new MessagesGetHandler(this.didResolver, this.messageStore, this.dataStore);
return handler.handle({ tenant, message });
}

/**
* Privileged method for writing a pruned initial `RecordsWrite` to a DWN without needing to supply associated data.
*/
Expand Down
114 changes: 2 additions & 112 deletions tests/dwn.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import { stubInterface } from 'ts-sinon';
import { TestDataGenerator } from './utils/test-data-generator.js';
import { TestStores } from './test-stores.js';
import { DwnInterfaceName, DwnMethodName, Message } from '../src/core/message.js';
import { Jws, RecordsRead } from '../src/index.js';

chai.use(chaiAsPromised);

Expand Down Expand Up @@ -53,7 +52,7 @@ export function testDwnClass(): void {
author: alice,
});

const reply = await dwn.handleRecordsWrite(alice.did, message, dataStream);
const reply = await dwn.processMessage(alice.did, message, dataStream);

expect(reply.status.code).to.equal(202);
});
Expand Down Expand Up @@ -146,78 +145,6 @@ export function testDwnClass(): void {
});
});

describe('handleRecordsRead', () => {
it('should return error if preprocessing checks fail', async () => {
const alice = await DidKeyResolver.generate();

const recordsRead = await RecordsRead.create({
filter: {
recordId: 'recordId-doesnt-matter',
},
authorizationSigner: Jws.createSigner(alice)
});
(recordsRead.message as any).descriptor.method = 'Write'; // Will cause interface and method check to fail
const reply = await dwn.handleRecordsRead(alice.did, recordsRead.message);

expect(reply.status.code).to.not.equal(200);
});
});

describe('handleMessagesGet', () => {
// increases test coverage :)
it('runs successfully', async () => {
const did = await DidKeyResolver.generate();
const alice = await TestDataGenerator.generatePersona(did);
const messageCids: string[] = [];

const { recordsWrite, dataStream } = await TestDataGenerator.generateRecordsWrite({
author: alice
});

const messageCid = await Message.getCid(recordsWrite.message);
messageCids.push(messageCid);

const reply = await dwn.handleRecordsWrite(alice.did, recordsWrite.toJSON(), dataStream);
expect(reply.status.code).to.equal(202);

const { messagesGet } = await TestDataGenerator.generateMessagesGet({
author: alice,
messageCids
});

const messagesGetReply = await dwn.handleMessagesGet(alice.did, messagesGet.message);
expect(messagesGetReply.status.code).to.equal(200);
expect(messagesGetReply.messages!.length).to.equal(messageCids.length);

for (const messageReply of messagesGetReply.messages!) {
expect(messageReply.messageCid).to.not.be.undefined;
expect(messageReply.message).to.not.be.undefined;
expect(messageCids).to.include(messageReply.messageCid);

const cid = await Message.getCid(messageReply.message!);
expect(messageReply.messageCid).to.equal(cid);
}
});

it('should return error if preprocessing checks fail', async () => {
const alice = await DidKeyResolver.generate();

const { recordsWrite } = await TestDataGenerator.generateRecordsWrite({
author: alice
});

const messageCids = [await Message.getCid(recordsWrite.message)];
const { messagesGet } = await TestDataGenerator.generateMessagesGet({
author: alice,
messageCids
});
(messagesGet.message as any).descriptor.interface = 'Protocols'; // Will cause interface and method check to fail
const reply = await dwn.handleMessagesGet(alice.did, messagesGet.message);

expect(reply.status.code).to.not.equal(200);
});
});

describe('synchronizePrunedInitialRecordsWrite()', () => {
it('should allow an initial `RecordsWrite` to be written without supplying data', async () => {
const alice = await DidKeyResolver.generate();
Expand Down Expand Up @@ -248,7 +175,7 @@ export function testDwnClass(): void {
data : newDataBytes
});

const newRecordsWriteReply = await dwn.handleRecordsWrite(alice.did, newRecordsWrite.message, newRecordsWrite.dataStream);
const newRecordsWriteReply = await dwn.processMessage(alice.did, newRecordsWrite.message, newRecordsWrite.dataStream);
expect(newRecordsWriteReply.status.code).to.equal(202);

// verify new `RecordsWrite` has overwritten the existing record with new data
Expand Down Expand Up @@ -328,42 +255,5 @@ export function testDwnClass(): void {
expect(reply3.status.detail).to.contain(`Expected method ${DwnInterfaceName.Records}${DwnMethodName.Write}`);
});
});

describe('handleRecordsWrite', () => {
it('should return 400 error for bad message (invalid method)', async () => {
const alice = await DidKeyResolver.generate();
const data = Encoder.stringToBytes('test');

// alice writes a record
const aliceWriteData = await TestDataGenerator.generateRecordsWrite({
author: alice,
data
});

(aliceWriteData.message as any).descriptor.method = 'Foo';

const reply = await dwn.handleRecordsWrite(alice.did, aliceWriteData.message);

expect(reply.status.code).to.equal(400);
expect(reply.status.detail).to.equal('Expected method RecordsWrite, received RecordsFoo');
});

it('should successfully write a record', async () => {
const alice = await DidKeyResolver.generate();
const data = Encoder.stringToBytes('test');

// alice writes a record
const aliceWriteData = await TestDataGenerator.generateRecordsWrite({
author: alice,
data
});

const reply = await dwn.handleRecordsWrite(alice.did, aliceWriteData.message, aliceWriteData.dataStream);

expect(reply.status.code).to.equal(202);
});

});

});
}
30 changes: 15 additions & 15 deletions tests/handlers/records-delete.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export function testRecordsDeleteHandler(): void {

// insert data
const { message, dataStream } = await TestDataGenerator.generateRecordsWrite({ author: alice });
const writeReply = await dwn.handleRecordsWrite(alice.did, message, dataStream);
const writeReply = await dwn.processMessage(alice.did, message, dataStream);
expect(writeReply.status.code).to.equal(202);

// ensure data is inserted
Expand Down Expand Up @@ -106,22 +106,22 @@ export function testRecordsDeleteHandler(): void {

// alice writes a records with data
const aliceWriteData = await TestDataGenerator.generateRecordsWrite({ author: alice, data });
const aliceWriteReply = await dwn.handleRecordsWrite(alice.did, aliceWriteData.message, aliceWriteData.dataStream);
const aliceWriteReply = await dwn.processMessage(alice.did, aliceWriteData.message, aliceWriteData.dataStream);
expect(aliceWriteReply.status.code).to.equal(202);

// alice writes another record with the same data
const aliceAssociateData = await TestDataGenerator.generateRecordsWrite({ author: alice, data });
const aliceAssociateReply = await dwn.handleRecordsWrite(alice.did, aliceAssociateData.message, aliceAssociateData.dataStream);
const aliceAssociateReply = await dwn.processMessage(alice.did, aliceAssociateData.message, aliceAssociateData.dataStream);
expect(aliceAssociateReply.status.code).to.equal(202);

// bob writes a records with same data
const bobWriteData = await TestDataGenerator.generateRecordsWrite({ author: bob, data });
const bobWriteReply = await dwn.handleRecordsWrite(bob.did, bobWriteData.message, bobWriteData.dataStream);
const bobWriteReply = await dwn.processMessage(bob.did, bobWriteData.message, bobWriteData.dataStream);
expect(bobWriteReply.status.code).to.equal(202);

// bob writes another record with the same data
const bobAssociateData = await TestDataGenerator.generateRecordsWrite({ author: bob, data });
const bobAssociateReply = await dwn.handleRecordsWrite(bob.did, bobAssociateData.message, bobAssociateData.dataStream);
const bobAssociateReply = await dwn.processMessage(bob.did, bobAssociateData.message, bobAssociateData.dataStream);
expect(bobAssociateReply.status.code).to.equal(202);

// alice deletes one of the two records
Expand All @@ -140,7 +140,7 @@ export function testRecordsDeleteHandler(): void {
authorizationSigner: Jws.createSigner(alice)
});

const aliceRead1Reply = await dwn.handleRecordsRead(alice.did, aliceRead1.message);
const aliceRead1Reply = await dwn.processMessage(alice.did, aliceRead1.message);
expect(aliceRead1Reply.status.code).to.equal(200);

const aliceDataFetched = await DataStream.toBytes(aliceRead1Reply.record!.data!);
Expand All @@ -155,7 +155,7 @@ export function testRecordsDeleteHandler(): void {
expect(aliceDeleteAssociateReply.status.code).to.equal(202);

// verify that alice can no longer fetch the 2nd record
const aliceRead2Reply = await dwn.handleRecordsRead(alice.did, aliceRead1.message);
const aliceRead2Reply = await dwn.processMessage(alice.did, aliceRead1.message);
expect(aliceRead2Reply.status.code).to.equal(404);

// verify that bob can still fetch record with the same data
Expand All @@ -166,7 +166,7 @@ export function testRecordsDeleteHandler(): void {
authorizationSigner: Jws.createSigner(bob)
});

const bobRead1Reply = await dwn.handleRecordsRead(bob.did, bobRead1.message);
const bobRead1Reply = await dwn.processMessage(bob.did, bobRead1.message);
expect(bobRead1Reply.status.code).to.equal(200);

const bobDataFetched = await DataStream.toBytes(bobRead1Reply.record!.data!);
Expand All @@ -191,7 +191,7 @@ export function testRecordsDeleteHandler(): void {

// initial write
const initialWriteData = await TestDataGenerator.generateRecordsWrite({ author: alice });
const initialWriteReply = await dwn.handleRecordsWrite(alice.did, initialWriteData.message, initialWriteData.dataStream);
const initialWriteReply = await dwn.processMessage(alice.did, initialWriteData.message, initialWriteData.dataStream);
expect(initialWriteReply.status.code).to.equal(202);

// generate subsequent write and delete with the delete having an earlier timestamp
Expand All @@ -207,7 +207,7 @@ export function testRecordsDeleteHandler(): void {
});

// subsequent write
const subsequentWriteReply = await dwn.handleRecordsWrite(alice.did, subsequentWriteData.message, subsequentWriteData.dataStream);
const subsequentWriteReply = await dwn.processMessage(alice.did, subsequentWriteData.message, subsequentWriteData.dataStream);
expect(subsequentWriteReply.status.code).to.equal(202);

// test that a delete with an earlier `messageTimestamp` results in a 409
Expand Down Expand Up @@ -236,7 +236,7 @@ export function testRecordsDeleteHandler(): void {
author: alice,
data
});
const aliceWriteReply = await dwn.handleRecordsWrite(alice.did, aliceWriteData.message, aliceWriteData.dataStream);
const aliceWriteReply = await dwn.processMessage(alice.did, aliceWriteData.message, aliceWriteData.dataStream);
expect(aliceWriteReply.status.code).to.equal(202);

const aliceQueryWriteAfterAliceWriteData = await TestDataGenerator.generateRecordsQuery({
Expand Down Expand Up @@ -269,7 +269,7 @@ export function testRecordsDeleteHandler(): void {
author: alice,
data
});
const aliceRewriteReply = await dwn.handleRecordsWrite(alice.did, aliceRewriteData.message, aliceRewriteData.dataStream);
const aliceRewriteReply = await dwn.processMessage(alice.did, aliceRewriteData.message, aliceRewriteData.dataStream);
expect(aliceRewriteReply.status.code).to.equal(202);

const aliceQueryWriteAfterAliceRewriteData = await TestDataGenerator.generateRecordsQuery({
Expand All @@ -287,7 +287,7 @@ export function testRecordsDeleteHandler(): void {
const alice = await DidKeyResolver.generate();

const { message, dataStream } = await TestDataGenerator.generateRecordsWrite({ author: alice });
const writeReply = await dwn.handleRecordsWrite(alice.did, message, dataStream);
const writeReply = await dwn.processMessage(alice.did, message, dataStream);
expect(writeReply.status.code).to.equal(202);

const recordsDelete = await RecordsDelete.create({
Expand Down Expand Up @@ -316,7 +316,7 @@ export function testRecordsDeleteHandler(): void {
const { message, author, dataStream, recordsWrite } = await TestDataGenerator.generateRecordsWrite();
TestStubGenerator.stubDidResolver(didResolver, [author]);

const reply = await dwn.handleRecordsWrite(author.did, message, dataStream);
const reply = await dwn.processMessage(author.did, message, dataStream);
expect(reply.status.code).to.equal(202);

const newWrite = await RecordsWrite.createFrom({
Expand All @@ -325,7 +325,7 @@ export function testRecordsDeleteHandler(): void {
authorizationSigner : Jws.createSigner(author)
});

const newWriteReply = await dwn.handleRecordsWrite(author.did, newWrite.message);
const newWriteReply = await dwn.processMessage(author.did, newWrite.message);
expect(newWriteReply.status.code).to.equal(202);

const recordsDelete = await RecordsDelete.create({
Expand Down
Loading

0 comments on commit 3049d40

Please sign in to comment.