dclient auth remove command, plus tests

This commit is contained in:
Simon Willison 2023-07-17 16:23:14 -07:00
commit 113ed48986
2 changed files with 62 additions and 7 deletions

View file

@ -95,10 +95,10 @@ def list_(_json):
click.echo(f"{alias} = {url}")
@alias.command()
@alias.command(name="add")
@click.argument("name")
@click.argument("url")
def add(name, url):
def alias_add(name, url):
"Add an alias"
config_dir = get_config_dir()
config_dir.mkdir(parents=True, exist_ok=True)
@ -108,9 +108,9 @@ def add(name, url):
aliases_file.write_text(json.dumps(aliases, indent=4))
@alias.command()
@alias.command(name="remove")
@click.argument("name")
def remove(name):
def alias_remove(name):
"Remove an alias"
config_dir = get_config_dir()
aliases_file = config_dir / "aliases.json"
@ -127,10 +127,10 @@ def auth():
"Manage authentication for different instances"
@auth.command()
@auth.command(name="add")
@click.argument("alias_or_url")
@click.option("--token", prompt=True, hide_input=True)
def add(alias_or_url, token):
def auth_add(alias_or_url, token):
"""
Add an authentication token for an alias or URL
@ -155,7 +155,7 @@ def add(alias_or_url, token):
@auth.command(name="list")
def list_():
def auth_list():
"List stored API tokens"
auths_file = get_config_dir() / "auth.json"
click.echo("Tokens file: {}".format(auths_file))
@ -166,6 +166,20 @@ def list_():
click.echo("{}:\t{}..".format(url, token[:1]))
@auth.command(name="remove")
@click.argument("alias_or_url")
def auth_remove(alias_or_url):
"Remove the API token for an alias or URL"
config_dir = get_config_dir()
auth_file = config_dir / "auth.json"
auths = _load_auths(auth_file)
try:
del auths[alias_or_url]
auth_file.write_text(json.dumps(auths, indent=4))
except KeyError:
raise click.ClickException("No such URL or alias")
def _load_aliases(aliases_file):
if aliases_file.exists():
aliases = json.loads(aliases_file.read_text())

41
tests/test_cli_auth.py Normal file
View file

@ -0,0 +1,41 @@
from click.testing import CliRunner
from dclient.cli import cli
import pathlib
import json
def test_auth(mocker, tmpdir):
mocker.patch("dclient.cli.get_config_dir", return_value=pathlib.Path(tmpdir))
runner = CliRunner()
result = runner.invoke(cli, ["auth", "list"])
assert result.exit_code == 0
assert result.output.startswith("Tokens file:")
# Should only have one line
assert len([line for line in result.output.split("\n") if line.strip()]) == 1
# Now add a token
result2 = runner.invoke(cli, ["auth", "add", "https://example.com"], input="xyz\n")
assert result2.exit_code == 0
# Check the tokens file
auth_file = pathlib.Path(tmpdir) / "auth.json"
assert json.loads(auth_file.read_text()) == {"https://example.com": "xyz"}
# auth list should show that now
result3 = runner.invoke(cli, ["auth", "list"])
assert result3.output.startswith("Tokens file:")
assert "https://example.com" in result3.output
# Remove should fail with an incorrect URL
result4 = runner.invoke(cli, ["auth", "remove", "https://example.com/foo"])
assert result4.exit_code == 1
assert result4.output == "Error: No such URL or alias\n"
# Remove should work with the correct URL
result5 = runner.invoke(cli, ["auth", "remove", "https://example.com"])
assert result5.exit_code == 0
assert result5.output == ""
# Check the tokens file
auth_file = pathlib.Path(tmpdir) / "auth.json"
assert json.loads(auth_file.read_text()) == {}