def test_authenticator_add_repository( config: Config, mock_remote: None, http: type[httpretty.httpretty], with_simple_keyring: None, dummy_keyring: DummyBackend, ): config.merge({ "http-basic": { "source": { "username": "******", "password": "******" }, }, }) authenticator = Authenticator(config, NullIO()) authenticator.request( "get", "https://foo.bar/simple/a/1.0.0/a-1.0.0.whl", ) request = http.last_request() assert "Authorization" not in request.headers authenticator.add_repository("source", "https://foo.bar/simple/") authenticator.request( "get", "https://foo.bar/simple/a/1.0.0/a-1.0.0.whl", ) request = http.last_request() basic_auth = base64.b64encode(b"foo:bar").decode() assert request.headers["Authorization"] == f"Basic {basic_auth}"
def test_install_with_trusted_host(config: Config): config.merge({"certificates": {"default": {"cert": False}}}) default = LegacyRepository("default", "https://foo.bar") pool = Pool() pool.add_repository(default, default=True) null_env = NullEnv() installer = PipInstaller(null_env, NullIO(), pool) foo = Package( "foo", "0.0.0", source_type="legacy", source_reference=default.name, source_url=default.url, ) installer.install(foo) assert len(null_env.executed) == 1 cmd = null_env.executed[0] assert "--trusted-host" in cmd cert_index = cmd.index("--trusted-host") assert cmd[cert_index + 1] == "foo.bar"
def test_publish_can_publish_to_given_repository( fixture_dir: FixtureDirGetter, mocker: MockerFixture, config: Config, fixture_name: str, ): uploader_auth = mocker.patch("poetry.publishing.uploader.Uploader.auth") uploader_upload = mocker.patch("poetry.publishing.uploader.Uploader.upload") config.merge( { "repositories": {"foo": {"url": "http://foo.bar"}}, "http-basic": {"foo": {"username": "******", "password": "******"}}, } ) mocker.patch("poetry.config.config.Config.create", return_value=config) poetry = Factory().create_poetry(fixture_dir(fixture_name)) io = BufferedIO() publisher = Publisher(poetry, io) publisher.publish("foo", None, None) assert [("foo", "bar")] == uploader_auth.call_args assert [ ("http://foo.bar",), {"cert": None, "client_cert": None, "dry_run": False, "skip_existing": False}, ] == uploader_upload.call_args assert "Publishing my-package (1.2.3) to foo" in io.fetch_output()
def test_authenticator_uses_username_only_credentials( config: Config, mock_remote: None, http: type[httpretty.httpretty], with_simple_keyring: None, ): config.merge({ "repositories": { "foo": { "url": "https://foo.bar/simple/" } }, "http-basic": { "foo": { "username": "******", "password": "******" } }, }) authenticator = Authenticator(config, NullIO()) authenticator.request("get", "https://[email protected]/files/foo-0.1.0.tar.gz") request = http.last_request() assert request.headers["Authorization"] == "Basic Zm9vMDAxOg=="
def test_authenticator_uses_certs_from_config_if_not_provided( config: Config, mock_remote: type[httpretty.httpretty], mock_config: Config, http: type[httpretty.httpretty], mocker: MockerFixture, cert: str | None, client_cert: str | None, ): configured_cert = "/path/to/cert" configured_client_cert = "/path/to/client-cert" mock_config.merge({ "certificates": { "foo": { "cert": configured_cert, "client-cert": configured_client_cert } }, }) authenticator = Authenticator(mock_config, NullIO()) url = "https://foo.bar/files/foo-0.1.0.tar.gz" session = authenticator.get_session(url) session_send = mocker.patch.object(session, "send") authenticator.request( "get", url, verify=cert, cert=client_cert, ) kwargs = session_send.call_args[1] assert Path(kwargs["verify"]) == Path(cert or configured_cert) assert Path(kwargs["cert"]) == Path(client_cert or configured_client_cert)
def test_deactivate_non_activated_but_existing( tmp_dir: str, manager: EnvManager, poetry: Poetry, config: Config, mocker: MockerFixture, ): if "VIRTUAL_ENV" in os.environ: del os.environ["VIRTUAL_ENV"] venv_name = manager.generate_env_name("simple-project", str(poetry.file.parent)) python = ".".join(str(c) for c in sys.version_info[:2]) (Path(tmp_dir) / f"{venv_name}-py{python}").mkdir() config.merge({"virtualenvs": {"path": str(tmp_dir)}}) mocker.patch( "subprocess.check_output", side_effect=check_output_wrapper(), ) manager.deactivate(NullIO()) env = manager.get() assert env.path == Path(tmp_dir) / f"{venv_name}-py{python}" assert Path("/prefix")
def test_get_prefers_explicitly_activated_virtualenvs_over_env_var( tmp_dir: str, manager: EnvManager, poetry: Poetry, config: Config, mocker: MockerFixture, ): os.environ["VIRTUAL_ENV"] = "/environment/prefix" venv_name = manager.generate_env_name("simple-project", str(poetry.file.parent)) config.merge({"virtualenvs": {"path": str(tmp_dir)}}) (Path(tmp_dir) / f"{venv_name}-py3.7").mkdir() envs_file = TOMLFile(Path(tmp_dir) / "envs.toml") doc = tomlkit.document() doc[venv_name] = {"minor": "3.7", "patch": "3.7.0"} envs_file.write(doc) mocker.patch( "subprocess.check_output", side_effect=check_output_wrapper(), ) mocker.patch( "subprocess.Popen.communicate", side_effect=[("/prefix", None)], ) env = manager.get() assert env.path == Path(tmp_dir) / f"{venv_name}-py3.7" assert env.base == Path("/prefix")
def test_remove_also_deactivates( tmp_dir: str, manager: EnvManager, poetry: Poetry, config: Config, mocker: MockerFixture, ): config.merge({"virtualenvs": {"path": str(tmp_dir)}}) venv_name = manager.generate_env_name("simple-project", str(poetry.file.parent)) (Path(tmp_dir) / f"{venv_name}-py3.7").mkdir() (Path(tmp_dir) / f"{venv_name}-py3.6").mkdir() mocker.patch( "subprocess.check_output", side_effect=check_output_wrapper(Version.parse("3.6.6")), ) envs_file = TOMLFile(Path(tmp_dir) / "envs.toml") doc = tomlkit.document() doc[venv_name] = {"minor": "3.6", "patch": "3.6.6"} envs_file.write(doc) venv = manager.remove("python3.6") expected_venv_path = Path(tmp_dir) / f"{venv_name}-py3.6" assert venv.path == expected_venv_path assert not expected_venv_path.exists() envs = envs_file.read() assert venv_name not in envs
def test_authenticator_uses_empty_strings_as_default_password( config: Config, mock_remote: None, http: type[httpretty.httpretty], with_simple_keyring: None, ): config.merge({ "repositories": { "foo": { "url": "https://foo.bar/simple/" } }, "http-basic": { "foo": { "username": "******" } }, }) authenticator = Authenticator(config, NullIO()) authenticator.request("get", "https://foo.bar/files/foo-0.1.0.tar.gz") request = http.last_request() assert request.headers["Authorization"] == "Basic YmFyOg=="
def test_chooser_no_binary_policy( env: MockEnv, mock_pypi: None, mock_legacy: None, source_type: str, pool: Pool, policy: str, filename: str, config: Config, ): config.merge({"installer": {"no-binary": policy.split(",")}}) chooser = Chooser(pool, env, config) package = Package("pytest", "3.5.0") if source_type == "legacy": package = Package( package.name, package.version.text, source_type="legacy", source_reference="foo", source_url="https://foo.bar/simple/", ) link = chooser.choose_for(package) assert link.filename == filename
def mock_config(config: Config, repo: dict[str, dict[str, str]]): config.merge({ "repositories": repo, "http-basic": { "foo": { "username": "******", "password": "******" } }, }) return config
def test_remove_keeps_dir_if_not_deleteable( tmp_dir: str, manager: EnvManager, poetry: Poetry, config: Config, mocker: MockerFixture, ): # Ensure we empty rather than delete folder if its is an active mount point. # See https://github.com/python-poetry/poetry/pull/2064 config.merge({"virtualenvs": {"path": str(tmp_dir)}}) venv_name = manager.generate_env_name("simple-project", str(poetry.file.parent)) venv_path = Path(tmp_dir) / f"{venv_name}-py3.6" venv_path.mkdir() folder1_path = venv_path / "folder1" folder1_path.mkdir() file1_path = folder1_path / "file1" file1_path.touch(exist_ok=False) file2_path = venv_path / "file2" file2_path.touch(exist_ok=False) mocker.patch( "subprocess.check_output", side_effect=check_output_wrapper(Version.parse("3.6.6")), ) def err_on_rm_venv_only(path: Path | str, *args: Any, **kwargs: Any) -> None: if str(path) == str(venv_path): raise OSError(16, "Test error") # ERRNO 16: Device or resource busy else: remove_directory(path) m = mocker.patch("poetry.utils.env.remove_directory", side_effect=err_on_rm_venv_only) venv = manager.remove(f"{venv_name}-py3.6") m.assert_any_call(venv_path) assert venv_path == venv.path assert venv_path.exists() assert not folder1_path.exists() assert not file1_path.exists() assert not file2_path.exists() m.side_effect = remove_directory # Avoid teardown using `err_on_rm_venv_only`
def test_activate_activates_different_virtualenv_with_envs_file( tmp_dir: str, manager: EnvManager, poetry: Poetry, config: Config, mocker: MockerFixture, ): if "VIRTUAL_ENV" in os.environ: del os.environ["VIRTUAL_ENV"] venv_name = manager.generate_env_name("simple-project", str(poetry.file.parent)) envs_file = TOMLFile(Path(tmp_dir) / "envs.toml") doc = tomlkit.document() doc[venv_name] = {"minor": "3.7", "patch": "3.7.1"} envs_file.write(doc) os.mkdir(os.path.join(tmp_dir, f"{venv_name}-py3.7")) config.merge({"virtualenvs": {"path": str(tmp_dir)}}) mocker.patch( "subprocess.check_output", side_effect=check_output_wrapper(Version.parse("3.6.6")), ) mocker.patch( "subprocess.Popen.communicate", side_effect=[("/prefix", None), ("/prefix", None), ("/prefix", None)], ) m = mocker.patch("poetry.utils.env.EnvManager.build_venv", side_effect=build_venv) env = manager.activate("python3.6", NullIO()) m.assert_called_with( Path(tmp_dir) / f"{venv_name}-py3.6", executable="/usr/bin/python3.6", flags={ "always-copy": False, "system-site-packages": False, "no-pip": False, "no-setuptools": False, }, prompt="simple-project-py3.6", ) assert envs_file.exists() envs = envs_file.read() assert envs[venv_name]["minor"] == "3.6" assert envs[venv_name]["patch"] == "3.6.6" assert env.path == Path(tmp_dir) / f"{venv_name}-py3.6" assert env.base == Path("/prefix")
def test_list(tmp_dir: str, manager: EnvManager, poetry: Poetry, config: Config): config.merge({"virtualenvs": {"path": str(tmp_dir)}}) venv_name = manager.generate_env_name("simple-project", str(poetry.file.parent)) (Path(tmp_dir) / f"{venv_name}-py3.7").mkdir() (Path(tmp_dir) / f"{venv_name}-py3.6").mkdir() venvs = manager.list() assert len(venvs) == 2 assert venvs[0].path == (Path(tmp_dir) / f"{venv_name}-py3.6") assert venvs[1].path == (Path(tmp_dir) / f"{venv_name}-py3.7")
def test_authenticator_git_repositories( config: Config, mock_remote: None, http: type[httpretty.httpretty], with_simple_keyring: None, dummy_keyring: DummyBackend, ): config.merge({ "repositories": { "one": { "url": "https://foo.bar/org/one.git" }, "two": { "url": "https://foo.bar/org/two.git" }, }, "http-basic": { "one": { "username": "******", "password": "******" }, "two": { "username": "******", "password": "******" }, }, }) authenticator = Authenticator(config, NullIO()) one = authenticator.get_credentials_for_git_url( "https://foo.bar/org/one.git") assert one.username == "foo" assert one.password == "bar" two = authenticator.get_credentials_for_git_url( "https://foo.bar/org/two.git") assert two.username == "baz" assert two.password == "qux" two_ssh = authenticator.get_credentials_for_git_url( "ssh://[email protected]/org/two.git") assert not two_ssh.username assert not two_ssh.password three = authenticator.get_credentials_for_git_url( "https://foo.bar/org/three.git") assert not three.username assert not three.password
def test_authenticator_uses_env_provided_credentials( config: Config, environ: None, mock_remote: type[httpretty.httpretty], http: type[httpretty.httpretty], environment_repository_credentials: None, ): config.merge({"repositories": {"foo": {"url": "https://foo.bar/simple/"}}}) authenticator = Authenticator(config, NullIO()) authenticator.request("get", "https://foo.bar/files/foo-0.1.0.tar.gz") request = http.last_request() assert request.headers["Authorization"] == "Basic YmFyOmJheg=="
def test_activate_does_not_recreate_when_switching_minor( tmp_dir: str, manager: EnvManager, poetry: Poetry, config: Config, mocker: MockerFixture, ): if "VIRTUAL_ENV" in os.environ: del os.environ["VIRTUAL_ENV"] venv_name = manager.generate_env_name("simple-project", str(poetry.file.parent)) envs_file = TOMLFile(Path(tmp_dir) / "envs.toml") doc = tomlkit.document() doc[venv_name] = {"minor": "3.7", "patch": "3.7.0"} envs_file.write(doc) os.mkdir(os.path.join(tmp_dir, f"{venv_name}-py3.7")) os.mkdir(os.path.join(tmp_dir, f"{venv_name}-py3.6")) config.merge({"virtualenvs": {"path": str(tmp_dir)}}) mocker.patch( "subprocess.check_output", side_effect=check_output_wrapper(Version.parse("3.6.6")), ) mocker.patch( "subprocess.Popen.communicate", side_effect=[("/prefix", None), ("/prefix", None), ("/prefix", None)], ) build_venv_m = mocker.patch("poetry.utils.env.EnvManager.build_venv", side_effect=build_venv) remove_venv_m = mocker.patch("poetry.utils.env.EnvManager.remove_venv", side_effect=EnvManager.remove_venv) env = manager.activate("python3.6", NullIO()) build_venv_m.assert_not_called() remove_venv_m.assert_not_called() assert envs_file.exists() envs = envs_file.read() assert envs[venv_name]["minor"] == "3.6" assert envs[venv_name]["patch"] == "3.6.6" assert env.path == Path(tmp_dir) / f"{venv_name}-py3.6" assert env.base == Path("/prefix") assert (Path(tmp_dir) / f"{venv_name}-py3.6").exists()
def test_authenticator_uses_credentials_from_config_if_not_provided( config: Config, mock_remote: None, http: type[httpretty.httpretty] ): config.merge( { "repositories": {"foo": {"url": "https://foo.bar/simple/"}}, "http-basic": {"foo": {"username": "******", "password": "******"}}, } ) authenticator = Authenticator(config, NullIO()) authenticator.request("get", "https://foo.bar/files/foo-0.1.0.tar.gz") request = http.last_request() assert request.headers["Authorization"] == "Basic YmFyOmJheg=="
def test_authenticator_azure_feed_guid_credentials( config: Config, mock_remote: None, http: type[httpretty.httpretty], with_simple_keyring: None, dummy_keyring: DummyBackend, ): config.merge({ "repositories": { "alpha": { "url": "https://foo.bar/org-alpha/_packaging/feed/pypi/simple/" }, "beta": { "url": "https://foo.bar/org-beta/_packaging/feed/pypi/simple/" }, }, "http-basic": { "alpha": { "username": "******", "password": "******" }, "beta": { "username": "******", "password": "******" }, }, }) authenticator = Authenticator(config, NullIO()) authenticator.request( "get", "https://foo.bar/org-alpha/_packaging/GUID/pypi/simple/a/1.0.0/a-1.0.0.whl", ) request = http.last_request() basic_auth = base64.b64encode(b"foo:bar").decode() assert request.headers["Authorization"] == f"Basic {basic_auth}" authenticator.request( "get", "https://foo.bar/org-beta/_packaging/GUID/pypi/simple/b/1.0.0/a-1.0.0.whl", ) request = http.last_request() basic_auth = base64.b64encode(b"baz:qux").decode() assert request.headers["Authorization"] == f"Basic {basic_auth}"
def test_repository_certificate_configuration_create( ca_cert: str | bool | None, client_cert: str | None, result: RepositoryCertificateConfig, config: Config, ) -> None: cert_config = {} if ca_cert is not None: cert_config["cert"] = ca_cert if client_cert is not None: cert_config["client-cert"] = client_cert config.merge({"certificates": {"foo": cert_config}}) assert RepositoryCertificateConfig.create("foo", config) == result
def test_authenticator_uses_env_provided_credentials( config: Config, environ: None, mock_remote: type[httpretty.httpretty], http: type[httpretty.httpretty], monkeypatch: MonkeyPatch, ): monkeypatch.setenv("POETRY_HTTP_BASIC_FOO_USERNAME", "bar") monkeypatch.setenv("POETRY_HTTP_BASIC_FOO_PASSWORD", "baz") config.merge({"repositories": {"foo": {"url": "https://foo.bar/simple/"}}}) authenticator = Authenticator(config, NullIO()) authenticator.request("get", "https://foo.bar/files/foo-0.1.0.tar.gz") request = http.last_request() assert request.headers["Authorization"] == "Basic YmFyOmJheg=="
def test_deactivate_activated( tmp_dir: str, manager: EnvManager, poetry: Poetry, config: Config, mocker: MockerFixture, ): if "VIRTUAL_ENV" in os.environ: del os.environ["VIRTUAL_ENV"] venv_name = manager.generate_env_name("simple-project", str(poetry.file.parent)) version = Version.from_parts(*sys.version_info[:3]) other_version = Version.parse( "3.4") if version.major == 2 else version.next_minor() (Path(tmp_dir) / f"{venv_name}-py{version.major}.{version.minor}").mkdir() (Path(tmp_dir) / f"{venv_name}-py{other_version.major}.{other_version.minor}").mkdir() envs_file = TOMLFile(Path(tmp_dir) / "envs.toml") doc = tomlkit.document() doc[venv_name] = { "minor": f"{other_version.major}.{other_version.minor}", "patch": other_version.text, } envs_file.write(doc) config.merge({"virtualenvs": {"path": str(tmp_dir)}}) mocker.patch( "subprocess.check_output", side_effect=check_output_wrapper(), ) manager.deactivate(NullIO()) env = manager.get() assert env.path == Path( tmp_dir) / f"{venv_name}-py{version.major}.{version.minor}" assert Path("/prefix") envs = envs_file.read() assert len(envs) == 0
def test_activate_with_in_project_setting_does_not_fail_if_no_venvs_dir( manager: EnvManager, poetry: Poetry, config: Config, tmp_dir: str, mocker: MockerFixture, ): if "VIRTUAL_ENV" in os.environ: del os.environ["VIRTUAL_ENV"] config.merge({ "virtualenvs": { "path": str(Path(tmp_dir) / "virtualenvs"), "in-project": True, } }) mocker.patch( "subprocess.check_output", side_effect=check_output_wrapper(), ) mocker.patch( "subprocess.Popen.communicate", side_effect=[("/prefix", None), ("/prefix", None)], ) m = mocker.patch("poetry.utils.env.EnvManager.build_venv") manager.activate("python3.7", NullIO()) m.assert_called_with( poetry.file.parent / ".venv", executable="/usr/bin/python3.7", flags={ "always-copy": False, "system-site-packages": False, "no-pip": False, "no-setuptools": False, }, prompt="simple-project-py3.7", ) envs_file = TOMLFile(Path(tmp_dir) / "virtualenvs" / "envs.toml") assert not envs_file.exists()
def test_configured_repository_http_auth( mocker: MockerFixture, source_url: str, config: Config ) -> None: from poetry.vcs.git import backend spy_clone_legacy = mocker.spy(Git, "_clone_legacy") spy_get_transport_and_path = mocker.spy(backend, "get_transport_and_path") config.merge( { "repositories": {"git-repo": {"url": source_url}}, "http-basic": { "git-repo": { "username": GIT_USERNAME, "password": GIT_PASSWORD, } }, } ) dummy_git_config = ConfigFile() mocker.patch( "poetry.vcs.git.backend.Repo.get_config_stack", return_value=dummy_git_config, ) mocker.patch( "poetry.vcs.git.backend.get_default_authenticator", return_value=Authenticator(config=config), ) with Git.clone(url=source_url, branch="0.1") as repo: assert_version(repo, BRANCH_TO_REVISION_MAP["0.1"]) spy_clone_legacy.assert_not_called() spy_get_transport_and_path.assert_called_with( location=source_url, config=dummy_git_config, username=GIT_USERNAME, password=GIT_PASSWORD, ) spy_get_transport_and_path.assert_called_once()
def test_authenticator_falls_back_to_keyring_netloc( config: Config, mock_remote: None, repo: dict[str, dict[str, str]], http: type[httpretty.httpretty], with_simple_keyring: None, dummy_keyring: DummyBackend, ): config.merge({ "repositories": repo, }) dummy_keyring.set_password("foo.bar", None, SimpleCredential(None, "bar")) authenticator = Authenticator(config, NullIO()) authenticator.request("get", "https://foo.bar/files/foo-0.1.0.tar.gz") request = http.last_request() assert request.headers["Authorization"] == "Basic OmJhcg=="
def test_authenticator_uses_credentials_from_config_matched_by_url_path( config: Config, mock_remote: None, http: type[httpretty.httpretty]): config.merge({ "repositories": { "foo-alpha": { "url": "https://foo.bar/alpha/files/simple/" }, "foo-beta": { "url": "https://foo.bar/beta/files/simple/" }, }, "http-basic": { "foo-alpha": { "username": "******", "password": "******" }, "foo-beta": { "username": "******", "password": "******" }, }, }) authenticator = Authenticator(config, NullIO()) authenticator.request( "get", "https://foo.bar/alpha/files/simple/foo-0.1.0.tar.gz") request = http.last_request() basic_auth = base64.b64encode(b"bar:alpha").decode() assert request.headers["Authorization"] == f"Basic {basic_auth}" # Make request on second repository with the same netloc but different credentials authenticator.request( "get", "https://foo.bar/beta/files/simple/foo-0.1.0.tar.gz") request = http.last_request() basic_auth = base64.b64encode(b"baz:beta").decode() assert request.headers["Authorization"] == f"Basic {basic_auth}"
def test_activate_activates_existing_virtualenv_no_envs_file( tmp_dir: str, manager: EnvManager, poetry: Poetry, config: Config, mocker: MockerFixture, ): if "VIRTUAL_ENV" in os.environ: del os.environ["VIRTUAL_ENV"] venv_name = manager.generate_env_name("simple-project", str(poetry.file.parent)) os.mkdir(os.path.join(tmp_dir, f"{venv_name}-py3.7")) config.merge({"virtualenvs": {"path": str(tmp_dir)}}) mocker.patch( "subprocess.check_output", side_effect=check_output_wrapper(), ) mocker.patch( "subprocess.Popen.communicate", side_effect=[("/prefix", None)], ) m = mocker.patch("poetry.utils.env.EnvManager.build_venv", side_effect=build_venv) env = manager.activate("python3.7", NullIO()) m.assert_not_called() envs_file = TOMLFile(Path(tmp_dir) / "envs.toml") assert envs_file.exists() envs = envs_file.read() assert envs[venv_name]["minor"] == "3.7" assert envs[venv_name]["patch"] == "3.7.1" assert env.path == Path(tmp_dir) / f"{venv_name}-py3.7" assert env.base == Path("/prefix")
def test_authenticator_uses_empty_strings_as_default_username( config: Config, mock_remote: None, repo: dict[str, dict[str, str]], http: type[httpretty.httpretty], ): config.merge({ "repositories": repo, "http-basic": { "foo": { "username": None, "password": "******" } }, }) authenticator = Authenticator(config, NullIO()) authenticator.request("get", "https://foo.bar/files/foo-0.1.0.tar.gz") request = http.last_request() assert request.headers["Authorization"] == "Basic OmJhcg=="
def test_authenticator_uses_env_provided_credentials_matched_by_url_path( config: Config, environ: None, mock_remote: type[httpretty.httpretty], http: type[httpretty.httpretty], monkeypatch: MonkeyPatch, ): monkeypatch.setenv("POETRY_HTTP_BASIC_FOO_ALPHA_USERNAME", "bar") monkeypatch.setenv("POETRY_HTTP_BASIC_FOO_ALPHA_PASSWORD", "alpha") monkeypatch.setenv("POETRY_HTTP_BASIC_FOO_BETA_USERNAME", "baz") monkeypatch.setenv("POETRY_HTTP_BASIC_FOO_BETA_PASSWORD", "beta") config.merge({ "repositories": { "foo-alpha": { "url": "https://foo.bar/alpha/files/simple/" }, "foo-beta": { "url": "https://foo.bar/beta/files/simple/" }, } }) authenticator = Authenticator(config, NullIO()) authenticator.request( "get", "https://foo.bar/alpha/files/simple/foo-0.1.0.tar.gz") request = http.last_request() basic_auth = base64.b64encode(b"bar:alpha").decode() assert request.headers["Authorization"] == f"Basic {basic_auth}" authenticator.request( "get", "https://foo.bar/beta/files/simple/foo-0.1.0.tar.gz") request = http.last_request() basic_auth = base64.b64encode(b"baz:beta").decode() assert request.headers["Authorization"] == f"Basic {basic_auth}"
def test_authenticator_falls_back_to_keyring_url_matched_by_path( config: Config, mock_remote: None, http: type[httpretty.httpretty], with_simple_keyring: None, dummy_keyring: DummyBackend, ): config.merge({ "repositories": { "foo-alpha": { "url": "https://foo.bar/alpha/files/simple/" }, "foo-beta": { "url": "https://foo.bar/beta/files/simple/" }, } }) dummy_keyring.set_password("https://foo.bar/alpha/files/simple/", None, SimpleCredential(None, "bar")) dummy_keyring.set_password("https://foo.bar/beta/files/simple/", None, SimpleCredential(None, "baz")) authenticator = Authenticator(config, NullIO()) authenticator.request( "get", "https://foo.bar/alpha/files/simple/foo-0.1.0.tar.gz") request = http.last_request() basic_auth = base64.b64encode(b":bar").decode() assert request.headers["Authorization"] == f"Basic {basic_auth}" authenticator.request( "get", "https://foo.bar/beta/files/simple/foo-0.1.0.tar.gz") request = http.last_request() basic_auth = base64.b64encode(b":baz").decode() assert request.headers["Authorization"] == f"Basic {basic_auth}"