-
Notifications
You must be signed in to change notification settings - Fork 7.8k
fix: core and community extension catalogs should be searchable without override envvar #1769
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
Changes from 2 commits
b60e60e
613971c
b63b574
7fef79d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -841,7 +841,7 @@ def test_cache_directory_creation(self, temp_dir): | |
| json.dumps( | ||
| { | ||
| "cached_at": datetime.now(timezone.utc).isoformat(), | ||
| "catalog_url": "http://test.com/catalog.json", | ||
| "catalog_urls": catalog.get_catalog_urls(), | ||
| } | ||
| ) | ||
|
dhilipkumars marked this conversation as resolved.
|
||
| ) | ||
|
|
@@ -870,7 +870,7 @@ def test_cache_expiration(self, temp_dir): | |
| json.dumps( | ||
| { | ||
| "cached_at": expired_datetime.isoformat(), | ||
| "catalog_url": "http://test.com/catalog.json", | ||
| "catalog_urls": catalog.get_catalog_urls(), | ||
| } | ||
| ) | ||
|
dhilipkumars marked this conversation as resolved.
|
||
| ) | ||
|
|
@@ -918,7 +918,7 @@ def test_search_all_extensions(self, temp_dir): | |
| json.dumps( | ||
| { | ||
| "cached_at": datetime.now(timezone.utc).isoformat(), | ||
| "catalog_url": "http://test.com", | ||
| "catalog_urls": catalog.get_catalog_urls(), | ||
| } | ||
| ) | ||
|
dhilipkumars marked this conversation as resolved.
|
||
| ) | ||
|
|
@@ -962,7 +962,7 @@ def test_search_by_query(self, temp_dir): | |
| json.dumps( | ||
| { | ||
| "cached_at": datetime.now(timezone.utc).isoformat(), | ||
| "catalog_url": "http://test.com", | ||
| "catalog_urls": catalog.get_catalog_urls(), | ||
| } | ||
| ) | ||
|
dhilipkumars marked this conversation as resolved.
|
||
| ) | ||
|
|
@@ -1014,7 +1014,7 @@ def test_search_by_tag(self, temp_dir): | |
| json.dumps( | ||
| { | ||
| "cached_at": datetime.now(timezone.utc).isoformat(), | ||
| "catalog_url": "http://test.com", | ||
| "catalog_urls": catalog.get_catalog_urls(), | ||
| } | ||
| ) | ||
|
dhilipkumars marked this conversation as resolved.
|
||
| ) | ||
|
|
@@ -1059,7 +1059,7 @@ def test_search_verified_only(self, temp_dir): | |
| json.dumps( | ||
| { | ||
| "cached_at": datetime.now(timezone.utc).isoformat(), | ||
| "catalog_url": "http://test.com", | ||
| "catalog_urls": catalog.get_catalog_urls(), | ||
| } | ||
| ) | ||
|
dhilipkumars marked this conversation as resolved.
|
||
| ) | ||
|
|
@@ -1097,7 +1097,7 @@ def test_get_extension_info(self, temp_dir): | |
| json.dumps( | ||
| { | ||
| "cached_at": datetime.now(timezone.utc).isoformat(), | ||
| "catalog_url": "http://test.com", | ||
| "catalog_urls": catalog.get_catalog_urls(), | ||
| } | ||
| ) | ||
|
dhilipkumars marked this conversation as resolved.
|
||
| ) | ||
|
|
@@ -1133,3 +1133,92 @@ def test_clear_cache(self, temp_dir): | |
|
|
||
| assert not catalog.cache_file.exists() | ||
| assert not catalog.cache_metadata_file.exists() | ||
|
|
||
| def test_fetch_catalog_merge_and_precedence(self, temp_dir, monkeypatch): | ||
| """Test that multiple catalogs are fetched, merged, and earlier URLs have precedence.""" | ||
| import json | ||
|
|
||
| project_dir = temp_dir / "project" | ||
| project_dir.mkdir() | ||
| (project_dir / ".specify").mkdir() | ||
|
|
||
| catalog = ExtensionCatalog(project_dir) | ||
| catalog.DEFAULT_CATALOG_URLS = ["http://catalog1.test", "http://catalog2.test"] | ||
|
|
||
|
Comment on lines
+1145
to
+1147
|
||
| # Mock responses | ||
| responses = { | ||
| "http://catalog1.test": { | ||
| "schema_version": "1.0", | ||
| "extensions": { | ||
| "ext-a": {"id": "ext-a", "version": "1.0.0", "source": "cat1"}, | ||
| "ext-b": {"id": "ext-b", "version": "1.0.0", "source": "cat1"} | ||
| } | ||
| }, | ||
| "http://catalog2.test": { | ||
| "schema_version": "1.0", | ||
| "extensions": { | ||
| "ext-a": {"id": "ext-a", "version": "2.0.0", "source": "cat2"}, # Duplicate | ||
| "ext-c": {"id": "ext-c", "version": "1.0.0", "source": "cat2"} # New | ||
| } | ||
| } | ||
| } | ||
|
|
||
| class MockResponse: | ||
| def __init__(self, url): | ||
| self.data = json.dumps(responses[url]).encode('utf-8') | ||
| def read(self): | ||
| return self.data | ||
| def __enter__(self): | ||
| return self | ||
| def __exit__(self, *args): | ||
| pass | ||
|
|
||
| def mock_urlopen(url, *args, **kwargs): | ||
| return MockResponse(url) | ||
|
|
||
| monkeypatch.setattr("urllib.request.urlopen", mock_urlopen) | ||
|
|
||
| # Force refresh to hit the network | ||
| merged = catalog.fetch_catalog(force_refresh=True) | ||
|
|
||
| assert "ext-a" in merged["extensions"] | ||
| assert "ext-b" in merged["extensions"] | ||
| assert "ext-c" in merged["extensions"] | ||
|
|
||
| # Precedence check: ext-a should come from catalog1 (version 1.0.0, source cat1) | ||
| assert merged["extensions"]["ext-a"]["source"] == "cat1" | ||
| assert merged["extensions"]["ext-a"]["version"] == "1.0.0" | ||
|
|
||
| # Cache correctly saved | ||
| assert catalog.cache_file.exists() | ||
| assert catalog.cache_metadata_file.exists() | ||
| metadata = json.loads(catalog.cache_metadata_file.read_text()) | ||
| assert metadata["catalog_urls"] == catalog.DEFAULT_CATALOG_URLS | ||
|
|
||
| def test_cache_backward_compatibility(self, temp_dir): | ||
| """Test that is_cache_valid handles the legacy 'catalog_url' string gracefully.""" | ||
| project_dir = temp_dir / "project" | ||
| project_dir.mkdir() | ||
| (project_dir / ".specify").mkdir() | ||
|
|
||
| catalog = ExtensionCatalog(project_dir) | ||
| catalog.DEFAULT_CATALOG_URLS = ["http://legacy-url.test"] | ||
|
|
||
| catalog.cache_dir.mkdir(parents=True, exist_ok=True) | ||
| catalog.cache_file.write_text("{}") | ||
|
|
||
| # Write legacy metadata with single string "catalog_url" | ||
| catalog.cache_metadata_file.write_text( | ||
| json.dumps({ | ||
| "cached_at": datetime.now(timezone.utc).isoformat(), | ||
| "catalog_url": "http://legacy-url.test" | ||
| }) | ||
| ) | ||
|
|
||
| # Cache should be valid because legacy URL matches DEFAULT_CATALOG_URLS exactly | ||
| # which evaluates to a normalized single-element list. | ||
| assert catalog.is_cache_valid() | ||
|
|
||
| # If url doesn't match, it should be invalid | ||
| catalog.DEFAULT_CATALOG_URLS = ["http://different.test"] | ||
| assert not catalog.is_cache_valid() | ||
Uh oh!
There was an error while loading. Please reload this page.