[fix] Question tests

This commit is contained in:
ljf 2021-09-07 20:09:27 +02:00
parent 6b3af5fa33
commit b007102842
3 changed files with 331 additions and 199 deletions

View file

@ -84,9 +84,12 @@ def pytest_cmdline_main(config):
class DummyInterface: class DummyInterface:
type = "test" type = "cli"
def prompt(*args, **kwargs): def prompt(self, *args, **kwargs):
raise NotImplementedError raise NotImplementedError
def display(self, message, *args, **kwargs):
print(message)
Moulinette._interface = DummyInterface() Moulinette._interface = DummyInterface()

View file

@ -1,14 +1,19 @@
import sys import sys
import pytest import pytest
import os
from mock import patch from mock import patch, MagicMock
from io import StringIO from io import StringIO
from collections import OrderedDict from collections import OrderedDict
from moulinette import Moulinette from moulinette import Moulinette
from yunohost import domain, user from yunohost import domain, user
from yunohost.utils.config import parse_args_in_yunohost_format, PasswordQuestion from yunohost.utils.config import (
parse_args_in_yunohost_format,
PasswordQuestion,
Question
)
from yunohost.utils.error import YunohostError from yunohost.utils.error import YunohostError
@ -70,7 +75,8 @@ def test_question_string_no_input():
] ]
answers = {} answers = {}
with pytest.raises(YunohostError): with pytest.raises(YunohostError), \
patch.object(os, "isatty", return_value=False):
parse_args_in_yunohost_format(answers, questions) parse_args_in_yunohost_format(answers, questions)
@ -84,7 +90,8 @@ def test_question_string_input():
answers = {} answers = {}
expected_result = OrderedDict({"some_string": ("some_value", "string")}) expected_result = OrderedDict({"some_string": ("some_value", "string")})
with patch.object(Moulinette.interface, "prompt", return_value="some_value"): with patch.object(Moulinette, "prompt", return_value="some_value"), \
patch.object(os, "isatty", return_value=True):
assert parse_args_in_yunohost_format(answers, questions) == expected_result assert parse_args_in_yunohost_format(answers, questions) == expected_result
@ -97,7 +104,8 @@ def test_question_string_input_no_ask():
answers = {} answers = {}
expected_result = OrderedDict({"some_string": ("some_value", "string")}) expected_result = OrderedDict({"some_string": ("some_value", "string")})
with patch.object(Moulinette.interface, "prompt", return_value="some_value"): with patch.object(Moulinette, "prompt", return_value="some_value"), \
patch.object(os, "isatty", return_value=True):
assert parse_args_in_yunohost_format(answers, questions) == expected_result assert parse_args_in_yunohost_format(answers, questions) == expected_result
@ -110,6 +118,7 @@ def test_question_string_no_input_optional():
] ]
answers = {} answers = {}
expected_result = OrderedDict({"some_string": ("", "string")}) expected_result = OrderedDict({"some_string": ("", "string")})
with patch.object(os, "isatty", return_value=False):
assert parse_args_in_yunohost_format(answers, questions) == expected_result assert parse_args_in_yunohost_format(answers, questions) == expected_result
@ -124,7 +133,8 @@ def test_question_string_optional_with_input():
answers = {} answers = {}
expected_result = OrderedDict({"some_string": ("some_value", "string")}) expected_result = OrderedDict({"some_string": ("some_value", "string")})
with patch.object(Moulinette.interface, "prompt", return_value="some_value"): with patch.object(Moulinette, "prompt", return_value="some_value"), \
patch.object(os, "isatty", return_value=True):
assert parse_args_in_yunohost_format(answers, questions) == expected_result assert parse_args_in_yunohost_format(answers, questions) == expected_result
@ -139,7 +149,8 @@ def test_question_string_optional_with_empty_input():
answers = {} answers = {}
expected_result = OrderedDict({"some_string": ("", "string")}) expected_result = OrderedDict({"some_string": ("", "string")})
with patch.object(Moulinette.interface, "prompt", return_value=""): with patch.object(Moulinette, "prompt", return_value=""), \
patch.object(os, "isatty", return_value=True):
assert parse_args_in_yunohost_format(answers, questions) == expected_result assert parse_args_in_yunohost_format(answers, questions) == expected_result
@ -153,7 +164,8 @@ def test_question_string_optional_with_input_without_ask():
answers = {} answers = {}
expected_result = OrderedDict({"some_string": ("some_value", "string")}) expected_result = OrderedDict({"some_string": ("some_value", "string")})
with patch.object(Moulinette.interface, "prompt", return_value="some_value"): with patch.object(Moulinette, "prompt", return_value="some_value"), \
patch.object(os, "isatty", return_value=True):
assert parse_args_in_yunohost_format(answers, questions) == expected_result assert parse_args_in_yunohost_format(answers, questions) == expected_result
@ -167,6 +179,7 @@ def test_question_string_no_input_default():
] ]
answers = {} answers = {}
expected_result = OrderedDict({"some_string": ("some_value", "string")}) expected_result = OrderedDict({"some_string": ("some_value", "string")})
with patch.object(os, "isatty", return_value=False):
assert parse_args_in_yunohost_format(answers, questions) == expected_result assert parse_args_in_yunohost_format(answers, questions) == expected_result
@ -181,10 +194,13 @@ def test_question_string_input_test_ask():
answers = {} answers = {}
with patch.object( with patch.object(
Moulinette.interface, "prompt", return_value="some_value" Moulinette, "prompt", return_value="some_value"
) as prompt: ) as prompt, patch.object(os, "isatty", return_value=True):
parse_args_in_yunohost_format(answers, questions) parse_args_in_yunohost_format(answers, questions)
prompt.assert_called_with(ask_text, False) prompt.assert_called_with(
message=ask_text, is_password=False, confirm=False,
prefill='', is_multiline=False
)
def test_question_string_input_test_ask_with_default(): def test_question_string_input_test_ask_with_default():
@ -200,10 +216,14 @@ def test_question_string_input_test_ask_with_default():
answers = {} answers = {}
with patch.object( with patch.object(
Moulinette.interface, "prompt", return_value="some_value" Moulinette, "prompt", return_value="some_value"
) as prompt: ) as prompt, patch.object(os, "isatty", return_value=True):
parse_args_in_yunohost_format(answers, questions) parse_args_in_yunohost_format(answers, questions)
prompt.assert_called_with("%s (default: %s)" % (ask_text, default_text), False) prompt.assert_called_with(
message=ask_text,
is_password=False, confirm=False,
prefill=default_text, is_multiline=False
)
@pytest.mark.skip # we should do something with this example @pytest.mark.skip # we should do something with this example
@ -220,11 +240,11 @@ def test_question_string_input_test_ask_with_example():
answers = {} answers = {}
with patch.object( with patch.object(
Moulinette.interface, "prompt", return_value="some_value" Moulinette, "prompt", return_value="some_value"
) as prompt: ) as prompt, patch.object(os, "isatty", return_value=True):
parse_args_in_yunohost_format(answers, questions) parse_args_in_yunohost_format(answers, questions)
assert ask_text in prompt.call_args[0][0] assert ask_text in prompt.call_args[1]['message']
assert example_text in prompt.call_args[0][0] assert example_text in prompt.call_args[1]['message']
@pytest.mark.skip # we should do something with this help @pytest.mark.skip # we should do something with this help
@ -241,11 +261,11 @@ def test_question_string_input_test_ask_with_help():
answers = {} answers = {}
with patch.object( with patch.object(
Moulinette.interface, "prompt", return_value="some_value" Moulinette, "prompt", return_value="some_value"
) as prompt: ) as prompt, patch.object(os, "isatty", return_value=True):
parse_args_in_yunohost_format(answers, questions) parse_args_in_yunohost_format(answers, questions)
assert ask_text in prompt.call_args[0][0] assert ask_text in prompt.call_args[1]['message']
assert help_text in prompt.call_args[0][0] assert help_text in prompt.call_args[1]['message']
def test_question_string_with_choice(): def test_question_string_with_choice():
@ -259,7 +279,8 @@ def test_question_string_with_choice_prompt():
questions = [{"name": "some_string", "type": "string", "choices": ["fr", "en"]}] questions = [{"name": "some_string", "type": "string", "choices": ["fr", "en"]}]
answers = {"some_string": "fr"} answers = {"some_string": "fr"}
expected_result = OrderedDict({"some_string": ("fr", "string")}) expected_result = OrderedDict({"some_string": ("fr", "string")})
with patch.object(Moulinette.interface, "prompt", return_value="fr"): with patch.object(Moulinette, "prompt", return_value="fr"), \
patch.object(os, "isatty", return_value=True):
assert parse_args_in_yunohost_format(answers, questions) == expected_result assert parse_args_in_yunohost_format(answers, questions) == expected_result
@ -267,7 +288,8 @@ def test_question_string_with_choice_bad():
questions = [{"name": "some_string", "type": "string", "choices": ["fr", "en"]}] questions = [{"name": "some_string", "type": "string", "choices": ["fr", "en"]}]
answers = {"some_string": "bad"} answers = {"some_string": "bad"}
with pytest.raises(YunohostError): with pytest.raises(YunohostError), \
patch.object(os, "isatty", return_value=False):
assert parse_args_in_yunohost_format(answers, questions) assert parse_args_in_yunohost_format(answers, questions)
@ -283,12 +305,13 @@ def test_question_string_with_choice_ask():
] ]
answers = {} answers = {}
with patch.object(Moulinette.interface, "prompt", return_value="ru") as prompt: with patch.object(Moulinette, "prompt", return_value="ru") as prompt, \
patch.object(os, "isatty", return_value=True):
parse_args_in_yunohost_format(answers, questions) parse_args_in_yunohost_format(answers, questions)
assert ask_text in prompt.call_args[0][0] assert ask_text in prompt.call_args[1]['message']
for choice in choices: for choice in choices:
assert choice in prompt.call_args[0][0] assert choice in prompt.call_args[1]['message']
def test_question_string_with_choice_default(): def test_question_string_with_choice_default():
@ -302,6 +325,7 @@ def test_question_string_with_choice_default():
] ]
answers = {} answers = {}
expected_result = OrderedDict({"some_string": ("en", "string")}) expected_result = OrderedDict({"some_string": ("en", "string")})
with patch.object(os, "isatty", return_value=False):
assert parse_args_in_yunohost_format(answers, questions) == expected_result assert parse_args_in_yunohost_format(answers, questions) == expected_result
@ -314,6 +338,8 @@ def test_question_password():
] ]
answers = {"some_password": "some_value"} answers = {"some_password": "some_value"}
expected_result = OrderedDict({"some_password": ("some_value", "password")}) expected_result = OrderedDict({"some_password": ("some_value", "password")})
Question.operation_logger = MagicMock()
with patch.object(Question.operation_logger, "data_to_redact", create=True):
assert parse_args_in_yunohost_format(answers, questions) == expected_result assert parse_args_in_yunohost_format(answers, questions) == expected_result
@ -326,7 +352,8 @@ def test_question_password_no_input():
] ]
answers = {} answers = {}
with pytest.raises(YunohostError): with pytest.raises(YunohostError), \
patch.object(os, "isatty", return_value=False):
parse_args_in_yunohost_format(answers, questions) parse_args_in_yunohost_format(answers, questions)
@ -339,9 +366,13 @@ def test_question_password_input():
} }
] ]
answers = {} answers = {}
Question.operation_logger = { 'data_to_redact': [] }
expected_result = OrderedDict({"some_password": ("some_value", "password")}) expected_result = OrderedDict({"some_password": ("some_value", "password")})
with patch.object(Moulinette.interface, "prompt", return_value="some_value"): Question.operation_logger = MagicMock()
with patch.object(Question.operation_logger, "data_to_redact", create=True), \
patch.object(Moulinette, "prompt", return_value="some_value"), \
patch.object(os, "isatty", return_value=True):
assert parse_args_in_yunohost_format(answers, questions) == expected_result assert parse_args_in_yunohost_format(answers, questions) == expected_result
@ -355,7 +386,10 @@ def test_question_password_input_no_ask():
answers = {} answers = {}
expected_result = OrderedDict({"some_password": ("some_value", "password")}) expected_result = OrderedDict({"some_password": ("some_value", "password")})
with patch.object(Moulinette.interface, "prompt", return_value="some_value"): Question.operation_logger = MagicMock()
with patch.object(Question.operation_logger, "data_to_redact", create=True), \
patch.object(Moulinette, "prompt", return_value="some_value"), \
patch.object(os, "isatty", return_value=True):
assert parse_args_in_yunohost_format(answers, questions) == expected_result assert parse_args_in_yunohost_format(answers, questions) == expected_result
@ -370,12 +404,18 @@ def test_question_password_no_input_optional():
answers = {} answers = {}
expected_result = OrderedDict({"some_password": ("", "password")}) expected_result = OrderedDict({"some_password": ("", "password")})
Question.operation_logger = MagicMock()
with patch.object(Question.operation_logger, "data_to_redact", create=True), \
patch.object(os, "isatty", return_value=False):
assert parse_args_in_yunohost_format(answers, questions) == expected_result assert parse_args_in_yunohost_format(answers, questions) == expected_result
questions = [ questions = [
{"name": "some_password", "type": "password", "optional": True, "default": ""} {"name": "some_password", "type": "password", "optional": True, "default": ""}
] ]
Question.operation_logger = MagicMock()
with patch.object(Question.operation_logger, "data_to_redact", create=True), \
patch.object(os, "isatty", return_value=False):
assert parse_args_in_yunohost_format(answers, questions) == expected_result assert parse_args_in_yunohost_format(answers, questions) == expected_result
@ -391,7 +431,10 @@ def test_question_password_optional_with_input():
answers = {} answers = {}
expected_result = OrderedDict({"some_password": ("some_value", "password")}) expected_result = OrderedDict({"some_password": ("some_value", "password")})
with patch.object(Moulinette.interface, "prompt", return_value="some_value"): Question.operation_logger = MagicMock()
with patch.object(Question.operation_logger, "data_to_redact", create=True), \
patch.object(Moulinette, "prompt", return_value="some_value"), \
patch.object(os, "isatty", return_value=True):
assert parse_args_in_yunohost_format(answers, questions) == expected_result assert parse_args_in_yunohost_format(answers, questions) == expected_result
@ -407,7 +450,10 @@ def test_question_password_optional_with_empty_input():
answers = {} answers = {}
expected_result = OrderedDict({"some_password": ("", "password")}) expected_result = OrderedDict({"some_password": ("", "password")})
with patch.object(Moulinette.interface, "prompt", return_value=""): Question.operation_logger = MagicMock()
with patch.object(Question.operation_logger, "data_to_redact", create=True), \
patch.object(Moulinette, "prompt", return_value=""), \
patch.object(os, "isatty", return_value=True):
assert parse_args_in_yunohost_format(answers, questions) == expected_result assert parse_args_in_yunohost_format(answers, questions) == expected_result
@ -422,7 +468,10 @@ def test_question_password_optional_with_input_without_ask():
answers = {} answers = {}
expected_result = OrderedDict({"some_password": ("some_value", "password")}) expected_result = OrderedDict({"some_password": ("some_value", "password")})
with patch.object(Moulinette.interface, "prompt", return_value="some_value"): Question.operation_logger = MagicMock()
with patch.object(Question.operation_logger, "data_to_redact", create=True), \
patch.object(Moulinette, "prompt", return_value="some_value"), \
patch.object(os, "isatty", return_value=True):
assert parse_args_in_yunohost_format(answers, questions) == expected_result assert parse_args_in_yunohost_format(answers, questions) == expected_result
@ -438,7 +487,8 @@ def test_question_password_no_input_default():
answers = {} answers = {}
# no default for password! # no default for password!
with pytest.raises(YunohostError): with pytest.raises(YunohostError), \
patch.object(os, "isatty", return_value=False):
parse_args_in_yunohost_format(answers, questions) parse_args_in_yunohost_format(answers, questions)
@ -455,7 +505,8 @@ def test_question_password_no_input_example():
answers = {"some_password": "some_value"} answers = {"some_password": "some_value"}
# no example for password! # no example for password!
with pytest.raises(YunohostError): with pytest.raises(YunohostError), \
patch.object(os, "isatty", return_value=False):
parse_args_in_yunohost_format(answers, questions) parse_args_in_yunohost_format(answers, questions)
@ -470,11 +521,16 @@ def test_question_password_input_test_ask():
] ]
answers = {} answers = {}
with patch.object( Question.operation_logger = MagicMock()
Moulinette.interface, "prompt", return_value="some_value" with patch.object(Question.operation_logger, "data_to_redact", create=True), \
) as prompt: patch.object(Moulinette, "prompt", return_value="some_value") as prompt, \
patch.object(os, "isatty", return_value=True):
parse_args_in_yunohost_format(answers, questions) parse_args_in_yunohost_format(answers, questions)
prompt.assert_called_with(ask_text, True) prompt.assert_called_with(
message=ask_text,
is_password=True, confirm=True,
prefill='', is_multiline=False
)
@pytest.mark.skip # we should do something with this example @pytest.mark.skip # we should do something with this example
@ -491,12 +547,13 @@ def test_question_password_input_test_ask_with_example():
] ]
answers = {} answers = {}
with patch.object( Question.operation_logger = MagicMock()
Moulinette.interface, "prompt", return_value="some_value" with patch.object(Question.operation_logger, "data_to_redact", create=True), \
) as prompt: patch.object(Moulinette, "prompt", return_value="some_value") as prompt, \
patch.object(os, "isatty", return_value=True):
parse_args_in_yunohost_format(answers, questions) parse_args_in_yunohost_format(answers, questions)
assert ask_text in prompt.call_args[0][0] assert ask_text in prompt.call_args[1]['message']
assert example_text in prompt.call_args[0][0] assert example_text in prompt.call_args[1]['message']
@pytest.mark.skip # we should do something with this help @pytest.mark.skip # we should do something with this help
@ -513,12 +570,13 @@ def test_question_password_input_test_ask_with_help():
] ]
answers = {} answers = {}
with patch.object( Question.operation_logger = MagicMock()
Moulinette.interface, "prompt", return_value="some_value" with patch.object(Question.operation_logger, "data_to_redact", create=True), \
) as prompt: patch.object(Moulinette, "prompt", return_value="some_value") as prompt, \
patch.object(os, "isatty", return_value=True):
parse_args_in_yunohost_format(answers, questions) parse_args_in_yunohost_format(answers, questions)
assert ask_text in prompt.call_args[0][0] assert ask_text in prompt.call_args[1]['message']
assert help_text in prompt.call_args[0][0] assert help_text in prompt.call_args[1]['message']
def test_question_password_bad_chars(): def test_question_password_bad_chars():
@ -532,7 +590,8 @@ def test_question_password_bad_chars():
] ]
for i in PasswordQuestion.forbidden_chars: for i in PasswordQuestion.forbidden_chars:
with pytest.raises(YunohostError): with pytest.raises(YunohostError), \
patch.object(os, "isatty", return_value=False):
parse_args_in_yunohost_format({"some_password": i * 8}, questions) parse_args_in_yunohost_format({"some_password": i * 8}, questions)
@ -546,11 +605,13 @@ def test_question_password_strong_enough():
} }
] ]
with pytest.raises(YunohostError): with pytest.raises(YunohostError), \
patch.object(os, "isatty", return_value=False):
# too short # too short
parse_args_in_yunohost_format({"some_password": "a"}, questions) parse_args_in_yunohost_format({"some_password": "a"}, questions)
with pytest.raises(YunohostError): with pytest.raises(YunohostError), \
patch.object(os, "isatty", return_value=False):
parse_args_in_yunohost_format({"some_password": "password"}, questions) parse_args_in_yunohost_format({"some_password": "password"}, questions)
@ -564,11 +625,13 @@ def test_question_password_optional_strong_enough():
} }
] ]
with pytest.raises(YunohostError): with pytest.raises(YunohostError), \
patch.object(os, "isatty", return_value=False):
# too short # too short
parse_args_in_yunohost_format({"some_password": "a"}, questions) parse_args_in_yunohost_format({"some_password": "a"}, questions)
with pytest.raises(YunohostError): with pytest.raises(YunohostError), \
patch.object(os, "isatty", return_value=False):
parse_args_in_yunohost_format({"some_password": "password"}, questions) parse_args_in_yunohost_format({"some_password": "password"}, questions)
@ -593,7 +656,8 @@ def test_question_path_no_input():
] ]
answers = {} answers = {}
with pytest.raises(YunohostError): with pytest.raises(YunohostError), \
patch.object(os, "isatty", return_value=False):
parse_args_in_yunohost_format(answers, questions) parse_args_in_yunohost_format(answers, questions)
@ -608,7 +672,8 @@ def test_question_path_input():
answers = {} answers = {}
expected_result = OrderedDict({"some_path": ("some_value", "path")}) expected_result = OrderedDict({"some_path": ("some_value", "path")})
with patch.object(Moulinette.interface, "prompt", return_value="some_value"): with patch.object(Moulinette, "prompt", return_value="some_value"), \
patch.object(os, "isatty", return_value=True):
assert parse_args_in_yunohost_format(answers, questions) == expected_result assert parse_args_in_yunohost_format(answers, questions) == expected_result
@ -622,7 +687,8 @@ def test_question_path_input_no_ask():
answers = {} answers = {}
expected_result = OrderedDict({"some_path": ("some_value", "path")}) expected_result = OrderedDict({"some_path": ("some_value", "path")})
with patch.object(Moulinette.interface, "prompt", return_value="some_value"): with patch.object(Moulinette, "prompt", return_value="some_value"), \
patch.object(os, "isatty", return_value=True):
assert parse_args_in_yunohost_format(answers, questions) == expected_result assert parse_args_in_yunohost_format(answers, questions) == expected_result
@ -636,6 +702,7 @@ def test_question_path_no_input_optional():
] ]
answers = {} answers = {}
expected_result = OrderedDict({"some_path": ("", "path")}) expected_result = OrderedDict({"some_path": ("", "path")})
with patch.object(os, "isatty", return_value=False):
assert parse_args_in_yunohost_format(answers, questions) == expected_result assert parse_args_in_yunohost_format(answers, questions) == expected_result
@ -651,7 +718,8 @@ def test_question_path_optional_with_input():
answers = {} answers = {}
expected_result = OrderedDict({"some_path": ("some_value", "path")}) expected_result = OrderedDict({"some_path": ("some_value", "path")})
with patch.object(Moulinette.interface, "prompt", return_value="some_value"): with patch.object(Moulinette, "prompt", return_value="some_value"), \
patch.object(os, "isatty", return_value=True):
assert parse_args_in_yunohost_format(answers, questions) == expected_result assert parse_args_in_yunohost_format(answers, questions) == expected_result
@ -667,7 +735,8 @@ def test_question_path_optional_with_empty_input():
answers = {} answers = {}
expected_result = OrderedDict({"some_path": ("", "path")}) expected_result = OrderedDict({"some_path": ("", "path")})
with patch.object(Moulinette.interface, "prompt", return_value=""): with patch.object(Moulinette, "prompt", return_value=""), \
patch.object(os, "isatty", return_value=True):
assert parse_args_in_yunohost_format(answers, questions) == expected_result assert parse_args_in_yunohost_format(answers, questions) == expected_result
@ -682,7 +751,8 @@ def test_question_path_optional_with_input_without_ask():
answers = {} answers = {}
expected_result = OrderedDict({"some_path": ("some_value", "path")}) expected_result = OrderedDict({"some_path": ("some_value", "path")})
with patch.object(Moulinette.interface, "prompt", return_value="some_value"): with patch.object(Moulinette, "prompt", return_value="some_value"), \
patch.object(os, "isatty", return_value=True):
assert parse_args_in_yunohost_format(answers, questions) == expected_result assert parse_args_in_yunohost_format(answers, questions) == expected_result
@ -697,6 +767,7 @@ def test_question_path_no_input_default():
] ]
answers = {} answers = {}
expected_result = OrderedDict({"some_path": ("some_value", "path")}) expected_result = OrderedDict({"some_path": ("some_value", "path")})
with patch.object(os, "isatty", return_value=False):
assert parse_args_in_yunohost_format(answers, questions) == expected_result assert parse_args_in_yunohost_format(answers, questions) == expected_result
@ -712,10 +783,14 @@ def test_question_path_input_test_ask():
answers = {} answers = {}
with patch.object( with patch.object(
Moulinette.interface, "prompt", return_value="some_value" Moulinette, "prompt", return_value="some_value"
) as prompt: ) as prompt, patch.object(os, "isatty", return_value=True):
parse_args_in_yunohost_format(answers, questions) parse_args_in_yunohost_format(answers, questions)
prompt.assert_called_with(ask_text, False) prompt.assert_called_with(
message=ask_text,
is_password=False, confirm=False,
prefill='', is_multiline=False
)
def test_question_path_input_test_ask_with_default(): def test_question_path_input_test_ask_with_default():
@ -732,10 +807,14 @@ def test_question_path_input_test_ask_with_default():
answers = {} answers = {}
with patch.object( with patch.object(
Moulinette.interface, "prompt", return_value="some_value" Moulinette, "prompt", return_value="some_value"
) as prompt: ) as prompt, patch.object(os, "isatty", return_value=True):
parse_args_in_yunohost_format(answers, questions) parse_args_in_yunohost_format(answers, questions)
prompt.assert_called_with("%s (default: %s)" % (ask_text, default_text), False) prompt.assert_called_with(
message=ask_text,
is_password=False, confirm=False,
prefill=default_text, is_multiline=False
)
@pytest.mark.skip # we should do something with this example @pytest.mark.skip # we should do something with this example
@ -753,11 +832,11 @@ def test_question_path_input_test_ask_with_example():
answers = {} answers = {}
with patch.object( with patch.object(
Moulinette.interface, "prompt", return_value="some_value" Moulinette, "prompt", return_value="some_value"
) as prompt: ) as prompt, patch.object(os, "isatty", return_value=True):
parse_args_in_yunohost_format(answers, questions) parse_args_in_yunohost_format(answers, questions)
assert ask_text in prompt.call_args[0][0] assert ask_text in prompt.call_args[1]['message']
assert example_text in prompt.call_args[0][0] assert example_text in prompt.call_args[1]['message']
@pytest.mark.skip # we should do something with this help @pytest.mark.skip # we should do something with this help
@ -775,11 +854,11 @@ def test_question_path_input_test_ask_with_help():
answers = {} answers = {}
with patch.object( with patch.object(
Moulinette.interface, "prompt", return_value="some_value" Moulinette, "prompt", return_value="some_value"
) as prompt: ) as prompt, patch.object(os, "isatty", return_value=True):
parse_args_in_yunohost_format(answers, questions) parse_args_in_yunohost_format(answers, questions)
assert ask_text in prompt.call_args[0][0] assert ask_text in prompt.call_args[1]['message']
assert help_text in prompt.call_args[0][0] assert help_text in prompt.call_args[1]['message']
def test_question_boolean(): def test_question_boolean():
@ -913,6 +992,7 @@ def test_question_boolean_no_input():
answers = {} answers = {}
expected_result = OrderedDict({"some_boolean": (0, "boolean")}) expected_result = OrderedDict({"some_boolean": (0, "boolean")})
with patch.object(os, "isatty", return_value=False):
assert parse_args_in_yunohost_format(answers, questions) == expected_result assert parse_args_in_yunohost_format(answers, questions) == expected_result
@ -925,7 +1005,8 @@ def test_question_boolean_bad_input():
] ]
answers = {"some_boolean": "stuff"} answers = {"some_boolean": "stuff"}
with pytest.raises(YunohostError): with pytest.raises(YunohostError), \
patch.object(os, "isatty", return_value=False):
parse_args_in_yunohost_format(answers, questions) parse_args_in_yunohost_format(answers, questions)
@ -940,11 +1021,13 @@ def test_question_boolean_input():
answers = {} answers = {}
expected_result = OrderedDict({"some_boolean": (1, "boolean")}) expected_result = OrderedDict({"some_boolean": (1, "boolean")})
with patch.object(Moulinette.interface, "prompt", return_value="y"): with patch.object(Moulinette, "prompt", return_value="y"), \
patch.object(os, "isatty", return_value=True):
assert parse_args_in_yunohost_format(answers, questions) == expected_result assert parse_args_in_yunohost_format(answers, questions) == expected_result
expected_result = OrderedDict({"some_boolean": (0, "boolean")}) expected_result = OrderedDict({"some_boolean": (0, "boolean")})
with patch.object(Moulinette.interface, "prompt", return_value="n"): with patch.object(Moulinette, "prompt", return_value="n"), \
patch.object(os, "isatty", return_value=True):
assert parse_args_in_yunohost_format(answers, questions) == expected_result assert parse_args_in_yunohost_format(answers, questions) == expected_result
@ -958,7 +1041,8 @@ def test_question_boolean_input_no_ask():
answers = {} answers = {}
expected_result = OrderedDict({"some_boolean": (1, "boolean")}) expected_result = OrderedDict({"some_boolean": (1, "boolean")})
with patch.object(Moulinette.interface, "prompt", return_value="y"): with patch.object(Moulinette, "prompt", return_value="y"), \
patch.object(os, "isatty", return_value=True):
assert parse_args_in_yunohost_format(answers, questions) == expected_result assert parse_args_in_yunohost_format(answers, questions) == expected_result
@ -972,6 +1056,7 @@ def test_question_boolean_no_input_optional():
] ]
answers = {} answers = {}
expected_result = OrderedDict({"some_boolean": (0, "boolean")}) # default to false expected_result = OrderedDict({"some_boolean": (0, "boolean")}) # default to false
with patch.object(os, "isatty", return_value=False):
assert parse_args_in_yunohost_format(answers, questions) == expected_result assert parse_args_in_yunohost_format(answers, questions) == expected_result
@ -987,7 +1072,8 @@ def test_question_boolean_optional_with_input():
answers = {} answers = {}
expected_result = OrderedDict({"some_boolean": (1, "boolean")}) expected_result = OrderedDict({"some_boolean": (1, "boolean")})
with patch.object(Moulinette.interface, "prompt", return_value="y"): with patch.object(Moulinette, "prompt", return_value="y"), \
patch.object(os, "isatty", return_value=True):
assert parse_args_in_yunohost_format(answers, questions) == expected_result assert parse_args_in_yunohost_format(answers, questions) == expected_result
@ -1003,7 +1089,8 @@ def test_question_boolean_optional_with_empty_input():
answers = {} answers = {}
expected_result = OrderedDict({"some_boolean": (0, "boolean")}) # default to false expected_result = OrderedDict({"some_boolean": (0, "boolean")}) # default to false
with patch.object(Moulinette.interface, "prompt", return_value=""): with patch.object(Moulinette, "prompt", return_value=""), \
patch.object(os, "isatty", return_value=True):
assert parse_args_in_yunohost_format(answers, questions) == expected_result assert parse_args_in_yunohost_format(answers, questions) == expected_result
@ -1018,7 +1105,8 @@ def test_question_boolean_optional_with_input_without_ask():
answers = {} answers = {}
expected_result = OrderedDict({"some_boolean": (0, "boolean")}) expected_result = OrderedDict({"some_boolean": (0, "boolean")})
with patch.object(Moulinette.interface, "prompt", return_value="n"): with patch.object(Moulinette, "prompt", return_value="n"), \
patch.object(os, "isatty", return_value=True):
assert parse_args_in_yunohost_format(answers, questions) == expected_result assert parse_args_in_yunohost_format(answers, questions) == expected_result
@ -1033,6 +1121,7 @@ def test_question_boolean_no_input_default():
] ]
answers = {} answers = {}
expected_result = OrderedDict({"some_boolean": (0, "boolean")}) expected_result = OrderedDict({"some_boolean": (0, "boolean")})
with patch.object(os, "isatty", return_value=False):
assert parse_args_in_yunohost_format(answers, questions) == expected_result assert parse_args_in_yunohost_format(answers, questions) == expected_result
@ -1061,9 +1150,14 @@ def test_question_boolean_input_test_ask():
] ]
answers = {} answers = {}
with patch.object(Moulinette.interface, "prompt", return_value=0) as prompt: with patch.object(Moulinette, "prompt", return_value=0) as prompt, \
patch.object(os, "isatty", return_value=True):
parse_args_in_yunohost_format(answers, questions) parse_args_in_yunohost_format(answers, questions)
prompt.assert_called_with(ask_text + " [yes | no] (default: no)", False) prompt.assert_called_with(
message=ask_text + " [yes | no]",
is_password=False, confirm=False,
prefill='no', is_multiline=False
)
def test_question_boolean_input_test_ask_with_default(): def test_question_boolean_input_test_ask_with_default():
@ -1079,9 +1173,14 @@ def test_question_boolean_input_test_ask_with_default():
] ]
answers = {} answers = {}
with patch.object(Moulinette.interface, "prompt", return_value=1) as prompt: with patch.object(Moulinette, "prompt", return_value=1) as prompt, \
patch.object(os, "isatty", return_value=True):
parse_args_in_yunohost_format(answers, questions) parse_args_in_yunohost_format(answers, questions)
prompt.assert_called_with("%s [yes | no] (default: yes)" % ask_text, False) prompt.assert_called_with(
message=ask_text + " [yes | no]",
is_password=False, confirm=False,
prefill='yes', is_multiline=False
)
def test_question_domain_empty(): def test_question_domain_empty():
@ -1095,9 +1194,9 @@ def test_question_domain_empty():
expected_result = OrderedDict({"some_domain": (main_domain, "domain")}) expected_result = OrderedDict({"some_domain": (main_domain, "domain")})
answers = {} answers = {}
with patch.object( with patch.object(domain, "_get_maindomain", return_value="my_main_domain.com"),\
domain, "_get_maindomain", return_value="my_main_domain.com" patch.object(domain, "domain_list", return_value={"domains": [main_domain]}), \
), patch.object(domain, "domain_list", return_value={"domains": [main_domain]}): patch.object(os, "isatty", return_value=False):
assert parse_args_in_yunohost_format(answers, questions) == expected_result assert parse_args_in_yunohost_format(answers, questions) == expected_result
@ -1164,7 +1263,8 @@ def test_question_domain_two_domains_wrong_answer():
with patch.object( with patch.object(
domain, "_get_maindomain", return_value=main_domain domain, "_get_maindomain", return_value=main_domain
), patch.object(domain, "domain_list", return_value={"domains": domains}): ), patch.object(domain, "domain_list", return_value={"domains": domains}):
with pytest.raises(YunohostError): with pytest.raises(YunohostError), \
patch.object(os, "isatty", return_value=False):
parse_args_in_yunohost_format(answers, questions) parse_args_in_yunohost_format(answers, questions)
@ -1184,7 +1284,8 @@ def test_question_domain_two_domains_default_no_ask():
with patch.object( with patch.object(
domain, "_get_maindomain", return_value=main_domain domain, "_get_maindomain", return_value=main_domain
), patch.object(domain, "domain_list", return_value={"domains": domains}): ), patch.object(domain, "domain_list", return_value={"domains": domains}), \
patch.object(os, "isatty", return_value=False):
assert parse_args_in_yunohost_format(answers, questions) == expected_result assert parse_args_in_yunohost_format(answers, questions) == expected_result
@ -1199,7 +1300,8 @@ def test_question_domain_two_domains_default():
with patch.object( with patch.object(
domain, "_get_maindomain", return_value=main_domain domain, "_get_maindomain", return_value=main_domain
), patch.object(domain, "domain_list", return_value={"domains": domains}): ), patch.object(domain, "domain_list", return_value={"domains": domains}), \
patch.object(os, "isatty", return_value=False):
assert parse_args_in_yunohost_format(answers, questions) == expected_result assert parse_args_in_yunohost_format(answers, questions) == expected_result
@ -1213,13 +1315,14 @@ def test_question_domain_two_domains_default_input():
with patch.object( with patch.object(
domain, "_get_maindomain", return_value=main_domain domain, "_get_maindomain", return_value=main_domain
), patch.object(domain, "domain_list", return_value={"domains": domains}): ), patch.object(domain, "domain_list", return_value={"domains": domains}), \
patch.object(os, "isatty", return_value=True):
expected_result = OrderedDict({"some_domain": (main_domain, "domain")}) expected_result = OrderedDict({"some_domain": (main_domain, "domain")})
with patch.object(Moulinette.interface, "prompt", return_value=main_domain): with patch.object(Moulinette, "prompt", return_value=main_domain):
assert parse_args_in_yunohost_format(answers, questions) == expected_result assert parse_args_in_yunohost_format(answers, questions) == expected_result
expected_result = OrderedDict({"some_domain": (other_domain, "domain")}) expected_result = OrderedDict({"some_domain": (other_domain, "domain")})
with patch.object(Moulinette.interface, "prompt", return_value=other_domain): with patch.object(Moulinette, "prompt", return_value=other_domain):
assert parse_args_in_yunohost_format(answers, questions) == expected_result assert parse_args_in_yunohost_format(answers, questions) == expected_result
@ -1243,7 +1346,8 @@ def test_question_user_empty():
answers = {} answers = {}
with patch.object(user, "user_list", return_value={"users": users}): with patch.object(user, "user_list", return_value={"users": users}):
with pytest.raises(YunohostError): with pytest.raises(YunohostError), \
patch.object(os, "isatty", return_value=False):
parse_args_in_yunohost_format(answers, questions) parse_args_in_yunohost_format(answers, questions)
@ -1269,8 +1373,8 @@ def test_question_user():
expected_result = OrderedDict({"some_user": (username, "user")}) expected_result = OrderedDict({"some_user": (username, "user")})
with patch.object(user, "user_list", return_value={"users": users}): with patch.object(user, "user_list", return_value={"users": users}), \
with patch.object(user, "user_info", return_value={}): patch.object(user, "user_info", return_value={}):
assert parse_args_in_yunohost_format(answers, questions) == expected_result assert parse_args_in_yunohost_format(answers, questions) == expected_result
@ -1303,15 +1407,15 @@ def test_question_user_two_users():
answers = {"some_user": other_user} answers = {"some_user": other_user}
expected_result = OrderedDict({"some_user": (other_user, "user")}) expected_result = OrderedDict({"some_user": (other_user, "user")})
with patch.object(user, "user_list", return_value={"users": users}): with patch.object(user, "user_list", return_value={"users": users}), \
with patch.object(user, "user_info", return_value={}): patch.object(user, "user_info", return_value={}):
assert parse_args_in_yunohost_format(answers, questions) == expected_result assert parse_args_in_yunohost_format(answers, questions) == expected_result
answers = {"some_user": username} answers = {"some_user": username}
expected_result = OrderedDict({"some_user": (username, "user")}) expected_result = OrderedDict({"some_user": (username, "user")})
with patch.object(user, "user_list", return_value={"users": users}): with patch.object(user, "user_list", return_value={"users": users}), \
with patch.object(user, "user_info", return_value={}): patch.object(user, "user_info", return_value={}):
assert parse_args_in_yunohost_format(answers, questions) == expected_result assert parse_args_in_yunohost_format(answers, questions) == expected_result
@ -1344,7 +1448,8 @@ def test_question_user_two_users_wrong_answer():
answers = {"some_user": "doesnt_exist.pouet"} answers = {"some_user": "doesnt_exist.pouet"}
with patch.object(user, "user_list", return_value={"users": users}): with patch.object(user, "user_list", return_value={"users": users}):
with pytest.raises(YunohostError): with pytest.raises(YunohostError), \
patch.object(os, "isatty", return_value=False):
parse_args_in_yunohost_format(answers, questions) parse_args_in_yunohost_format(answers, questions)
@ -1372,7 +1477,8 @@ def test_question_user_two_users_no_default():
answers = {} answers = {}
with patch.object(user, "user_list", return_value={"users": users}): with patch.object(user, "user_list", return_value={"users": users}):
with pytest.raises(YunohostError): with pytest.raises(YunohostError), \
patch.object(os, "isatty", return_value=False):
parse_args_in_yunohost_format(answers, questions) parse_args_in_yunohost_format(answers, questions)
@ -1399,17 +1505,18 @@ def test_question_user_two_users_default_input():
questions = [{"name": "some_user", "type": "user", "ask": "choose a user"}] questions = [{"name": "some_user", "type": "user", "ask": "choose a user"}]
answers = {} answers = {}
with patch.object(user, "user_list", return_value={"users": users}): with patch.object(user, "user_list", return_value={"users": users}), \
patch.object(os, "isatty", return_value=True):
with patch.object(user, "user_info", return_value={}): with patch.object(user, "user_info", return_value={}):
expected_result = OrderedDict({"some_user": (username, "user")}) expected_result = OrderedDict({"some_user": (username, "user")})
with patch.object(Moulinette.interface, "prompt", return_value=username): with patch.object(Moulinette, "prompt", return_value=username):
assert ( assert (
parse_args_in_yunohost_format(answers, questions) parse_args_in_yunohost_format(answers, questions)
== expected_result == expected_result
) )
expected_result = OrderedDict({"some_user": (other_user, "user")}) expected_result = OrderedDict({"some_user": (other_user, "user")})
with patch.object(Moulinette.interface, "prompt", return_value=other_user): with patch.object(Moulinette, "prompt", return_value=other_user):
assert ( assert (
parse_args_in_yunohost_format(answers, questions) parse_args_in_yunohost_format(answers, questions)
== expected_result == expected_result
@ -1437,8 +1544,9 @@ def test_question_number_no_input():
] ]
answers = {} answers = {}
expected_result = OrderedDict({"some_number": (0, "number")}) with pytest.raises(YunohostError), \
assert parse_args_in_yunohost_format(answers, questions) == expected_result patch.object(os, "isatty", return_value=False):
parse_args_in_yunohost_format(answers, questions)
def test_question_number_bad_input(): def test_question_number_bad_input():
@ -1450,11 +1558,13 @@ def test_question_number_bad_input():
] ]
answers = {"some_number": "stuff"} answers = {"some_number": "stuff"}
with pytest.raises(YunohostError): with pytest.raises(YunohostError), \
patch.object(os, "isatty", return_value=False):
parse_args_in_yunohost_format(answers, questions) parse_args_in_yunohost_format(answers, questions)
answers = {"some_number": 1.5} answers = {"some_number": 1.5}
with pytest.raises(YunohostError): with pytest.raises(YunohostError), \
patch.object(os, "isatty", return_value=False):
parse_args_in_yunohost_format(answers, questions) parse_args_in_yunohost_format(answers, questions)
@ -1469,14 +1579,17 @@ def test_question_number_input():
answers = {} answers = {}
expected_result = OrderedDict({"some_number": (1337, "number")}) expected_result = OrderedDict({"some_number": (1337, "number")})
with patch.object(Moulinette.interface, "prompt", return_value="1337"): with patch.object(Moulinette, "prompt", return_value="1337"), \
patch.object(os, "isatty", return_value=True):
assert parse_args_in_yunohost_format(answers, questions) == expected_result assert parse_args_in_yunohost_format(answers, questions) == expected_result
with patch.object(Moulinette.interface, "prompt", return_value=1337): with patch.object(Moulinette, "prompt", return_value=1337), \
patch.object(os, "isatty", return_value=True):
assert parse_args_in_yunohost_format(answers, questions) == expected_result assert parse_args_in_yunohost_format(answers, questions) == expected_result
expected_result = OrderedDict({"some_number": (0, "number")}) expected_result = OrderedDict({"some_number": (0, "number")})
with patch.object(Moulinette.interface, "prompt", return_value=""): with patch.object(Moulinette, "prompt", return_value="0"), \
patch.object(os, "isatty", return_value=True):
assert parse_args_in_yunohost_format(answers, questions) == expected_result assert parse_args_in_yunohost_format(answers, questions) == expected_result
@ -1490,7 +1603,8 @@ def test_question_number_input_no_ask():
answers = {} answers = {}
expected_result = OrderedDict({"some_number": (1337, "number")}) expected_result = OrderedDict({"some_number": (1337, "number")})
with patch.object(Moulinette.interface, "prompt", return_value="1337"): with patch.object(Moulinette, "prompt", return_value="1337"), \
patch.object(os, "isatty", return_value=True):
assert parse_args_in_yunohost_format(answers, questions) == expected_result assert parse_args_in_yunohost_format(answers, questions) == expected_result
@ -1503,7 +1617,8 @@ def test_question_number_no_input_optional():
} }
] ]
answers = {} answers = {}
expected_result = OrderedDict({"some_number": (0, "number")}) # default to 0 expected_result = OrderedDict({"some_number": (None, "number")}) # default to 0
with patch.object(os, "isatty", return_value=False):
assert parse_args_in_yunohost_format(answers, questions) == expected_result assert parse_args_in_yunohost_format(answers, questions) == expected_result
@ -1519,7 +1634,8 @@ def test_question_number_optional_with_input():
answers = {} answers = {}
expected_result = OrderedDict({"some_number": (1337, "number")}) expected_result = OrderedDict({"some_number": (1337, "number")})
with patch.object(Moulinette.interface, "prompt", return_value="1337"): with patch.object(Moulinette, "prompt", return_value="1337"), \
patch.object(os, "isatty", return_value=True):
assert parse_args_in_yunohost_format(answers, questions) == expected_result assert parse_args_in_yunohost_format(answers, questions) == expected_result
@ -1534,7 +1650,8 @@ def test_question_number_optional_with_input_without_ask():
answers = {} answers = {}
expected_result = OrderedDict({"some_number": (0, "number")}) expected_result = OrderedDict({"some_number": (0, "number")})
with patch.object(Moulinette.interface, "prompt", return_value="0"): with patch.object(Moulinette, "prompt", return_value="0"), \
patch.object(os, "isatty", return_value=True):
assert parse_args_in_yunohost_format(answers, questions) == expected_result assert parse_args_in_yunohost_format(answers, questions) == expected_result
@ -1549,6 +1666,7 @@ def test_question_number_no_input_default():
] ]
answers = {} answers = {}
expected_result = OrderedDict({"some_number": (1337, "number")}) expected_result = OrderedDict({"some_number": (1337, "number")})
with patch.object(os, "isatty", return_value=False):
assert parse_args_in_yunohost_format(answers, questions) == expected_result assert parse_args_in_yunohost_format(answers, questions) == expected_result
@ -1562,7 +1680,8 @@ def test_question_number_bad_default():
} }
] ]
answers = {} answers = {}
with pytest.raises(YunohostError): with pytest.raises(YunohostError), \
patch.object(os, "isatty", return_value=False):
parse_args_in_yunohost_format(answers, questions) parse_args_in_yunohost_format(answers, questions)
@ -1577,9 +1696,14 @@ def test_question_number_input_test_ask():
] ]
answers = {} answers = {}
with patch.object(Moulinette.interface, "prompt", return_value="1111") as prompt: with patch.object(Moulinette, "prompt", return_value="1111") as prompt, \
patch.object(os, "isatty", return_value=True):
parse_args_in_yunohost_format(answers, questions) parse_args_in_yunohost_format(answers, questions)
prompt.assert_called_with("%s (default: 0)" % (ask_text), False) prompt.assert_called_with(
message=ask_text,
is_password=False, confirm=False,
prefill='', is_multiline=False
)
def test_question_number_input_test_ask_with_default(): def test_question_number_input_test_ask_with_default():
@ -1595,9 +1719,14 @@ def test_question_number_input_test_ask_with_default():
] ]
answers = {} answers = {}
with patch.object(Moulinette.interface, "prompt", return_value="1111") as prompt: with patch.object(Moulinette, "prompt", return_value="1111") as prompt, \
patch.object(os, "isatty", return_value=True):
parse_args_in_yunohost_format(answers, questions) parse_args_in_yunohost_format(answers, questions)
prompt.assert_called_with("%s (default: %s)" % (ask_text, default_value), False) prompt.assert_called_with(
message=ask_text,
is_password=False, confirm=False,
prefill=str(default_value), is_multiline=False
)
@pytest.mark.skip # we should do something with this example @pytest.mark.skip # we should do something with this example
@ -1614,10 +1743,11 @@ def test_question_number_input_test_ask_with_example():
] ]
answers = {} answers = {}
with patch.object(Moulinette.interface, "prompt", return_value="1111") as prompt: with patch.object(Moulinette, "prompt", return_value="1111") as prompt, \
patch.object(os, "isatty", return_value=True):
parse_args_in_yunohost_format(answers, questions) parse_args_in_yunohost_format(answers, questions)
assert ask_text in prompt.call_args[0][0] assert ask_text in prompt.call_args[1]['message']
assert example_value in prompt.call_args[0][0] assert example_value in prompt.call_args[1]['message']
@pytest.mark.skip # we should do something with this help @pytest.mark.skip # we should do something with this help
@ -1634,16 +1764,18 @@ def test_question_number_input_test_ask_with_help():
] ]
answers = {} answers = {}
with patch.object(Moulinette.interface, "prompt", return_value="1111") as prompt: with patch.object(Moulinette, "prompt", return_value="1111") as prompt, \
patch.object(os, "isatty", return_value=True):
parse_args_in_yunohost_format(answers, questions) parse_args_in_yunohost_format(answers, questions)
assert ask_text in prompt.call_args[0][0] assert ask_text in prompt.call_args[1]['message']
assert help_value in prompt.call_args[0][0] assert help_value in prompt.call_args[1]['message']
def test_question_display_text(): def test_question_display_text():
questions = [{"name": "some_app", "type": "display_text", "ask": "foobar"}] questions = [{"name": "some_app", "type": "display_text", "ask": "foobar"}]
answers = {} answers = {}
with patch.object(sys, "stdout", new_callable=StringIO) as stdout: with patch.object(sys, "stdout", new_callable=StringIO) as stdout, \
patch.object(os, "isatty", return_value=True):
parse_args_in_yunohost_format(answers, questions) parse_args_in_yunohost_format(answers, questions)
assert "foobar" in stdout.getvalue() assert "foobar" in stdout.getvalue()

