Skip to content

fix(plugins): keep the plugin query tests off the plugin registry - #1888

Merged
giswqs merged 1 commit into
mainfrom
fix/plugin-query-api-coverage
Aug 14, 2026
Merged

fix(plugins): keep the plugin query tests off the plugin registry#1888
giswqs merged 1 commit into
mainfrom
fix/plugin-query-api-coverage

Conversation

@giswqs

@giswqs giswqs commented Aug 14, 2026

Copy link
Copy Markdown
Member

main has been red since #1784. This restores it.

What broke

#1784 added tests/plugin-query-api.test.ts, which reaches the new read-only query API through createAppAPI in usePlugins.ts. That module imports the entire built-in plugin registry, so loading it dragged in MapCanvas, CesiumCanvas, and every maplibre-* plugin.

Coverage is reported only over files a test actually imports (as CLAUDE.md notes, a module with no test does not appear at all rather than as 0%). So those 39 browser-only modules entered the denominator at 1-30% function coverage:

files counted lines branches functions
before #1784 (3697baf8) 405 82.89% 84.46% 72.90%
after #1784 (6093aa80) 444 81.82% 84.30% 60.36%

That is under the 63% floor, so npm run ci fails. Worst offenders: MapCanvas.tsx at 2.50% functions, maplibre-duckdb.ts at 1.67%, maplibre-openaerialmap.ts at 2.38%.

Nothing got less tested. #1784 added 256 lines of tests. The metric moved because the denominator grew, so the gate was measuring module reachability rather than test quality.

The fix

Move the six query methods and readPluginSelection into apps/geolibre-desktop/src/lib/plugin-layer-queries.ts, which needs only the store, and have createAppAPI spread them in. The test imports that module directly.

This follows the precedent already in the tree: geo-editor-geometry.ts is documented as "Kept free of the Geoman/MapLibre runtime imports ... so they can be unit-tested under Node without a browser environment."

Knock-on cleanups:

  • The test drops its maplibre-gl module-hook shim and its window / location / sessionStorage / localStorage globals. It no longer needs a browser to load, and runs in ~7ms.
  • SKETCHES_SOURCE_KIND gets a subpath export alongside the five already in @geolibre/plugins, so the test shares the constant instead of repeating the "geoeditor-sketches" literal as it did before.

Trade-off

The test now covers createPluginLayerQueries rather than asserting that createAppAPI exposes these methods. That wiring is a typed spread, so tsc enforces it on every build. Testing it at runtime is what requires loading the whole registry, which is the thing this PR is removing.

Result

files counted lines branches functions
this PR 406 82.84% 84.45% 72.55%

The single added file is the extracted module, at 100% lines / 95.45% functions. All 8 tests pass, npm run lint is unchanged (0 errors, the same 40 pre-existing warnings), npm run build is clean, and pre-commit run --files ... passes including the npm-build hook.

Note on a separate flake

While diagnosing this I found that line coverage is nondeterministic run to run on identical sources: 81.82% (main's CI), 76.47% (a PR's CI on the same tree), 79.78% locally. Per file, the function column is identical across runs while the line column swings, which is why one run reported an extra "76.47% line coverage does not meet threshold of 78%" error that another did not. The 78% line floor can therefore redden unrelated PRs. Out of scope here; worth its own issue.

Summary by CodeRabbit

  • New Features

    • Added plugin layer query capabilities for viewing layer metadata, features, selections, selected layers, drawn sketches, and selection changes.
    • Added a public export for Geo Editor geometry functionality.
    • Query results are safely isolated from application state, and invalid layer lookups provide clear errors.
  • Tests

    • Expanded coverage for layer queries, selections, drawn features, empty results, and error handling.

The read-only query API added in #1784 is exercised through
`createAppAPI`, which lives in `usePlugins.ts`. That module imports the
whole built-in plugin registry, so loading it in a Node test pulled in
MapCanvas, CesiumCanvas, and every `maplibre-*` plugin: 39 browser-only
modules, none of them meaningfully exercised, all of them newly counted
by the coverage reporter.

Coverage is reported only over files a test actually imports, so those 39
files landed in the denominator at 1-30% function coverage and dropped
the total from 72.90% to 60.36%, under the 63% floor. CI has been red on
`main` since, and the report is measuring module reachability rather than
how well the code is tested.

Move the six query methods and `readPluginSelection` into
`lib/plugin-layer-queries.ts`, which needs only the store, and have
`createAppAPI` spread them in. The test imports that module directly and
no longer stubs `maplibre-gl`, `window`, `sessionStorage`, or
`localStorage` to get off the ground. Same reasoning, and the same shape,
as `geo-editor-geometry.ts` in `@geolibre/plugins`, which is already kept
free of the Geoman/MapLibre runtime so it can be unit-tested under Node.

`SKETCHES_SOURCE_KIND` gets a subpath export alongside the five already
in that package, so the test can share the constant instead of repeating
the string literal as it did before.

The wiring into the plugin-facing API is now a typed spread rather than
something this test asserts; `tsc` covers it on every build.

