from id_configurator.config import Configuration from id_configurator.context import Context from id_configurator.modules.rust import RustModule CONFIG_WITH_REPO = { "uuid": "12345678-1234-5678-1234-567812345678", "organisation": "InterDiode", "configurations": { "rust": { "repositories": [ { "name": "demo", "url": "https://example.invalid/", "is_sparse": True, } ] } }, } CONFIG_WITH_TWO_REPOS = { "uuid": "12345678-1234-5678-1234-567812345678", "organisation": "InterDiode", "configurations": { "rust": { "repositories": [ { "name": "demo", "url": "https://example.invalid/", "is_sparse": True, }, { "name": "other", "url": "https://other.invalid/", "is_sparse": True, }, ] } }, } EMPTY_CONFIG = { "uuid": "12345678-1234-5678-1234-567812345678", "organisation": "InterDiode", } def make_config(data: dict) -> Configuration: return Configuration.model_validate(data) def test_is_relevant_false_when_no_repositories(tmp_path) -> None: context = Context(config=make_config(EMPTY_CONFIG), dst=tmp_path / "dst", src=None) assert RustModule().is_relevant(context) is False def test_is_relevant_true_with_repository(tmp_path) -> None: context = Context( config=make_config(CONFIG_WITH_REPO), dst=tmp_path / "dst", src=None ) assert RustModule().is_relevant(context) is True def test_apply_writes_replacement_source(tmp_path) -> None: dst = tmp_path / "dst" context = Context(config=make_config(CONFIG_WITH_REPO), dst=dst, src=None) RustModule().apply(context) config_toml = (dst / ".cargo/config.toml").read_text(encoding="utf-8") assert config_toml == ( "[source.crates-io]\n" 'replace-with = "demo"\n' "\n" "[source.demo]\n" 'registry = "sparse+https://example.invalid/"\n' ) def test_apply_sanitizes_repository_names_with_special_characters(tmp_path) -> None: data = { "uuid": "12345678-1234-5678-1234-567812345678", "organisation": "InterDiode", "configurations": { "rust": { "repositories": [ { "name": "weird.demo]\nname", "url": "https://example.invalid/", "is_sparse": True, } ] } }, } dst = tmp_path / "dst" context = Context(config=make_config(data), dst=dst, src=None) RustModule().apply(context) config_toml = (dst / ".cargo/config.toml").read_text(encoding="utf-8") assert config_toml == ( "[source.crates-io]\n" 'replace-with = "weird_demo__name"\n' "\n" "[source.weird_demo__name]\n" 'registry = "sparse+https://example.invalid/"\n' ) def test_apply_does_not_prefix_url_when_not_sparse(tmp_path) -> None: data = { "uuid": "12345678-1234-5678-1234-567812345678", "organisation": "InterDiode", "configurations": { "rust": { "repositories": [{"name": "demo", "url": "https://example.invalid/"}] } }, } dst = tmp_path / "dst" context = Context(config=make_config(data), dst=dst, src=None) RustModule().apply(context) config_toml = (dst / ".cargo/config.toml").read_text(encoding="utf-8") assert config_toml == ( "[source.crates-io]\n" 'replace-with = "demo"\n' "\n" "[source.demo]\n" 'registry = "https://example.invalid/"\n' ) def test_apply_prefixes_url_with_sparse_when_configured(tmp_path) -> None: dst = tmp_path / "dst" context = Context(config=make_config(CONFIG_WITH_REPO), dst=dst, src=None) RustModule().apply(context) config_toml = (dst / ".cargo/config.toml").read_text(encoding="utf-8") assert config_toml == ( "[source.crates-io]\n" 'replace-with = "demo"\n' "\n" "[source.demo]\n" 'registry = "sparse+https://example.invalid/"\n' ) def test_apply_writes_cargo_config_for_each_configured_user(tmp_path) -> None: dst = tmp_path / "dst" context = Context( config=make_config(CONFIG_WITH_REPO), dst=dst, src=None, users=["alice"] ) RustModule().apply(context) root_content = (dst / ".cargo/config.toml").read_text(encoding="utf-8") alice_content = (dst / "home/alice/.cargo/config.toml").read_text(encoding="utf-8") assert alice_content == root_content def test_apply_writes_additional_repositories_as_named_registries(tmp_path) -> None: dst = tmp_path / "dst" context = Context(config=make_config(CONFIG_WITH_TWO_REPOS), dst=dst, src=None) RustModule().apply(context) config_toml = (dst / ".cargo/config.toml").read_text(encoding="utf-8") assert config_toml == ( "[source.crates-io]\n" 'replace-with = "demo"\n' "\n" "[source.demo]\n" 'registry = "sparse+https://example.invalid/"\n' "\n" "[registries.other]\n" 'index = "sparse+https://other.invalid/"\n' )