Skip to content

Commit

Permalink
increase testing for sync edge cases
Browse files Browse the repository at this point in the history
  • Loading branch information
LiranCohen committed Aug 21, 2024
1 parent dc758a4 commit ea0016a
Show file tree
Hide file tree
Showing 2 changed files with 253 additions and 3 deletions.
6 changes: 3 additions & 3 deletions packages/agent/src/sync-engine-level.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ export class SyncEngineLevel implements SyncEngine {
permissionGrantId = messagesReadGrant.grant.id;
granteeDid = delegateDid;
} catch(error:any) {
console.log('SyncEngineLevel: Error fetching permission grant for delegate DID', error);
console.error('SyncEngineLevel: pull - Error fetching MessagesRead permission grant for delegate DID', error);
continue;
}
}
Expand Down Expand Up @@ -407,7 +407,7 @@ export class SyncEngineLevel implements SyncEngine {

permissionGrantId = messagesQueryGrant.grant.id;
} catch(error:any) {
console.log('SyncEngineLevel: Error fetching permission grant for delegate DID', error);
console.error('SyncEngineLevel: Error fetching MessagesQuery permission grant for delegate DID', error);
return [];
}
}
Expand Down Expand Up @@ -474,7 +474,7 @@ export class SyncEngineLevel implements SyncEngine {

permissionGrantId = messagesReadGrant.grant.id;
} catch(error:any) {
console.log('SyncEngineLevel: Error fetching permission grant for delegate DID', error);
console.error('SyncEngineLevel: push - Error fetching MessagesRead permission grant for delegate DID', error);
return;
}
}
Expand Down
250 changes: 250 additions & 0 deletions packages/agent/tests/sync-engine-level.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1397,6 +1397,136 @@ describe('SyncEngineLevel', () => {
sendDwnRequestSpy.restore();
});

it('logs an error if could not fetch MessagesQuery permission needed for a sync', async () => {
// create new identity to not conflict the previous tests's remote records
const aliceSync = await testHarness.createIdentity({ name: 'Alice', testDwnUrls });

const delegateDid = await testHarness.agent.identity.create({
store : true,
didMethod : 'jwk',
metadata : { name: 'Alice Delegate', connectedDid: aliceSync.did.uri }
});

await testHarness.agent.sync.registerIdentity({
did : aliceSync.did.uri,
options : {
delegateDid : delegateDid.did.uri,
protocols : [ 'https://protocol.xyz/foo' ]
}
});

// spy on console.error to check if the error message is logged
const consoleErrorSpy = sinon.stub(console, 'error').resolves();

await syncEngine.sync('pull');
expect(consoleErrorSpy.called).to.be.true;
expect(consoleErrorSpy.args[0][0]).to.include('SyncEngineLevel: Error fetching MessagesQuery permission grant for delegate DID');
});

it('logs an error if could not fetch MessagesRead permission needed for a sync', async () => {
// create new identity to not conflict the previous tests's remote records
const aliceSync = await testHarness.createIdentity({ name: 'Alice', testDwnUrls });

// create 3 local protocols
const protocolFoo: ProtocolDefinition = {
published : true,
protocol : 'https://protocol.xyz/foo',
types : {
foo: {
schema : 'https://schemas.xyz/foo',
dataFormats : ['text/plain', 'application/json']
}
},
structure: {
foo: {}
}
};

// install a protocol on the remote node for aliceSync
const protocolsFoo = await testHarness.agent.sendDwnRequest({
author : aliceSync.did.uri,
target : aliceSync.did.uri,
messageType : DwnInterface.ProtocolsConfigure,
messageParams : {
definition: protocolFoo
}
});
expect(protocolsFoo.reply.status.code).to.equal(202);


// create a record that will be read as a part of sync
const record1 = await testHarness.agent.sendDwnRequest({
author : aliceSync.did.uri,
target : aliceSync.did.uri,
messageType : DwnInterface.RecordsWrite,
messageParams : {
protocol : 'https://protocol.xyz/foo',
protocolPath : 'foo',
schema : 'https://schemas.xyz/foo',
dataFormat : 'text/plain',
},
dataStream: new Blob(['Hello, world!'])
});
expect(record1.reply.status.code).to.equal(202);


const delegateDid = await testHarness.agent.identity.create({
store : true,
didMethod : 'jwk',
metadata : { name: 'Alice Delegate', connectedDid: aliceSync.did.uri }
});

// write a MessagesQuery permission grant for the delegate DID
const messagesQueryGrant = await testHarness.agent.permissions.createGrant({
store : true,
author : aliceSync.did.uri,
grantedTo : delegateDid.did.uri,
dateExpires : Time.createOffsetTimestamp({ seconds: 60 }),
scope : {
interface : DwnInterfaceName.Messages,
method : DwnMethodName.Query,
protocol : 'https://protocol.xyz/foo'
}
});

const { encodedData: messagesQueryGrantData, ...messagesQueryGrantMessage } = messagesQueryGrant.message;
// send to the remote node
const sendGrant = await testHarness.agent.sendDwnRequest({
author : aliceSync.did.uri,
target : aliceSync.did.uri,
messageType : DwnInterface.RecordsWrite,
rawMessage : messagesQueryGrantMessage,
dataStream : new Blob([ Convert.base64Url(messagesQueryGrantData).toUint8Array() ]),
});
expect(sendGrant.reply.status.code).to.equal(202);

// store it as the delegate DID so that it can be fetched during sync
const processGrant = await testHarness.agent.processDwnRequest({
author : delegateDid.did.uri,
target : delegateDid.did.uri,
messageType : DwnInterface.RecordsWrite,
rawMessage : messagesQueryGrantMessage,
dataStream : new Blob([ Convert.base64Url(messagesQueryGrantData).toUint8Array() ]),
signAsOwner : true
});
expect(processGrant.reply.status.code).to.equal(202);

await testHarness.agent.sync.registerIdentity({
did : aliceSync.did.uri,
options : {
delegateDid : delegateDid.did.uri,
protocols : [ 'https://protocol.xyz/foo' ]
}
});

// spy on console.error to check if the error message is logged
const consoleErrorSpy = sinon.stub(console, 'error').resolves();

await syncEngine.sync('pull');
expect(consoleErrorSpy.called).to.be.true;
expect(consoleErrorSpy.args[0][0]).to.include('SyncEngineLevel: pull - Error fetching MessagesRead permission grant for delegate DID');
});

