Skip to content

test: Migrate Polygon specs to the REST client#10485

Open
dblythy wants to merge 10 commits into
parse-community:alphafrom
dblythy:chore/spec-rest-polygon
Open

test: Migrate Polygon specs to the REST client#10485
dblythy wants to merge 10 commits into
parse-community:alphafrom
dblythy:chore/spec-rest-polygon

Conversation

@dblythy
Copy link
Copy Markdown
Member

@dblythy dblythy commented May 29, 2026

Towards #8787.

Stacked on #10484 (chore/spec-rest-geopoint) — review/merge that first; the diff here will shrink to just the Polygon files once it lands.

Third slice of the REST-first spec migration:

  • Ports spec/ParsePolygon.spec.js to REST-based specs under spec/rest/objects/: polygon.spec.ts (object lifecycle, equalTo, validation), polygon-query.spec.ts ($geoIntersects point-in-polygon queries, incl. Update test case polygons so some should fail when lat / long is used… #4608 regressions), polygon-mongo.spec.ts (MongoDB storage format + 2d/2dsphere indexes).
  • Adds polygon/geoIntersects builders to spec/helpers/geo.ts and a describe_only_db ambient declaration.
  • No Parse JS SDK. Objects are created over REST throughout; the storage spec touches the database adapter directly only where there is no REST surface (raw stored document, index metadata).

Next: another spec migration in a follow-up PR using the same helpers.

Summary by CodeRabbit

  • Tests

    • Reorganized test infrastructure with TypeScript support and comprehensive REST API test suites for analytics, GeoPoint, and Polygon query functionality.
  • Chores

    • Added Babel runtime TypeScript support for test execution and updated testing configuration.

Review Change Stack

@parse-github-assistant
Copy link
Copy Markdown

🚀 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

  • Keep pull requests small. Large PRs will be rejected. Break complex features into smaller, incremental PRs.
  • Use Test Driven Development. Write failing tests before implementing functionality. Ensure tests pass.
  • Group code into logical blocks. Add a short comment before each block to explain its purpose.
  • We offer conceptual guidance. Coding is up to you. PRs must be merge-ready for human review.
  • Our review focuses on concept, not quality. PRs with code issues will be rejected. Use an AI agent.
  • Human review time is precious. Avoid review ping-pong. Inspect and test your AI-generated code.

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.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 29, 2026

Warning

Review limit reached

@dblythy, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 3 minutes and 17 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 14171d61-8400-4d56-ac13-d986b1879857

📥 Commits

Reviewing files that changed from the base of the PR and between 8dbc778 and 27fdf42.

📒 Files selected for processing (23)
  • package-lock.json
  • package.json
  • spec/Analytics.spec.js
  • spec/ParseGeoPoint.spec.js
  • spec/ParsePolygon.spec.js
  • spec/helpers/analytics.ts
  • spec/helpers/client.ts
  • spec/helpers/config.ts
  • spec/helpers/errors.ts
  • spec/helpers/geo.ts
  • spec/helpers/globals.d.ts
  • spec/helpers/headers.ts
  • spec/helpers/request.ts
  • spec/rest/objects/geopoint-polygon.spec.ts
  • spec/rest/objects/geopoint-query.spec.ts
  • spec/rest/objects/geopoint.spec.ts
  • spec/rest/objects/polygon-mongo.spec.ts
  • spec/rest/objects/polygon-query.spec.ts
  • spec/rest/objects/polygon.spec.ts
  • spec/server/analytics.spec.ts
  • spec/spec_migration.md
  • spec/support/jasmine.json
  • spec/support/tsRegister.js
📝 Walkthrough

Walkthrough

This PR establishes infrastructure for incrementally migrating Parse Server's test suite from JavaScript/Parse SDK to TypeScript/REST API-first testing. It adds Babel TypeScript registration, modular REST helper clients for CRUD and geo operations, comprehensive migration documentation, and converts GeoPoint/Polygon tests to REST-based test suites.

Changes

TypeScript REST Test Infrastructure and GeoPoint/Polygon Migration

Layer / File(s) Summary
Babel TypeScript Registration and Jasmine Configuration
package.json, package-lock.json, spec/support/tsRegister.js, spec/support/jasmine.json
Added @babel/register dependency and a Babel bootstrap helper that enables on-the-fly TypeScript transpilation for spec/ files during Jasmine execution without affecting existing JS specs.
REST Request/Response Client and Core Contracts
spec/helpers/config.ts, spec/helpers/headers.ts, spec/helpers/request.ts, spec/helpers/errors.ts, spec/helpers/globals.d.ts
Foundational REST client layer with typed request/response contracts, HTTP method abstraction, header building from test configuration and auth options, error extraction, and typed restRequest and expectParseError functions.
Domain-Specific Helper Clients
spec/helpers/client.ts, spec/helpers/analytics.ts, spec/helpers/geo.ts
Specialized typed wrappers for CRUD operations (createObject, find, count), analytics event tracking (track, appOpened), and geo query constraint builders (geoPoint, polygon, near, withinRadians, geoIntersects).
Migration Plan and Strategy Documentation
spec/spec_migration.md
Comprehensive roadmap for REST-first, TypeScript-based test migration, covering goals, architectural decisions, target directory taxonomy, per-file quality checklist, and phased rollout with success criteria.
GeoPoint Object Lifecycle and Query Tests
spec/rest/objects/geopoint.spec.ts, spec/rest/objects/geopoint-query.spec.ts
New REST test suites validating GeoPoint roundtrip serialization, updates, type tagging, nested/array support, and distance queries (radians/miles/kilometers), geobox filtering, and equality/inequality constraints.
Polygon Lifecycle and Point-in-Polygon Query Tests
spec/rest/objects/polygon.spec.ts, spec/rest/objects/polygon-query.spec.ts
New REST test suites for polygon open/closed path normalization, updates, counterclockwise handling, and $geoIntersects point-in-polygon queries including regression coverage for coordinate order, with validation error handling.
GeoPoint-Polygon Integration: withinPolygon Query Tests
spec/rest/objects/geopoint-polygon.spec.ts
REST test suite exercising withinPolygon queries against seeded Polygon objects, verifying success for open/closed paths and Polygon-shaped input, and error handling for malformed/invalid polygon and geoPoint inputs.
MongoDB-Specific Polygon Storage and Index Tests
spec/rest/objects/polygon-mongo.spec.ts
MongoDB test suite validating polygon index creation (2d/2dsphere), GeoJSON coordinate persistence in [longitude, latitude] order with automatic ring closure, and rejection of self-intersecting polygons.
Legacy JS Test Removal and New Analytics Test Suite
spec/server/analytics.spec.ts
Removes three old JavaScript Parse SDK test files (Analytics.spec.js, ParseGeoPoint.spec.js, ParsePolygon.spec.js); introduces new TypeScript analytics test suite with adapter stubbing and spy-based assertions for track/appOpened behavior.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • mtrezza
  • Moumouls
🚥 Pre-merge checks | ✅ 5 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description provides issue reference, approach explanation, and context about the stacked PR, but omits all structured sections from the template (Issue, Approach, Tasks checklist). Restructure the description using the template format: explicitly label the Issue section, reorganize the approach content, and include the Tasks checklist with relevant items checked or removed.
Engage In Review Feedback ❓ Inconclusive Cannot access GitHub PR review comments to verify user engagement with feedback in the sandboxed repository context. Review PR #10485 on GitHub directly to examine reviewer comments, user replies, and whether feedback was addressed via commits or discussions.
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The PR title 'test: Migrate Polygon specs to the REST client' follows the required 'test:' prefix and clearly describes the main change of migrating Polygon test specs to REST.
Docstring Coverage ✅ Passed Docstring coverage is 83.33% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Security Check ✅ Passed No security vulnerabilities detected. @babel/register 7.27.1 is patched against CVE-2025-27789. Test helpers use safe patterns, no eval/exec, placeholder configs only, and narrow Babel scope.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

dblythy added 10 commits May 30, 2026 01:17
Adds a narrow @babel/register hook (spec/support/tsRegister.js) loaded by Jasmine before helper.js so .ts spec/helper files are transpiled at require time. spec_files glob widened to discover .ts specs. Existing .js specs are unaffected — the hook only intercepts .ts under spec/.
Introduces spec/helpers/*.ts — a typed REST client over fetch (request, client, headers, config, errors, globals) so specs can talk to Parse Server through its public HTTP API without going through the Parse JS SDK. Also lands spec/spec_migration.md, the plan that drives the upcoming REST-first migration of the spec suite (towards parse-community#8787).
Replaces spec/Analytics.spec.js (Parse SDK + done() callbacks) with spec/server/analytics.spec.ts (REST client + async/await), plus spec/helpers/analytics.ts. No SDK import, no done(), no setTimeout. First spec to land under the new REST-first layout.
…sn't break them

CI runs Node 24, which natively strips TypeScript and loads .ts as ESM, bypassing the @babel/register CJS hook. ESM needs explicit extensions, so extensionless relative imports failed. Force Jasmine's require loader (engages the hook on Node 20), add explicit .ts extensions, and mark type-only imports with 'import type' so the suite loads identically on Node 20/22/24.
Guard undefined response data in find/count helpers and fix grammar in
the analytics spec description.
Use a dedicated maintenance-key value in buildHeaders, assert the Parse-error
shape in expectParseError, drop the redundant local reconfigureServer decl
(it lives in globals.d.ts), and fix the REST-client description in the plan.
Internal-server-error bodies use { code, message } rather than { code, error },
so a numeric code is the reliable signal that a rejection is a Parse error.
Port spec/ParseGeoPoint.spec.js to REST-based specs under spec/rest/objects
(lifecycle, queries, withinPolygon) and add a geo query helper, removing the
Parse JS SDK from these tests.
- Drop the misleading GeoPointLiteral[] | unknown union on withinPolygon
  (negative-path specs deliberately pass invalid values, so the param is unknown)
- Drop the unnecessary masterKey auth in the __type response test
- Filter the sub-object and array specs on a sentinel tag instead of an
  unfiltered find, so they don't depend on global cleanup ordering
- Clarify the seed-point comments (inside / on boundary / outside)
Ports spec/ParsePolygon.spec.js to REST-based specs under spec/rest/objects/:
- polygon.spec.ts: object lifecycle, equalTo, and validation
- polygon-query.spec.ts: $geoIntersects point-in-polygon queries (parse-community#4608)
- polygon-mongo.spec.ts: MongoDB storage format and 2d/2dsphere indexes

Adds polygon/geoIntersects builders to spec/helpers/geo.ts and a
describe_only_db ambient declaration. No Parse JS SDK; the storage spec uses
the database adapter directly only where there is no REST surface.
@dblythy dblythy force-pushed the chore/spec-rest-polygon branch from 8dbc778 to 27fdf42 Compare May 29, 2026 15:19
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (4)
spec/server/analytics.spec.ts (3)

4-7: ⚡ Quick win

Consider returning promises from adapter stub methods.

The stub methods return undefined instead of promises. While the tests work (the controller wraps adapter calls in a promise chain), the stubs don't match the AnalyticsAdapter contract, which specifies that both methods should return Promise.resolve({}).

📝 Proposed fix to match the adapter contract
   const analyticsAdapter = {
-    appOpened: function () {},
-    trackEvent: function () {},
+    appOpened: function () {
+      return Promise.resolve({});
+    },
+    trackEvent: function () {
+      return Promise.resolve({});
+    },
   };

Based on learnings from Context snippet 1: AnalyticsAdapter interface specifies appOpened(parameters, req) and trackEvent(eventName, parameters, req) should return Promise.resolve({}).

🤖 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 `@spec/server/analytics.spec.ts` around lines 4 - 7, The analyticsAdapter stub
methods currently return undefined; update the analyticsAdapter object so its
appOpened and trackEvent functions return resolved promises (e.g., return
Promise.resolve({}) or make them async and return {}), matching the
AnalyticsAdapter contract and signatures used by the controller (ensure you
modify the analyticsAdapter.appOpened and analyticsAdapter.trackEvent methods
accordingly).

21-30: 💤 Low value

Consider verifying the req parameter is passed to the adapter.

The test verifies parameters (args[0]) but doesn't verify that the request object is passed as args[1]. According to the AnalyticsAdapter contract, appOpened(parameters, req) receives the Express request as the second parameter.

🔍 Optional: Add req parameter verification
     expect(appOpenedSpy).toHaveBeenCalled();
     const args = appOpenedSpy.calls.first().args;
     expect(args[0]).toEqual({ dimensions: { key: 'value', count: '0' } });
+    expect(args[1]).toBeDefined(); // Request object is passed

Based on learnings from Context snippet 1: AnalyticsAdapter interface shows appOpened(parameters, req) receives two parameters including the HTTP request.

🤖 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 `@spec/server/analytics.spec.ts` around lines 21 - 30, The test currently only
asserts the adapter parameters but not that the Express request was forwarded;
update the spec to also verify the second argument passed to
analyticsAdapter.appOpened is the request object by inspecting
appOpenedSpy.calls.first().args[1] (or using a more specific matcher) after
calling reconfigureServer({ analyticsAdapter }) and appOpened(...); ensure you
reference analyticsAdapter.appOpened (via appOpenedSpy) and assert args[1] is
the expected req (e.g., defined or matches the test request shape) so the
contract appOpened(parameters, req) is validated.

9-19: 💤 Low value

Consider verifying the req parameter is passed to the adapter.

The test verifies eventName (args[0]) and parameters (args[1]) but doesn't verify that the request object is passed as args[2]. According to the AnalyticsAdapter contract, trackEvent(eventName, parameters, req) receives the Express request as the third parameter.

🔍 Optional: Add req parameter verification
     expect(trackSpy).toHaveBeenCalled();
     const args = trackSpy.calls.first().args;
     expect(args[0]).toEqual('MyEvent');
     expect(args[1]).toEqual({ dimensions: { key: 'value', count: '0' } });
+    expect(args[2]).toBeDefined(); // Request object is passed

Based on learnings from Context snippet 1: AnalyticsAdapter interface shows trackEvent(eventName, parameters, req) receives three parameters including the HTTP request.

🤖 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 `@spec/server/analytics.spec.ts` around lines 9 - 19, The test currently
asserts trackEvent's eventName and parameters but doesn't verify the request is
forwarded; update the spec that spies on analyticsAdapter.trackEvent (and uses
track('MyEvent', ...)) to also assert that args[2] is the Express request
object—e.g., add an expectation that args[2] is defined and looks like the req
(has properties such as method or url) or otherwise equals the request passed
into the server so trackEvent(eventName, parameters, req) is called with the
req.
package-lock.json (1)

68-68: No known GitHub advisories for @babel/register et al.; bump @babel/register for currency.

  • GitHub advisory feed shows no vulnerabilities for @babel/register, clone-deep, pirates, pkg-dir, shallow-clone, is-plain-object, or isobject; kind-of has a HIGH advisory for >=6.0.0, <6.0.3, patched in 6.0.3 (your lock uses 6.0.3).
  • Lockfile has @babel/register 7.27.1; latest is 7.29.3 (May 2026) — consider updating.
🤖 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 `@package-lock.json` at line 68, Update the pinned dependency for
"`@babel/register`" to a more current, non-vulnerable release (e.g., bump from
7.27.1 to the latest 7.29.3) by updating the dependency declaration in
package.json (or the lockfile resolution) and regenerating the lockfile via your
package manager (npm install / npm ci) so package-lock.json reflects the new
"`@babel/register`" version; verify tests/builds pass and that the updated version
appears in package-lock.json under the "`@babel/register`" entry.
🤖 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.

Nitpick comments:
In `@package-lock.json`:
- Line 68: Update the pinned dependency for "`@babel/register`" to a more current,
non-vulnerable release (e.g., bump from 7.27.1 to the latest 7.29.3) by updating
the dependency declaration in package.json (or the lockfile resolution) and
regenerating the lockfile via your package manager (npm install / npm ci) so
package-lock.json reflects the new "`@babel/register`" version; verify
tests/builds pass and that the updated version appears in package-lock.json
under the "`@babel/register`" entry.

In `@spec/server/analytics.spec.ts`:
- Around line 4-7: The analyticsAdapter stub methods currently return undefined;
update the analyticsAdapter object so its appOpened and trackEvent functions
return resolved promises (e.g., return Promise.resolve({}) or make them async
and return {}), matching the AnalyticsAdapter contract and signatures used by
the controller (ensure you modify the analyticsAdapter.appOpened and
analyticsAdapter.trackEvent methods accordingly).
- Around line 21-30: The test currently only asserts the adapter parameters but
not that the Express request was forwarded; update the spec to also verify the
second argument passed to analyticsAdapter.appOpened is the request object by
inspecting appOpenedSpy.calls.first().args[1] (or using a more specific matcher)
after calling reconfigureServer({ analyticsAdapter }) and appOpened(...); ensure
you reference analyticsAdapter.appOpened (via appOpenedSpy) and assert args[1]
is the expected req (e.g., defined or matches the test request shape) so the
contract appOpened(parameters, req) is validated.
- Around line 9-19: The test currently asserts trackEvent's eventName and
parameters but doesn't verify the request is forwarded; update the spec that
spies on analyticsAdapter.trackEvent (and uses track('MyEvent', ...)) to also
assert that args[2] is the Express request object—e.g., add an expectation that
args[2] is defined and looks like the req (has properties such as method or url)
or otherwise equals the request passed into the server so trackEvent(eventName,
parameters, req) is called with the req.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 1ce0fb0d-0dc6-4029-bedd-9fb03a5fb47e

📥 Commits

Reviewing files that changed from the base of the PR and between 1e0d6ce and 8dbc778.

📒 Files selected for processing (23)
  • package-lock.json
  • package.json
  • spec/Analytics.spec.js
  • spec/ParseGeoPoint.spec.js
  • spec/ParsePolygon.spec.js
  • spec/helpers/analytics.ts
  • spec/helpers/client.ts
  • spec/helpers/config.ts
  • spec/helpers/errors.ts
  • spec/helpers/geo.ts
  • spec/helpers/globals.d.ts
  • spec/helpers/headers.ts
  • spec/helpers/request.ts
  • spec/rest/objects/geopoint-polygon.spec.ts
  • spec/rest/objects/geopoint-query.spec.ts
  • spec/rest/objects/geopoint.spec.ts
  • spec/rest/objects/polygon-mongo.spec.ts
  • spec/rest/objects/polygon-query.spec.ts
  • spec/rest/objects/polygon.spec.ts
  • spec/server/analytics.spec.ts
  • spec/spec_migration.md
  • spec/support/jasmine.json
  • spec/support/tsRegister.js
💤 Files with no reviewable changes (3)
  • spec/Analytics.spec.js
  • spec/ParsePolygon.spec.js
  • spec/ParseGeoPoint.spec.js

@codecov
Copy link
Copy Markdown

codecov Bot commented May 29, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.60%. Comparing base (552c6dd) to head (27fdf42).
⚠️ Report is 1 commits behind head on alpha.

Additional details and impacted files
@@           Coverage Diff           @@
##            alpha   #10485   +/-   ##
=======================================
  Coverage   92.60%   92.60%           
=======================================
  Files         193      193           
  Lines       16893    16893           
  Branches      234      234           
=======================================
  Hits        15643    15643           
  Misses       1227     1227           
  Partials       23       23           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant