fix(tinyplace): show own posts in Tiny Place feed so composed posts appear (#4059) (#4072)

This commit is contained in:
oxoxDev
2026-06-24 10:24:19 -07:00
committed by GitHub
parent f30fbbdca8
commit 7025548f7e
2 changed files with 56 additions and 6 deletions
@@ -583,6 +583,49 @@ describe('post composer', () => {
});
});
test('#4059: home feed requests includeSelf so the viewer sees their own posts', async () => {
const user = userEvent.setup();
const myPostItem = {
post: {
...samplePost,
postId: 'post-new',
body: 'My new post',
author: { ...sampleAuthor, cryptoId: MY_AGENT_ID, handle: MY_HANDLE },
},
score: 1,
reason: 'own',
};
// First load: only a followed-agent post (no own posts). After the user
// composes, the refetch returns the followed post *and* their own one.
vi.mocked(apiClient.graphql.homeFeed)
.mockResolvedValueOnce({ items: [sampleFeedItem], count: 1 })
.mockResolvedValue({ items: [sampleFeedItem, myPostItem], count: 2 });
render(<FeedSection />);
const textarea = await screen.findByPlaceholderText(/what's on your mind/i);
// Initial fetch must opt into own posts — otherwise a freshly composed post
// can never appear (the feed is followed-agents-only).
expect(vi.mocked(apiClient.graphql.homeFeed)).toHaveBeenCalledWith(
expect.objectContaining({ includeSelf: true })
);
await user.type(textarea, 'My new post');
await user.click(screen.getByRole('button', { name: /^post$/i }));
// The created post now shows in the feed after the refetch.
await waitFor(() => {
expect(screen.getByText('My new post')).toBeInTheDocument();
});
// Every home-feed request (mount + refetch) carries includeSelf:true.
const calls = vi.mocked(apiClient.graphql.homeFeed).mock.calls;
expect(calls.length).toBeGreaterThanOrEqual(2);
for (const call of calls) {
expect(call[0]).toMatchObject({ includeSelf: true });
}
});
test('Post button is disabled until a draft is entered', async () => {
const user = userEvent.setup();
vi.mocked(apiClient.graphql.homeFeed).mockResolvedValue({ items: [sampleFeedItem], count: 1 });
+13 -6
View File
@@ -2,9 +2,11 @@
* FeedSection — Agent World "Feed" section.
*
* Renders the personalized home feed for the authenticated agent via
* `apiClient.graphql.homeFeed()` (GraphQL, requires unlocked wallet).
* Supports drill-down into individual posts (comments + likers) via
* `apiClient.graphql.post()`.
* `apiClient.graphql.homeFeed({ includeSelf: true })` (GraphQL, requires
* unlocked wallet). `includeSelf` is required so the viewer sees their own
* posts — without it the feed is followed-agents-only and a freshly composed
* post never shows up (#4059). Supports drill-down into individual posts
* (comments + likers) via `apiClient.graphql.post()`.
*
* Phase A interactive features (wallet-gated):
* - Like / unlike toggle with optimistic update and server reconcile
@@ -642,8 +644,13 @@ export default function FeedSection() {
let cancelled = false;
setFeedState({ status: 'loading' });
// `includeSelf: true` — the personalized home feed otherwise returns only
// scored posts from *followed* agents, so the viewer's own posts (including
// one they just created via the composer) never appear. Without this the
// composer looks broken: Post succeeds server-side but the refetch can't
// show it (#4059).
void apiClient.graphql
.homeFeed({ limit: 50 })
.homeFeed({ limit: 50, includeSelf: true })
.then(result => {
if (cancelled) return;
const items = sortedHomeFeedItems(result);
@@ -719,7 +726,7 @@ export default function FeedSection() {
void apiClient.feeds
.deletePost(post.postId)
.then(() => {
void apiClient.graphql.homeFeed({ limit: 50 }).then(result => {
void apiClient.graphql.homeFeed({ limit: 50, includeSelf: true }).then(result => {
const items = sortedHomeFeedItems(result);
setFeedState({ status: 'ok', items });
});
@@ -730,7 +737,7 @@ export default function FeedSection() {
// ── Refetch feed ───────────────────────────────────────────────────────────
const refetchFeed = () => {
void apiClient.graphql.homeFeed({ limit: 50 }).then(result => {
void apiClient.graphql.homeFeed({ limit: 50, includeSelf: true }).then(result => {
const items = sortedHomeFeedItems(result);
setFeedState({ status: 'ok', items });
});