Repository navigation
Conversation
Setting username on a persisted anonymous user and calling save() now unlinks the anonymous provider server-side and leaves the local authData consistent with the cleaned server record — without requiring a follow-up GET. Previously, the save's PUT response carried only the dirty fields written by the client (no authData), so the additive response merge in _handleSingleResult could not reconcile the local authData copy. Apps had to follow up with GET /users/me to refresh local state. This mirrors iOS PFUser's stripAnonymity + cleanUpAuthData pattern. No public API changes; the new helpers are private.
save() and update() both run _cleanUpAuthData() in their success branch but were patched independently. Add a parallel test that invokes update() instead of save() so a future regression in either path is caught. Also tightened test descriptions to focus on client-side behavior.
On the lazy (no objectId) path of _stripAnonymity, removing the anonymous provider could leave an empty map in _unsavedChanges under keyVarAuthData. The empty map then serialized into the POST body via toJson(forApiRQ: true) on signUp, sending wire noise the SDK shouldn't emit. Mirrors the isEmpty handling already present in _cleanUpAuthData.
Addresses upstream PR parse-community#1136 review feedback. The loginAnonymous request body literally wrote 'anonymous' while the rest of the file (stripAnonymity branches at lines 537/541/543) references the `_keyAuthAnonymous` constant defined at line 46. One-line change brings the body into alignment.
|
🚀 Thanks for opening this pull request! We appreciate your effort in improving the project. Please let us know once your pull request is ready for review. Tip
Note Please respond to review comments from AI agents just like you would to comments from a human reviewer. Let the reviewer resolve their own comments, unless they have reviewed and accepted your commit, or agreed with your explanation for why the feedback was incorrect. Caution Pull requests must be written using an AI agent with human supervision. Pull requests written entirely by a human will likely be rejected, because of lower code quality, higher review effort and the higher risk of introducing bugs. Please note that AI review comments on this pull request alone do not satisfy this requirement. Our CI and AI review are safeguards, not development tools. If many issues are flagged, rethink your development approach. Invest more effort in planning and design rather than using review cycles to fix low-quality code. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (3)
Included review availability: Your plan provides up to 4 included reviews per hour; 2 remain after this review. 📝 WalkthroughWalkthroughThis PR updates ChangesAnonymous Account Conversion for ParseUser
Priority: ⬇️ Low Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant App
participant ParseUser
participant ParseServer
App->>ParseUser: Set username
ParseUser->>ParseUser: Reconcile anonymous authData
App->>ParseUser: Call save() or update()
ParseUser->>ParseServer: Send authData.anonymous = null for persisted conversion
ParseServer-->>ParseUser: Return successful response
ParseUser->>ParseUser: Remove null authData entries
ParseUser-->>App: Return updated ParseUser
Merge Risk: ⚪ Minimal · up to The anonymous-account conversion behavior is covered by the supplied tests, and the remaining investigated concern is not introduced by this PR. 🚥 Pre-merge checks | ✅ 7✅ Passed checks (7 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #1138 +/- ##
==========================================
+ Coverage 44.42% 46.42% +2.00%
==========================================
Files 62 62
Lines 3730 3752 +22
==========================================
+ Hits 1657 1742 +85
+ Misses 2073 2010 -63 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
packages/dart/test/src/objects/parse_user/parse_user_anonymous_link_test.dart (1)
218-239: ⚡ Quick winExercise the lazy sign-up request body too.
This branch only checks local state. The behavior the new helper is actually protecting here is dropping
authDatafrom the lazy-user POST once the anonymous map becomes empty, so aclient.post(...)assertion would catch regressions that still serializeauthData: {}.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/dart/test/src/objects/parse_user/parse_user_anonymous_link_test.dart` around lines 218 - 239, The test only checks local state after setting ParseUser.username but doesn't assert the lazy sign-up HTTP body; extend the test to perform the lazy sign-up (e.g., call the code path that triggers client.post for unpersisted users) and add an assertion on the mocked client.post invocation to ensure the posted JSON does not include an empty authData (i.e., no "authData" key or no empty map) after the anonymous map was dropped; locate the test around ParseUser creation and user.username assignment in parse_user_anonymous_link_test.dart and add the client.post verification referencing client.post, ParseUser, and the lazy sign-up call.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/dart/lib/src/objects/parse_user.dart`:
- Around line 74-77: The username setter currently calls _stripAnonymity() even
when username is being cleared, which causes anonymous auth to be nulled; update
the setter (the set username(String? username) method) to only call
_stripAnonymity() when the incoming username is non-null (i.e., guard
_stripAnonymity() behind a username != null check) before calling
set<String?>(keyVarUsername, username) so clearing username does not queue
anonymous unlinking.
---
Nitpick comments:
In
`@packages/dart/test/src/objects/parse_user/parse_user_anonymous_link_test.dart`:
- Around line 218-239: The test only checks local state after setting
ParseUser.username but doesn't assert the lazy sign-up HTTP body; extend the
test to perform the lazy sign-up (e.g., call the code path that triggers
client.post for unpersisted users) and add an assertion on the mocked
client.post invocation to ensure the posted JSON does not include an empty
authData (i.e., no "authData" key or no empty map) after the anonymous map was
dropped; locate the test around ParseUser creation and user.username assignment
in parse_user_anonymous_link_test.dart and add the client.post verification
referencing client.post, ParseUser, and the lazy sign-up call.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: d3fdeb84-d5c1-48b9-b3af-a00aa85093bd
📒 Files selected for processing (2)
packages/dart/lib/src/objects/parse_user.dartpackages/dart/test/src/objects/parse_user/parse_user_anonymous_link_test.dart
The lazy-user cleanup exists to keep an emptied anonymous map out of the sign-up POST; the test previously checked only local state. It now captures the mocked sign-up request and asserts no authData key is serialized. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Addressed the review nitpick in fd0ddf3 — the lazy-user test now performs the sign-up and asserts the captured POST body contains no |
… clean CI resolves fresh (no lockfile) and its build_runner/source_gen emit a blank line after the ignore_for_file header; the committed mocks lacked it, so CI's own regeneration dirtied the tree and 'dart pub publish --dry-run' failed with exit 65 on the stable Dart legs. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Issue
No existing issue.
Approach
Split out from #1136 at maintainer request. This PR contains only the
original concern of that PR — reconciling local
authDatawhen ananonymous user is converted to email/password.
When a persisted anonymous user has its
usernameset and is saved,parseUser.save()issues aPUT /classes/_User/:objectIdcarryingonly the dirty fields. The Dart SDK treated this as a generic
property update — it neither emitted an
authDataunlink signal inthe request body nor cleaned up the local cache after the save.
The iOS Parse SDK handles this via two helpers in
PFUser.m:stripAnonymity(PFUser.m:593-607): theusernamesetterwrites
authData[anonymous] = NSNullinto the local user. ThePUT body re-injects the map, so the request carries
authData: { anonymous: null }— Parse Server's documentedunlink signal.
cleanUpAuthData(PFUser.m:300-313): after a successfulsave, the local
authDatahas any null entries stripped.Ported to
ParseUseras two private helpers:_stripAnonymity()invoked from theusernamesetter. On apersisted user it sets
authData['anonymous'] = nulllocally; ona lazy user (no
objectId) it removes the entry outright._cleanUpAuthData()invoked fromsave()andupdate()betweenthe response merge and
_onResponseSuccess().A dartdoc paragraph was added to
loginAnonymousdocumenting theconversion path. The
loginAnonymousrequest body was also updatedto use the new
_keyAuthAnonymousconstant rather than the literal'anonymous'.Tasks
Behavior change disclosure
objectIdis setand
authDatacontains ananonymousentry, settingusernameand saving now produces a PUT body that includes
authData: { anonymous: null }. Previously noauthDatafieldwas sent for that save.
usernameonan anonymous-with-
objectIdParseUsernow mutates the localauthDatamap. After a successful save, theanonymousentryis removed entirely.
Tests
packages/dart/test/src/objects/parse_user/parse_user_anonymous_link_test.dart— 6 tests covering:
save()reconcilesauthDataon conversion (anonymous-with-objectId)update()reconcilesauthDataon conversion_cleanUpAuthDataremoves the localanonymous: nullmarker after saveobjectId) path removes the entry outright instead of leaving a nullauthDatamap is not serialized into the lazy POST bodyauthDatafieldAll 213 tests in
packages/dart/test/pass.Summary by CodeRabbit
Bug Fixes
Documentation
Tests