diff --git a/lib/tool_shed/managers/categories.py b/lib/tool_shed/managers/categories.py index 5341c4dea450..1d418f1aa8fa 100644 --- a/lib/tool_shed/managers/categories.py +++ b/lib/tool_shed/managers/categories.py @@ -26,6 +26,9 @@ class CategoryManager: def __init__(self, app: ToolShedApp): self.app = app + def get(self, encoded_category_id: str) -> Category: + return suc.get_category(self.app, encoded_category_id) + def create(self, trans: ProvidesUserContext, category_request: CreateCategoryRequest) -> Category: name = category_request.name description = category_request.description or name @@ -71,6 +74,7 @@ def to_model(self, category: Category) -> CategoryResponse: name=as_dict["name"], description=as_dict["description"], repositories=as_dict["repositories"], + deleted=as_dict["deleted"], ) diff --git a/lib/tool_shed/test/base/populators.py b/lib/tool_shed/test/base/populators.py index 9b63e1f7a559..19b6b697b46e 100644 --- a/lib/tool_shed/test/base/populators.py +++ b/lib/tool_shed/test/base/populators.py @@ -266,9 +266,12 @@ def get_categories(self) -> List[Category]: response.raise_for_status() return [Category(**c) for c in response.json()] - def get_category_with_name(self, name: str) -> Optional[Category]: - response = self._api_interactor.get("categories") + def get_category_with_id(self, category_id: str) -> Category: + response = self._api_interactor.get(f"categories/{category_id}") response.raise_for_status() + return Category(**response.json()) + + def get_category_with_name(self, name: str) -> Optional[Category]: categories = [c for c in self.get_categories() if c.name == name] return categories[0] if categories else None diff --git a/lib/tool_shed/test/functional/test_shed_categories.py b/lib/tool_shed/test/functional/test_shed_categories.py index 63120b72d83c..3f9dd14fa516 100644 --- a/lib/tool_shed/test/functional/test_shed_categories.py +++ b/lib/tool_shed/test/functional/test_shed_categories.py @@ -10,7 +10,18 @@ def test_create_requires_name(self): def test_create_okay(self): name = random_name(prefix="createokay") - body = {"name": name, "description": "testcreateokaydescript"} + description = "testcreateokaydescript" + body = {"name": name, "description": description} response = self.admin_api_interactor.post("categories", json=body) assert response.status_code == 200 assert response.json()["name"] == name + + category = self.populator.get_category_with_name(name) + assert category is not None + assert category.name == name + assert category.description == description + + category_id = category.id + category = self.populator.get_category_with_id(category_id) + assert category.name == name + assert category.description == description diff --git a/lib/tool_shed/webapp/api2/categories.py b/lib/tool_shed/webapp/api2/categories.py index 023242469dd1..cd8696f65cfb 100644 --- a/lib/tool_shed/webapp/api2/categories.py +++ b/lib/tool_shed/webapp/api2/categories.py @@ -56,6 +56,18 @@ def index(self, trans: SessionRequestContext = DependsOnTrans) -> List[CategoryR categories = self.category_manager.index_db(trans, deleted) return [self.category_manager.to_model(c) for c in categories] + @router.get( + "/api/categories/{encoded_category_id}", + description="show category", + operation_id="categories__show", + ) + def show(self, encoded_category_id: str = CategoryIdPathParam) -> CategoryResponse: + """ + Return a list of dictionaries that contain information about each Category. + """ + category = self.category_manager.get(encoded_category_id) + return self.category_manager.to_model(category) + @router.get( "/api/categories/{encoded_category_id}/repositories", description="display repositories by category", diff --git a/lib/tool_shed/webapp/frontend/src/schema/schema.ts b/lib/tool_shed/webapp/frontend/src/schema/schema.ts index 91fd9d54ea0c..c49abf299742 100644 --- a/lib/tool_shed/webapp/frontend/src/schema/schema.ts +++ b/lib/tool_shed/webapp/frontend/src/schema/schema.ts @@ -20,6 +20,13 @@ export interface paths { */ post: operations["categories__create"] } + "/api/categories/{encoded_category_id}": { + /** + * Show + * @description show category + */ + get: operations["categories__show"] + } "/api/categories/{encoded_category_id}/repositories": { /** * Repositories @@ -261,6 +268,8 @@ export interface components { } /** Category */ Category: { + /** Deleted */ + deleted: boolean /** Description */ description: string /** Id */ @@ -1128,6 +1137,32 @@ export interface operations { } } } + categories__show: { + /** + * Show + * @description show category + */ + parameters: { + /** @description The encoded database identifier of the category. */ + path: { + encoded_category_id: string + } + } + responses: { + /** @description Successful Response */ + 200: { + content: { + "application/json": components["schemas"]["Category"] + } + } + /** @description Validation Error */ + 422: { + content: { + "application/json": components["schemas"]["HTTPValidationError"] + } + } + } + } categories__repositories: { /** * Repositories diff --git a/lib/tool_shed_client/schema/__init__.py b/lib/tool_shed_client/schema/__init__.py index a97ca4f3401b..2f4de2cc198f 100644 --- a/lib/tool_shed_client/schema/__init__.py +++ b/lib/tool_shed_client/schema/__init__.py @@ -69,6 +69,7 @@ class Category(BaseModel): id: str name: str description: str + deleted: bool repositories: int