it('synchronizes records for 1 identity from remote DWN to local DWN', async () => {
// Write a test record to Alice's remote DWN.
let writeResponse = await testHarness.agent.dwn.sendRequest({
Expand Down Expand Up @@ -1973,6 +2103,126 @@ describe('SyncEngineLevel', () => {
processRequestSpy.restore();
});

it('logs an error if could not fetch MessagesQuery permission needed for a sync', async () => {
// create new identity to not conflict the previous tests's remote records
const aliceSync = await testHarness.createIdentity({ name: 'Alice', testDwnUrls });

const delegateDid = await testHarness.agent.identity.create({
store : true,
didMethod : 'jwk',
metadata : { name: 'Alice Delegate', connectedDid: aliceSync.did.uri }
});

await testHarness.agent.sync.registerIdentity({
did : aliceSync.did.uri,
options : {
delegateDid : delegateDid.did.uri,
protocols : [ 'https://protocol.xyz/foo' ]
}
});

// spy on console.error to check if the error message is logged
const consoleErrorSpy = sinon.stub(console, 'error').resolves();

await syncEngine.sync('push');
expect(consoleErrorSpy.called).to.be.true;
expect(consoleErrorSpy.args[0][0]).to.include('SyncEngineLevel: Error fetching MessagesQuery permission grant for delegate DID');
});

it('logs an error if could not fetch MessagesRead permission needed for a sync', async () => {
// create new identity to not conflict the previous tests's remote records
const aliceSync = await testHarness.createIdentity({ name: 'Alice', testDwnUrls });

// create 3 local protocols
const protocolFoo: ProtocolDefinition = {
published : true,
protocol : 'https://protocol.xyz/foo',
types : {
foo: {
schema : 'https://schemas.xyz/foo',
dataFormats : ['text/plain', 'application/json']
}
},
structure: {
foo: {}
}
};

// install a protocol on the local node for aliceSync
const protocolsFoo = await testHarness.agent.processDwnRequest({
author : aliceSync.did.uri,
target : aliceSync.did.uri,
messageType : DwnInterface.ProtocolsConfigure,
messageParams : {
definition: protocolFoo
}
});
expect(protocolsFoo.reply.status.code).to.equal(202);


// create a record that will be read as a part of sync
const record1 = await testHarness.agent.processDwnRequest({
author : aliceSync.did.uri,
target : aliceSync.did.uri,
messageType : DwnInterface.RecordsWrite,
messageParams : {
protocol : 'https://protocol.xyz/foo',
protocolPath : 'foo',
schema : 'https://schemas.xyz/foo',
dataFormat : 'text/plain',
},
dataStream: new Blob(['Hello, world!'])
});
expect(record1.reply.status.code).to.equal(202);


const delegateDid = await testHarness.agent.identity.create({
store : true,
didMethod : 'jwk',
metadata : { name: 'Alice Delegate', connectedDid: aliceSync.did.uri }
});

// write a MessagesQuery permission grant for the delegate DID
const messagesQueryGrant = await testHarness.agent.permissions.createGrant({
store : true,
author : aliceSync.did.uri,
grantedTo : delegateDid.did.uri,
dateExpires : Time.createOffsetTimestamp({ seconds: 60 }),
scope : {
interface : DwnInterfaceName.Messages,
method : DwnMethodName.Query,
protocol : 'https://protocol.xyz/foo'
}
});

// store it as the delegate DID so that it can be fetched during sync
const { encodedData: messagesQueryGrantData, ...messagesQueryGrantMessage } = messagesQueryGrant.message;
const processGrant = await testHarness.agent.processDwnRequest({
author : delegateDid.did.uri,
target : delegateDid.did.uri,
messageType : DwnInterface.RecordsWrite,
rawMessage : messagesQueryGrantMessage,
dataStream : new Blob([ Convert.base64Url(messagesQueryGrantData).toUint8Array() ]),
signAsOwner : true
});
expect(processGrant.reply.status.code).to.equal(202);

await testHarness.agent.sync.registerIdentity({
did : aliceSync.did.uri,
options : {
delegateDid : delegateDid.did.uri,
protocols : [ 'https://protocol.xyz/foo' ]
}
});

// spy on console.error to check if the error message is logged
const consoleErrorSpy = sinon.stub(console, 'error').resolves();

await syncEngine.sync('push');
expect(consoleErrorSpy.called).to.be.true;
expect(consoleErrorSpy.args[0][0]).to.include('SyncEngineLevel: push - Error fetching MessagesRead permission grant for delegate DID');
});

it('synchronizes records for 1 identity from local DWN to remote DWN', async () => {
// Write a record that we can use for this test.
let writeResponse = await testHarness.agent.dwn.processRequest({
Expand Down

0 comments on commit ea0016a

Please sign in to comment.