-
-
Notifications
You must be signed in to change notification settings - Fork 10.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added preview-as anonymous/free/paid to previews endpoint #22168
base: main
Are you sure you want to change the base?
Conversation
ref https://linear.app/ghost/issue/PLG-352 - updated `/p/` endpoint to accept an optional `?memberStatus` query parameter with three allowed values: `anonymous/free/paid` - when a `memberStatus` query param is provided: - `frame.apiType` is set to `content` which triggers the content-gating paths of our output serializer's post mapper - where needed, `frame.original.content.member` is set to a minimal member object with a `status` property to allow content-gating NQL queries to match - the combination of both changes our API output to match what the Content API does when rendering posts with a particular logged-in member status - if no `memberStatus` query param is provided the existing behaviour is preserved of rendering as we do for Admin API requests, showing content for all segments simultaneously
WalkthroughThis pull request introduces modifications across both the frontend and backend preview handling. On the frontend, an additional property, Possibly related PRs
Suggested labels
✨ Finishing Touches
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (4)
ghost/core/core/server/api/endpoints/previews.js (2)
13-36
: Consider enhancing error handling in _addMemberContextToFrame.The helper function could be more defensive:
- Validate frame.options early
- Use object literals instead of multiple if statements
Consider this refactoring:
const _addMemberContextToFrame = (frame) => { - if (!frame?.options?.memberStatus) { + if (!frame?.options) { return; } + const {memberStatus} = frame.options; + if (!memberStatus) { + return; + } frame.apiType = 'content'; frame.original ??= {}; frame.original.context ??= {}; - if (frame.options?.memberStatus === 'free') { - frame.original.context.member = { - status: 'free' - }; - } - - if (frame.options?.memberStatus === 'paid') { - frame.original.context.member = { - status: 'paid' - }; - } + const memberContextMap = { + free: {status: 'free'}, + paid: {status: 'paid'} + }; + + frame.original.context.member = memberContextMap[memberStatus]; };
69-71
: Consider adding error logging.The function call to
_addMemberContextToFrame
should include error logging to help with debugging.query(frame) { + try { _addMemberContextToFrame(frame); + } catch (err) { + debug('Failed to add member context to frame:', err); + }ghost/core/test/unit/frontend/services/routing/controllers/previews.test.js (1)
69-74
: Consider adding test cases for memberStatus variations.The test only covers undefined memberStatus. Consider adding test cases for:
- Anonymous member
- Free member
- Paid member
ghost/core/core/frontend/services/routing/controllers/previews.js (1)
22-24
: Consider validating memberStatus input.The memberStatus is directly passed from query params without validation. Consider validating against ALLOWED_MEMBER_STATUSES.
+const {ALLOWED_MEMBER_STATUSES} = require('../../../../server/api/endpoints/previews'); const params = { uuid: req.params.uuid, status: 'all', include: 'authors,tags,tiers', - memberStatus: req.query?.memberStatus + memberStatus: ALLOWED_MEMBER_STATUSES.includes(req.query?.memberStatus) ? req.query.memberStatus : undefined };
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
ghost/core/core/frontend/services/routing/controllers/previews.js
(1 hunks)ghost/core/core/server/api/endpoints/previews.js
(4 hunks)ghost/core/test/e2e-frontend/preview_routes.test.js
(2 hunks)ghost/core/test/unit/api/endpoints/previews.test.js
(1 hunks)ghost/core/test/unit/frontend/services/routing/controllers/previews.test.js
(1 hunks)ghost/core/test/utils/fixture-utils.js
(1 hunks)
🔇 Additional comments (4)
ghost/core/test/unit/api/endpoints/previews.test.js (1)
1-56
: Well-structured and comprehensive test coverage!The test suite effectively covers all scenarios for the new
memberStatus
feature, including:
- Status-based API type setting
- Member context population
- Edge cases (anonymous, undefined)
ghost/core/test/e2e-frontend/preview_routes.test.js (2)
69-78
: LGTM!The test case effectively verifies content gating for free members by checking both the presence of content before the paywall and the absence of content after the paywall.
80-89
: LGTM!The test case effectively verifies content gating for paid members by checking the presence of content both before and after the paywall.
ghost/core/test/utils/fixture-utils.js (1)
149-167
: LGTM!The function effectively sets up test data for gated posts by:
- Creating a post with appropriate properties (id, title, status, etc.)
- Including a paywall marker in the content
- Setting the visibility to 'paid'
This provides good test coverage for the preview-as functionality.
ref https://linear.app/ghost/issue/PLG-352
/p/
endpoint to accept an optional?memberStatus
query parameter with three allowed values:anonymous/free/paid
memberStatus
query param is provided:frame.apiType
is set tocontent
which triggers the content-gating paths of our output serializer's post mapperframe.original.context.member
is set to a minimal member object with astatus
property to allow content-gating NQL queries to matchmemberStatus
query param is provided the existing behaviour is preserved, where we render as we do for Admin API requests, showing content for all segments simultaneously