Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added the ability to hide button #60

Merged
merged 6 commits into from
Aug 10, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions migrations/versions/52230bfc3f86_56_add_is_hidden_field.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
"""#56_add_is_hidden_field

Revision ID: 52230bfc3f86
Revises: 1bb798899506
Create Date: 2024-07-29 20:05:34.777852

"""

import sqlalchemy as sa
from alembic import op


# revision identifiers, used by Alembic.
revision = '52230bfc3f86'
down_revision = '1bb798899506'
branch_labels = None
depends_on = None


def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('button', sa.Column('is_hidden', sa.Boolean(), nullable=False))
# ### end Alembic commands ###


def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column('button', 'is_hidden')
# ### end Alembic commands ###
1 change: 1 addition & 0 deletions services_backend/models/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ class Button(Base):
icon: Mapped[str] = mapped_column(String)
link: Mapped[str] = mapped_column(String)
type: Mapped[Type] = mapped_column(DbEnum(Type, native_enum=False), nullable=False)
is_hidden: Mapped[bool] = mapped_column(Boolean, default=False)

_scopes: Mapped[list[Scope]] = relationship("Scope", back_populates="button", lazy='joined', cascade='delete')

Expand Down
38 changes: 30 additions & 8 deletions services_backend/routes/button.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ class ButtonCreate(Base):
name: str = Field(description='Название кнопки')
link: str = Field(description='Ссылка, на которую перенаправляет кнопка')
type: Type = Field(description='Тип открываемой ссылки (Ссылка приложения/Браузер в приложении/Браузер')
required_scopes: set[str] | None = Field(description='Каким скоупы нужны, чтобы кнопка была доступна', default=None)
optional_scopes: set[str] | None = Field(description='Каким скоупы желательны', default=None)
is_hidden: bool = Field(description='Спрятана ли кнопка от пользователя', default=False)
required_scopes: set[str] | None = Field(description='Какие скоупы нужны, чтобы кнопка была доступна', default=None)
optional_scopes: set[str] | None = Field(description='Какиеп скоупы желательны', default=None)


class ButtonUpdate(Base):
Expand All @@ -35,13 +36,15 @@ class ButtonUpdate(Base):
type: Type | None = Field(
description='Тип открываемой ссылки (Ссылка приложения/Браузер в приложении/Браузер', default=None
)
required_scopes: set[str] | None = Field(description='Каким скоупы нужны, чтобы кнопка была доступна', default=None)
optional_scopes: set[str] | None = Field(description='Каким скоупы желательны', default=None)
is_hidden: bool | None = Field(description='Спрятана ли кнопка от пользователя', default=None)
required_scopes: set[str] | None = Field(description='Какие скоупы нужны, чтобы кнопка была доступна', default=None)
optional_scopes: set[str] | None = Field(description='Какие скоупы желательны', default=None)


class ButtonView(Enum):
ACTIVE = "active"
BLOCKED = "blocked"
HIDDEN = "hidden"