View file

@ -403,9 +403,9 @@ class Question(object):
return value return value
def ask_if_needed(self): def ask_if_needed(self):
while True: for i in range(5):
# Display question if no value filled or if it's a readonly message # Display question if no value filled or if it's a readonly message
if Moulinette.interface.type == "cli": if Moulinette.interface.type == "cli" and os.isatty(1):
text_for_user_input_in_cli = self._format_text_for_user_input_in_cli() text_for_user_input_in_cli = self._format_text_for_user_input_in_cli()
if getattr(self, "readonly", False): if getattr(self, "readonly", False):
Moulinette.display(text_for_user_input_in_cli) Moulinette.display(text_for_user_input_in_cli)
@ -415,7 +415,7 @@ class Question(object):
if self.current_value is not None: if self.current_value is not None:
prefill = self.humanize(self.current_value, self) prefill = self.humanize(self.current_value, self)
elif self.default is not None: elif self.default is not None:
prefill = self.default prefill = self.humanize(self.default, self)
self.value = Moulinette.prompt( self.value = Moulinette.prompt(
message=text_for_user_input_in_cli, message=text_for_user_input_in_cli,
is_password=self.hide_user_input_in_prompt, is_password=self.hide_user_input_in_prompt,
@ -424,27 +424,33 @@ class Question(object):
is_multiline=(self.type == "text"), is_multiline=(self.type == "text"),
) )
# Normalization
# This is done to enforce a certain formating like for boolean
self.value = self.normalize(self.value, self)
# Apply default value # Apply default value
if self.value in [None, ""] and self.default is not None: class_default= getattr(self, "default_value", None)
if self.value in [None, ""] and \
(self.default is not None or class_default is not None):
self.value = ( self.value = (
getattr(self, "default_value", None) class_default
if self.default is None if self.default is None
else self.default else self.default
) )
# Normalization
# This is done to enforce a certain formating like for boolean
self.value = self.normalize(self.value, self)
# Prevalidation # Prevalidation
try: try:
self._prevalidate() self._prevalidate()
except YunohostValidationError as e: except YunohostValidationError as e:
if Moulinette.interface.type == "api": # If in interactive cli, re-ask the current question
raise if i < 4 and Moulinette.interface.type == "cli" and os.isatty(1):
Moulinette.display(str(e), "error") logger.error(str(e))
self.value = None self.value = None
continue continue
# Otherwise raise the ValidationError
raise
break break
self.value = self._post_parse_value() self.value = self._post_parse_value()
@ -561,7 +567,7 @@ class PasswordQuestion(Question):
def _prevalidate(self): def _prevalidate(self):
super()._prevalidate() super()._prevalidate()
if self.value is not None: if self.value not in [None, ""]:
if any(char in self.value for char in self.forbidden_chars): if any(char in self.value for char in self.forbidden_chars):
raise YunohostValidationError( raise YunohostValidationError(
"pattern_password_app", forbidden_chars=self.forbidden_chars "pattern_password_app", forbidden_chars=self.forbidden_chars
@ -580,7 +586,7 @@ class PathQuestion(Question):
class BooleanQuestion(Question): class BooleanQuestion(Question):
argument_type = "boolean" argument_type = "boolean"
default_value = False default_value = 0
yes_answers = ["1", "yes", "y", "true", "t", "on"] yes_answers = ["1", "yes", "y", "true", "t", "on"]
no_answers = ["0", "no", "n", "false", "f", "off"] no_answers = ["0", "no", "n", "false", "f", "off"]
@ -633,17 +639,13 @@ class BooleanQuestion(Question):
self.yes = question.get("yes", 1) self.yes = question.get("yes", 1)
self.no = question.get("no", 0) self.no = question.get("no", 0)
if self.default is None: if self.default is None:
self.default = False self.default = self.no
def _format_text_for_user_input_in_cli(self): def _format_text_for_user_input_in_cli(self):
text_for_user_input_in_cli = _value_for_locale(self.ask) text_for_user_input_in_cli = super()._format_text_for_user_input_in_cli()
text_for_user_input_in_cli += " [yes | no]" text_for_user_input_in_cli += " [yes | no]"
if self.default is not None:
formatted_default = self.humanize(self.default)
text_for_user_input_in_cli += " (default: {0})".format(formatted_default)
return text_for_user_input_in_cli return text_for_user_input_in_cli
def get(self, key, default=None): def get(self, key, default=None):
@ -698,11 +700,7 @@ class UserQuestion(Question):
class NumberQuestion(Question): class NumberQuestion(Question):
argument_type = "number" argument_type = "number"
default_value = "" default_value = None
@staticmethod
def humanize(value, option={}):
return str(value)
def __init__(self, question, user_answers): def __init__(self, question, user_answers):
super().__init__(question, user_answers) super().__init__(question, user_answers)
@ -710,16 +708,25 @@ class NumberQuestion(Question):
self.max = question.get("max", None) self.max = question.get("max", None)
self.step = question.get("step", None) self.step = question.get("step", None)
@staticmethod
def normalize(value, option={}):
if isinstance(value, int):
return value
if isinstance(value, str) and value.isdigit():
return int(value)
if value in [None, ""]:
return value
raise YunohostValidationError(
"app_argument_invalid", name=option.name, error=m18n.n("invalid_number")
)
def _prevalidate(self): def _prevalidate(self):
super()._prevalidate() super()._prevalidate()
if not isinstance(self.value, int) and not ( if self.value in [None, ""]:
isinstance(self.value, str) and self.value.isdigit() return
):
raise YunohostValidationError(
"app_argument_invalid",
name=self.name,
error=m18n.n("invalid_number"),
)
if self.min is not None and int(self.value) < self.min: if self.min is not None and int(self.value) < self.min:
raise YunohostValidationError( raise YunohostValidationError(
@ -735,16 +742,6 @@ class NumberQuestion(Question):
error=m18n.n("invalid_number"), error=m18n.n("invalid_number"),
) )
def _post_parse_value(self):
if isinstance(self.value, int):
return super()._post_parse_value()
if isinstance(self.value, str) and self.value.isdigit():
return int(self.value)
raise YunohostValidationError(
"app_argument_invalid", name=self.name, error=m18n.n("invalid_number")
)
class DisplayTextQuestion(Question): class DisplayTextQuestion(Question):
@ -755,10 +752,10 @@ class DisplayTextQuestion(Question):
super().__init__(question, user_answers) super().__init__(question, user_answers)
self.optional = True self.optional = True
self.style = question.get("style", "info") self.style = question.get("style", "info" if question['type'] == 'alert' else '')
def _format_text_for_user_input_in_cli(self): def _format_text_for_user_input_in_cli(self):
text = self.ask["en"] text = _value_for_locale(self.ask)
if self.style in ["success", "info", "warning", "danger"]: if self.style in ["success", "info", "warning", "danger"]:
color = { color = {