import { test, expect } from "../../base.js"; import { login } from "../../helpers.js"; import { userProfile } from "../../testData.js"; import { MockServer } from "../../mockServer.js"; import { createNotification, createPost, createProfile, } from "../../../shared/factories.js"; test.describe("Delete post flow", () => { test("should remove post from home feed after deleting from profile", async ({ page, }) => { const mockServer = new MockServer(); const post = createPost({ uri: `at://${userProfile.did}/app.bsky.feed.post/mypost1`, text: "My post to delete", authorHandle: userProfile.handle, authorDisplayName: userProfile.displayName, }); mockServer.addTimelinePosts([post]); mockServer.addAuthorFeedPosts(userProfile.did, "posts_and_author_threads", [ post, ]); await mockServer.setup(page); await login(page); // Verify the post is on the home feed await page.goto("/"); const homeView = page.locator("#home-view"); await expect(homeView.locator('[data-testid="feed-item"]')).toHaveCount(1, { timeout: 10000, }); await expect(homeView).toContainText("My post to delete"); // Navigate to own profile await page.goto(`/profile/${userProfile.did}`); const profileView = page.locator("#profile-view"); const feedItem = profileView.locator('[data-testid="feed-item"]'); await expect(feedItem).toHaveCount(1, { timeout: 10000 }); // Open the post action menu and click "Delete post" await feedItem.locator(".text-button").click(); await page.locator('[data-testid="menu-action-post-delete"]').click(); // Confirm deletion if a confirmation dialog appears const confirmButton = page.locator("button.confirm-button"); await expect(confirmButton).toBeVisible({ timeout: 5000 }); await confirmButton.click(); // Verify the post is removed from the profile await expect( profileView.locator( '.feed-container:not([hidden]) [data-testid="feed-end-message"]', ), ).toBeVisible({ timeout: 10000 }); // Navigate to home and verify the post is gone await page.goto("/"); await expect( homeView.locator('[data-testid="feed-end-message"]'), ).toBeVisible({ timeout: 10000 }); }); test("should update thread view after deleting post from thread", async ({ page, }) => { const mockServer = new MockServer(); const post = createPost({ uri: `at://${userProfile.did}/app.bsky.feed.post/mypost2`, text: "My thread post to delete", authorHandle: userProfile.handle, authorDisplayName: userProfile.displayName, }); mockServer.addPosts([post]); await mockServer.setup(page); await login(page); // Navigate to the thread view await page.goto(`/profile/${userProfile.handle}/post/mypost2`); const view = page.locator("#post-detail-view"); const largePost = view.locator('[data-testid="large-post"]'); await expect(largePost).toBeVisible({ timeout: 10000 }); await expect(view).toContainText("My thread post to delete"); // Open the post action menu and click "Delete post" await largePost.locator(".text-button").click(); await page.locator('[data-testid="menu-action-post-delete"]').click(); // Confirm deletion if a confirmation dialog appears const confirmButton = page.locator("button.confirm-button"); await expect(confirmButton).toBeVisible({ timeout: 5000 }); await confirmButton.click(); // After deleting from thread view, the app should navigate away // or the post should no longer be visible await expect(largePost).not.toBeVisible({ timeout: 10000 }); }); test("should hide like notification after deleting the liked post", async ({ page, }) => { const mockServer = new MockServer(); const post = createPost({ uri: `at://${userProfile.did}/app.bsky.feed.post/mypost3`, text: "Post that will be deleted", authorHandle: userProfile.handle, authorDisplayName: userProfile.displayName, }); const alice = createProfile({ did: "did:plc:alice1", handle: "alice.bsky.social", displayName: "Alice", }); mockServer.addPosts([post]); mockServer.addAuthorFeedPosts(userProfile.did, "posts_and_author_threads", [ post, ]); mockServer.addNotifications([ createNotification({ reason: "like", author: alice, reasonSubject: post.uri, indexedAt: new Date().toISOString(), }), ]); await mockServer.setup(page); await login(page); // Confirm the like notification is initially visible await page.goto("/notifications"); const notificationsView = page.locator("#notifications-view"); await expect(notificationsView.locator(".notification-item")).toHaveCount( 1, { timeout: 10000 }, ); await expect(notificationsView).toContainText("liked your post"); // Delete the post from the profile view await page.goto(`/profile/${userProfile.did}`); const profileView = page.locator("#profile-view"); const feedItem = profileView.locator('[data-testid="feed-item"]'); await expect(feedItem).toHaveCount(1, { timeout: 10000 }); await feedItem.locator(".text-button").click(); await page.locator('[data-testid="menu-action-post-delete"]').click(); const confirmButton = page.locator("button.confirm-button"); await expect(confirmButton).toBeVisible({ timeout: 5000 }); await confirmButton.click(); await expect(feedItem).toHaveCount(0, { timeout: 10000 }); // Notification should now be hidden because the post is a notFoundPost await page.goto("/notifications"); await expect(notificationsView.locator(".feed-end-message")).toContainText( "No notifications yet!", { timeout: 10000 }, ); await expect(notificationsView.locator(".notification-item")).toHaveCount( 0, ); }); });