From 078329eadc9cf7e67a9fe8049acaaffdc56b391a Mon Sep 17 00:00:00 2001 From: Takitsuse Nagisa Date: Mon, 20 Jan 2020 23:16:57 +0900 Subject: [PATCH 01/11] Refactor login function --- evalai/login.py | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/evalai/login.py b/evalai/login.py index 001f2676c..08b6e0273 100644 --- a/evalai/login.py +++ b/evalai/login.py @@ -17,19 +17,12 @@ def login(ctx): password = click.prompt("Enter password", type=str, hide_input=True) token = get_user_auth_token_by_login(username, password) - if os.path.exists(AUTH_TOKEN_PATH): - with open(str(AUTH_TOKEN_PATH), "w") as TokenFile: - try: - json.dump(token, TokenFile) - except (OSError, IOError) as e: - echo(e) - else: - if not os.path.exists(AUTH_TOKEN_DIR): - os.makedirs(AUTH_TOKEN_DIR) - with open(str(AUTH_TOKEN_PATH), "w+") as TokenFile: - try: - json.dump(token, TokenFile) - except (OSError, IOError) as e: - echo(e) + if not os.path.exists(AUTH_TOKEN_DIR): + os.makedirs(AUTH_TOKEN_DIR) + with open(AUTH_TOKEN_PATH, "w") as TokenFile: + try: + json.dump(token, TokenFile) + except (OSError, IOError) as e: + echo(e) echo(style("\nLogged in successfully!", bold=True)) From 3f7d3c65cbbf46cc096f1fe8c2a872354c900be9 Mon Sep 17 00:00:00 2001 From: Takitsuse Nagisa Date: Tue, 21 Jan 2020 16:24:04 +0900 Subject: [PATCH 02/11] Improve error message --- evalai/login.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/evalai/login.py b/evalai/login.py index 08b6e0273..d629fd833 100644 --- a/evalai/login.py +++ b/evalai/login.py @@ -23,6 +23,12 @@ def login(ctx): try: json.dump(token, TokenFile) except (OSError, IOError) as e: - echo(e) + echo( + style( + "Unable to store token data due to error: {}".format(e), + bold=True, + fg="red", + ) + ) echo(style("\nLogged in successfully!", bold=True)) From a747c8b67c7d5dd859df4e5adab81f36930d5539 Mon Sep 17 00:00:00 2001 From: Takitsuse Nagisa Date: Tue, 21 Jan 2020 16:31:31 +0900 Subject: [PATCH 03/11] Define store_data_to_json function --- evalai/login.py | 14 ++------------ evalai/utils/common.py | 18 +++++++++++++++++- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/evalai/login.py b/evalai/login.py index d629fd833..6064e5591 100644 --- a/evalai/login.py +++ b/evalai/login.py @@ -1,9 +1,9 @@ import os import click -import json from click import echo, style from evalai.utils.auth import get_user_auth_token_by_login +from evalai.utils.common import store_data_to_json from evalai.utils.config import AUTH_TOKEN_PATH, AUTH_TOKEN_DIR @@ -19,16 +19,6 @@ def login(ctx): if not os.path.exists(AUTH_TOKEN_DIR): os.makedirs(AUTH_TOKEN_DIR) - with open(AUTH_TOKEN_PATH, "w") as TokenFile: - try: - json.dump(token, TokenFile) - except (OSError, IOError) as e: - echo( - style( - "Unable to store token data due to error: {}".format(e), - bold=True, - fg="red", - ) - ) + store_data_to_json(AUTH_TOKEN_PATH, token, "Unable to store token data due to error: {}") echo(style("\nLogged in successfully!", bold=True)) diff --git a/evalai/utils/common.py b/evalai/utils/common.py index e59430720..135e20439 100644 --- a/evalai/utils/common.py +++ b/evalai/utils/common.py @@ -1,5 +1,6 @@ -import sys import click +import json +import sys from bs4 import BeautifulSoup from click import echo, style @@ -88,3 +89,18 @@ def clean_data(data): def notify_user(message, color="green", bold=False): echo(style(message, fg=color, bold=bold)) + + +def store_data_to_json(path, content, message): + with open(path, "w") as file: + try: + json.dump(content, file) + except (OSError, IOError) as e: + echo( + style( + message.format(e), + bold=True, + fg="red", + ) + ) + sys.exit(1) From 279fa76b02e901ecc5cd592c8d703432abf23f8b Mon Sep 17 00:00:00 2001 From: Takitsuse Nagisa Date: Tue, 21 Jan 2020 16:34:28 +0900 Subject: [PATCH 04/11] Remove unneeded line --- evalai/utils/common.py | 1 - 1 file changed, 1 deletion(-) diff --git a/evalai/utils/common.py b/evalai/utils/common.py index 135e20439..bc4cc4949 100644 --- a/evalai/utils/common.py +++ b/evalai/utils/common.py @@ -103,4 +103,3 @@ def store_data_to_json(path, content, message): fg="red", ) ) - sys.exit(1) From 8c261357c9cf9704b337261c660ac18c00bf7d62 Mon Sep 17 00:00:00 2001 From: Takitsuse Nagisa Date: Tue, 21 Jan 2020 17:08:39 +0900 Subject: [PATCH 05/11] Add a test case for store_data_to_json --- tests/test_login.py | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 tests/test_login.py diff --git a/tests/test_login.py b/tests/test_login.py new file mode 100644 index 000000000..376f32c88 --- /dev/null +++ b/tests/test_login.py @@ -0,0 +1,37 @@ +import responses + +from unittest.mock import patch +from click.testing import CliRunner +from evalai.utils.auth import ( + get_host_url, + URLS +) +from evalai.login import login + +from .base import BaseTestClass + + +class TestLogin(BaseTestClass): + def setup(self): + payload = {"username": "username", "password": "password"} + + url = "{}{}" + responses.add( + responses.POST, + url.format(get_host_url(), URLS.login.value), + headers=payload, + json={"token": "test"}, + status=200, + ) + + @responses.activate + @patch("evalai.utils.common.json.dump") + def test_login_when_storing_json_fails(self, mock_dump): + error = "Exception" + expected = "Unable to store token data due to error: {}".format(error) + mock_dump.side_effect = OSError(error) + + runner = CliRunner() + result = runner.invoke(login, input="username\npassword") + response = result.output.rstrip() + assert expected in response From ce81947783b3359d9f7410a9a8ac75a1dbb34da1 Mon Sep 17 00:00:00 2001 From: Takitsuse Nagisa Date: Tue, 21 Jan 2020 17:21:33 +0900 Subject: [PATCH 06/11] Improve test codes --- tests/test_login.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/tests/test_login.py b/tests/test_login.py index 376f32c88..6f5227d91 100644 --- a/tests/test_login.py +++ b/tests/test_login.py @@ -1,11 +1,10 @@ import responses +import json from unittest.mock import patch from click.testing import CliRunner -from evalai.utils.auth import ( - get_host_url, - URLS -) +from evalai.utils.auth import URLS +from evalai.utils.config import API_HOST_URL from evalai.login import login from .base import BaseTestClass @@ -13,14 +12,13 @@ class TestLogin(BaseTestClass): def setup(self): - payload = {"username": "username", "password": "password"} + token = json.loads("""{"token": "test"}""") url = "{}{}" responses.add( responses.POST, - url.format(get_host_url(), URLS.login.value), - headers=payload, - json={"token": "test"}, + url.format(API_HOST_URL, URLS.login.value), + json=token, status=200, ) @@ -33,5 +31,5 @@ def test_login_when_storing_json_fails(self, mock_dump): runner = CliRunner() result = runner.invoke(login, input="username\npassword") - response = result.output.rstrip() + response = result.output assert expected in response From 90e1db0e05f930d8a33d8fc398e28c3fb3ece5b0 Mon Sep 17 00:00:00 2001 From: Takitsuse Nagisa Date: Tue, 21 Jan 2020 18:23:57 +0900 Subject: [PATCH 07/11] Experimental commit --- tests/test_login.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/test_login.py b/tests/test_login.py index 6f5227d91..946a94cf9 100644 --- a/tests/test_login.py +++ b/tests/test_login.py @@ -2,6 +2,7 @@ import json from unittest.mock import patch +from unittest import TestCase from click.testing import CliRunner from evalai.utils.auth import URLS from evalai.utils.config import API_HOST_URL @@ -10,8 +11,8 @@ from .base import BaseTestClass -class TestLogin(BaseTestClass): - def setup(self): +class TestLogin(TestCase): + def setUp(self): token = json.loads("""{"token": "test"}""") url = "{}{}" From 5688649142a953126ae0cd00469b60415bae6d9c Mon Sep 17 00:00:00 2001 From: Takitsuse Nagisa Date: Tue, 21 Jan 2020 18:51:41 +0900 Subject: [PATCH 08/11] Experimental commit --- tests/test_login.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/tests/test_login.py b/tests/test_login.py index 946a94cf9..aaafecc29 100644 --- a/tests/test_login.py +++ b/tests/test_login.py @@ -1,19 +1,23 @@ import responses -import json +import os from unittest.mock import patch -from unittest import TestCase from click.testing import CliRunner from evalai.utils.auth import URLS -from evalai.utils.config import API_HOST_URL +from evalai.utils.config import ( + API_HOST_URL, + AUTH_TOKEN_DIR, + AUTH_TOKEN_FILE_NAME +) from evalai.login import login from .base import BaseTestClass -class TestLogin(TestCase): - def setUp(self): - token = json.loads("""{"token": "test"}""") +class TestLogin(BaseTestClass): + def setup(self): + with open(os.path.join(AUTH_TOKEN_DIR, AUTH_TOKEN_FILE_NAME)) as f: + token = f.read() url = "{}{}" responses.add( From 5e0cf965e39af4086233f8cb342c5133b5fd03c6 Mon Sep 17 00:00:00 2001 From: Takitsuse Nagisa Date: Tue, 21 Jan 2020 20:02:31 +0900 Subject: [PATCH 09/11] Delete test_login.py --- tests/test_login.py | 40 ---------------------------------------- 1 file changed, 40 deletions(-) delete mode 100644 tests/test_login.py diff --git a/tests/test_login.py b/tests/test_login.py deleted file mode 100644 index aaafecc29..000000000 --- a/tests/test_login.py +++ /dev/null @@ -1,40 +0,0 @@ -import responses -import os - -from unittest.mock import patch -from click.testing import CliRunner -from evalai.utils.auth import URLS -from evalai.utils.config import ( - API_HOST_URL, - AUTH_TOKEN_DIR, - AUTH_TOKEN_FILE_NAME -) -from evalai.login import login - -from .base import BaseTestClass - - -class TestLogin(BaseTestClass): - def setup(self): - with open(os.path.join(AUTH_TOKEN_DIR, AUTH_TOKEN_FILE_NAME)) as f: - token = f.read() - - url = "{}{}" - responses.add( - responses.POST, - url.format(API_HOST_URL, URLS.login.value), - json=token, - status=200, - ) - - @responses.activate - @patch("evalai.utils.common.json.dump") - def test_login_when_storing_json_fails(self, mock_dump): - error = "Exception" - expected = "Unable to store token data due to error: {}".format(error) - mock_dump.side_effect = OSError(error) - - runner = CliRunner() - result = runner.invoke(login, input="username\npassword") - response = result.output - assert expected in response From 781c153ef4df071398bbc70d679a8ecc303166b1 Mon Sep 17 00:00:00 2001 From: Takitsuse Nagisa Date: Tue, 21 Jan 2020 20:04:52 +0900 Subject: [PATCH 10/11] Add tests for store_data_to_json --- tests/utils/__init__.py | 0 tests/utils/test_common.py | 27 +++++++++++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 tests/utils/__init__.py create mode 100644 tests/utils/test_common.py diff --git a/tests/utils/__init__.py b/tests/utils/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/utils/test_common.py b/tests/utils/test_common.py new file mode 100644 index 000000000..5f91e28e0 --- /dev/null +++ b/tests/utils/test_common.py @@ -0,0 +1,27 @@ +from unittest.mock import patch, mock_open +from evalai.utils.common import store_data_to_json + +from ..base import BaseTestClass + + +@patch("evalai.utils.common.json.dump") +@patch("evalai.utils.common.click.echo") +class TestStoreDataToJson(BaseTestClass): + def setup(self): + self.path = "test_path" + self.content = "test content" + self.message = "test message" + + def test_store_data_to_json(self, mock_echo, mock_dump): + mock_file = mock_open() + with patch("evalai.utils.common.open", mock_file): + store_data_to_json(self.path, self.content, self.message) + mock_dump.assert_called() + mock_echo.assert_not_called() + + def test_store_data_to_json_when_error_is_raised(self, mock_dump, mock_echo): + mock_dump.side_effect = OSError("Exception") + mock_file = mock_open() + with patch("evalai.utils.common.open", mock_file): + store_data_to_json(self.path, self.content, self.message) + mock_echo.assert_called() From 08d523db7daf9fb0c24b4686ed032cdbc57d98f0 Mon Sep 17 00:00:00 2001 From: Takitsuse Nagisa Date: Tue, 21 Jan 2020 21:31:47 +0900 Subject: [PATCH 11/11] Improve test cases --- tests/utils/test_common.py | 56 ++++++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 21 deletions(-) diff --git a/tests/utils/test_common.py b/tests/utils/test_common.py index 5f91e28e0..f8325f2c0 100644 --- a/tests/utils/test_common.py +++ b/tests/utils/test_common.py @@ -1,27 +1,41 @@ -from unittest.mock import patch, mock_open -from evalai.utils.common import store_data_to_json +import os + +from click.testing import CliRunner +from evalai.login import login +from evalai.utils.config import ( + AUTH_TOKEN_DIR, + AUTH_TOKEN_FILE_NAME, +) +from unittest.mock import patch from ..base import BaseTestClass -@patch("evalai.utils.common.json.dump") -@patch("evalai.utils.common.click.echo") +@patch("evalai.login.get_user_auth_token_by_login") class TestStoreDataToJson(BaseTestClass): def setup(self): - self.path = "test_path" - self.content = "test content" - self.message = "test message" - - def test_store_data_to_json(self, mock_echo, mock_dump): - mock_file = mock_open() - with patch("evalai.utils.common.open", mock_file): - store_data_to_json(self.path, self.content, self.message) - mock_dump.assert_called() - mock_echo.assert_not_called() - - def test_store_data_to_json_when_error_is_raised(self, mock_dump, mock_echo): - mock_dump.side_effect = OSError("Exception") - mock_file = mock_open() - with patch("evalai.utils.common.open", mock_file): - store_data_to_json(self.path, self.content, self.message) - mock_echo.assert_called() + token_file = os.path.join(AUTH_TOKEN_DIR, AUTH_TOKEN_FILE_NAME) + + with open(token_file) as f: + self.token = f.read() + + def test_store_data_to_json(self, mock_get_user_auth_token_by_login): + mock_get_user_auth_token_by_login.return_value = self.token + + expected = "\n\nLogged in successfully!" + runner = CliRunner() + result = runner.invoke(login, input="username\npassword") + response = result.output + assert expected in response + + @patch("evalai.utils.common.json.dump") + def test_store_data_to_json_when_error_is_raised(self, mock_dump, mock_get_user_auth_token_by_login): + mock_get_user_auth_token_by_login.return_value = self.token + error = "Exception" + mock_dump.side_effect = OSError(error) + + expected = "Unable to store token data due to error: {}".format(error) + runner = CliRunner() + result = runner.invoke(login, input="username\npassword") + response = result.output + assert expected in response