class ButtonGet(Base):
Expand Down Expand Up @@ -95,7 +98,20 @@ def create_button(
button.optional_scopes = optional_scopes
db.session.add(button)
db.session.flush()
return button
grigoriev-semyon marked this conversation as resolved.
Show resolved Hide resolved
view = ButtonView.HIDDEN if button.is_hidden else ButtonView.ACTIVE
result = {
"id": button.id,
"icon": button.icon,
"name": button.name,
"link": button.link if view == ButtonView.ACTIVE else None,
"order": button.order,
"type": button.type,
"view": view.value,
"required_scopes": button.required_scopes,
"optional_scopes": button.optional_scopes,
"scopes": [],
}
return result


@button.get("", response_model=ButtonsGet, response_model_exclude_unset=True)
Expand All @@ -120,7 +136,9 @@ def get_buttons(
for button in category.buttons:
view = ButtonView.ACTIVE
scopes = set()
if button.required_scopes - user_scopes:
if button.is_hidden:
view = ButtonView.HIDDEN
elif button.required_scopes - user_scopes:
view = ButtonView.BLOCKED
else:
scopes |= button.required_scopes
Expand Down Expand Up @@ -169,7 +187,9 @@ def get_button(
raise HTTPException(status_code=404, detail="Button is not this category")
view = ButtonView.ACTIVE
scopes = set()
if button.required_scopes - user_scopes:
if button.is_hidden:
view = ButtonView.HIDDEN
elif button.required_scopes - user_scopes:
view = ButtonView.BLOCKED
else:
scopes |= button.required_scopes
Expand Down Expand Up @@ -297,7 +317,9 @@ def get_service(
raise HTTPException(status_code=404, detail="Button does not exist")
view = ButtonView.ACTIVE
scopes = set()
if button.required_scopes - user_scopes:
if button.is_hidden:
view = ButtonView.HIDDEN
elif button.required_scopes - user_scopes:
view = ButtonView.BLOCKED
else:
scopes |= button.required_scopes
Expand Down
2 changes: 1 addition & 1 deletion services_backend/routes/category.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from fastapi_sqlalchemy import db
from pydantic import Field, conint

from services_backend.models.database import Button, Category, Type
from services_backend.models.database import Button, Category
from services_backend.schemas import Base

from .button import ButtonGet, ButtonView
Expand Down
49 changes: 49 additions & 0 deletions tests/api/button.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,3 +235,52 @@ def test_type_not_enum(client, dbsession, db_category):
}
res = client.post(f"/category/{db_category.id}/button", data=json.dumps(body))
assert res.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY

grigoriev-semyon marked this conversation as resolved.
Show resolved Hide resolved

def test_post_hidden_success(client, dbsession, db_category):
body = {"icon": "qq", "name": "new", "link": "google.com", "type": "inapp", "is_hidden": "True"}
grigoriev-semyon marked this conversation as resolved.
Show resolved Hide resolved
res = client.post(f"/category/{db_category.id}/button", data=json.dumps(body))
assert res.status_code == status.HTTP_200_OK
res_body = res.json()
assert res_body["icon"] == body["icon"]
assert res_body["order"] == 1
assert res_body["name"] == body["name"]
assert "link" not in res_body
assert res_body["type"] == body["type"]
db_button_created: Button = dbsession.query(Button).filter(Button.id == res_body["id"]).one_or_none()
assert db_button_created
assert db_button_created.icon == body["icon"]
assert db_button_created.name == body["name"]
assert db_button_created.category == db_category
assert db_button_created.link == body["link"]
assert db_button_created.type == body["type"]
assert db_button_created.order == 1
grigoriev-semyon marked this conversation as resolved.
Show resolved Hide resolved


def test_get_hidden_by_id_success(client, db_button, db_category):
db_button.is_hidden = True
grigoriev-semyon marked this conversation as resolved.
Show resolved Hide resolved
res = client.get(f"/category/{db_category.id}/button/{db_button.id}")
assert res.status_code == status.HTTP_200_OK
res_body = res.json()
assert res_body['icon'] == db_button.icon
assert res_body['name'] == db_button.name
assert res_body['order'] == db_button.order
assert res_body['link'] is None
assert res_body['type'] == db_button.type
grigoriev-semyon marked this conversation as resolved.
Show resolved Hide resolved


def test_patch_to_hide_success(client, db_button, db_category):
body = {"is_hidden": "True"}
res = client.patch(f"/category/{db_category.id}/button/{db_button.id}", data=json.dumps(body))
assert res.status_code == status.HTTP_200_OK
res_body = res.json()
assert res_body["icon"] == db_button.icon
assert res_body["order"] == db_button.order
assert res_body["name"] == db_button.name
assert res_body["link"] == db_button.link
assert res_body["type"] == db_button.type
assert res_body["is_hidden"] == True
res = client.get(f"/category/{db_category.id}/button/{db_button.id}")
assert res.status_code == status.HTTP_200_OK
assert res.json()["link"] is None
assert res.json()["view"] == "hidden"
Loading