Coverage returns to 82.84% lines / 84.45% branches / 72.55% functions
(baseline before #1784: 82.89 / 84.46 / 72.90), with the counted file set
back from 444 to 406. The one addition is the extracted module itself, at
100% lines and 95.45% functions. All 8 tests still pass.
Copilot AI lite review requested due to automatic review settings August 14, 2026 02:55

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@coderabbitai

coderabbitai Bot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 1f47f7c1-aaad-41c8-9408-de0a483709cf

📥 Commits

Reviewing files that changed from the base of the PR and between 6093aa8 and ddd7ab0.

📒 Files selected for processing (4)
  • apps/geolibre-desktop/src/hooks/usePlugins.ts
  • apps/geolibre-desktop/src/lib/plugin-layer-queries.ts
  • packages/plugins/package.json
  • tests/plugin-query-api.test.ts

📝 Walkthrough

Walkthrough

The change moves plugin layer-query and selection methods into createPluginLayerQueries(). createAppAPI uses the new helper. The package adds a geometry export, and tests call the query factory directly.

Changes

Plugin query API

Layer / File(s) Summary
Read-only query implementation
apps/geolibre-desktop/src/lib/plugin-layer-queries.ts
Adds live layer, feature, selection, sketch, and subscription queries. Returned features are cloned, and missing layers raise errors.
createAppAPI integration
apps/geolibre-desktop/src/hooks/usePlugins.ts
Removes duplicate query logic and incorporates methods from createPluginLayerQueries().
Public export and direct validation
packages/plugins/package.json, tests/plugin-query-api.test.ts
Adds the geo-editor-geometry export and updates tests to use the direct query factory.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Merge Risk: ⚪ Minimal · up to ddd7a

This PR moves plugin query logic out of the browser-only registry path and updates its test coverage; the reported checks pass, and no actionable merge-blocking risk remains beyond normal review.

Possibly related PRs

  • opengeos/GeoLibre#1784: Introduces the plugin layer-query and selection APIs that this change extracts from createAppAPI.

Poem

A rabbit hops through layers bright,
Queries features left and right.
Selections change; callbacks run,
Cloned sketches greet the sun.
One clean API now leads the way.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main change: isolating plugin query tests from the built-in plugin registry.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/plugin-query-api-coverage

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed: dependency version conflict. Check your lock file or package.json.


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.

❤️ Share

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

@github-actions

Copy link
Copy Markdown
Contributor

Code review

I reviewed the diff (usePlugins.ts, the new plugin-layer-queries.ts, the packages/plugins/package.json export addition, and the rewritten test file) and traced the surrounding context (geo-editor-geometry.ts, @geolibre/plugins/src/index.ts and types.ts) to verify correctness of the extraction.

Bugs: None found. The extracted createPluginLayerQueries() is a byte-for-byte move of the original inline methods (listLayers, getLayerFeatures, getSelectedFeatures, getSelectedLayerId, getDrawnFeatures, onSelectionChange, readPluginSelection) with no behavioral changes; usePlugins.ts now spreads it in at the same call site. Confidence: high.

Security: None found. structuredClone is still applied everywhere features leave the store, preserving the no-mutation guarantee for plugin consumers. Confidence: high.

Performance: None found. This is a pure code-motion refactor with no new allocations or hot-path changes.

Quality:

  • The new subpath export @geolibre/plugins/geo-editor-geometry follows the existing precedent already used by cog-spectral-profile, local-netcdf, etc. (confirmed several other files already import subpaths this way), and GeoLibreSelection is correctly available via export * from "./types" in the plugins package index. Confidence: high.
  • Minor/non-issue: readPluginSelection is now exported from plugin-layer-queries.ts but has no external consumers yet (only used internally by getSelectedFeatures/onSelectionChange). This mirrors the stated intent of making it testable/reusable like geo-editor-geometry.ts, so not worth changing. Confidence: low.

CLAUDE.md: The change follows the documented pattern of isolating store-only logic from browser/runtime-heavy modules (explicitly citing the geo-editor-geometry.ts precedent), and the type-only import type { GeoLibreSelection } from "@geolibre/plugins" avoids pulling the full plugin registry into the new module at runtime. No violations found. Confidence: high.

No inline comments were posted — this PR is a clean, well-scoped mechanical refactor that does exactly what its description claims, with no correctness, security, or performance concerns identified.

@github-actions

Copy link
Copy Markdown
Contributor

🔍 Cloudflare PR preview

Item Value
Site https://fc46f856.geolibre-preview.pages.dev
Demo app https://fc46f856.geolibre-preview.pages.dev/demo/
Commit ddd7ab0

@github-actions

Copy link
Copy Markdown
Contributor

🔍 GitHub Pages PR preview

Item Value
Site https://opengeos.org/pages-preview/GeoLibre/pr-1888/
Demo app https://opengeos.org/pages-preview/GeoLibre/pr-1888/demo/
Commit ddd7ab0

Note

GitHub Pages built this preview successfully, but its serving edge returned HTTP 403 when checked. The links may still be propagating.

@giswqs
giswqs merged commit 728d52f into main Aug 14, 2026
19 checks passed
@giswqs
giswqs deleted the fix/plugin-query-api-coverage branch August 14, 2026 03:08
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.

2 participants