diff --git a/silkaj/cli.py b/silkaj/cli.py index fb4c0c86058eebee1937e6b07033c9dfcae83699..1d2744588c778373b70f3ea256449ae5a196f5d2 100644 --- a/silkaj/cli.py +++ b/silkaj/cli.py @@ -97,6 +97,13 @@ from silkaj.constants import ( help="By-pass licence, confirmation. \ Do not send the document, but display it instead", ) +@option( + "--g1-license-web", + "-w", + is_flag=True, + help="Display Ğ1 monetary license in a web browser if not running on a headless system. \ +Defaults to terminal display.", +) @pass_context def cli( ctx, @@ -110,6 +117,7 @@ def cli( auth_wif, display, dry_run, + g1_license_web, ): if display and dry_run: sys.exit("ERROR: display and dry-run options can not be used together") @@ -126,6 +134,7 @@ def cli( ctx.obj["AUTH_WIF"] = auth_wif ctx.obj["DISPLAY_DOCUMENT"] = display ctx.obj["DRY_RUN"] = dry_run + ctx.obj["G1_LICENSE_WEB"] = g1_license_web cli.add_command(argos_info) diff --git a/silkaj/license.py b/silkaj/license.py index 0f06e0a756a72980445b9e859d8551c648b40f2a..9e44d234335c7098bb7f32f2480d88847c6608e6 100644 --- a/silkaj/license.py +++ b/silkaj/license.py @@ -17,9 +17,20 @@ along with Silkaj. If not, see <https://www.gnu.org/licenses/>. import click import webbrowser +from pathlib import Path +import g1_monetary_license as gml -def license_approval(currency): + +languages = ["es", "en", "eo", "fr", "pt"] + +licenses_urls = { + "en": "https://duniter.org/en/wiki/g1-license/", + "fr": "https://duniter.org/fr/wiki/licence-g1/", +} + + +def license_approval(currency: str) -> None: if currency != "g1": return if click.confirm( @@ -29,16 +40,46 @@ def license_approval(currency): click.confirm("Do you approve Ğ1 license?", abort=True) -@click.command("license", help="Display Ğ1 license") -def license_command(): +@click.command("license", help="Display Ğ1 monetary license") +def license_command() -> None: display_license() -def display_license(): - language = input("In which language would you like to display Ğ1 license [en/fr]? ") - if language == "en": - if not webbrowser.open("https://duniter.org/en/wiki/g1-license/"): - click.echo_via_pager(open("licence-G1/license/license_g1-en.rst").read()) +@click.pass_context +def display_license(ctx) -> None: + """ + Display in web browser if flag set and not headless system + Otherwise, display in the terminal + """ + if ctx.obj["G1_LICENSE_WEB"] and has_web_browser(): + languages_choices = list(licenses_urls.keys()) + language = language_prompt(languages_choices) + webbrowser.open(licenses_urls[language]) else: - if not webbrowser.open("https://duniter.org/fr/wiki/licence-g1/"): - click.echo_via_pager(open("licence-G1/license/license_g1-fr-FR.rst").read()) + language = language_prompt(languages) + path = license_path(language) + with open(path) as license: + click.echo_via_pager(license.read()) + + +def has_web_browser() -> bool: + try: + webbrowser.get() + return True + except webbrowser.Error: + return False + + +def language_prompt(languages_choices: list) -> str: + return click.prompt( + f"In which language would you like to display the Ğ1 monetary license?", + type=click.Choice(languages_choices), + show_choices=True, + show_default=True, + default="en", + ) + + +def license_path(lang: str) -> Path: + path = gml.__path__.__dict__["_path"][0] # type: ignore # mypy issue #1422 + return Path(path, f"g1_monetary_license_{lang}.rst") diff --git a/tests/test_license.py b/tests/test_license.py new file mode 100644 index 0000000000000000000000000000000000000000..49a6c36e74b712f92d076a5a42b02fc7562d69e2 --- /dev/null +++ b/tests/test_license.py @@ -0,0 +1,109 @@ +""" +Copyright 2016-2021 Maël Azimi <m.a@moul.re> + +Silkaj is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Silkaj is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with Silkaj. If not, see <https://www.gnu.org/licenses/>. +""" + +import pytest +from unittest.mock import patch +from click.testing import CliRunner + +import webbrowser +from pathlib import Path + +from silkaj import cli, license +from silkaj.constants import SUCCESS_EXIT_STATUS + + +def test_license_approval_g1_test(capsys): + license.license_approval("g1-test") + assert not capsys.readouterr().out + + +# TODO: approve is not tested +@pytest.mark.parametrize( + "display, approve", + [ + (True, True), + (True, False), + (False, True), + (False, False), + ], +) +@patch("click.confirm") +@patch.object(license, "display_license") +def test_license_approval_g1(mock_display_license, mock_confirm, display, approve): + # https://stackoverflow.com/a/62939130 + mock_confirm.return_value = display + license.license_approval("g1") + if display: + mock_display_license.assert_called_once() + mock_confirm.assert_called() + + +@pytest.mark.parametrize( + "language, web, license_sample", + [ + ("en", False, "**Currency licensing"), + ("fr", False, "**Licence de la monnaie"), + ("en", True, "**Currency licensing"), + ("fr", True, "**Licence de la monnaie"), + ], +) +@patch("webbrowser.open") +def test_display_license(webbrowser_open, language, web, license_sample): + args = [] + if web: + args += ["--g1-license-web"] + args += ["license"] + + result = CliRunner().invoke(cli.cli, args=args, input=language) + assert "In which language" in result.output + if web and license.has_web_browser(): + webbrowser_open.assert_called_once_with(license.licenses_urls[language]) + else: + assert license_sample in result.output + assert result.exit_code == SUCCESS_EXIT_STATUS + + +def test_has_web_browser(): + """ + https://stackoverflow.com/a/50990039 + """ + with patch("webbrowser.get", side_effect=webbrowser.Error): + assert not license.has_web_browser() + + with patch("webbrowser.get", side_effect=None): + assert license.has_web_browser() + + +@pytest.mark.parametrize( + "language, license_sample", + [ + ("en", "**Currency licensing"), + ("", "**Currency licensing"), + ("fr", "**Licence de la monnaie"), + ("blabla", ""), + ], +) +def test_language_prompt(language, license_sample): + result = CliRunner().invoke(cli.cli, args=["license"], input=language) + assert "In which language" in result.output + assert license_sample in result.output + assert result.exit_code == SUCCESS_EXIT_STATUS + + +def test_license_path(): + for lang in license.languages: + assert license.license_path(lang).is_file()