305 lines
14 KiB
Python
305 lines
14 KiB
Python
# pyright: reportCallIssue=false
|
||
|
||
from __future__ import annotations
|
||
import allure # pyright: ignore[reportMissingImports]
|
||
from allure_commons.types import AttachmentType # pyright: ignore[reportMissingImports]
|
||
from behave import then, when
|
||
import json
|
||
from typing import Any
|
||
from Ticket.testdata.ticket_test_data import TicketTestData
|
||
from worklib.graphql_client import execute_graphql
|
||
|
||
def _attach_json(name: str, payload: Any) -> None:
|
||
allure.attach(
|
||
json.dumps(payload, ensure_ascii=False, indent=2),
|
||
name=name,
|
||
attachment_type=AttachmentType.JSON,
|
||
)
|
||
DEFAULT_TICKETINFO_PLACE_ID = "682733c16773cfa73dc8d0a7"
|
||
|
||
|
||
@when("create user for ticket") # pyright: ignore[reportGeneralTypeIssues]
|
||
def step_create_user_for_ticket(context) -> None:
|
||
td = TicketTestData.from_behave_context(context)
|
||
td.create_user()
|
||
context.ticket_account_id = td.account_id
|
||
context.ticket_username = td.username
|
||
|
||
|
||
@when("create employee for created user") # pyright: ignore[reportGeneralTypeIssues]
|
||
def step_create_employee(context) -> None:
|
||
td = TicketTestData.from_behave_context(context)
|
||
td.create_employee()
|
||
context.ticket_employee_id = td.employee_id
|
||
|
||
|
||
@when("create category group for created category") # pyright: ignore[reportGeneralTypeIssues]
|
||
def step_create_category_group(context) -> None:
|
||
td = TicketTestData.from_behave_context(context)
|
||
td.create_category_group()
|
||
context.ticket_category_group_id = td.category_group_id
|
||
|
||
|
||
@when("connect employee to category group") # pyright: ignore[reportGeneralTypeIssues]
|
||
def step_connect_employee(context) -> None:
|
||
td = TicketTestData.from_behave_context(context)
|
||
td.connect_employee_to_category_group()
|
||
|
||
|
||
@when("prepare ticket and employees for assign employee test") # pyright: ignore[reportGeneralTypeIssues]
|
||
def step_prepare_ticket_and_employees_for_assign(context) -> None:
|
||
"""
|
||
Подготовка:
|
||
- 1 place
|
||
- 1 category
|
||
- 1 category group (для этой категории)
|
||
- 3 employee:
|
||
- fixed employee (в группе)
|
||
- новый in_group employee (в группе)
|
||
- новый out_group employee (вне группы)
|
||
- 1 ticket в этой категории
|
||
"""
|
||
td = TicketTestData.from_behave_context(context)
|
||
token = td.ensure_token()
|
||
|
||
# Берём существующую заявку и её категорию (createTicket часто запрещён)
|
||
query = """
|
||
query ticketinfo($place_id: String!) {
|
||
ticket(pagination:{skip:0,limit:25} ,filter:{place_id:$place_id}){
|
||
results {
|
||
id
|
||
category { id title }
|
||
assignee { id user { id username } }
|
||
}
|
||
}
|
||
}
|
||
""".strip()
|
||
td.place_id = DEFAULT_TICKETINFO_PLACE_ID
|
||
resp = execute_graphql(query=query, variables={"place_id": td.place_id}, company_id=td.company_id, access_token=token)
|
||
results = resp.get("data", {}).get("ticket", {}).get("results", [])
|
||
if isinstance(results, list) and results:
|
||
ticket0 = results[0]
|
||
assert isinstance(ticket0, dict) and ticket0.get("id"), f"Некорректный ticket: {ticket0!r}"
|
||
category = ticket0.get("category")
|
||
assert isinstance(category, dict) and category.get("id"), f"У ticket нет category: {ticket0!r}"
|
||
context.ticket_id = ticket0["id"]
|
||
td.ticket_id = ticket0["id"]
|
||
category_id = category["id"]
|
||
else:
|
||
# fallback: создаём свою заявку, если это разрешено
|
||
td.place_id = None
|
||
td.ensure_place()
|
||
category_id = td.ensure_ticket_category()
|
||
try:
|
||
td.create_ticket_with_category(category_id=category_id, place_id=td.place_id)
|
||
except AssertionError as e:
|
||
raise AssertionError(
|
||
"Нет доступных tickets для проверки assignTicketEmployee (по умолчанию берём place_id "
|
||
f"{DEFAULT_TICKETINFO_PLACE_ID}) и createTicket запрещён на стенде. "
|
||
"Укажите place_id с существующими заявками (поменяйте DEFAULT_TICKETINFO_PLACE_ID в шаге) "
|
||
"или дайте права на createTicket. "
|
||
f"Детали: {e}"
|
||
)
|
||
context.ticket_id = td.ticket_id
|
||
with allure.step("GraphQL: ticket(pagination:skip:0,limit:25,filter:place_id)"):
|
||
resp = execute_graphql(query=query, variables={"place_id": td.place_id}, company_id=td.company_id, access_token=token)
|
||
_attach_json("ticket response", resp)
|
||
context.ticket_response = resp
|
||
# employee #2 (new in-group)
|
||
td.create_employee()
|
||
assert td.account_id and td.employee_id, "Не создался in-group employee"
|
||
in_group_user_id = td.account_id
|
||
in_group_employee_id = td.employee_id
|
||
|
||
fixed_member = {"user_id": td.fixed_user_id, "employee_id": td.fixed_employee_id}
|
||
new_in_group_member = {"user_id": in_group_user_id, "employee_id": in_group_employee_id}
|
||
|
||
td.create_category_group_for_categories([category_id], members=[fixed_member, new_in_group_member], cache=False)
|
||
|
||
# employee #3 (out-group): создаём ещё одного нового employee, но НЕ добавляем в group
|
||
td_out = TicketTestData(company_id=td.company_id)
|
||
td_out.access_token = td.access_token
|
||
td_out._cleanup_fns = getattr(context, "_cleanup_fns", None)
|
||
td_out.create_employee()
|
||
assert td_out.account_id and td_out.employee_id, "Не создался out-group employee"
|
||
out_group_user_id = td_out.account_id
|
||
|
||
# сохраняем ids для проверок
|
||
context.assign_fixed_user_id = td.fixed_user_id
|
||
context.assign_in_group_user_id = in_group_user_id
|
||
context.assign_out_group_user_id = out_group_user_id
|
||
|
||
|
||
def _assign_ticket_employee(context, *, employee_user_id: str, expect_error: bool) -> None:
|
||
td = TicketTestData.from_behave_context(context)
|
||
token = td.ensure_token()
|
||
ticket_id = td.ticket_id or getattr(context, "ticket_id", None)
|
||
assert ticket_id, "Нет ticket_id."
|
||
|
||
mutation = """
|
||
mutation assignTicketEmployee($ticket_id: String!, $employee_user_id: String!) {
|
||
assignTicketEmployee(dto: {ticket_id: $ticket_id, employee_user_id: $employee_user_id})
|
||
}
|
||
""".strip()
|
||
variables = {"ticket_id": ticket_id, "employee_user_id": employee_user_id}
|
||
try:
|
||
resp = execute_graphql(query=mutation, variables=variables, company_id=td.company_id, access_token=token)
|
||
context.assign_ticket_employee_response = resp
|
||
if expect_error:
|
||
raise AssertionError(f"Ожидали ошибку при assignTicketEmployee, но получили успех: {resp}")
|
||
except Exception as e:
|
||
context.assign_ticket_employee_error = str(e)
|
||
if not expect_error:
|
||
raise
|
||
|
||
|
||
@when("assign ticket to fixed in_group employee") # pyright: ignore[reportGeneralTypeIssues]
|
||
def step_assign_ticket_fixed_employee(context) -> None:
|
||
_assign_ticket_employee(context, employee_user_id=getattr(context, "assign_fixed_user_id"), expect_error=False)
|
||
|
||
|
||
@when("assign ticket to new in_group employee") # pyright: ignore[reportGeneralTypeIssues]
|
||
def step_assign_ticket_new_in_group_employee(context) -> None:
|
||
_assign_ticket_employee(context, employee_user_id=getattr(context, "assign_in_group_user_id"), expect_error=False)
|
||
|
||
|
||
@when("assign ticket to out_group employee (should fail)") # pyright: ignore[reportGeneralTypeIssues]
|
||
def step_assign_ticket_out_group_employee(context) -> None:
|
||
_assign_ticket_employee(context, employee_user_id=getattr(context, "assign_out_group_user_id"), expect_error=True)
|
||
|
||
|
||
@when("prepare ticket and employees for unassign employee test") # pyright: ignore[reportGeneralTypeIssues]
|
||
def step_prepare_ticket_and_employees_for_unassign(context) -> None:
|
||
"""
|
||
Подготовка для unassign:
|
||
- 1 категория + 1 группа категорий (для этой категории)
|
||
- 2 работника:
|
||
- fixed employee (в группе): user_id/employee_id заданы константами
|
||
- новый employee (в группе) — его будем assign/unassign
|
||
- 1 ticket (существующий по place_id либо созданный, если разрешено)
|
||
"""
|
||
td = TicketTestData.from_behave_context(context)
|
||
token = td.ensure_token()
|
||
|
||
query = """
|
||
query ticketinfo($place_id: String!) {
|
||
ticket(pagination:{skip:0,limit:25} ,filter:{place_id:$place_id}){
|
||
results {
|
||
id
|
||
category { id title }
|
||
assignee { id user { id username } }
|
||
}
|
||
}
|
||
}
|
||
""".strip()
|
||
td.place_id = DEFAULT_TICKETINFO_PLACE_ID
|
||
resp = execute_graphql(query=query, variables={"place_id": td.place_id}, company_id=td.company_id, access_token=token)
|
||
results = resp.get("data", {}).get("ticket", {}).get("results", [])
|
||
|
||
if isinstance(results, list) and results:
|
||
ticket0 = results[0]
|
||
assert isinstance(ticket0, dict) and ticket0.get("id"), f"Некорректный ticket: {ticket0!r}"
|
||
category = ticket0.get("category")
|
||
assert isinstance(category, dict) and category.get("id"), f"У ticket нет category: {ticket0!r}"
|
||
context.ticket_id = ticket0["id"]
|
||
td.ticket_id = ticket0["id"]
|
||
category_id = category["id"]
|
||
else:
|
||
# fallback: создаём свою заявку, если это разрешено
|
||
td.place_id = None
|
||
td.ensure_place()
|
||
category_id = td.ensure_ticket_category()
|
||
try:
|
||
td.create_ticket_with_category(category_id=category_id, place_id=td.place_id)
|
||
except AssertionError as e:
|
||
raise AssertionError(
|
||
"Нет доступных tickets для проверки unassignTicketEmployee (по умолчанию берём place_id "
|
||
f"{DEFAULT_TICKETINFO_PLACE_ID}) и createTicket запрещён на стенде. "
|
||
"Укажите place_id с существующими заявками (поменяйте DEFAULT_TICKETINFO_PLACE_ID в шаге) "
|
||
"или дайте права на createTicket. "
|
||
f"Детали: {e}"
|
||
)
|
||
context.ticket_id = td.ticket_id
|
||
|
||
# новый employee (его будем assign/unassign)
|
||
td_new = TicketTestData(company_id=td.company_id)
|
||
td_new.access_token = td.access_token
|
||
td_new._cleanup_fns = getattr(context, "_cleanup_fns", None)
|
||
td_new.create_employee()
|
||
assert td_new.account_id and td_new.employee_id, "Не создался новый employee для unassign"
|
||
|
||
fixed_member = {"user_id": td.fixed_user_id, "employee_id": td.fixed_employee_id}
|
||
new_member = {"user_id": td_new.account_id, "employee_id": td_new.employee_id}
|
||
td.create_category_group_for_categories([category_id], members=[fixed_member, new_member], cache=False)
|
||
|
||
context.unassign_new_user_id = td_new.account_id
|
||
|
||
|
||
@when("assign ticket to new grouped employee") # pyright: ignore[reportGeneralTypeIssues]
|
||
def step_assign_ticket_to_new_grouped_employee(context) -> None:
|
||
_assign_ticket_employee(context, employee_user_id=getattr(context, "unassign_new_user_id"), expect_error=False)
|
||
|
||
|
||
@when("unassign ticket from new grouped employee") # pyright: ignore[reportGeneralTypeIssues]
|
||
def step_unassign_ticket_from_new_grouped_employee(context) -> None:
|
||
td = TicketTestData.from_behave_context(context)
|
||
token = td.ensure_token()
|
||
ticket_id = td.ticket_id or getattr(context, "ticket_id", None)
|
||
assert ticket_id, "Нет ticket_id."
|
||
employee_user_id = getattr(context, "unassign_new_user_id", None)
|
||
assert isinstance(employee_user_id, str) and employee_user_id, "Нет unassign_new_user_id."
|
||
|
||
mutation = """
|
||
mutation unassignTicketEmployee($ticket_id: String!, $employee_user_id: String!) {
|
||
unassignTicketEmployee(dto: {ticket_id: $ticket_id, employee_user_id: $employee_user_id})
|
||
}
|
||
""".strip()
|
||
variables = {"ticket_id": ticket_id, "employee_user_id": employee_user_id}
|
||
resp = execute_graphql(query=mutation, variables=variables, company_id=td.company_id, access_token=token)
|
||
context.unassign_ticket_employee_response = resp
|
||
|
||
|
||
def _get_ticket_assignee_user_id(context) -> str | None:
|
||
td = TicketTestData.from_behave_context(context)
|
||
ticket_id = td.ticket_id or getattr(context, "ticket_id", None)
|
||
assert ticket_id, "Нет ticket_id."
|
||
resp = getattr(context, "ticket_query_response", None)
|
||
assert isinstance(resp, dict), f"Нет ticket_query_response: {resp!r}"
|
||
results = resp.get("data", {}).get("ticket", {}).get("results", [])
|
||
assert isinstance(results, list), f"ticket.results не list: {results!r}"
|
||
for item in results:
|
||
if isinstance(item, dict) and item.get("id") == ticket_id:
|
||
assignee = item.get("assignee")
|
||
if assignee is None:
|
||
return None
|
||
if isinstance(assignee, dict) and isinstance(assignee.get("user"), dict):
|
||
return assignee["user"].get("id")
|
||
raise AssertionError(f"Неожиданная структура assignee: {assignee!r}")
|
||
raise AssertionError(f"Не нашли ticket id={ticket_id} в results")
|
||
|
||
|
||
@then("ticket assignee is fixed employee") # pyright: ignore[reportGeneralTypeIssues]
|
||
def step_assert_assignee_fixed(context) -> None:
|
||
assert _get_ticket_assignee_user_id(context) == getattr(context, "assign_fixed_user_id")
|
||
|
||
|
||
@then("ticket assignee is new in_group employee") # pyright: ignore[reportGeneralTypeIssues]
|
||
def step_assert_assignee_new_in_group(context) -> None:
|
||
assert _get_ticket_assignee_user_id(context) == getattr(context, "assign_in_group_user_id")
|
||
|
||
|
||
@then("ticket assignee is still new in_group employee") # pyright: ignore[reportGeneralTypeIssues]
|
||
def step_assert_assignee_still_new_in_group(context) -> None:
|
||
assert _get_ticket_assignee_user_id(context) == getattr(context, "assign_in_group_user_id")
|
||
|
||
|
||
@then("ticket assignee is new grouped employee") # pyright: ignore[reportGeneralTypeIssues]
|
||
def step_assert_assignee_new_grouped_employee(context) -> None:
|
||
assert _get_ticket_assignee_user_id(context) == getattr(context, "unassign_new_user_id")
|
||
|
||
|
||
@then("ticket assignee is empty") # pyright: ignore[reportGeneralTypeIssues]
|
||
def step_assert_assignee_empty(context) -> None:
|
||
assignee_user_id = _get_ticket_assignee_user_id(context)
|
||
assert assignee_user_id is None, f"Ожидали пустой assignee после unassign, получили user_id={assignee_user_id!r}"
|