# Copyright (c) 2017 Ansible Project # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # SPDX-License-Identifier: GPL-3.0-or-later from __future__ import annotations import pytest from ansible.module_utils import basic from ansible_collections.community.general.plugins.modules import maven_artifact pytestmark = pytest.mark.usefixtures("patch_ansible_module") maven_metadata_example = b""" junit junit 4.13-beta-2 4.13-beta-2 3.7 3.8 3.8.1 3.8.2 4.0 4.1 4.2 4.3 4.3.1 4.4 4.5 4.6 4.7 4.8 4.8.1 4.8.2 4.9 4.10 4.11-beta-1 4.11 4.12-beta-1 4.12-beta-2 4.12-beta-3 4.12 4.13-beta-1 4.13-beta-2 20190202141051 """ @pytest.mark.parametrize( "patch_ansible_module, version_by_spec, version_choosed", [ (None, "(,3.9]", "3.8.2"), (None, "3.0", "3.8.2"), (None, "[3.7]", "3.7"), (None, "[4.10, 4.12]", "4.12"), (None, "[4.10, 4.12)", "4.11"), (None, "[2.0,)", "4.13-beta-2"), ], ) def test_find_version_by_spec(mocker, version_by_spec, version_choosed): _getContent = mocker.patch( "ansible_collections.community.general.plugins.modules.maven_artifact.MavenDownloader._getContent" ) _getContent.return_value = maven_metadata_example artifact = maven_artifact.Artifact("junit", "junit", None, version_by_spec, "jar") mvn_downloader = maven_artifact.MavenDownloader(basic.AnsibleModule, "https://repo1.maven.org/maven2") assert mvn_downloader.find_version_by_spec(artifact) == version_choosed # Metadata with multiple snapshotVersion entries per extension (as produced by GitHub Packages). # The entries are deliberately NOT in chronological order to verify that # resolution uses the timestamp rather than relying on list position. snapshot_metadata_multiple_entries = b""" com.example my-lib 1.0.0-SNAPSHOT 20260210.152345 3 20260210153158 jar 1.0.0-20260205.091032-2 20260205091858 jar 1.0.0-20260210.152345-3 20260210153154 pom 1.0.0-20260210.152345-3 20260210153153 jar 1.0.0-20260203.123107-1 20260203123944 pom 1.0.0-20260203.123107-1 20260203123943 pom 1.0.0-20260205.091032-2 20260205091857 """ # Metadata without a block but with only. snapshot_metadata_no_snapshot_block = b""" com.example my-lib 1.0.0-SNAPSHOT 20260210153158 jar 1.0.0-20260203.123107-1 20260203123944 pom 1.0.0-20260203.123107-1 20260203123943 """ @pytest.mark.parametrize("patch_ansible_module", [None]) def test_find_uri_for_snapshot_resolves_to_latest(mocker): """When metadata has multiple snapshotVersion entries per extension, the entry with the newest updated timestamp should be resolved.""" _getContent = mocker.patch( "ansible_collections.community.general.plugins.modules.maven_artifact.MavenDownloader._getContent" ) _getContent.return_value = snapshot_metadata_multiple_entries artifact = maven_artifact.Artifact("com.example", "my-lib", "1.0.0-SNAPSHOT", None, "", "jar") mvn_downloader = maven_artifact.MavenDownloader(basic.AnsibleModule, "https://repo.example.com") uri = mvn_downloader.find_uri_for_artifact(artifact) assert "1.0.0-20260210.152345-3.jar" in uri @pytest.mark.parametrize("patch_ansible_module", [None]) def test_find_uri_for_snapshot_without_snapshot_block_uses_snapshot_versions(mocker): """When metadata lacks a block, fall back to scanning entries.""" _getContent = mocker.patch( "ansible_collections.community.general.plugins.modules.maven_artifact.MavenDownloader._getContent" ) _getContent.return_value = snapshot_metadata_no_snapshot_block artifact = maven_artifact.Artifact("com.example", "my-lib", "1.0.0-SNAPSHOT", None, "", "jar") mvn_downloader = maven_artifact.MavenDownloader(basic.AnsibleModule, "https://repo.example.com") uri = mvn_downloader.find_uri_for_artifact(artifact) assert "1.0.0-20260203.123107-1.jar" in uri # Metadata with a block that has but no . # This is schema-valid but non-standard (e.g. produced by non-Maven tools). # The module should fall back to scanning. snapshot_metadata_incomplete_snapshot_block = b""" com.example my-lib 1.0.0-SNAPSHOT 20260210.152345 20260210153158 jar 1.0.0-20260210.152345-3 20260210153154 pom 1.0.0-20260210.152345-3 20260210153153 """ @pytest.mark.parametrize("patch_ansible_module", [None]) def test_find_uri_for_snapshot_incomplete_snapshot_block_uses_snapshot_versions(mocker): """When the block is incomplete (e.g. missing ), fall back to instead of raising an error.""" _getContent = mocker.patch( "ansible_collections.community.general.plugins.modules.maven_artifact.MavenDownloader._getContent" ) _getContent.return_value = snapshot_metadata_incomplete_snapshot_block artifact = maven_artifact.Artifact("com.example", "my-lib", "1.0.0-SNAPSHOT", None, "", "jar") mvn_downloader = maven_artifact.MavenDownloader(basic.AnsibleModule, "https://repo.example.com") uri = mvn_downloader.find_uri_for_artifact(artifact) assert "1.0.0-20260210.152345-3.jar" in uri @pytest.mark.parametrize("patch_ansible_module", [None]) def test_find_uri_for_release_version_unaffected(mocker): """Non-SNAPSHOT versions must not be affected by snapshot resolution logic.""" artifact = maven_artifact.Artifact("com.example", "my-lib", "2.1.0", None, "", "jar") mvn_downloader = maven_artifact.MavenDownloader(basic.AnsibleModule, "https://repo.example.com") uri = mvn_downloader.find_uri_for_artifact(artifact) assert uri == "https://repo.example.com/com/example/my-lib/2.1.0/my-lib-2.1.0.jar"