From 631241bafbe3395626a9f19121a538f86ae66e24 Mon Sep 17 00:00:00 2001 From: Aaron Guise Date: Mon, 16 May 2022 10:46:34 +1200 Subject: [PATCH] Basic API Call complete with exceptions/tests --- .gitignore | 6 +- __init__.py | 0 akauntingpy/__init__.py | 2 +- akauntingpy/api.py | 117 +++++++++++++++++++ akauntingpy/exceptions.py | 20 ++++ data/CreateTransactionIncomeFailed.json | 140 +++++++++++++++++++++++ data/CreateTransactionIncomeSuccess.json | 94 +++++++++++++++ data/GetAccountsList.json | 70 ++++++++++++ data/pingFailure.json | 55 +++++++++ data/pingSuccess.json | 4 + requirements.txt | 2 + scratch.py | 7 ++ tests/api_test.py | 106 +++++++++++++++++ tests/helpers.py | 7 ++ 14 files changed, 628 insertions(+), 2 deletions(-) create mode 100644 __init__.py create mode 100644 data/CreateTransactionIncomeFailed.json create mode 100644 data/CreateTransactionIncomeSuccess.json create mode 100644 data/GetAccountsList.json create mode 100644 data/pingFailure.json create mode 100644 data/pingSuccess.json create mode 100644 requirements.txt create mode 100644 scratch.py create mode 100644 tests/api_test.py create mode 100644 tests/helpers.py diff --git a/.gitignore b/.gitignore index 600d2d3..fb1717b 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,5 @@ -.vscode \ No newline at end of file +.vscode +# Cached python code +__pycache__ +# Cached test code +.pytest_cache \ No newline at end of file diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/akauntingpy/__init__.py b/akauntingpy/__init__.py index ca64440..fbff91d 100644 --- a/akauntingpy/__init__.py +++ b/akauntingpy/__init__.py @@ -1,2 +1,2 @@ -from akauntingpy.api import WHMCS +from akauntingpy.api import Client from akauntingpy.exceptions import * \ No newline at end of file diff --git a/akauntingpy/api.py b/akauntingpy/api.py index e69de29..3c24b32 100644 --- a/akauntingpy/api.py +++ b/akauntingpy/api.py @@ -0,0 +1,117 @@ +import requests +import json +from requests.auth import HTTPBasicAuth +from akauntingpy import exceptions + +def MergeDict(dict1, dict2): + dict2.update(dict1) + return dict2 + +def RemoveFromString(items, string): + for item in items: + string = string.replace(item, '') + return string +class Client(object): + """ + Akaunting interface. + """ + def __init__( + self, + url, + username, + password, + company_id): + """ + Create a new instance. + Args: + url (str): The URL to the Akaunting api. + username (str): The username of the Akaunting credentials. + password (str): The password of the Akaunting credentials. + """ + self.url = url + self.authentication = HTTPBasicAuth(username, password) + self.headers = { + 'User-Agent': 'AkauntingPy 1.0', + } + self.company_id = company_id + self.default_params = {'company_id': company_id} + + def call(self, method="get", endpoint=None, + **params) -> dict(): + response = None + + if params is None: + response = requests.request(method=method, + url=self.url + "/" + endpoint, + headers=self.headers, + auth=self.authentication, + params=self.default_params) + else: + response = requests.request(method=method, + url=self.url + "/" + endpoint, + headers=self.headers, + auth=self.authentication, + params=MergeDict(self.default_params, params) + ) + + print(response) + response_ = response.json() + print(response_) + # try: + # result = response_['status'] + # except KeyError: + # result = response_['status_code'] + if response.status_code == 401: + raise exceptions.MissingPermission(response_['message']) + elif response.status_code == 422: + errors = [] + for key in response_['errors']: + errors.append(RemoveFromString(["",""], + response_['errors'][key][0]) + " (" + key + ")") + raise exceptions.InvalidData(response_['message'] + + "\n" + + "\n".join(errors)) + elif response.status_code != 200 and response.status_code != 201: + raise exceptions.Error(response_['message']) + return response_ + + def ping(self): + data = self.call(endpoint="ping") + return data + + def get_accounts(self, params=None): + data = self.call(endpoint="accounts", params=params) + + return data['data'] + + def create_transaction(self, + type='income', # Payment method type + account_id=None, # Account ID to assign + category_id=None, # Category ID to assign + contact_id=None, # Contact ID/Client to assign + paid_at=None, # Date of expense/transfer or income + reference=None, # Reference for the payment + payment_method=None, # Payment method + currency_code=None, # Currency code + currency_rate=None, # Currency rate + amount=None, # Amount received/paid + **params # Any additional parameters + ): + + + data = self.call(endpoint="transactions", + method="POST", + search="type:" + type, + type=type, + account_id=account_id, + category_id=category_id, + paid_at=paid_at, + contact_id=contact_id, + payment_method=payment_method, + reference=reference, + currency_code=currency_code, + currency_rate=currency_rate, + amount=amount, + **params + ) + return data \ No newline at end of file diff --git a/akauntingpy/exceptions.py b/akauntingpy/exceptions.py index e69de29..e51926a 100644 --- a/akauntingpy/exceptions.py +++ b/akauntingpy/exceptions.py @@ -0,0 +1,20 @@ +class Error(Exception): + """ + An unspecified error. + + """ + + +class MissingPermission(Error): + """ + Missing permission when calling the API. + + """ + +class InvalidData(Error): + """ + Missing Data required for request + + Args: + Error (_type_): _description_ + """ diff --git a/data/CreateTransactionIncomeFailed.json b/data/CreateTransactionIncomeFailed.json new file mode 100644 index 0000000..c59bfd6 --- /dev/null +++ b/data/CreateTransactionIncomeFailed.json @@ -0,0 +1,140 @@ +{ + "message":"The given data was invalid.", + "errors":{ + "type":[ + "The type field is required." + ], + "account_id":[ + "The account id field is required." + ], + "paid_at":[ + "The paid at field is required." + ], + "amount":[ + "The amount field is required." + ], + "currency_code":[ + "The currency code field is required." + ], + "currency_rate":[ + "The currency rate field is required." + ], + "category_id":[ + "The category id field is required." + ], + "payment_method":[ + "The payment method field is required." + ] + }, + "status_code":422, + "debug":{ + "line":138, + "file":"/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/FormRequest.php", + "class":"Illuminate\\Validation\\ValidationException", + "trace":[ + "#0 /var/www/html/vendor/laravel/framework/src/Illuminate/Validation/ValidatesWhenResolvedTrait.php(26): Illuminate\\Foundation\\Http\\FormRequest->failedValidation(Object(Illuminate\\Validation\\Validator))", + "#1 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Providers/FormRequestServiceProvider.php(30): Illuminate\\Foundation\\Http\\FormRequest->validateResolved()", + "#2 /var/www/html/vendor/laravel/framework/src/Illuminate/Container/Container.php(1265): Illuminate\\Foundation\\Providers\\FormRequestServiceProvider->Illuminate\\Foundation\\Providers\\{closure}(Object(App\\Http\\Requests\\Banking\\Transaction), Object(Illuminate\\Foundation\\Application))", + "#3 /var/www/html/vendor/laravel/framework/src/Illuminate/Container/Container.php(1230): Illuminate\\Container\\Container->fireCallbackArray(Object(App\\Http\\Requests\\Banking\\Transaction), Array)", + "#4 /var/www/html/vendor/laravel/framework/src/Illuminate/Container/Container.php(1215): Illuminate\\Container\\Container->fireAfterResolvingCallbacks('App\\\\Http\\\\Reques...', Object(App\\Http\\Requests\\Banking\\Transaction))", + "#5 /var/www/html/vendor/laravel/framework/src/Illuminate/Container/Container.php(778): Illuminate\\Container\\Container->fireResolvingCallbacks('App\\\\Http\\\\Reques...', Object(App\\Http\\Requests\\Banking\\Transaction))", + "#6 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(851): Illuminate\\Container\\Container->resolve('App\\\\Http\\\\Reques...', Array, true)", + "#7 /var/www/html/vendor/laravel/framework/src/Illuminate/Container/Container.php(694): Illuminate\\Foundation\\Application->resolve('App\\\\Http\\\\Reques...', Array)", + "#8 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(836): Illuminate\\Container\\Container->make('App\\\\Http\\\\Reques...', Array)", + "#9 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/RouteDependencyResolverTrait.php(79): Illuminate\\Foundation\\Application->make('App\\\\Http\\\\Reques...')", + "#10 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/RouteDependencyResolverTrait.php(48): Illuminate\\Routing\\ControllerDispatcher->transformDependency(Object(ReflectionParameter), Array, Object(stdClass))", + "#11 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/RouteDependencyResolverTrait.php(28): Illuminate\\Routing\\ControllerDispatcher->resolveMethodDependencies(Array, Object(ReflectionMethod))", + "#12 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php(41): Illuminate\\Routing\\ControllerDispatcher->resolveClassMethodDependencies(Array, Object(App\\Http\\Controllers\\Api\\Banking\\Transactions), 'store')", + "#13 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Route.php(262): Illuminate\\Routing\\ControllerDispatcher->dispatch(Object(Illuminate\\Routing\\Route), Object(App\\Http\\Controllers\\Api\\Banking\\Transactions), 'store')", + "#14 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Route.php(205): Illuminate\\Routing\\Route->runController()", + "#15 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(721): Illuminate\\Routing\\Route->run()", + "#16 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(128): Illuminate\\Routing\\Router->Illuminate\\Routing\\{closure}(Object(Dingo\\Api\\Http\\Request))", + "#17 /var/www/html/vendor/santigarcor/laratrust/src/Middleware/LaratrustPermission.php(25): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Dingo\\Api\\Http\\Request))", + "#18 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Laratrust\\Middleware\\LaratrustPermission->handle(Object(Dingo\\Api\\Http\\Request), Object(Closure), 'create-sales-re...')", + "#19 /var/www/html/app/Http/Middleware/Dropzone.php(75): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Dingo\\Api\\Http\\Request))", + "#20 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): App\\Http\\Middleware\\Dropzone->handle(Object(Dingo\\Api\\Http\\Request), Object(Closure))", + "#21 /var/www/html/app/Http/Middleware/Money.php(98): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Dingo\\Api\\Http\\Request))", + "#22 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): App\\Http\\Middleware\\Money->handle(Object(Dingo\\Api\\Http\\Request), Object(Closure))", + "#23 /var/www/html/app/Http/Middleware/DateFormat.php(39): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Dingo\\Api\\Http\\Request))", + "#24 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): App\\Http\\Middleware\\DateFormat->handle(Object(Dingo\\Api\\Http\\Request), Object(Closure))", + "#25 /var/www/html/vendor/akaunting/laravel-firewall/src/Abstracts/Middleware.php(36): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Dingo\\Api\\Http\\Request))", + "#26 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Akaunting\\Firewall\\Abstracts\\Middleware->handle(Object(Dingo\\Api\\Http\\Request), Object(Closure))", + "#27 /var/www/html/vendor/akaunting/laravel-firewall/src/Abstracts/Middleware.php(36): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Dingo\\Api\\Http\\Request))", + "#28 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Akaunting\\Firewall\\Abstracts\\Middleware->handle(Object(Dingo\\Api\\Http\\Request), Object(Closure))", + "#29 /var/www/html/vendor/akaunting/laravel-firewall/src/Abstracts/Middleware.php(36): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Dingo\\Api\\Http\\Request))", + "#30 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Akaunting\\Firewall\\Abstracts\\Middleware->handle(Object(Dingo\\Api\\Http\\Request), Object(Closure))", + "#31 /var/www/html/vendor/akaunting/laravel-firewall/src/Abstracts/Middleware.php(36): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Dingo\\Api\\Http\\Request))", + "#32 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Akaunting\\Firewall\\Abstracts\\Middleware->handle(Object(Dingo\\Api\\Http\\Request), Object(Closure))", + "#33 /var/www/html/vendor/akaunting/laravel-firewall/src/Abstracts/Middleware.php(36): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Dingo\\Api\\Http\\Request))", + "#34 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Akaunting\\Firewall\\Abstracts\\Middleware->handle(Object(Dingo\\Api\\Http\\Request), Object(Closure))", + "#35 /var/www/html/vendor/akaunting/laravel-firewall/src/Abstracts/Middleware.php(36): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Dingo\\Api\\Http\\Request))", + "#36 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Akaunting\\Firewall\\Abstracts\\Middleware->handle(Object(Dingo\\Api\\Http\\Request), Object(Closure))", + "#37 /var/www/html/vendor/akaunting/laravel-firewall/src/Abstracts/Middleware.php(29): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Dingo\\Api\\Http\\Request))", + "#38 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Akaunting\\Firewall\\Abstracts\\Middleware->handle(Object(Dingo\\Api\\Http\\Request), Object(Closure))", + "#39 /var/www/html/vendor/akaunting/laravel-firewall/src/Abstracts/Middleware.php(36): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Dingo\\Api\\Http\\Request))", + "#40 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Akaunting\\Firewall\\Abstracts\\Middleware->handle(Object(Dingo\\Api\\Http\\Request), Object(Closure))", + "#41 /var/www/html/vendor/akaunting/laravel-firewall/src/Abstracts/Middleware.php(36): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Dingo\\Api\\Http\\Request))", + "#42 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Akaunting\\Firewall\\Abstracts\\Middleware->handle(Object(Dingo\\Api\\Http\\Request), Object(Closure))", + "#43 /var/www/html/vendor/akaunting/laravel-firewall/src/Abstracts/Middleware.php(36): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Dingo\\Api\\Http\\Request))", + "#44 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Akaunting\\Firewall\\Abstracts\\Middleware->handle(Object(Dingo\\Api\\Http\\Request), Object(Closure))", + "#45 /var/www/html/vendor/akaunting/laravel-firewall/src/Abstracts/Middleware.php(36): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Dingo\\Api\\Http\\Request))", + "#46 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Akaunting\\Firewall\\Abstracts\\Middleware->handle(Object(Dingo\\Api\\Http\\Request), Object(Closure))", + "#47 /var/www/html/vendor/akaunting/laravel-language/src/Middleware/SetLocale.php(95): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Dingo\\Api\\Http\\Request))", + "#48 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Akaunting\\Language\\Middleware\\SetLocale->handle(Object(Dingo\\Api\\Http\\Request), Object(Closure))", + "#49 /var/www/html/app/Http/Middleware/CheckForReadOnlyMode.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Dingo\\Api\\Http\\Request))", + "#50 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): App\\Http\\Middleware\\CheckForReadOnlyMode->handle(Object(Dingo\\Api\\Http\\Request), Object(Closure))", + "#51 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php(50): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Dingo\\Api\\Http\\Request))", + "#52 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Routing\\Middleware\\SubstituteBindings->handle(Object(Dingo\\Api\\Http\\Request), Object(Closure))", + "#53 /var/www/html/app/Http/Middleware/IdentifyCompany.php(60): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Dingo\\Api\\Http\\Request))", + "#54 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): App\\Http\\Middleware\\IdentifyCompany->handle(Object(Dingo\\Api\\Http\\Request), Object(Closure))", + "#55 /var/www/html/vendor/santigarcor/laratrust/src/Middleware/LaratrustPermission.php(25): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Dingo\\Api\\Http\\Request))", + "#56 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Laratrust\\Middleware\\LaratrustPermission->handle(Object(Dingo\\Api\\Http\\Request), Object(Closure), 'read-api')", + "#57 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php(127): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Dingo\\Api\\Http\\Request))", + "#58 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php(103): Illuminate\\Routing\\Middleware\\ThrottleRequests->handleRequest(Object(Dingo\\Api\\Http\\Request), Object(Closure), Array)", + "#59 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php(55): Illuminate\\Routing\\Middleware\\ThrottleRequests->handleRequestUsingNamedLimiter(Object(Dingo\\Api\\Http\\Request), Object(Closure), 'api', Object(Closure))", + "#60 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Routing\\Middleware\\ThrottleRequests->handle(Object(Dingo\\Api\\Http\\Request), Object(Closure), 'api')", + "#61 /var/www/html/app/Http/Middleware/LogoutIfUserDisabled.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Dingo\\Api\\Http\\Request))", + "#62 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): App\\Http\\Middleware\\LogoutIfUserDisabled->handle(Object(Dingo\\Api\\Http\\Request), Object(Closure))", + "#63 /var/www/html/vendor/dingo/api/src/Http/Middleware/Auth.php(55): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Dingo\\Api\\Http\\Request))", + "#64 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Dingo\\Api\\Http\\Middleware\\Auth->handle(Object(Dingo\\Api\\Http\\Request), Object(Closure))", + "#65 /var/www/html/vendor/dingo/api/src/Http/Middleware/PrepareController.php(45): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Dingo\\Api\\Http\\Request))", + "#66 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Dingo\\Api\\Http\\Middleware\\PrepareController->handle(Object(Dingo\\Api\\Http\\Request), Object(Closure))", + "#67 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(103): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Dingo\\Api\\Http\\Request))", + "#68 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(723): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))", + "#69 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(698): Illuminate\\Routing\\Router->runRouteWithinStack(Object(Illuminate\\Routing\\Route), Object(Dingo\\Api\\Http\\Request))", + "#70 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(662): Illuminate\\Routing\\Router->runRoute(Object(Dingo\\Api\\Http\\Request), Object(Illuminate\\Routing\\Route))", + "#71 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(651): Illuminate\\Routing\\Router->dispatchToRoute(Object(Dingo\\Api\\Http\\Request))", + "#72 /var/www/html/vendor/dingo/api/src/Routing/Adapter/Laravel.php(88): Illuminate\\Routing\\Router->dispatch(Object(Dingo\\Api\\Http\\Request))", + "#73 /var/www/html/vendor/dingo/api/src/Routing/Router.php(518): Dingo\\Api\\Routing\\Adapter\\Laravel->dispatch(Object(Dingo\\Api\\Http\\Request), 'v3')", + "#74 /var/www/html/vendor/dingo/api/src/Http/Middleware/Request.php(126): Dingo\\Api\\Routing\\Router->dispatch(Object(Dingo\\Api\\Http\\Request))", + "#75 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(128): Dingo\\Api\\Http\\Middleware\\Request->Dingo\\Api\\Http\\Middleware\\{closure}(Object(Dingo\\Api\\Http\\Request))", + "#76 /var/www/html/vendor/barryvdh/laravel-debugbar/src/Middleware/InjectDebugbar.php(60): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Dingo\\Api\\Http\\Request))", + "#77 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Barryvdh\\Debugbar\\Middleware\\InjectDebugbar->handle(Object(Dingo\\Api\\Http\\Request), Object(Closure))", + "#78 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Dingo\\Api\\Http\\Request))", + "#79 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php(31): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle(Object(Dingo\\Api\\Http\\Request), Object(Closure))", + "#80 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull->handle(Object(Dingo\\Api\\Http\\Request), Object(Closure))", + "#81 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Dingo\\Api\\Http\\Request))", + "#82 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php(40): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle(Object(Dingo\\Api\\Http\\Request), Object(Closure))", + "#83 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Foundation\\Http\\Middleware\\TrimStrings->handle(Object(Dingo\\Api\\Http\\Request), Object(Closure))", + "#84 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php(27): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Dingo\\Api\\Http\\Request))", + "#85 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize->handle(Object(Dingo\\Api\\Http\\Request), Object(Closure))", + "#86 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php(86): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Dingo\\Api\\Http\\Request))", + "#87 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance->handle(Object(Dingo\\Api\\Http\\Request), Object(Closure))", + "#88 /var/www/html/vendor/fruitcake/laravel-cors/src/HandleCors.php(52): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Dingo\\Api\\Http\\Request))", + "#89 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Fruitcake\\Cors\\HandleCors->handle(Object(Dingo\\Api\\Http\\Request), Object(Closure))", + "#90 /var/www/html/vendor/fideloper/proxy/src/TrustProxies.php(57): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Dingo\\Api\\Http\\Request))", + "#91 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Fideloper\\Proxy\\TrustProxies->handle(Object(Dingo\\Api\\Http\\Request), Object(Closure))", + "#92 /var/www/html/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustHosts.php(48): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Dingo\\Api\\Http\\Request))", + "#93 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Http\\Middleware\\TrustHosts->handle(Object(Dingo\\Api\\Http\\Request), Object(Closure))", + "#94 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(103): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Dingo\\Api\\Http\\Request))", + "#95 /var/www/html/vendor/dingo/api/src/Http/Middleware/Request.php(127): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))", + "#96 /var/www/html/vendor/dingo/api/src/Http/Middleware/Request.php(103): Dingo\\Api\\Http\\Middleware\\Request->sendRequestThroughRouter(Object(Dingo\\Api\\Http\\Request))", + "#97 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Dingo\\Api\\Http\\Middleware\\Request->handle(Object(Dingo\\Api\\Http\\Request), Object(Closure))", + "#98 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(103): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))", + "#99 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(142): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))", + "#100 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(111): Illuminate\\Foundation\\Http\\Kernel->sendRequestThroughRouter(Object(Illuminate\\Http\\Request))", + "#101 /var/www/html/index.php(20): Illuminate\\Foundation\\Http\\Kernel->handle(Object(Illuminate\\Http\\Request))", + "#102 {main}" + ] + } + } \ No newline at end of file diff --git a/data/CreateTransactionIncomeSuccess.json b/data/CreateTransactionIncomeSuccess.json new file mode 100644 index 0000000..a1dce95 --- /dev/null +++ b/data/CreateTransactionIncomeSuccess.json @@ -0,0 +1,94 @@ +{ + "data":{ + "id":8, + "company_id":1, + "type":"income", + "account_id":"2", + "paid_at":"2022-05-15T07:44:49+12:00", + "amount":25, + "amount_formatted":"$25.00", + "currency_code":"NZD", + "currency_rate":1, + "document_id":"None", + "contact_id":"None", + "description":"None", + "category_id":"3", + "payment_method":"bank_transfer", + "reference":"None", + "attachment":false, + "created_by":1, + "created_at":"2022-05-16T07:44:49+12:00", + "updated_at":"2022-05-16T07:44:49+12:00", + "account":{ + "data":{ + "id":2, + "company_id":1, + "name":"WHS Account", + "number":"38-9011-0510023-03", + "currency_code":"NZD", + "opening_balance":0, + "opening_balance_formatted":"$0.00", + "current_balance":300, + "current_balance_formatted":"$300.00", + "bank_name":"Kiwibank", + "bank_phone":"None", + "bank_address":"None", + "enabled":true, + "created_by":1, + "created_at":"2022-05-13T16:16:16+12:00", + "updated_at":"2022-05-13T16:16:16+12:00" + } + }, + "category":{ + "data":{ + "id":3, + "company_id":1, + "name":"Sales", + "type":"income", + "color":"#6da252", + "enabled":true, + "created_by":"None", + "created_at":"2022-05-13T03:14:40+12:00", + "updated_at":"2022-05-13T03:14:40+12:00" + } + }, + "contact":{ + "data":{ + "id":"None", + "company_id":"None", + "user_id":"None", + "type":"None", + "name":"N/A", + "email":"None", + "tax_number":"None", + "phone":"None", + "address":"None", + "website":"None", + "currency_code":"None", + "enabled":"None", + "reference":"None", + "created_by":"None", + "created_at":"", + "updated_at":"" + } + }, + "currency":{ + "data":{ + "id":5, + "company_id":1, + "name":"NZ Dollar", + "code":"NZD", + "rate":1, + "enabled":true, + "precision":2, + "symbol":"$", + "symbol_first":1, + "decimal_mark":".", + "thousands_separator":",", + "created_by":1, + "created_at":"2022-05-13T03:21:17+12:00", + "updated_at":"2022-05-13T03:21:17+12:00" + } + } + } + } \ No newline at end of file diff --git a/data/GetAccountsList.json b/data/GetAccountsList.json new file mode 100644 index 0000000..d0e9765 --- /dev/null +++ b/data/GetAccountsList.json @@ -0,0 +1,70 @@ +{ + "data":[ + { + "id":1, + "company_id":1, + "name":"Cash", + "number":"1", + "currency_code":"NZD", + "opening_balance":0, + "opening_balance_formatted":"$0.00", + "current_balance":-250, + "current_balance_formatted":"-$250.00", + "bank_name":"Cash", + "bank_phone":"None", + "bank_address":"None", + "enabled":true, + "created_by":"None", + "created_at":"2022-05-13T03:14:40+12:00", + "updated_at":"2022-05-13T03:32:28+12:00" + }, + { + "id":3, + "company_id":1, + "name":"Kiwibank Visa", + "number":"4446-89**-****-5385", + "currency_code":"NZD", + "opening_balance":-250, + "opening_balance_formatted":"-$250.00", + "current_balance":-250, + "current_balance_formatted":"-$250.00", + "bank_name":"None", + "bank_phone":"None", + "bank_address":"None", + "enabled":true, + "created_by":1, + "created_at":"2022-05-13T16:19:26+12:00", + "updated_at":"2022-05-13T16:19:26+12:00" + }, + { + "id":2, + "company_id":1, + "name":"WHS Account", + "number":"38-9011-0510023-03", + "currency_code":"NZD", + "opening_balance":0, + "opening_balance_formatted":"$0.00", + "current_balance":200, + "current_balance_formatted":"$200.00", + "bank_name":"Kiwibank", + "bank_phone":"None", + "bank_address":"None", + "enabled":true, + "created_by":1, + "created_at":"2022-05-13T16:16:16+12:00", + "updated_at":"2022-05-13T16:16:16+12:00" + } + ], + "meta":{ + "pagination":{ + "total":3, + "count":3, + "per_page":25, + "current_page":1, + "total_pages":1, + "links":{ + + } + } + } + } \ No newline at end of file diff --git a/data/pingFailure.json b/data/pingFailure.json new file mode 100644 index 0000000..b598e45 --- /dev/null +++ b/data/pingFailure.json @@ -0,0 +1,55 @@ +{ + "message":"Invalid credentials.", + "status_code":401, + "debug":{ + "line":352, + "file":"/var/www/html/vendor/laravel/framework/src/Illuminate/Auth/SessionGuard.php", + "class":"Symfony\\Component\\HttpKernel\\Exception\\UnauthorizedHttpException", + "trace":[ + "#0 /var/www/html/vendor/laravel/framework/src/Illuminate/Auth/SessionGuard.php(308): Illuminate\\Auth\\SessionGuard->failedBasicResponse()", + "#1 /var/www/html/vendor/laravel/framework/src/Illuminate/Auth/AuthManager.php(336): Illuminate\\Auth\\SessionGuard->onceBasic('email')", + "#2 /var/www/html/vendor/dingo/api/src/Auth/Provider/Basic.php(52): Illuminate\\Auth\\AuthManager->__call('onceBasic', Array)", + "#3 /var/www/html/vendor/dingo/api/src/Auth/Auth.php(82): Dingo\\Api\\Auth\\Provider\\Basic->authenticate(Object(Dingo\\Api\\Http\\Request), Object(Dingo\\Api\\Routing\\Route))", + "#4 /var/www/html/vendor/dingo/api/src/Http/Middleware/Auth.php(52): Dingo\\Api\\Auth\\Auth->authenticate(Array)", + "#5 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Dingo\\Api\\Http\\Middleware\\Auth->handle(Object(Dingo\\Api\\Http\\Request), Object(Closure))", + "#6 /var/www/html/vendor/dingo/api/src/Http/Middleware/PrepareController.php(45): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Dingo\\Api\\Http\\Request))", + "#7 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Dingo\\Api\\Http\\Middleware\\PrepareController->handle(Object(Dingo\\Api\\Http\\Request), Object(Closure))", + "#8 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(103): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Dingo\\Api\\Http\\Request))", + "#9 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(723): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))", + "#10 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(698): Illuminate\\Routing\\Router->runRouteWithinStack(Object(Illuminate\\Routing\\Route), Object(Dingo\\Api\\Http\\Request))", + "#11 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(662): Illuminate\\Routing\\Router->runRoute(Object(Dingo\\Api\\Http\\Request), Object(Illuminate\\Routing\\Route))", + "#12 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(651): Illuminate\\Routing\\Router->dispatchToRoute(Object(Dingo\\Api\\Http\\Request))", + "#13 /var/www/html/vendor/dingo/api/src/Routing/Adapter/Laravel.php(88): Illuminate\\Routing\\Router->dispatch(Object(Dingo\\Api\\Http\\Request))", + "#14 /var/www/html/vendor/dingo/api/src/Routing/Router.php(518): Dingo\\Api\\Routing\\Adapter\\Laravel->dispatch(Object(Dingo\\Api\\Http\\Request), 'v3')", + "#15 /var/www/html/vendor/dingo/api/src/Http/Middleware/Request.php(126): Dingo\\Api\\Routing\\Router->dispatch(Object(Dingo\\Api\\Http\\Request))", + "#16 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(128): Dingo\\Api\\Http\\Middleware\\Request->Dingo\\Api\\Http\\Middleware\\{closure}(Object(Dingo\\Api\\Http\\Request))", + "#17 /var/www/html/vendor/barryvdh/laravel-debugbar/src/Middleware/InjectDebugbar.php(60): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Dingo\\Api\\Http\\Request))", + "#18 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Barryvdh\\Debugbar\\Middleware\\InjectDebugbar->handle(Object(Dingo\\Api\\Http\\Request), Object(Closure))", + "#19 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Dingo\\Api\\Http\\Request))", + "#20 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php(31): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle(Object(Dingo\\Api\\Http\\Request), Object(Closure))", + "#21 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull->handle(Object(Dingo\\Api\\Http\\Request), Object(Closure))", + "#22 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Dingo\\Api\\Http\\Request))", + "#23 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php(40): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle(Object(Dingo\\Api\\Http\\Request), Object(Closure))", + "#24 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Foundation\\Http\\Middleware\\TrimStrings->handle(Object(Dingo\\Api\\Http\\Request), Object(Closure))", + "#25 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php(27): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Dingo\\Api\\Http\\Request))", + "#26 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize->handle(Object(Dingo\\Api\\Http\\Request), Object(Closure))", + "#27 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php(86): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Dingo\\Api\\Http\\Request))", + "#28 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance->handle(Object(Dingo\\Api\\Http\\Request), Object(Closure))", + "#29 /var/www/html/vendor/fruitcake/laravel-cors/src/HandleCors.php(52): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Dingo\\Api\\Http\\Request))", + "#30 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Fruitcake\\Cors\\HandleCors->handle(Object(Dingo\\Api\\Http\\Request), Object(Closure))", + "#31 /var/www/html/vendor/fideloper/proxy/src/TrustProxies.php(57): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Dingo\\Api\\Http\\Request))", + "#32 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Fideloper\\Proxy\\TrustProxies->handle(Object(Dingo\\Api\\Http\\Request), Object(Closure))", + "#33 /var/www/html/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustHosts.php(48): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Dingo\\Api\\Http\\Request))", + "#34 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Http\\Middleware\\TrustHosts->handle(Object(Dingo\\Api\\Http\\Request), Object(Closure))", + "#35 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(103): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Dingo\\Api\\Http\\Request))", + "#36 /var/www/html/vendor/dingo/api/src/Http/Middleware/Request.php(127): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))", + "#37 /var/www/html/vendor/dingo/api/src/Http/Middleware/Request.php(103): Dingo\\Api\\Http\\Middleware\\Request->sendRequestThroughRouter(Object(Dingo\\Api\\Http\\Request))", + "#38 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Dingo\\Api\\Http\\Middleware\\Request->handle(Object(Dingo\\Api\\Http\\Request), Object(Closure))", + "#39 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(103): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))", + "#40 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(142): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))", + "#41 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(111): Illuminate\\Foundation\\Http\\Kernel->sendRequestThroughRouter(Object(Illuminate\\Http\\Request))", + "#42 /var/www/html/index.php(20): Illuminate\\Foundation\\Http\\Kernel->handle(Object(Illuminate\\Http\\Request))", + "#43 {main}" + ] + } + } \ No newline at end of file diff --git a/data/pingSuccess.json b/data/pingSuccess.json new file mode 100644 index 0000000..b8c4d02 --- /dev/null +++ b/data/pingSuccess.json @@ -0,0 +1,4 @@ +{ + "status": "ok", + "timestamp": "2022-05-14T04:47:30.612024Z" +} \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..8f91654 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +requests >= 2.21.0 +pytest \ No newline at end of file diff --git a/scratch.py b/scratch.py new file mode 100644 index 0000000..1fd84ed --- /dev/null +++ b/scratch.py @@ -0,0 +1,7 @@ +def MergeDict(dict1, dict2): + dict2.update(dict1) + return dict2 + +dict1 = {'company_id': 1} +dict2 = {'page':1, 'limit': 25} + diff --git a/tests/api_test.py b/tests/api_test.py new file mode 100644 index 0000000..2c8594b --- /dev/null +++ b/tests/api_test.py @@ -0,0 +1,106 @@ +import sys +from this import d +sys.path.insert(1, '.') +import pytest +import akauntingpy +from akauntingpy.exceptions import * +from helpers import RetrieveJSONFromFile +from requests.auth import HTTPBasicAuth + +class TestAPI: + @pytest.fixture() + def setUp(self): + c = akauntingpy.Client("https://akaunting.guise.net.nz/api", + "aaron@guise.net.nz", + "L3Tm31N0w", + 1) + yield c + + @pytest.fixture() + def setUpFailed(self): + c = akauntingpy.Client("https://akaunting.guise.net.nz/api", + "aaron@guise.net.nz", + "L3Tm31N0w1", + 1) + yield c + + def test_init(self, setUp): + c = setUp + assert isinstance(c, akauntingpy.Client) + assert c.url == "https://akaunting.guise.net.nz/api" + assert isinstance(c.authentication, HTTPBasicAuth) + + def test_ping_success(self, setUp, requests_mock): + c = setUp + requests_mock.get(c.url + '/ping', + json=RetrieveJSONFromFile("data/pingSuccess.json"), + status_code=200) + data = c.ping() + # The returned data should have status = ok + assert data['status'] == 'ok' + + def test_ping_failed(self, setUpFailed, requests_mock): + c = setUpFailed + requests_mock.get(c.url + '/ping', + json=RetrieveJSONFromFile("data/pingFailure.json"), + status_code=401) + with pytest.raises(MissingPermission, match="Invalid credentials."): + + data = c.ping() + assert data['status_code'] == 401 + + def test_get_accounts(self, setUp, requests_mock): + c = setUp + requests_mock.get(c.url + "/accounts", + json=RetrieveJSONFromFile("data/GetAccountsList.json")) + data = c.get_accounts(params={'page': 1, 'limit': 200}) + + def test_create_transaction_success(self, setUp, requests_mock, + type='income', # Payment method type + account_id=2, # Account ID to assign + category_id=3, # Category ID to assign + contact_id=None, # Contact ID/Client to assign + paid_at="2022-05-15", # Date of expense/transfer or income + reference=None, # Reference for the payment + payment_method="bank_transfer", # Payment method + currency_code="NZD", # Currency code + currency_rate=1, # Currency rate + amount="25.00", # Amount received/paid + ): + c = setUp + requests_mock.post(c.url + "/transactions", + json=RetrieveJSONFromFile("data/CreateTransactionIncomeSuccess.json"), + status_code=201) + data = c.create_transaction(type=type, + account_id=account_id, + category_id=category_id, + paid_at=paid_at, + contact_id=contact_id, + payment_method=payment_method, + reference=reference, + currency_code=currency_code, + currency_rate=currency_rate, + amount=amount, + description="Some description of the transaction" + ) + + def test_create_transaction_failed(self, setUp, requests_mock, + contact_id=None, # Contact ID/Client to assign + reference=None, # Reference for the payment + currency_code="NZD", # Currency code + currency_rate=1, # Currency rate + amount="25.00", # Amount received/paid + ): + c = setUp + requests_mock.post(c.url + "/transactions", + json=RetrieveJSONFromFile("data/CreateTransactionIncomeFailed.json"), + status_code=422) + with pytest.raises(InvalidData, match="The given data was invalid.*"): + data = c.create_transaction(contact_id=contact_id, + reference=reference, + currency_code=currency_code, + currency_rate=currency_rate, + amount=amount, + description="Some description of the transaction" + ) + diff --git a/tests/helpers.py b/tests/helpers.py new file mode 100644 index 0000000..a02131e --- /dev/null +++ b/tests/helpers.py @@ -0,0 +1,7 @@ +import json + +def RetrieveJSONFromFile(filename): + with open(filename) as f: + data = json.load(f) + + return data \ No newline at end of file