From 7e02adbf45b27fef39a5fecb4e309f39234a68ba Mon Sep 17 00:00:00 2001 From: Peter Ott Date: Thu, 23 May 2024 09:55:57 +0200 Subject: [PATCH 1/8] feat(index): adds placeholder for unit tests --- test/command/feed.spec.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/command/feed.spec.ts b/test/command/feed.spec.ts index baa50364..c320a706 100644 --- a/test/command/feed.spec.ts +++ b/test/command/feed.spec.ts @@ -110,6 +110,9 @@ describeCommand( expect(getLastMessage()).toContain('Number of Updates') expect(getLastMessage()).toContain('2') }) + + // Write feed index specific unit tests here + }, { configFileName: 'feed' }, ) From 689b2bb80e98b646ea9306933f176eea51cad5f2 Mon Sep 17 00:00:00 2001 From: Peter Ott Date: Thu, 23 May 2024 13:58:58 +0200 Subject: [PATCH 2/8] test: adds unit test for feed write --- test/command/feed.spec.ts | 86 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 84 insertions(+), 2 deletions(-) diff --git a/test/command/feed.spec.ts b/test/command/feed.spec.ts index c320a706..26798ed6 100644 --- a/test/command/feed.spec.ts +++ b/test/command/feed.spec.ts @@ -111,8 +111,90 @@ describeCommand( expect(getLastMessage()).toContain('2') }) - // Write feed index specific unit tests here - + it('should write to correct index', async () => { + // create identity + await invokeTestCli(['identity', 'create', 'test', '--password', 'test']) + // upload data to index 22 + await invokeTestCli([ + 'feed', + 'upload', + `${__dirname}/../testpage/images/swarm.png`, + '--identity', + 'test', + '--topic-string', + 'test', + '--password', + 'test', + '--quiet', + '--index', + '22', + ...getStampOption(), + ]) + // print with identity and password + await invokeTestCli([ + 'feed', + 'print', + '--identity', + 'test', + '--topic-string', + 'test', + '--password', + 'test', + '--quiet', + '--index', + '22', + ...getStampOption(), + ]) + expect(getLastMessage()).toMatch(/[a-z0-9]{64}/) + + // Zero index should work as well + await invokeTestCli(['identity', 'create', 'test', '--password', 'test']) + await invokeTestCli([ + 'feed', + 'upload', + `${__dirname}/../testpage/images/swarm.png`, + '--identity', 'test', + '--topic-string', + 'test', + '--password', + 'test', + '--quiet', + '--index', + '0', + ...getStampOption(), + ]) + await invokeTestCli([ + 'feed', + 'print', + '--identity', + 'test', + '--topic-string', + 'test', + '--password', + 'test', + '--quiet', + '--index', + '0', + ...getStampOption(), + ]) + expect(getLastMessage()).toMatch(/[a-z0-9]{64}/) + + // It should work without specifying the index as well + await invokeTestCli([ + 'feed', + 'print', + '--identity', + 'test', + '--topic-string', + 'test', + '--password', + 'test', + '--quiet', + ...getStampOption(), + ]) + expect(getLastMessage()).toMatch(/[a-z0-9]{64}/) + }) + }, { configFileName: 'feed' }, ) From 5a420a8ebd25c0e08c030d86a08cab348bf63503 Mon Sep 17 00:00:00 2001 From: Peter Ott Date: Thu, 23 May 2024 16:02:11 +0200 Subject: [PATCH 3/8] feat: adds optional index parameter for feed command --- src/command/feed/feed-command.ts | 14 ++++++++++++-- src/command/feed/update.ts | 2 +- src/command/feed/upload.ts | 2 +- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/command/feed/feed-command.ts b/src/command/feed/feed-command.ts index a3fc4d30..29dd9729 100644 --- a/src/command/feed/feed-command.ts +++ b/src/command/feed/feed-command.ts @@ -38,6 +38,9 @@ export class FeedCommand extends RootCommand { @Option({ key: 'password', alias: 'P', description: 'Password for the wallet' }) public password!: string + @Option({ key: 'index', description: 'Index for the feed to write to, or read from', required: false }) + + public act!: boolean protected async updateFeedAndPrint(chunkReference: string): Promise { const wallet = await this.getWallet() const topic = this.topic || this.bee.makeFeedTopic(this.topicString) @@ -79,7 +82,7 @@ export class FeedCommand extends RootCommand { return identities[this.identity] || identities[await pickIdentity(this.commandConfig, this.console)] } - private async writeFeed(wallet: Wallet, topic: string, chunkReference: string): Promise { + private async writeFeed(wallet: Wallet, topic: string, chunkReference: string, index?: number): Promise { const spinner = createSpinner('Writing feed...') if (this.verbosity !== VerbosityLevel.Quiet && !this.curl) { @@ -88,7 +91,14 @@ export class FeedCommand extends RootCommand { try { const writer = this.bee.makeFeedWriter('sequence', topic, wallet.getPrivateKey()) - const reference = await writer.upload(this.stamp, chunkReference as Reference) + let reference: Reference + if (index === undefined) { + // Index was not specified + reference = await writer.upload(this.stamp, chunkReference as Reference) + } else { + // Index was specified + reference = await writer.upload(this.stamp, chunkReference as Reference, { index }) + } const { reference: manifest } = await this.bee.createFeedManifest( this.stamp, 'sequence', diff --git a/src/command/feed/update.ts b/src/command/feed/update.ts index 5d9af4ae..b21ea382 100644 --- a/src/command/feed/update.ts +++ b/src/command/feed/update.ts @@ -5,7 +5,7 @@ import { FeedCommand } from './feed-command' export class Update extends FeedCommand implements LeafCommand { public readonly name = 'update' - public readonly description = 'Update feed' + public readonly description = 'Update feed (with reference)' @Option({ key: 'reference', alias: 'r', description: 'The new reference', required: true }) public reference!: string diff --git a/src/command/feed/upload.ts b/src/command/feed/upload.ts index c3548d22..e5ac6315 100644 --- a/src/command/feed/upload.ts +++ b/src/command/feed/upload.ts @@ -6,7 +6,7 @@ import { FeedCommand } from './feed-command' export class Upload extends FeedCommand implements LeafCommand { public readonly name = 'upload' - public readonly description = 'Upload to a feed' + public readonly description = 'Upload to a feed (file or folder)' public feedManifest?: string From 75ebc7db3aada1f20cbf3642cbdba33b6f1816dc Mon Sep 17 00:00:00 2001 From: Peter Ott Date: Thu, 23 May 2024 16:25:23 +0200 Subject: [PATCH 4/8] docs: changes description for index option --- src/command/feed/feed-command.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/command/feed/feed-command.ts b/src/command/feed/feed-command.ts index 29dd9729..a31b4368 100644 --- a/src/command/feed/feed-command.ts +++ b/src/command/feed/feed-command.ts @@ -38,7 +38,7 @@ export class FeedCommand extends RootCommand { @Option({ key: 'password', alias: 'P', description: 'Password for the wallet' }) public password!: string - @Option({ key: 'index', description: 'Index for the feed to write to, or read from', required: false }) + @Option({ key: 'index', description: 'Feed index to write to or read from', required: false }) public act!: boolean protected async updateFeedAndPrint(chunkReference: string): Promise { From 1b6319a3f0f8075f335cc5aae627ebfbb37f360b Mon Sep 17 00:00:00 2001 From: Peter Ott Date: Thu, 23 May 2024 16:51:12 +0200 Subject: [PATCH 5/8] fix: removes unnecessary act variable, and adds index --- src/command/feed/feed-command.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/command/feed/feed-command.ts b/src/command/feed/feed-command.ts index a31b4368..9f0a44d0 100644 --- a/src/command/feed/feed-command.ts +++ b/src/command/feed/feed-command.ts @@ -39,8 +39,8 @@ export class FeedCommand extends RootCommand { public password!: string @Option({ key: 'index', description: 'Feed index to write to or read from', required: false }) + public index!: number - public act!: boolean protected async updateFeedAndPrint(chunkReference: string): Promise { const wallet = await this.getWallet() const topic = this.topic || this.bee.makeFeedTopic(this.topicString) From 7a2e32e0b043cf587c5a26d8c35225691d7566d0 Mon Sep 17 00:00:00 2001 From: Peter Ott Date: Thu, 23 May 2024 18:05:36 +0200 Subject: [PATCH 6/8] fix: adds index to print as well --- src/command/feed/feed-command.ts | 4 ++-- src/command/feed/print.ts | 15 ++++++++++++++- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/command/feed/feed-command.ts b/src/command/feed/feed-command.ts index 9f0a44d0..4e33d383 100644 --- a/src/command/feed/feed-command.ts +++ b/src/command/feed/feed-command.ts @@ -39,12 +39,12 @@ export class FeedCommand extends RootCommand { public password!: string @Option({ key: 'index', description: 'Feed index to write to or read from', required: false }) - public index!: number + public index!: number | undefined protected async updateFeedAndPrint(chunkReference: string): Promise { const wallet = await this.getWallet() const topic = this.topic || this.bee.makeFeedTopic(this.topicString) - const { reference, manifest } = await this.writeFeed(wallet, topic, chunkReference) + const { reference, manifest } = await this.writeFeed(wallet, topic, chunkReference, this.index) this.console.verbose(createKeyValue('Chunk Reference', chunkReference)) this.console.verbose(createKeyValue('Chunk Reference URL', `${this.bee.url}/bzz/${chunkReference}/`)) diff --git a/src/command/feed/print.ts b/src/command/feed/print.ts index 15bda9d3..542c62af 100644 --- a/src/command/feed/print.ts +++ b/src/command/feed/print.ts @@ -8,6 +8,7 @@ import { getFieldOrNull } from '../../utils' import { createSpinner } from '../../utils/spinner' import { createKeyValue } from '../../utils/text' import { FeedCommand } from './feed-command' +import { FetchFeedUpdateResponse } from '@ethersphere/bee-js/dist/types/modules/feed' export class Print extends FeedCommand implements LeafCommand { public readonly name = 'print' @@ -28,12 +29,24 @@ export class Print extends FeedCommand implements LeafCommand { await super.init() const topic = this.topic || this.bee.makeFeedTopic(this.topicString) + const index: number | undefined = this.index const spinner = createSpinner(`Looking up feed topic ${topic}`) spinner.start() try { const addressString = this.address || (await this.getAddressString()) const reader = this.bee.makeFeedReader('sequence', topic, addressString) - const { reference, feedIndex, feedIndexNext } = await reader.download() + + let result: FetchFeedUpdateResponse | null = null; + if (index === undefined) { + // Index was not specified + result = await reader.download() + } else { + // Index was specified + const x = Number(index) // typeof index is string, and we don't understand why. This is why we are doing this conversion. + result = await reader.download({ index: x }) + } + if (!result) throw Error('Error downloading feed update') + const { reference, feedIndex, feedIndexNext } = result; if (!this.stamp) { spinner.stop() From d65c3aa8facdf530d830951ce231de0ed85233a1 Mon Sep 17 00:00:00 2001 From: Peter Ott Date: Thu, 23 May 2024 20:50:20 +0200 Subject: [PATCH 7/8] fix: changes bee-js version, and fixes some bugs related to feed index --- package.json | 2 +- src/command/feed/feed-command.ts | 4 ++-- src/command/feed/print.ts | 4 ++-- test/command/feed.spec.ts | 15 ++++++++------- 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index a1d9591a..31e56c46 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,7 @@ "typescript": "^4.8.4" }, "dependencies": { - "@ethersphere/bee-js": "^6.7.3", + "@ethersphere/bee-js": "^6.9.1", "@fairdatasociety/bmt-js": "^2.1.0", "bignumber.js": "^9.1.0", "chalk": "^2.4.2", diff --git a/src/command/feed/feed-command.ts b/src/command/feed/feed-command.ts index 4e33d383..f035941e 100644 --- a/src/command/feed/feed-command.ts +++ b/src/command/feed/feed-command.ts @@ -88,7 +88,7 @@ export class FeedCommand extends RootCommand { if (this.verbosity !== VerbosityLevel.Quiet && !this.curl) { spinner.start() } - + try { const writer = this.bee.makeFeedWriter('sequence', topic, wallet.getPrivateKey()) let reference: Reference @@ -97,7 +97,7 @@ export class FeedCommand extends RootCommand { reference = await writer.upload(this.stamp, chunkReference as Reference) } else { // Index was specified - reference = await writer.upload(this.stamp, chunkReference as Reference, { index }) + reference = await writer.upload(this.stamp, chunkReference as Reference, { index: Number(index) }) } const { reference: manifest } = await this.bee.createFeedManifest( this.stamp, diff --git a/src/command/feed/print.ts b/src/command/feed/print.ts index 542c62af..03399fde 100644 --- a/src/command/feed/print.ts +++ b/src/command/feed/print.ts @@ -42,8 +42,8 @@ export class Print extends FeedCommand implements LeafCommand { result = await reader.download() } else { // Index was specified - const x = Number(index) // typeof index is string, and we don't understand why. This is why we are doing this conversion. - result = await reader.download({ index: x }) + // typeof index is string, and we don't understand why. This is why we are doing this conversion. + result = await reader.download({ index: Number(index) }) } if (!result) throw Error('Error downloading feed update') const { reference, feedIndex, feedIndexNext } = result; diff --git a/test/command/feed.spec.ts b/test/command/feed.spec.ts index 26798ed6..3483d205 100644 --- a/test/command/feed.spec.ts +++ b/test/command/feed.spec.ts @@ -112,15 +112,16 @@ describeCommand( }) it('should write to correct index', async () => { + const identityName = 'test' // create identity - await invokeTestCli(['identity', 'create', 'test', '--password', 'test']) + await invokeTestCli(['identity', 'create', identityName, '--password', 'test']) // upload data to index 22 await invokeTestCli([ 'feed', 'upload', `${__dirname}/../testpage/images/swarm.png`, '--identity', - 'test', + identityName, '--topic-string', 'test', '--password', @@ -135,7 +136,7 @@ describeCommand( 'feed', 'print', '--identity', - 'test', + identityName, '--topic-string', 'test', '--password', @@ -148,12 +149,12 @@ describeCommand( expect(getLastMessage()).toMatch(/[a-z0-9]{64}/) // Zero index should work as well - await invokeTestCli(['identity', 'create', 'test', '--password', 'test']) await invokeTestCli([ 'feed', 'upload', `${__dirname}/../testpage/images/swarm.png`, - '--identity', 'test', + '--identity', + identityName, '--topic-string', 'test', '--password', @@ -167,7 +168,7 @@ describeCommand( 'feed', 'print', '--identity', - 'test', + identityName, '--topic-string', 'test', '--password', @@ -184,7 +185,7 @@ describeCommand( 'feed', 'print', '--identity', - 'test', + identityName, '--topic-string', 'test', '--password', From abfc37128f9cf9d542cdbc2c50c8798df1d2c8d8 Mon Sep 17 00:00:00 2001 From: Peter Ott Date: Thu, 23 May 2024 21:19:15 +0200 Subject: [PATCH 8/8] test: adds unit test for feed update as well (with ref) --- test/command/feed.spec.ts | 77 +++++++++++++++++++++++++++++++++------ 1 file changed, 65 insertions(+), 12 deletions(-) diff --git a/test/command/feed.spec.ts b/test/command/feed.spec.ts index 3483d205..52b1bcc4 100644 --- a/test/command/feed.spec.ts +++ b/test/command/feed.spec.ts @@ -111,8 +111,11 @@ describeCommand( expect(getLastMessage()).toContain('2') }) - it('should write to correct index', async () => { + + it('upload should write to correct index', async () => { const identityName = 'test' + const topicName = 'test' + const password = 'test' // create identity await invokeTestCli(['identity', 'create', identityName, '--password', 'test']) // upload data to index 22 @@ -123,9 +126,9 @@ describeCommand( '--identity', identityName, '--topic-string', - 'test', + topicName, '--password', - 'test', + password, '--quiet', '--index', '22', @@ -138,16 +141,16 @@ describeCommand( '--identity', identityName, '--topic-string', - 'test', + topicName, '--password', - 'test', + password, '--quiet', '--index', '22', ...getStampOption(), ]) expect(getLastMessage()).toMatch(/[a-z0-9]{64}/) - + // Zero index should work as well await invokeTestCli([ 'feed', @@ -156,9 +159,9 @@ describeCommand( '--identity', identityName, '--topic-string', - 'test', + topicName, '--password', - 'test', + password, '--quiet', '--index', '0', @@ -170,16 +173,16 @@ describeCommand( '--identity', identityName, '--topic-string', - 'test', + topicName, '--password', - 'test', + password, '--quiet', '--index', '0', ...getStampOption(), ]) expect(getLastMessage()).toMatch(/[a-z0-9]{64}/) - + // It should work without specifying the index as well await invokeTestCli([ 'feed', @@ -187,15 +190,65 @@ describeCommand( '--identity', identityName, '--topic-string', + topicName, + '--password', + password, + '--quiet', + ...getStampOption(), + ]) + expect(getLastMessage()).toMatch(/[a-z0-9]{64}/) + }) + + it('update should write to correct index', async () => { + const identityName = 'test' + const topicName = 'test' + const password = 'test' + // create identity + await invokeTestCli(['identity', 'create', 'test', '--password', 'test']) + // upload data and get reference + await invokeTestCli([ + 'upload', + `${__dirname}/../testpage/images/swarm.png`, + '--quiet', + ...getStampOption(), + ]) + const reference = getLastMessage(); + // update the feed with newly got reference + await invokeTestCli([ + 'feed', + 'update', + '--reference', + reference, + '--identity', + identityName, + '--topic-string', + topicName, + '--password', + password, + '--quiet', + '--index', + '22', + ...getStampOption(), + ]) + + // print with identity and password + await invokeTestCli([ + 'feed', + 'print', + '--identity', + 'test', + '--topic-string', 'test', '--password', 'test', '--quiet', + '--index', + '22', ...getStampOption(), ]) expect(getLastMessage()).toMatch(/[a-z0-9]{64}/) }) - + }, { configFileName: 'feed' }, )