feat(mobile-expo): CardRenderer section component#327
Conversation
Replace the Card stub with a real renderer displaying media image, title, description, and tappable link. Supports default and featured variant styling with shadow/elevation differences. Resolves #312 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
WalkthroughIntroduces a production Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (2)
mobile/expo/src/components/sections/CardRenderer.test.tsx (1)
21-26: Tests only verifycreateElementdoesn't throw, not actual rendering.Using
createElementwithout a test renderer means these tests don't execute the component's render logic or verify the DOM output. Runtime errors in JSX (e.g., accessing properties on null) won't be caught.Consider using
@testing-library/react-native'srenderto actually mount the component and optionally assert on rendered content.♻️ Example with actual rendering
-import { createElement } from "react" +import { render, screen } from "@testing-library/react-native" import type { CardSection } from "../../lib/sectionModels" import { CardRenderer } from "./CardRenderer" // ... baseSection fixture ... describe("CardRenderer", () => { it("renders without throwing with all fields", () => { - expect(() => - createElement(CardRenderer, { section: baseSection }), - ).not.toThrow() + render(<CardRenderer section={baseSection} />) + expect(screen.getByText("Explore the Easter Story")).toBeTruthy() })🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@mobile/expo/src/components/sections/CardRenderer.test.tsx` around lines 21 - 26, The test currently only calls createElement(CardRenderer, { section: baseSection }) which doesn't mount or execute rendering logic; replace the no-throw check with an actual render using `@testing-library/react-native`'s render(CardRenderer with props) (or render(<CardRenderer section={baseSection} />)) and add at least one assertion that verifies rendered output (e.g., queryByText or getByTestId) to catch runtime JSX errors and validate UI; update imports to include render from "@testing-library/react-native" and reference CardRenderer and baseSection in the new test.mobile/expo/src/components/sections/CardRenderer.tsx (1)
13-17: Consider handlingLinking.openURLerrors.
Linking.openURLcan reject if the URL scheme is unsupported or malformed. Silently ignoring the promise may leave users without feedback when a link fails to open.♻️ Suggested improvement with error handling
const handlePress = () => { if (link) { - void Linking.openURL(link) + Linking.openURL(link).catch((err) => { + console.warn("CardRenderer: failed to open link", link, err) + }) } }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@mobile/expo/src/components/sections/CardRenderer.tsx` around lines 13 - 17, The handlePress function currently calls Linking.openURL(link) without handling rejections; update handlePress to await or attach a catch to Linking.openURL(link) and handle errors (e.g., call Alert.alert or processLogger.error and optionally fallback behavior) so users receive feedback when the URL fails to open; reference the handlePress function and the Linking.openURL call when making this change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@mobile/expo/src/components/sections/CardRenderer.test.tsx`:
- Around line 21-26: The test currently only calls createElement(CardRenderer, {
section: baseSection }) which doesn't mount or execute rendering logic; replace
the no-throw check with an actual render using `@testing-library/react-native`'s
render(CardRenderer with props) (or render(<CardRenderer section={baseSection}
/>)) and add at least one assertion that verifies rendered output (e.g.,
queryByText or getByTestId) to catch runtime JSX errors and validate UI; update
imports to include render from "@testing-library/react-native" and reference
CardRenderer and baseSection in the new test.
In `@mobile/expo/src/components/sections/CardRenderer.tsx`:
- Around line 13-17: The handlePress function currently calls
Linking.openURL(link) without handling rejections; update handlePress to await
or attach a catch to Linking.openURL(link) and handle errors (e.g., call
Alert.alert or processLogger.error and optionally fallback behavior) so users
receive feedback when the URL fails to open; reference the handlePress function
and the Linking.openURL call when making this change.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 052e8143-18f0-4a35-9266-85f60eb010ae
📒 Files selected for processing (5)
mobile/expo/src/components/sections/CardRenderer.test.tsxmobile/expo/src/components/sections/CardRenderer.tsxmobile/expo/src/components/sections/CardStub.tsxmobile/expo/src/components/sections/SectionDispatcher.tsxmobile/expo/src/components/sections/index.ts
💤 Files with no reviewable changes (1)
- mobile/expo/src/components/sections/CardStub.tsx
Summary
Pressablewhenlinkis present (opens URL viaLinking)defaultandfeaturedvariant styling (larger image, bolder title, stronger shadow for featured)Contracts Changed
No
Regeneration Required
No
Validation
pnpm --filter @forge/expo lint— passes with 0 warningspnpm --filter @forge/expo test -- --testPathPattern=CardRenderer— 5/5 tests passpnpm --filter @forge/expo test -- --testPathPattern=SectionDispatcher— 11/11 tests pass (no regressions)Resolves #312
🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Tests