From b8a10d3706729498cad2553ef5aa4d45e17c91bb Mon Sep 17 00:00:00 2001 From: Chris Troutner Date: Fri, 28 Aug 2026 10:43:52 -0700 Subject: [PATCH] Spec topic post, follow, and unfollow actions Add client specs for the topic post composer and topic follow/unfollow buttons, plus the DB read side for topic follow state and followers. By specifier. --- psf-memo-client/specs/topic-follow.feature | 52 +++++++++++++++++++ psf-memo-client/specs/topic-post.feature | 57 +++++++++++++++++++++ psf-memo-db/specs/topic-follow-read.feature | 38 ++++++++++++++ 3 files changed, 147 insertions(+) create mode 100644 psf-memo-client/specs/topic-follow.feature create mode 100644 psf-memo-client/specs/topic-post.feature create mode 100644 psf-memo-db/specs/topic-follow-read.feature diff --git a/psf-memo-client/specs/topic-follow.feature b/psf-memo-client/specs/topic-follow.feature new file mode 100644 index 0000000..1a3448a --- /dev/null +++ b/psf-memo-client/specs/topic-follow.feature @@ -0,0 +1,52 @@ +# Scenarios: Topic Follow - 1, Topic Follow - 2, Topic Follow - 3, Topic Follow - 4 +# +# The topic feed page has a Follow/Unfollow button that broadcasts a Memo +# topic follow (0x6d0d) or topic unfollow (0x6d0e) action. Unlike user +# follows, the topic payload is plain UTF-8 text (the topic name); no +# cashaddr conversion is needed. +Feature: Topic Follow + + Background: + Given a wallet authenticated for the address bitcoincash:qqlrzp23w08434twmvr4fxw672whkjy0py26r63g3d + Given the wallet has spendable output to pay the transaction fee + + Scenario Outline: Topic Follow - 1 the topic feed page shows a Follow button when I do not follow the topic + Given the psf-memo-db API reports that I do not follow the topic + Given I open the topic feed for the topic + Then the topic feed page shows a Follow button + + Examples: + | topic | + | bitcoin | + | cash | + + Scenario Outline: Topic Follow - 2 clicking Follow broadcasts the topic follow action and shows Unfollow + Given I open the topic feed for the topic + When I click the Follow button + Then the app broadcasts an OP_RETURN transaction with the Memo topic-follow prefix for the topic + Then the topic feed page shows an Unfollow button + + Examples: + | topic | + | bitcoin | + + Scenario Outline: Topic Follow - 3 clicking Unfollow broadcasts the topic unfollow action and shows Follow + Given the psf-memo-db API reports that I follow the topic + Given I open the topic feed for the topic + When I click the Unfollow button + Then the app broadcasts an OP_RETURN transaction with the Memo topic-unfollow prefix for the topic + Then the topic feed page shows a Follow button + + Examples: + | topic | + | bitcoin | + + Scenario Outline: Topic Follow - 4 the topic feed page shows Unfollow when I already follow the topic + Given the psf-memo-db API reports that I follow the topic + Given I open the topic feed for the topic + Then the topic feed page shows an Unfollow button + + Examples: + | topic | + | bitcoin | + | cash | diff --git a/psf-memo-client/specs/topic-post.feature b/psf-memo-client/specs/topic-post.feature new file mode 100644 index 0000000..da0719d --- /dev/null +++ b/psf-memo-client/specs/topic-post.feature @@ -0,0 +1,57 @@ +# Scenarios: Topic Post - 1, Topic Post - 2, Topic Post - 3, Topic Post - 4 +# +# The topic feed page has a composer that broadcasts a Memo topic message +# (0x6d0c). The payload is the topic name plus the message, with a combined +# limit of 214 bytes. The composer counts bytes (not characters) so the +# remaining count reflects the topic name plus the typed message. +Feature: Topic Post + + Background: + Given a wallet authenticated for the address bitcoincash:qqlrzp23w08434twmvr4fxw672whkjy0py26r63g3d + Given the wallet has spendable output to pay the transaction fee + + Scenario Outline: Topic Post - 1 a valid topic message is broadcast and shown in the topic feed + Given I open the topic feed for the topic + When I compose a topic message with the text "" + When I submit the topic message + Then the app broadcasts an OP_RETURN transaction with the Memo topic-message prefix for the topic + Then the topic feed shows a new post from my address with the text "" + + Examples: + | topic | message | + | bitcoin | hello bitcoin | + | cash | a longer topic message with several words and punctuation. | + | bitcoin | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | + + Scenario Outline: Topic Post - 2 an empty topic message is rejected + Given I open the topic feed for the topic + When I compose a topic message with the text "" + When I submit the topic message + Then the topic post composer shows a validation error + Then the app does not broadcast any transaction + + Examples: + | topic | message | + | bitcoin | | + + Scenario Outline: Topic Post - 3 an over-long topic message is rejected + Given I open the topic feed for the topic + When I compose a topic message with the text "" + When I submit the topic message + Then the topic post composer shows a length error + Then the app does not broadcast any transaction + + Examples: + | topic | message | + | bitcoin | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | + + Scenario Outline: Topic Post - 4 the byte counter counts down from the combined topic limit + Given I open the topic feed for the topic + When I compose a topic message with the text "" + Then the topic post composer shows a remaining byte count of + + Examples: + | topic | message | count | + | bitcoin | | 207 | + | bitcoin | hello | 202 | + | bitcoin | é | 205 | diff --git a/psf-memo-db/specs/topic-follow-read.feature b/psf-memo-db/specs/topic-follow-read.feature new file mode 100644 index 0000000..a86a6c7 --- /dev/null +++ b/psf-memo-db/specs/topic-follow-read.feature @@ -0,0 +1,38 @@ +# Scenarios: Topic Follow Read - 1, Topic Follow Read - 2 +# +# The indexer stores topic follows in the rooms store keyed `${room}:${addr}` +# with type 'follow' and an `unfollow` boolean. The read side exposes whether +# an address follows a topic and the list of addresses that follow a topic. +# +# Fixture "topic-follows": +# rooms store: +# bitcoin:addr-a { room: bitcoin, addr: addr-a, type: follow, unfollow: false } +# bitcoin:addr-b { room: bitcoin, addr: addr-b, type: follow, unfollow: false } +# bitcoin:addr-c { room: bitcoin, addr: addr-c, type: follow, unfollow: true } +# cash:addr-a { room: cash, addr: addr-a, type: follow, unfollow: false } +Feature: Topic Follow Read + + Background: + Given a psf-memo-db instance with a rooms store + Given the fixture "topic-follows" is loaded into the rooms store + + Scenario Outline: Topic Follow Read - 1 GET /topics/:room/follow/state reports whether an address follows a topic + When the client requests the topic follow state for room and address + Then the topic follow state reports following + + Examples: + | room | addr | following | + | bitcoin | addr-a | true | + | bitcoin | addr-c | false | + | bitcoin | addr-x | false | + | cash | addr-a | true | + + Scenario Outline: Topic Follow Read - 2 GET /topics/:room/followers lists the addresses that follow a topic + When the client requests the topic followers list for room + Then the topic followers list contains the addresses + + Examples: + | room | expected | + | bitcoin | addr-a,addr-b | + | cash | addr-a | + | lone | |