Add some first unit tests
This commit is contained in:
Generated
+1
@@ -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" />
|
||||
|
||||
Generated
+20
@@ -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="""" />
|
||||
<option name="_new_additionalArguments" value="""" />
|
||||
<option name="_new_target" value="""" />
|
||||
<option name="_new_targetType" value=""PATH"" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -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,
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
Reference in New Issue
Block a user