blob: 44b0ce4b356543e0e281b3d0ca784aeb9fe10bd5 [file]
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
"""Unit tests for dev/registry/patch_providers_json.py."""
from __future__ import annotations
import json
import sys
from unittest.mock import patch as mock_patch
import pytest
from patch_providers_json import main, patch
def _write_providers(tmp_path, providers):
p = tmp_path / "providers.json"
p.write_text(json.dumps({"providers": providers}, indent=2))
return p
class TestPatch:
def test_appends_missing_version(self, tmp_path):
p = _write_providers(
tmp_path,
[{"id": "amazon", "version": "9.26.0", "versions": ["9.26.0", "9.25.0"]}],
)
rc = patch(p, "amazon", ["9.24.0"])
assert rc == 0
data = json.loads(p.read_text())
amazon = next(p for p in data["providers"] if p["id"] == "amazon")
assert amazon["versions"] == ["9.26.0", "9.25.0", "9.24.0"]
def test_skips_already_present_version(self, tmp_path):
p = _write_providers(
tmp_path,
[{"id": "amazon", "version": "9.26.0", "versions": ["9.26.0", "9.25.0"]}],
)
before = json.loads(p.read_text())
rc = patch(p, "amazon", ["9.25.0"])
after = json.loads(p.read_text())
assert rc == 0
# Same content; sorting may rewrite the file but the array is unchanged.
assert before["providers"][0]["versions"] == after["providers"][0]["versions"]
def test_unknown_provider_id_errors(self, tmp_path, capsys):
p = _write_providers(tmp_path, [{"id": "amazon", "version": "9.26.0", "versions": []}])
rc = patch(p, "nonexistent-provider", ["1.0.0"])
assert rc == 1
captured = capsys.readouterr()
assert "nonexistent-provider" in captured.out
def test_multiple_versions_one_call(self, tmp_path):
p = _write_providers(
tmp_path,
[{"id": "amazon", "version": "9.26.0", "versions": ["9.26.0"]}],
)
rc = patch(p, "amazon", ["9.24.0", "9.22.0"])
assert rc == 0
data = json.loads(p.read_text())
amazon = next(p for p in data["providers"] if p["id"] == "amazon")
# Sorted newest-first
assert amazon["versions"] == ["9.26.0", "9.24.0", "9.22.0"]
def test_invalid_version_falls_back_to_lex_sort(self, tmp_path):
p = _write_providers(
tmp_path,
[{"id": "weird", "version": "1.0.0", "versions": ["1.0.0", "not-a-semver"]}],
)
# Should not raise
rc = patch(p, "weird", ["custom-tag"])
assert rc == 0
data = json.loads(p.read_text())
weird = next(p for p in data["providers"] if p["id"] == "weird")
# All three should be present
assert set(weird["versions"]) == {"1.0.0", "not-a-semver", "custom-tag"}
def test_includes_latest_when_versions_was_empty(self, tmp_path):
"""Regression: empty `versions[]` must not exclude `provider.version`.
After patch, providerVersions.js treats non-empty versions[] as
authoritative. If we patch only the new version into an empty list,
the latest field would be excluded from the dropdown.
"""
p = _write_providers(
tmp_path,
[{"id": "newish", "version": "1.0.0", "versions": []}],
)
rc = patch(p, "newish", ["0.9.0"])
assert rc == 0
data = json.loads(p.read_text())
newish = next(p for p in data["providers"] if p["id"] == "newish")
assert "1.0.0" in newish["versions"]
assert "0.9.0" in newish["versions"]
def test_provider_version_field_unchanged(self, tmp_path):
"""The `version` (singular, latest) field is never touched by the patch."""
p = _write_providers(
tmp_path,
[{"id": "amazon", "version": "9.26.0", "versions": ["9.26.0", "9.25.0"]}],
)
rc = patch(p, "amazon", ["9.24.0"])
assert rc == 0
data = json.loads(p.read_text())
amazon = next(p for p in data["providers"] if p["id"] == "amazon")
# Latest pointer must remain 9.26.0 even though we added an older version.
assert amazon["version"] == "9.26.0"
def test_other_providers_untouched(self, tmp_path):
p = _write_providers(
tmp_path,
[
{"id": "amazon", "version": "9.26.0", "versions": ["9.26.0"]},
{"id": "google", "version": "21.2.0", "versions": ["21.2.0", "21.1.0"]},
],
)
rc = patch(p, "amazon", ["9.24.0"])
assert rc == 0
data = json.loads(p.read_text())
google = next(p for p in data["providers"] if p["id"] == "google")
assert google["versions"] == ["21.2.0", "21.1.0"]
assert google["version"] == "21.2.0"
class TestMainCli:
def test_main_exits_with_patch_returncode(self, tmp_path, capsys):
p = _write_providers(
tmp_path,
[{"id": "amazon", "version": "9.26.0", "versions": ["9.26.0"]}],
)
argv = [
"patch_providers_json.py",
"--providers-json",
str(p),
"--provider",
"amazon",
"--version",
"9.24.0",
]
with mock_patch.object(sys, "argv", argv):
rc = main()
assert rc == 0
data = json.loads(p.read_text())
amazon = next(p for p in data["providers"] if p["id"] == "amazon")
assert "9.24.0" in amazon["versions"]
def test_main_unknown_provider_exits_1(self, tmp_path):
p = _write_providers(
tmp_path,
[{"id": "amazon", "version": "9.26.0", "versions": []}],
)
argv = [
"patch_providers_json.py",
"--providers-json",
str(p),
"--provider",
"ghost",
"--version",
"1.0.0",
]
with mock_patch.object(sys, "argv", argv):
rc = main()
assert rc == 1
def test_main_requires_version_argument(self, tmp_path):
p = _write_providers(tmp_path, [])
argv = [
"patch_providers_json.py",
"--providers-json",
str(p),
"--provider",
"amazon",
]
with mock_patch.object(sys, "argv", argv):
with pytest.raises(SystemExit) as exc:
main()
assert exc.value.code != 0