qdpqut37t: Add the frosted bottom dock that likes and comments on the post on screen
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { createElement } from "react";
|
||||
import { renderToStaticMarkup } from "react-dom/server";
|
||||
import { readFileSync } from "node:fs";
|
||||
import { FeedView, type FeedViewProps } from "@/components/FeedView";
|
||||
import { MobileDock, dockState } from "@/components/MobileDock";
|
||||
import { CompactLayoutContext } from "@/components/layout-context";
|
||||
import { toCardPosts } from "@/lib/feed-model";
|
||||
|
||||
const item = (id: string, likes: number, comments: number, liked = false) => ({
|
||||
type: "post",
|
||||
publishedAt: "2026-10-19T11:00:00Z",
|
||||
likesCount: likes,
|
||||
commentsCount: comments,
|
||||
isLiked: liked,
|
||||
post: { id, content: `text ${id}`, author: { id: "a", displayName: `Author ${id}` }, mediaItems: [] },
|
||||
});
|
||||
const POSTS = toCardPosts([item("p1", 12, 3), item("p2", 40, 1, true)]);
|
||||
|
||||
function feed(over: Partial<FeedViewProps>, compact = true) {
|
||||
const props: FeedViewProps = {
|
||||
posts: POSTS, status: "ready", loadingMore: false, loadMoreFailed: false,
|
||||
newCount: 0, onRetry: () => {}, onShowNew: () => {}, onToggleLike: () => {}, ...over,
|
||||
};
|
||||
return renderToStaticMarkup(createElement(CompactLayoutContext.Provider, { value: compact }, createElement(FeedView, props)));
|
||||
}
|
||||
|
||||
describe("dock state", () => {
|
||||
it("shows the counts and liked state of the post on screen", () => {
|
||||
const s = dockState({ index: 1, kind: "post", post: POSTS[1] }, { canLike: true });
|
||||
expect(s.likes).toBe(POSTS[1].likesCount);
|
||||
expect(s.comments).toBe(POSTS[1].commentsCount);
|
||||
expect(s.liked).toBe(POSTS[1].isLiked);
|
||||
expect(s.likeDisabled).toBe(false);
|
||||
expect(s.commentsDisabled).toBe(false);
|
||||
});
|
||||
it("disables like and comments on the featured and loading slides", () => {
|
||||
for (const kind of ["featured", "load"] as const) {
|
||||
const s = dockState({ index: 2, kind, post: null });
|
||||
expect(s.likeDisabled).toBe(true);
|
||||
expect(s.commentsDisabled).toBe(true);
|
||||
expect(s.likes).toBeNull();
|
||||
}
|
||||
});
|
||||
it("disables like while the like call is in flight", () => {
|
||||
expect(dockState({ index: 0, kind: "post", post: POSTS[0] }, { canLike: true, likeBusy: true }).likeDisabled).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("dock markup", () => {
|
||||
it("renders like with aria-pressed, comments, the sparkle new-post button and More", () => {
|
||||
const out = renderToStaticMarkup(createElement(MobileDock, { slide: { index: 1, kind: "post", post: POSTS[1] }, onToggleLike: () => {} }));
|
||||
expect(out).toContain('aria-label="Post actions"');
|
||||
expect(out).toMatch(/class="dk dk-like dk-like-on"[^>]*aria-pressed="true"/);
|
||||
expect(out).toContain(`>${POSTS[1].likesCount}</span>`);
|
||||
expect(out).toContain(`Open comments, ${POSTS[1].commentsCount} comment`);
|
||||
expect(out).toContain("btn-spark btn-spark-fab dk-plus");
|
||||
expect(out).not.toContain("btn-spark-fold");
|
||||
expect(out).toContain('aria-label="View more"');
|
||||
});
|
||||
it("is part of the phone feed and follows the first slide", () => {
|
||||
const out = feed({});
|
||||
expect(out).toContain('data-testid="feed-dock"');
|
||||
expect(out).toContain(`data-testid="dock-likes">${POSTS[0].likesCount}<`);
|
||||
});
|
||||
it("is absent on desktop", () => {
|
||||
expect(feed({}, false)).not.toContain("feed-dock");
|
||||
});
|
||||
});
|
||||
|
||||
describe("dock stylesheet", () => {
|
||||
const css = readFileSync("src/styles/mobile.css", "utf8");
|
||||
it("floats 16px above the bottom on frosted glass", () => {
|
||||
expect(css).toMatch(/\.dock \{[^}]*bottom: calc\(16px[^}]*backdrop-filter: blur/);
|
||||
});
|
||||
it("keeps touch targets at least 44px and disabled buttons fully opaque", () => {
|
||||
expect(css).toMatch(/\.dk \{[^}]*min-width: 44px;[^}]*height: 52px/);
|
||||
expect(css).toMatch(/\.dk:disabled \{ opacity: 1;/);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user