Skip to content

fix(import): preserve QGIS source paths and group visibility - #1584

Merged
giswqs merged 3 commits into
opengeos:mainfrom
ShiroKSH:fix/qgis-project-import-paths
Jul 31, 2026
Merged

fix(import): preserve QGIS source paths and group visibility#1584
giswqs merged 3 commits into
opengeos:mainfrom
ShiroKSH:fix/qgis-project-import-paths

Conversation

@ShiroKSH

@ShiroKSH ShiroKSH commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Summary

  • preserve query parameters on remote QGIS GeoJSON sources, including signed URLs
  • retain UNC hosts from file://server/share/... sources so network paths are rejected explicitly
  • propagate unchecked parent-group visibility into flattened nested groups

Root cause

The importer normalized remote URLs with the same query stripping used for local file options, discarded the hostname while converting file URLs, and stored only each flattened group's own checked state. Those transformations could break authenticated fetches, treat UNC sources as local paths, and show layers beneath a hidden parent group.

Validation

  • node --import tsx --test tests/qgis-project-import.test.ts (13 passed)
  • scoped pre-commit hooks for both changed files, including oxfmt, ESLint, and production build
  • frontend suite: 4,555 passed, 1 skipped
  • worker TypeScript checks
  • backend pytest coverage: 313 passed, 20 skipped, 64.77% coverage
  • cargo check --manifest-path apps/geolibre-desktop/src-tauri/Cargo.toml

Summary by CodeRabbit

  • Bug Fixes

    • Corrected QGIS layer visibility so nested layers inherit unchecked parent-group states.
    • Improved import handling for quoted, encoded, malformed, remote, and UNC-style file paths.
    • Preserved query credentials in remote GeoJSON URLs and improved source extension detection.
    • Added clearer handling for unsupported network-based file locations.
  • Tests

    • Expanded coverage for inherited visibility, URL validation, encoded filenames, malformed escapes, and remote URL handling.

@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 5ccb7fc7-6a71-42cd-9c87-26b917b7895b

📥 Commits

Reviewing files that changed from the base of the PR and between 24ca49f and dc4a389.

📒 Files selected for processing (2)
  • apps/geolibre-desktop/src/lib/qgis-project-import.ts
  • tests/qgis-project-import.test.ts

📝 Walkthrough

Walkthrough

The QGIS importer now inherits visibility from unchecked ancestor groups. It also normalizes quoted paths and file URLs, handles malformed file URLs, preserves HTTP query components, and tests remote URL and nested-group behavior.

Changes

QGIS import updates

Layer / File(s) Summary
Inherited group visibility
apps/geolibre-desktop/src/lib/qgis-project-import.ts, tests/qgis-project-import.test.ts
The importer sets nested groups to invisible when an ancestor group is unchecked. Tests cover parent and child group visibility.
Source URL normalization
apps/geolibre-desktop/src/lib/qgis-project-import.ts, tests/qgis-project-import.test.ts
The importer removes surrounding quotes, handles local and remote file:// URLs, provides malformed-URL fallback handling, preserves HTTP query and fragment components, and tests UNC rejection, /vsicurl query decoding, encoded filenames, and malformed escapes.

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

Possibly related PRs

Suggested reviewers: giswqs

Poem

A rabbit checks each group in line,
And marks child visibility fine.
URLs shed quotes and keep their trail,
While UNC paths raise a warning pale.
/vsicurl keeps its query bright—
The importer hops through paths just right.

🚥 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 summarizes the main changes to QGIS source paths and group visibility.
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 💡 1
⚔️ Resolve merge conflicts 💡
  • Resolve merge conflict in branch fix/qgis-project-import-paths
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 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 `@apps/geolibre-desktop/src/lib/qgis-project-import.ts`:
- Line 471: Move the quote normalization in the source-processing flow before
the `/vsicurl` prefix removal so quoted remote URLs match the virtual-prefix
expression and retain their query string. Update the relevant logic around
source handling and add a regression test covering a quoted
`/vsicurl/https://...?...` remote source.

In `@tests/qgis-project-import.test.ts`:
- Around line 275-278: Update the test assertion near the existing unc.warnings
check to also assert that unc.project.layers is empty, verifying the UNC layer
is excluded while preserving the current network-path warning assertion.
🪄 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: ASSERTIVE

Plan: Pro Plus

Run ID: fc5fb7b5-ccb7-4a51-8d57-8d7ce4d4590d

📥 Commits

Reviewing files that changed from the base of the PR and between 3060b53 and 0c6fcdd.

📒 Files selected for processing (2)
  • apps/geolibre-desktop/src/lib/qgis-project-import.ts
  • tests/qgis-project-import.test.ts

Comment thread apps/geolibre-desktop/src/lib/qgis-project-import.ts Outdated
Comment thread tests/qgis-project-import.test.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
tests/qgis-project-import.test.ts (1)

282-296: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Assert the nested layer visibility.

The test asserts that the parent and nested groups are hidden, but it does not assert the flattened cities layer visibility. A regression could leave that layer visible while the group metadata is hidden.

Assert that the imported cities layer has visible: false when the Transport ancestor is unchecked.

