Add some first unit tests

This commit is contained in:
2024-02-23 20:42:16 +00:00
parent 229281c5ff
commit 81fe923fb3
6 changed files with 149 additions and 24 deletions
+1
View File
@@ -3,6 +3,7 @@
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/.venv" />
</content>
<orderEntry type="jdk" jdkName="Python 3.10 (ActiveCollabAPI)" jdkType="Python SDK" />
+20
View File
@@ -0,0 +1,20 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Unittests" type="tests" factoryName="Unittests">
<module name="ActiveCollabAPI" />
<option name="ENV_FILES" value="" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<option name="SDK_HOME" value="$PROJECT_DIR$/.venv/bin/python" />
<option name="SDK_NAME" value="Python 3.10 (ActiveCollabAPI)" />
<option name="WORKING_DIRECTORY" value="" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="_new_pattern" value="&quot;&quot;" />
<option name="_new_additionalArguments" value="&quot;&quot;" />
<option name="_new_target" value="&quot;&quot;" />
<option name="_new_targetType" value="&quot;PATH&quot;" />
<method v="2" />
</configuration>
</component>
+12 -5
View File
@@ -3,17 +3,20 @@ import json
# 3rd party libs
import requests
from requests import Response
from ActiveCollabAPI import AC_LOGIN_BASE_URL, AC_USER_AGENT
class ACAuthenticator:
base_url = AC_LOGIN_BASE_URL
base_url = ""
user = None
accounts = None
def __init__(self, base_url: str):
self.base_url = base_url
def headers(self):
return {
'Content-Type': 'application/json; charset=utf8',
@@ -21,14 +24,18 @@ class ACAuthenticator:
'User-Agent': AC_USER_AGENT
}
def login(self, email, password):
def login(self, email: str, password: str) -> Response:
login_data = {
'email': email,
'password': password
}
res = requests.post(self.base_url,
return requests.post(self.base_url,
data=json.dumps(login_data),
headers=self.headers())
def login_with_check(self, email: str, password: str):
res = self.login(email, password)
if res.status_code != 200:
raise Exception('Login failed!')
@@ -38,7 +45,7 @@ class ACAuthenticator:
self.user = login_res['user']
self.accounts = login_res['accounts']
return login_res
return res
def find_account(self, value, key='user_display_name'):
found = list(filter(lambda a: a[key] == value,
+29 -17
View File
@@ -2,6 +2,7 @@ import configparser
import logging
from pprint import pprint
from ActiveCollabAPI import AC_LOGIN_BASE_URL
from ActiveCollabAPI.ACAuthenticator import ACAuthenticator
from ActiveCollabAPI.ACClient import ACClient
from ActiveCollabAPI.ACTokenAuthenticator import ACTokenAuthenticator
@@ -19,7 +20,8 @@ requests_log = logging.getLogger("urllib3")
requests_log.setLevel(logging.DEBUG)
requests_log.propagate = True
if __name__ == "__main__":
def main():
config = configparser.ConfigParser()
config.read('config.ini')
@@ -28,32 +30,37 @@ if __name__ == "__main__":
account_name = config['LOGIN']['account_name']
# 1. you need to log in to get a session and a list of accounts
auth = ACAuthenticator()
session = auth.login(username, password)
pprint(session)
user = session['user']
auth = ACAuthenticator(AC_LOGIN_BASE_URL)
auth.login_with_check(username, password)
# use first account
account = auth.find_account(account_name)
# 2. you need to get a token for this account
# token = ACTokenAuthenticator(account, user).issue_token_intent()
token = ACTokenAuthenticator(account, auth.user).issue_token_intent()
# pprint(token)
# 3. now you can query the API
# ac = ACClient(account, token)
ac = ACClient(account, token)
# check version
res = ac.get_info()
ac_version = res.json()
pprint(ac_version)
if ac_version['version'] != '7.4.337':
raise Exception("Supporting only Version 7.4.337!")
# get a list of all projects
# res = ac.get_projects()
# pprint(res.json())
# get task with sub tasks
# https://app.activecollab.com/416910/projects/310/tasks/6274
# get task with sub-tasks
# "https://app.activecollab.com/416910/projects/310/tasks/6260"
# project_id = 310
# task_id = 6281
# task_id = 6260
# task_res = ac.get_project_task(project_id, task_id)
# pprint(task_res.json())
# task = task_res.json()
# res = ac.unassign_all_sub_task(task)
# ac.delete_all_open_subtasks(task)
# create a new subtask for the task without assignment
# subtask = {
@@ -66,10 +73,10 @@ if __name__ == "__main__":
# pprint(res.json())
# # bulk create subtasks
subtask_texts = []
with open("sub-tasks.txt", "r", encoding="utf-8") as fh:
for line in fh:
subtask_texts.append(line.rstrip('\n'))
# subtask_texts = []
# with open("sub-tasks.txt", "r", encoding="utf-8") as fh:
# for line in fh:
# subtask_texts.append(line.rstrip('\n'))
# create
# for text in subtask_texts:
# subtask['body'] = text
@@ -98,5 +105,10 @@ if __name__ == "__main__":
# res = ac.delete_subtask(subtask)
# pprint(res.json())
# res = ac.get_info()
# pprint(res.json())
res = ac.get_projects()
if res.status_code == 200:
pprint(res.json())
if __name__ == "__main__":
main()
View File
+85
View File
@@ -0,0 +1,85 @@
import json
from unittest import TestCase
from unittest.mock import patch
from ActiveCollabAPI import AC_LOGIN_BASE_URL
from ActiveCollabAPI.ACAuthenticator import ACAuthenticator
class TestACAuthenticator(TestCase):
def test_headers(self):
authenticator = ACAuthenticator(AC_LOGIN_BASE_URL)
headers = authenticator.headers()
self.assertIn('Content-Type', headers)
self.assertEqual('application/json; charset=utf8', headers['Content-Type'])
self.assertIn('Accept', headers)
self.assertEqual('application/json', headers['Accept'])
self.assertIn('User-Agent', headers)
def mock_login_success(self):
return {
"accounts": [
{
"name": 12345678,
"url": "https:\/\/app.activecollab.com\/12345678",
"display_name": "433339",
"user_display_name": "#12345678",
"position": 1,
"class": "ActiveCollab\\Shepherd\\Model\\Account\\ActiveCollab\\FeatherAccount",
"status": "trial"
}
],
"is_ok": 1,
"user": {
"avatar_url": "https:\/\/activecollab.com\/avatar.php?user_id=12345678&size=80",
"first_name": "users first",
"last_name": "users last",
"intent": "random-string"}
}
def mock_login_failed(self):
return {
"is_ok": 3
}
def test_login_success_gets_user_and_accounts_list(self):
with patch("ActiveCollabAPI.ACAuthenticator.requests.post") as mock_post:
mock_post.return_value.status_code = 200
mock_post.return_value.json.return_value = self.mock_login_success()
email = "collab@example.com"
password = "VeryS3cret!"
authenticator = ACAuthenticator(AC_LOGIN_BASE_URL)
response = authenticator.login_with_check(email, password)
self.assertEquals(200, response.status_code)
res_data = response.json()
self.assertEqual(1, res_data['is_ok'])
user = res_data["user"]
self.assertEqual("users first", user["first_name"])
self.assertEqual("users last", user["last_name"])
accounts = res_data["accounts"]
self.assertGreater(len(accounts), 0)
self.assertEqual(12345678, accounts[0]["name"])
def test_login_failed_http401(self):
with self.assertRaises(Exception) as exc:
with patch("ActiveCollabAPI.ACAuthenticator.requests.post") as mock_post:
mock_post.return_value.status_code = 401
mock_post.return_value.json.return_value = self.mock_login_failed()
email = "collab@example.com"
password = "VeryS3cret!"
authenticator = ACAuthenticator(AC_LOGIN_BASE_URL)
response = authenticator.login_with_check(email, password)
def test_login_failed_not_ok(self):
with self.assertRaises(Exception) as exc:
with patch("ActiveCollabAPI.ACAuthenticator.requests.post") as mock_post:
mock_post.return_value.status_code = 200
mock_post.return_value.json.return_value = self.mock_login_failed()
email = "collab@example.com"
password = "VeryS3cret!"
authenticator = ACAuthenticator(AC_LOGIN_BASE_URL)
response = authenticator.login_with_check(email, password)