first
This commit is contained in:
commit
fa9d154db9
260 files changed
+17643
No files matched your search
@@ -0,0 +1,290 @@
|
||||
import io
|
||||
|
||||
import pytest
|
||||
from django.core.management import call_command
|
||||
from playwright.sync_api import expect
|
||||
|
||||
from apps.accounts.models import User
|
||||
from apps.customers.models import CustomerProfile
|
||||
from apps.staff.models import OrganizationalUnit, StaffProfile
|
||||
from apps.tickets.models import Ticket, TicketCategory
|
||||
from tests.e2e.pages.auth import AuthenticationPage
|
||||
from tests.e2e.pages.tickets import PublicTicketCreatePage
|
||||
|
||||
|
||||
pytestmark = [pytest.mark.e2e, pytest.mark.django_db(transaction=True)]
|
||||
PASSWORD = "E2e-public-workflow-2026"
|
||||
|
||||
|
||||
def image_file(name, image_format, color):
|
||||
pillow = pytest.importorskip("PIL.Image")
|
||||
stream = io.BytesIO()
|
||||
pillow.new("RGB", (8, 8), color).save(stream, format=image_format)
|
||||
return {
|
||||
"name": name,
|
||||
"mimeType": "image/jpeg" if image_format == "JPEG" else "image/png",
|
||||
"buffer": stream.getvalue(),
|
||||
}
|
||||
|
||||
|
||||
def pdf_file(name, marker="one"):
|
||||
return {
|
||||
"name": name,
|
||||
"mimeType": "application/pdf",
|
||||
"buffer": (
|
||||
"%PDF-1.4\n1 0 obj<</Type/Catalog/Pages 2 0 R>>endobj\n"
|
||||
"2 0 obj<</Type/Pages/Count 0/Kids[]>>endobj\n"
|
||||
f"% {marker}\n%%EOF\n"
|
||||
).encode(),
|
||||
}
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def public_workflow(settings, tmp_path):
|
||||
settings.MEDIA_ROOT = tmp_path
|
||||
call_command("bootstrap")
|
||||
customer = User.objects.create_user(
|
||||
username="e2e-public-workflow",
|
||||
mobile="09120008301",
|
||||
password=PASSWORD,
|
||||
account_type=User.AccountType.CUSTOMER,
|
||||
)
|
||||
CustomerProfile.objects.create(user=customer, first_name="مشتری", last_name="مرورگر")
|
||||
units = {
|
||||
slug: OrganizationalUnit.objects.get(slug=slug)
|
||||
for slug in ("sales", "warehouse-loading", "finance")
|
||||
}
|
||||
categories = {
|
||||
"sales_general": TicketCategory.objects.get(slug="sales-general"),
|
||||
"sales_secondary": TicketCategory.objects.create(
|
||||
unit=units["sales"],
|
||||
title="شرایط فروش E2E",
|
||||
slug="sales-secondary-e2e",
|
||||
is_active=True,
|
||||
show_in_customer_form=True,
|
||||
),
|
||||
"warehouse": TicketCategory.objects.get(slug="warehouse-loading-general"),
|
||||
"finance": TicketCategory.objects.get(slug="finance-general"),
|
||||
}
|
||||
return customer, units, categories
|
||||
|
||||
|
||||
def open_form(page, live_server, customer):
|
||||
AuthenticationPage(page, live_server.url).login_customer(customer, PASSWORD)
|
||||
form = PublicTicketCreatePage(page, live_server.url)
|
||||
form.open()
|
||||
return form
|
||||
|
||||
|
||||
def assert_ticket_record(subject, *, unit, category, expert_name, attachment_names=()):
|
||||
ticket = Ticket.objects.select_related("selected_expert__staff_profile").get(subject=subject)
|
||||
assert ticket.owning_unit == unit
|
||||
assert ticket.assigned_unit == unit
|
||||
assert ticket.category == category
|
||||
actual_expert = ticket.selected_expert.staff_profile.display_name if ticket.selected_expert_id else "صف عمومی"
|
||||
assert actual_expert == expert_name
|
||||
attachments = ticket.ticket_messages.get().attachments.order_by("original_name")
|
||||
assert set(attachments.values_list("original_name", flat=True)) == set(attachment_names)
|
||||
|
||||
|
||||
def assert_final_ticket_ui(page, *, category, expert_name, attachment_names=()):
|
||||
expect(page.locator("#ticket-info")).to_contain_text(category.title)
|
||||
expect(page.locator("#ticket-info")).to_contain_text(expert_name)
|
||||
for name in attachment_names:
|
||||
expect(page.locator("[data-conversation]")).to_contain_text(name)
|
||||
|
||||
|
||||
def test_e2e_07_sales_general_queue_creates_verifiable_ticket(live_server, browser_page, public_workflow):
|
||||
customer, units, categories = public_workflow
|
||||
subject = "ثبت واقعی در صف عمومی فروش E2E"
|
||||
with browser_page() as page:
|
||||
form = open_form(page, live_server, customer)
|
||||
form.select_unit(units["sales"].pk)
|
||||
form.select_category(categories["sales_general"].pk)
|
||||
form.select_general_queue()
|
||||
form.submit(subject=subject, body="شرح کامل تیکت بدون پیوست")
|
||||
assert_final_ticket_ui(page, category=categories["sales_general"], expert_name="صف عمومی")
|
||||
assert_ticket_record(
|
||||
subject, unit=units["sales"], category=categories["sales_general"], expert_name="صف عمومی"
|
||||
)
|
||||
|
||||
|
||||
def test_e2e_08_repeated_staff_changes_store_only_last_choice(live_server, browser_page, public_workflow):
|
||||
customer, units, categories = public_workflow
|
||||
subject = "آخرین کارشناس انتخابی E2E"
|
||||
with browser_page() as page:
|
||||
form = open_form(page, live_server, customer)
|
||||
form.select_unit(units["sales"].pk)
|
||||
form.select_category(categories["sales_general"].pk)
|
||||
for name in ("کیمیا غفاری", "زهرا جمالی", "مریم فتوت", "زهرا جمالی"):
|
||||
form.select_expert(name)
|
||||
form.submit(subject=subject, body="تغییر چندباره کارشناس")
|
||||
assert_final_ticket_ui(page, category=categories["sales_general"], expert_name="زهرا جمالی")
|
||||
assert_ticket_record(
|
||||
subject, unit=units["sales"], category=categories["sales_general"], expert_name="زهرا جمالی"
|
||||
)
|
||||
|
||||
|
||||
def test_e2e_subject_stays_empty_for_manual_and_search_routing_until_user_types(
|
||||
live_server, browser_page, public_workflow
|
||||
):
|
||||
customer, units, categories = public_workflow
|
||||
subject = "موضوع کاملاً دستی E2E"
|
||||
with browser_page() as page:
|
||||
form = open_form(page, live_server, customer)
|
||||
subject_input = page.locator("[data-ticket-subject]")
|
||||
unit_box = form.unit.bounding_box()
|
||||
category_box = form.category.bounding_box()
|
||||
assert unit_box and category_box
|
||||
assert abs(unit_box["y"] - category_box["y"]) < 2
|
||||
assert unit_box["x"] + unit_box["width"] <= category_box["x"] or category_box["x"] + category_box["width"] <= unit_box["x"]
|
||||
expect(subject_input).to_have_value("")
|
||||
expect(subject_input).to_have_attribute("required", "")
|
||||
form.select_unit(units["finance"].pk)
|
||||
form.select_category(categories["finance"].pk)
|
||||
expect(subject_input).to_have_value("")
|
||||
form.select_search_result("عمومی فروش", "عمومی فروش")
|
||||
expect(form.unit).to_have_value(str(units["sales"].pk))
|
||||
expect(subject_input).to_have_value("")
|
||||
subject_input.fill(subject)
|
||||
form.select_unit(units["finance"].pk)
|
||||
expect(subject_input).to_have_value(subject)
|
||||
form.select_unit(units["sales"].pk)
|
||||
form.select_category(categories["sales_general"].pk)
|
||||
form.select_general_queue()
|
||||
form.submit(subject=subject, body="موضوع فقط توسط کاربر وارد شده است")
|
||||
assert_final_ticket_ui(page, category=categories["sales_general"], expert_name="صف عمومی")
|
||||
assert_ticket_record(
|
||||
subject, unit=units["sales"], category=categories["sales_general"], expert_name="صف عمومی"
|
||||
)
|
||||
|
||||
|
||||
def test_e2e_experts_follow_configured_numeric_order(live_server, browser_page, public_workflow):
|
||||
customer, units, _ = public_workflow
|
||||
configured = {
|
||||
"زهرا جمالی": 10,
|
||||
"مریم فتوت": 20,
|
||||
"کیمیا غفاری": 30,
|
||||
"مرتضی سخائی فرد": 40,
|
||||
}
|
||||
for name, order in configured.items():
|
||||
StaffProfile.objects.filter(primary_unit=units["sales"], display_name=name).update(sort_order=order)
|
||||
with browser_page() as page:
|
||||
form = open_form(page, live_server, customer)
|
||||
form.select_unit(units["sales"].pk)
|
||||
names = form.expert_picker.locator(
|
||||
"label.expert-card:not([data-general-queue]) strong"
|
||||
).all_text_contents()
|
||||
assert names == ["زهرا جمالی", "مریم فتوت", "کیمیا غفاری", "مرتضی سخائی فرد"]
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"suffix,images,documents,expected",
|
||||
[
|
||||
("jpg", [image_file("photo.jpg", "JPEG", "red")], [], ["photo.jpg"]),
|
||||
("pdf", [], [pdf_file("document.pdf")], ["document.pdf"]),
|
||||
(
|
||||
"mixed",
|
||||
[image_file("first.jpg", "JPEG", "blue"), image_file("second.png", "PNG", "green")],
|
||||
[pdf_file("combined.pdf")],
|
||||
["first.jpg", "second.png", "combined.pdf"],
|
||||
),
|
||||
(
|
||||
"multi-file",
|
||||
[],
|
||||
[pdf_file("first.pdf", "first"), pdf_file("second.pdf", "second")],
|
||||
["first.pdf", "second.pdf"],
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_e2e_09_10_11_attachment_variants_are_saved_and_rendered(
|
||||
live_server, browser_page, public_workflow, suffix, images, documents, expected
|
||||
):
|
||||
customer, units, categories = public_workflow
|
||||
subject = f"پیوست واقعی {suffix} E2E"
|
||||
with browser_page() as page:
|
||||
form = open_form(page, live_server, customer)
|
||||
form.select_unit(units["sales"].pk)
|
||||
form.select_category(categories["sales_general"].pk)
|
||||
form.select_general_queue()
|
||||
if images:
|
||||
form.upload_gallery(images)
|
||||
if documents:
|
||||
form.upload_documents(documents, total_count=len(images) + len(documents))
|
||||
form.submit(subject=subject, body="بررسی ذخیره و نمایش تمام پیوستها")
|
||||
assert_final_ticket_ui(
|
||||
page, category=categories["sales_general"], expert_name="صف عمومی", attachment_names=expected
|
||||
)
|
||||
assert_ticket_record(
|
||||
subject,
|
||||
unit=units["sales"],
|
||||
category=categories["sales_general"],
|
||||
expert_name="صف عمومی",
|
||||
attachment_names=expected,
|
||||
)
|
||||
|
||||
|
||||
def test_e2e_11_removed_attachment_is_not_submitted(live_server, browser_page, public_workflow):
|
||||
customer, units, categories = public_workflow
|
||||
subject = "حذف پیوست پیش از ثبت E2E"
|
||||
keep = image_file("keep.png", "PNG", "yellow")
|
||||
remove = pdf_file("remove.pdf")
|
||||
with browser_page() as page:
|
||||
form = open_form(page, live_server, customer)
|
||||
form.select_unit(units["sales"].pk)
|
||||
form.select_category(categories["sales_general"].pk)
|
||||
form.upload_gallery([keep])
|
||||
form.upload_documents([remove], total_count=2)
|
||||
form.remove_attachment("remove.pdf")
|
||||
form.submit(subject=subject, body="فقط تصویر باید ذخیره شود")
|
||||
assert_final_ticket_ui(
|
||||
page, category=categories["sales_general"], expert_name="صف عمومی", attachment_names=["keep.png"]
|
||||
)
|
||||
assert_ticket_record(
|
||||
subject,
|
||||
unit=units["sales"],
|
||||
category=categories["sales_general"],
|
||||
expert_name="صف عمومی",
|
||||
attachment_names=["keep.png"],
|
||||
)
|
||||
|
||||
|
||||
def test_e2e_12_sequential_unit_staff_category_and_attachment_state(live_server, browser_page, public_workflow):
|
||||
customer, units, categories = public_workflow
|
||||
subject = "مدیریت وضعیت متوالی فرم E2E"
|
||||
image_one = image_file("state-one.jpg", "JPEG", "purple")
|
||||
image_two = image_file("state-two.png", "PNG", "orange")
|
||||
removed_pdf = pdf_file("state-remove.pdf")
|
||||
with browser_page() as page:
|
||||
form = open_form(page, live_server, customer)
|
||||
form.select_unit(units["sales"].pk)
|
||||
form.select_expert("کیمیا غفاری")
|
||||
form.select_category(categories["sales_secondary"].pk)
|
||||
form.upload_gallery([image_one])
|
||||
form.upload_documents([removed_pdf], total_count=2)
|
||||
form.select_unit(units["finance"].pk)
|
||||
expect(form.expert_picker).not_to_contain_text("کیمیا غفاری")
|
||||
expect(form.queue).to_contain_text("صف عمومی مالی / حسابداری")
|
||||
form.select_category(categories["finance"].pk)
|
||||
form.select_unit(units["sales"].pk)
|
||||
form.select_category(categories["sales_general"].pk)
|
||||
form.select_expert("کیمیا غفاری")
|
||||
form.select_expert("زهرا جمالی")
|
||||
form.select_expert("کیمیا غفاری")
|
||||
form.remove_attachment("state-remove.pdf")
|
||||
form.upload_gallery([image_two], total_count=2)
|
||||
expect(form.file_preview.locator(".file-chip")).to_have_count(2)
|
||||
form.submit(subject=subject, body="فرم پس از تغییرات متوالی سالم ماند")
|
||||
assert_final_ticket_ui(
|
||||
page,
|
||||
category=categories["sales_general"],
|
||||
expert_name="کیمیا غفاری",
|
||||
attachment_names=["state-one.jpg", "state-two.png"],
|
||||
)
|
||||
assert_ticket_record(
|
||||
subject,
|
||||
unit=units["sales"],
|
||||
category=categories["sales_general"],
|
||||
expert_name="کیمیا غفاری",
|
||||
attachment_names=["state-one.jpg", "state-two.png"],
|
||||
)
|
||||
Reference in new issue
Block a user