diff --git a/.changeset/nip-62-integration-tests.md b/.changeset/nip-62-integration-tests.md new file mode 100644 index 00000000..9009ab5f --- /dev/null +++ b/.changeset/nip-62-integration-tests.md @@ -0,0 +1,5 @@ +--- +"nostream": patch +--- + +Add NIP-62 integration tests for Request to Vanish \ No newline at end of file diff --git a/test/integration/features/nip-62/nip-62.feature b/test/integration/features/nip-62/nip-62.feature new file mode 100644 index 00000000..1a347f12 --- /dev/null +++ b/test/integration/features/nip-62/nip-62.feature @@ -0,0 +1,15 @@ +Feature: NIP-62 + Scenario: Alice requests to vanish + Given someone called Alice + And someone called Bob + And Alice sends a set_metadata event + And Alice sends a text_note event with content "please forget this" + When Alice sends a request_to_vanish event + And Bob subscribes to author Alice + Then Bob receives 1 request_to_vanish event from Alice and EOSE + + Scenario: Alice cannot publish after requesting to vanish + Given someone called Alice + When Alice sends a request_to_vanish event + And Alice drafts a text_note event with content "I should be blocked" + Then Alice sends their last draft event unsuccessfully because "blocked: request to vanish active for pubkey" diff --git a/test/integration/features/nip-62/nip-62.feature.ts b/test/integration/features/nip-62/nip-62.feature.ts new file mode 100644 index 00000000..ec2ac45b --- /dev/null +++ b/test/integration/features/nip-62/nip-62.feature.ts @@ -0,0 +1,57 @@ +import { Then, When } from '@cucumber/cucumber' +import { expect } from 'chai' +import WebSocket from 'ws' + +import { createEvent, sendEvent, waitForEventCount } from '../helpers' +import { ALL_RELAYS, EventKinds, EventTags } from '../../../../src/constants/base' +import { Event } from '../../../../src/@types/event' +import { isDraft } from '../shared' + +When(/^(\w+) sends a request_to_vanish event$/, async function (name: string) { + const ws = this.parameters.clients[name] as WebSocket + const { pubkey, privkey } = this.parameters.identities[name] + + const event: Event = await createEvent( + { pubkey, kind: EventKinds.REQUEST_TO_VANISH, content: '', tags: [[EventTags.Relay, ALL_RELAYS]] }, + privkey, + ) + + await sendEvent(ws, event) + this.parameters.events[name].push(event) +}) + +Then( + /(\w+) receives (\d+) request_to_vanish events? from (\w+) and EOSE$/, + async function (name: string, count: string, author: string) { + const ws = this.parameters.clients[name] as WebSocket + const subscription = this.parameters.subscriptions[name][this.parameters.subscriptions[name].length - 1] + const expectedCount = Number(count) + const expectedPubkey = this.parameters.identities[author].pubkey + const events = await waitForEventCount(ws, subscription.name, expectedCount, true) + + expect(events.length).to.equal(expectedCount) + for (const event of events) { + expect(event.kind).to.equal(EventKinds.REQUEST_TO_VANISH) + expect(event.pubkey).to.equal(expectedPubkey) + } + }, +) + +Then( + /^(\w+) sends their last draft event unsuccessfully because "([^"]+)"$/, + async function (name: string, reason: string) { + const ws = this.parameters.clients[name] as WebSocket + const event = this.parameters.events[name].findLast((event: Event) => event[isDraft]) + + if (!event) { + throw new Error(`No draft event found for ${name}`) + } + + delete event[isDraft] + + const command = await sendEvent(ws, event, false) + expect(command[1]).to.equal(event.id) + expect(command[2]).to.be.false + expect(command[3]).to.equal(reason) + }, +)