🤖 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 `@tests/qgis-project-import.test.ts` around lines 282 - 296, Extend the test in
“inherits visibility from unchecked parent groups” to also locate the imported
cities layer in result.project and assert its visible property is false when the
Transport ancestor is unchecked, while preserving the existing group visibility
assertions.
apps/geolibre-desktop/src/lib/qgis-project-import.ts (1)

472-486: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Preserve encoded query and fragment characters in file paths.

Line 475 decodes %3F and %23 into ? and #. Line 486 then treats those characters as query or fragment delimiters and truncates the filename. For example, file:///tmp/a%23b.geojson becomes /tmp/a.

Skip generic query/fragment stripping for successfully decoded file URLs, and add a regression test for an encoded # filename.

🤖 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 `@apps/geolibre-desktop/src/lib/qgis-project-import.ts` around lines 472 - 486,
Track whether the file URL was successfully parsed and decoded in the
file-source normalization block, then skip the generic query/fragment removal
after that path when the flag is set. Preserve stripping for non-file sources
and fallback parsing, and add a regression test covering an encoded “#” filename
such as file:///tmp/a%23b.geojson.
🤖 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.

Outside diff comments:
In `@apps/geolibre-desktop/src/lib/qgis-project-import.ts`:
- Around line 472-486: Track whether the file URL was successfully parsed and
decoded in the file-source normalization block, then skip the generic
query/fragment removal after that path when the flag is set. Preserve stripping
for non-file sources and fallback parsing, and add a regression test covering an
encoded “#” filename such as file:///tmp/a%23b.geojson.

In `@tests/qgis-project-import.test.ts`:
- Around line 282-296: Extend the test in “inherits visibility from unchecked
parent groups” to also locate the imported cities layer in result.project and
assert its visible property is false when the Transport ancestor is unchecked,
while preserving the existing group visibility assertions.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 6edf6882-dce0-466a-a9f8-714bb5a4f16b

📥 Commits

Reviewing files that changed from the base of the PR and between 0c6fcdd and 24ca49f.

📒 Files selected for processing (2)
  • apps/geolibre-desktop/src/lib/qgis-project-import.ts
  • tests/qgis-project-import.test.ts

@giswqs

giswqs commented Jul 31, 2026

Copy link
Copy Markdown
Member

/claude-review

@github-actions

Copy link
Copy Markdown
Contributor

🔍 Cloudflare PR preview

Item Value
Site https://6a961e74.geolibre-preview.pages.dev
Demo app https://6a961e74.geolibre-preview.pages.dev/demo/
Commit 24ca49f

@github-actions

Copy link
Copy Markdown
Contributor

🔍 GitHub Pages PR preview

Item Value
Site https://opengeos.org/pages-preview/GeoLibre/pr-1584/
Demo app https://opengeos.org/pages-preview/GeoLibre/pr-1584/demo/
Commit 24ca49f

Comment thread apps/geolibre-desktop/src/lib/qgis-project-import.ts
Comment thread apps/geolibre-desktop/src/lib/qgis-project-import.ts Outdated
@github-actions

Copy link
Copy Markdown
Contributor

Code review

Bugs

  • qgisSourcePath's catch fallback for malformed file:// URLs doesn't replicate the drive-letter handling from the try branch, so a local Windows path with a malformed %-escape (e.g. file://C:/data%zzfile.gpkg) could be misclassified as a UNC network path and rejected with the wrong warning reason. Narrow trigger (requires both the 2-slash drive-letter form and a decode failure). Confidence: low.

Security

  • Preserving query strings on HTTP(S) sources means signed/token URLs from the QGIS project now persist verbatim in layer.sourcePath/source.url, including into saved .geolibre.json files — likely intended (the fetch needs the token), but worth confirming there's no unintended credential-sharing risk when projects are saved/shared. Confidence: low-medium.

Quality / Correctness verification

  • Traced the group-visibility fix (qgisGroupVisible) against the existing groupDisplayName traversal pattern and the new tests: unchecked-parent propagation into flattened nested groups is correctly computed, and combines correctly with applyGroupEffects in @geolibre/core (which ANDs a layer's own visibility with its immediate group's — already-propagated — visibility). No issue found.
  • Traced the UNC/file-URL and vsicurl/query-preservation logic against both new and pre-existing tests (quoted VSI sources, Windows drive-letter paths, raw UNC paths, credentialed remote URLs) — all check out correctly, and the reordering of quote-stripping before /vsicurl/ prefix matching is necessary and correct.
  • network-path is a pre-existing warning reason (already localized in en.json), so no missing i18n string was introduced by making this path reachable.

Performance / CLAUDE.md

  • No issues found. The new traversal in qgisGroupVisible follows the same O(depth) climb-per-node pattern already used by groupDisplayName, so no new complexity class introduced. No CLAUDE.md conventions (i18n, RTL, mirrored-constant sync notes) apply to this diff.

@giswqs
giswqs merged commit bd2883e into opengeos:main Jul 31, 2026
17 of 19 checks passed
giswqs added a commit that referenced this pull request Jul 31, 2026
#1593 changed QGIS layer-group names from flattened ("Transport /
Places") to plain names plus a parentId. #1584 branched before that
change and added a visibility-inheritance test still asserting the
flattened name, so main went red once both landed.

The importer behavior is correct; only the expectation was stale.
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