Skip to content

Commit

Permalink
feat(application): Implemented Installation API (#142)
Browse files Browse the repository at this point in the history
  • Loading branch information
OmAximani0 authored Dec 22, 2023
1 parent b4075ab commit 6b60cbf
Show file tree
Hide file tree
Showing 4 changed files with 263 additions and 3 deletions.
14 changes: 14 additions & 0 deletions crowdin_api/api_resources/application/enums.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from enum import Enum


class UserPermissions(Enum):
OWNER = "owner"
MANAGERS = "managers"
ALL = "all"
GUESTS = "guests"
RESTRICTED = "restricted"


class ProjectPermissions(Enum):
OWN = "own"
RESTRICTED = "restricted"
85 changes: 84 additions & 1 deletion crowdin_api/api_resources/application/resource.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
from typing import Optional, Iterable
from crowdin_api.parser import dumps

from crowdin_api.api_resources.application.types import (
ApplicationPermissions,
ApplicationInstallationPatchRequest,
)
from crowdin_api.api_resources.abstract.resources import BaseResource


Expand All @@ -19,6 +23,85 @@ class ApplicationResource(BaseResource):
def get_application_path(self, applicationIdentifier: str, path: str):
return f"applications/{applicationIdentifier}/api/{path}"

def get_application_installations_path(self, identifier: Optional[str] = None):
if identifier:
return f"applications/installations/{identifier}"
return "applications/installations"

def list_application_installations(
self,
offset: Optional[int] = None,
limit: Optional[int] = None,
):
"""
List Application Installations
Link to documentaion:
https://developer.crowdin.com/api/v2/#operation/api.applications.installations.getMany
"""
return self.requester.request(
method="get",
path=self.get_application_installations_path(),
params=self.get_page_params(offset=offset, limit=limit),
)

def install_application(
self, url: str, permissions: Optional[ApplicationPermissions] = None
):
"""
Install Application
Link to documentation:
https://developer.crowdin.com/api/v2/#operation/api.applications.installations.post
"""
request_data = {"url": url, "permissions": permissions}
return self.requester.request(
method="post",
path=self.get_application_installations_path(),
request_data=request_data,
)

def get_application_installation(self, identifier: str):
"""
Get Application Installation
Link to documentation:
https://developer.crowdin.com/api/v2/#operation/api.applications.installations.get
"""
return self.requester.request(
method="get",
path=self.get_application_installations_path(identifier=identifier),
)

def delete_application_installation(
self, identifier: str, force: Optional[bool] = None
):
"""
Delete Applcation Installation
Link to documentation:
https://developer.crowdin.com/api/v2/#operation/api.applications.installations.delete
"""
params = {"force": force}

return self.requester.request(
method="delete",
path=self.get_application_installations_path(identifier=identifier),
params=params,
)

def edit_applicatoin_installation(
self, identifier: str, data: Iterable[ApplicationInstallationPatchRequest]
):
"""
Edit Application Installation
"""
return self.requester.request(
method="patch",
path=self.get_application_installations_path(identifier=identifier),
request_data=data,
)

def get_application_data(self, applicationIdentifier: str, path: str):
"""
Get Application Data.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
from unittest import mock


import pytest
from crowdin_api.api_resources.application.resource import ApplicationResource
from crowdin_api.api_resources.application.enums import (
UserPermissions,
ProjectPermissions,
)
from crowdin_api.requester import APIRequester


Expand All @@ -22,6 +24,140 @@ def test_get_applications_path(self, in_params, path, base_absolut_url):
resource = self.get_resource(base_absolut_url)
assert resource.get_application_path(**in_params) == path

@pytest.mark.parametrize(
"in_params, path",
(
(None, "applications/installations"),
("test", "applications/installations/test"),
),
)
def test_get_application_installation_path(self, in_params, path, base_absolut_url):
resource = self.get_resource(base_absolut_url)
assert resource.get_application_installations_path(in_params) == path

@mock.patch("crowdin_api.requester.APIRequester.request")
def test_list_application_installations(self, m_request, base_absolut_url):
m_request.return_value = "response"

resource = self.get_resource(base_absolut_url)
assert resource.list_application_installations() == "response"
m_request.assert_called_once_with(
method="get",
path=resource.get_application_installations_path(),
params=resource.get_page_params()
)

@pytest.mark.parametrize(
"in_params, request_data",
(
(
{
"url": "https://localhost.dev/crowdin.json",
},
{
"url": "https://localhost.dev/crowdin.json",
"permissions": None
}
),
(
{
"url": "https://localhost.dev/crowdin.json",
"permissions": {
"user": {
"value": UserPermissions.OWNER,
"ids": [1, 2, 3]
},
"project": {
"value": ProjectPermissions.OWN,
"ids": [4, 5, 6]
}
}
},
{
"url": "https://localhost.dev/crowdin.json",
"permissions": {
"user": {
"value": UserPermissions.OWNER,
"ids": [1, 2, 3]
},
"project": {
"value": ProjectPermissions.OWN,
"ids": [4, 5, 6]
}
}
}
),
),
)
@mock.patch("crowdin_api.requester.APIRequester.request")
def test_install_application(self, m_request, in_params, request_data, base_absolut_url):
m_request.return_value = "response"

resource = self.get_resource(base_absolut_url)
assert resource.install_application(**in_params) == "response"
m_request.assert_called_once_with(
method="post",
path=resource.get_application_installations_path(),
request_data=request_data
)

@mock.patch("crowdin_api.requester.APIRequester.request")
def test_get_applcation_installation(self, m_request, base_absolut_url):
m_request.return_value = "response"

identifier = "example-application"
resource = self.get_resource(base_absolut_url)
assert resource.get_application_installation(identifier) == "response"
m_request.assert_called_once_with(
method="get",
path=resource.get_application_installations_path(identifier),
)

@pytest.mark.parametrize(
"in_params, request_param",
(
({}, {"force": None}),
({"force": True}, {"force": True}),
),
)
@mock.patch("crowdin_api.requester.APIRequester.request")
def test_delete_application_installation(
self, m_request, in_params, request_param, base_absolut_url
):
m_request.return_value = "response"

resource = self.get_resource(base_absolut_url)
assert (
resource.delete_application_installation(
identifier="example-app", **in_params
)
== "response"
)
m_request.assert_called_once_with(
method="delete",
path=resource.get_application_installations_path(identifier="example-app"),
params=request_param
)

@mock.patch("crowdin_api.requester.APIRequester.request")
def test_edit_application_installation(
self, m_request, base_absolut_url
):
m_request.return_value = "response"

identifier = "exmaple-application"
data = [{"op": "replace", "path": "/permissions", "value": "test"}]
resource = self.get_resource(base_absolut_url)
assert resource.edit_applicatoin_installation(
identifier=identifier,
data=data,
)
m_request.assert_called_once_with(
method="patch",
path=resource.get_application_installations_path(identifier=identifier),
request_data=data,
)

@mock.patch("crowdin_api.requester.APIRequester.request")
def test_get_application_data(self, m_request, base_absolut_url):
m_request.return_value = "response"
Expand Down
27 changes: 27 additions & 0 deletions crowdin_api/api_resources/application/types.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from typing import Iterable
from crowdin_api.typing import TypedDict
from crowdin_api.api_resources.application.enums import (
UserPermissions,
ProjectPermissions,
)


class ApplicationUser(TypedDict):
value: UserPermissions
ids: Iterable[int]


class ApplicationProject(TypedDict):
value: ProjectPermissions
ids: Iterable[int]


class ApplicationPermissions(TypedDict):
user: ApplicationUser
project: ApplicationProject


class ApplicationInstallationPatchRequest(TypedDict):
op: str
path: str
value: str

0 comments on commit 6b60cbf

Please sign in to comment.