From d3c3a80bbf4a4c0a2005b4a4e1eecfba3e042e41 Mon Sep 17 00:00:00 2001 From: Chris Troutner Date: Fri, 28 Aug 2026 06:15:58 -0700 Subject: [PATCH] Spec topic list/discovery and topic feed By specifier. --- psf-memo-client/specs/topic-discovery.feature | 30 +++++++++ psf-memo-client/specs/topic-feed.feature | 23 +++++++ psf-memo-db/specs/topic-read.feature | 61 +++++++++++++++++++ 3 files changed, 114 insertions(+) create mode 100644 psf-memo-client/specs/topic-discovery.feature create mode 100644 psf-memo-client/specs/topic-feed.feature create mode 100644 psf-memo-db/specs/topic-read.feature diff --git a/psf-memo-client/specs/topic-discovery.feature b/psf-memo-client/specs/topic-discovery.feature new file mode 100644 index 0000000..ddc74f2 --- /dev/null +++ b/psf-memo-client/specs/topic-discovery.feature @@ -0,0 +1,30 @@ +# Scenarios: Topic Discovery - 1, Topic Discovery - 2 +# +# The topics page lists the topics served by the psf-memo-db /topics endpoint +# and links each one to its feed. +Feature: Topic Discovery + + Background: + Given the psf-memo-db API serves a topic named "bitcoin" with 2 posts + Given the psf-memo-db API serves a topic named "cash" with 1 post + Given the psf-memo-db API serves a topic named "dev" with 1 post + + Scenario Outline: Topic Discovery - 1 the topics page lists each topic with its post count + When I open the topics page + Then the topics page shows the topic with posts + + Examples: + | topic | count | + | bitcoin | 2 | + | cash | 1 | + | dev | 1 | + + Scenario Outline: Topic Discovery - 2 clicking a topic opens its feed + Given I open the topics page + When I click the topic + Then the app navigates to the topic feed for + + Examples: + | topic | + | bitcoin | + | cash | diff --git a/psf-memo-client/specs/topic-feed.feature b/psf-memo-client/specs/topic-feed.feature new file mode 100644 index 0000000..55f6bfe --- /dev/null +++ b/psf-memo-client/specs/topic-feed.feature @@ -0,0 +1,23 @@ +# Scenarios: Topic Feed - 1, Topic Feed - 2 +# +# The topic feed page shows the posts served by the psf-memo-db +# /topics/:room/posts endpoint for a single topic. +Feature: Topic Feed + + Background: + Given the psf-memo-db API serves a post with txid aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa in the topic "bitcoin" authored by the address bitcoincash:qqlrzp23w08434twmvr4fxw672whkjy0py26r63g3d with text "hello bitcoin" + Given the psf-memo-db API serves a post with txid bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb in the topic "bitcoin" authored by a second address with text "bitcoin again" + + Scenario Outline: Topic Feed - 1 the topic feed shows the posts for the topic + When I open the topic feed for + Then the feed shows the post with txid with text + + Examples: + | topic | txid | text | + | bitcoin | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | hello bitcoin | + | bitcoin | bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb | bitcoin again | + + Scenario: Topic Feed - 2 a topic with no posts shows an empty message + Given the psf-memo-db API serves no posts for the topic "lone" + When I open the topic feed for "lone" + Then the feed shows a message that there are no posts diff --git a/psf-memo-db/specs/topic-read.feature b/psf-memo-db/specs/topic-read.feature new file mode 100644 index 0000000..79d5d18 --- /dev/null +++ b/psf-memo-db/specs/topic-read.feature @@ -0,0 +1,61 @@ +# Scenarios: Topic Read - 1, Topic Read - 2, Topic Read - 3, Topic Read - 4 +# +# The indexer stores topic activity in the rooms store. Topic messages are +# keyed `${room}:${txid}` with type 'post'; topic follows are keyed +# `${room}:${addr}` with type 'follow'. The read side lists distinct topics +# with their post counts and returns a topic's posts ordered by block height. +# +# Fixture "topics-with-posts": +# rooms store: +# bitcoin:post-300 { room: bitcoin, txid: post-300, type: post, blockHeight: 300 } +# bitcoin:post-200 { room: bitcoin, txid: post-200, type: post, blockHeight: 200 } +# bitcoin:addr-f { room: bitcoin, addr: addr-f, type: follow, unfollow: false } +# cash:post-250 { room: cash, txid: post-250, type: post, blockHeight: 250 } +# dev:post-100 { room: dev, txid: post-100, type: post, blockHeight: 100 } +# lone:addr-f { room: lone, addr: addr-f, type: follow, unfollow: false } +# posts store: +# post-300 { txid: post-300, addr: addr-a, text: hello bitcoin, blockHeight: 300 } +# post-200 { txid: post-200, addr: addr-b, text: bitcoin again, blockHeight: 200 } +# post-250 { txid: post-250, addr: addr-a, text: cash rules, blockHeight: 250 } +# post-100 { txid: post-100, addr: addr-c, text: dev stuff, blockHeight: 100 } +Feature: Topic Read + + Background: + Given a psf-memo-db instance with a rooms store and a posts store + Given the fixture "topics-with-posts" is loaded into the rooms and posts stores + + Scenario Outline: Topic Read - 1 GET /topics lists distinct topics with their post counts + When the client requests /topics + Then the response contains the topic with post count + + Examples: + | topic | count | + | bitcoin | 2 | + | cash | 1 | + | dev | 1 | + | lone | 0 | + + Scenario Outline: Topic Read - 2 GET /topics/:room/posts returns the posts for a topic sorted by block height descending + When the client requests /topics//posts + Then the response posts are sorted by block height descending + And the response contains the txids + + Examples: + | room | expected_txids | + | bitcoin | post-300,post-200 | + | cash | post-250 | + + Scenario Outline: Topic Read - 3 GET /topics/:room/posts paginates + When the client requests /topics//posts with limit and offset + Then the response contains the txids + And the response pagination shows total and hasMore + + Examples: + | room | limit | offset | expected_txids | total | hasMore | + | bitcoin | 1 | 0 | post-300 | 2 | true | + | bitcoin | 2 | 0 | post-300,post-200 | 2 | false | + | bitcoin | 1 | 1 | post-200 | 2 | true | + + Scenario: Topic Read - 4 GET /topics/:room/posts returns no posts for a topic with no posts + When the client requests /topics/lone/posts + Then the response contains no posts