describe("Discount Codes Advanced Features", () => { beforeEach(() => { cy.login(); cy.visit("/discount-codes"); cy.waitForLoading(); }); describe("Form Validation", () => { beforeEach(() => { cy.get('[title="کد تخفیف جدید"]').click(); }); it("should validate code format and uniqueness", () => { // Test invalid characters (if implemented) cy.get('input[name="code"]').type("TEST CODE"); // Space in code cy.get('input[name="name"]').type("Test Name"); cy.get('select[name="type"]').select("percentage"); cy.get('input[name="value"]').type("10"); cy.get('select[name="status"]').select("active"); cy.get('select[name="application_level"]').select("invoice"); // Try to submit - may show validation error for invalid characters cy.get('button[type="submit"]').click(); // Clear and use valid code cy.get('input[name="code"]').clear().type("TESTCODE123"); cy.get('button[type="submit"]').click(); cy.url().should("include", "/discount-codes"); }); it("should validate name length constraints", () => { cy.get('input[name="code"]').type("NAMETEST"); // Test name too long cy.get('input[name="name"]').type("A".repeat(101)); cy.contains("نام نباید بیشتر از ۱۰۰ کاراکتر باشد").should("be.visible"); // Clear and use valid name cy.get('input[name="name"]').clear().type("Valid Name"); cy.get('select[name="type"]').select("percentage"); cy.get('input[name="value"]').type("10"); cy.get('select[name="status"]').select("active"); cy.get('select[name="application_level"]').select("invoice"); }); it("should validate description length", () => { cy.get('input[name="code"]').type("DESCTEST"); cy.get('input[name="name"]').type("Description Test"); // Test description too long cy.get('textarea[name="description"]').type("A".repeat(501)); cy.contains("توضیحات نباید بیشتر از ۵۰۰ کاراکتر باشد").should( "be.visible" ); }); it("should validate percentage values", () => { cy.get('input[name="code"]').type("PERCENTTEST"); cy.get('input[name="name"]').type("Percent Test"); cy.get('select[name="type"]').select("percentage"); // Test negative value cy.get('input[name="value"]').type("-10"); cy.contains("مقدار باید بیشتر از صفر باشد").should("be.visible"); // Test zero value cy.get('input[name="value"]').clear().type("0"); cy.contains("مقدار باید بیشتر از صفر باشد").should("be.visible"); // Test valid value cy.get('input[name="value"]').clear().type("25"); }); it("should validate usage limits", () => { cy.get('input[name="code"]').type("USAGETEST"); cy.get('input[name="name"]').type("Usage Test"); cy.get('select[name="type"]').select("percentage"); cy.get('input[name="value"]').type("10"); cy.get('select[name="status"]').select("active"); cy.get('select[name="application_level"]').select("invoice"); // Test invalid usage limit cy.get('input[name="usage_limit"]').type("0"); cy.contains("حداقل ۱ بار استفاده").should("be.visible"); // Test invalid user usage limit cy.get('input[name="user_usage_limit"]').type("0"); cy.contains("حداقل ۱ بار استفاده").should("be.visible"); }); it("should validate amount constraints", () => { cy.get('input[name="code"]').type("AMOUNTTEST"); cy.get('input[name="name"]').type("Amount Test"); cy.get('select[name="type"]').select("fixed"); cy.get('input[name="value"]').type("1000"); cy.get('select[name="status"]').select("active"); cy.get('select[name="application_level"]').select("invoice"); // Test invalid minimum purchase amount cy.get('input[name="min_purchase_amount"]').type("0"); cy.contains("مبلغ باید بیشتر از صفر باشد").should("be.visible"); // Test invalid maximum discount amount cy.get('input[name="max_discount_amount"]').type("-100"); cy.contains("مبلغ باید بیشتر از صفر باشد").should("be.visible"); }); }); describe("Date and Time Handling", () => { beforeEach(() => { cy.get('[title="کد تخفیف جدید"]').click(); // Fill required fields cy.get('input[name="code"]').type("DATETEST"); cy.get('input[name="name"]').type("Date Test"); cy.get('select[name="type"]').select("percentage"); cy.get('input[name="value"]').type("10"); cy.get('select[name="status"]').select("active"); cy.get('select[name="application_level"]').select("invoice"); }); it("should handle date range validation", () => { // Set end date before start date cy.get('input[name="valid_from"]').type("2024-12-31T23:59"); cy.get('input[name="valid_to"]').type("2024-01-01T00:00"); // Form should still accept it (backend validation) cy.get('button[type="submit"]').click(); cy.url().should("include", "/discount-codes"); }); it("should preserve datetime values in edit mode", () => { // Set specific datetime values const fromDate = "2024-06-01T10:30"; const toDate = "2024-06-30T18:45"; cy.get('input[name="valid_from"]').type(fromDate); cy.get('input[name="valid_to"]').type(toDate); cy.get('button[type="submit"]').click(); cy.url().should("include", "/discount-codes"); // Edit the created discount code cy.contains("DATETEST") .parent() .parent() .within(() => { cy.get('[title="ویرایش"]').click(); }); // Values should be preserved cy.get('input[name="valid_from"]').should("have.value", fromDate); cy.get('input[name="valid_to"]').should("have.value", toDate); }); }); describe("User Restrictions", () => { beforeEach(() => { cy.get('[title="کد تخفیف جدید"]').click(); // Fill required fields cy.get('input[name="code"]').type("USERTEST"); cy.get('input[name="name"]').type("User Test"); cy.get('select[name="type"]').select("percentage"); cy.get('input[name="value"]').type("15"); cy.get('select[name="status"]').select("active"); cy.get('select[name="application_level"]').select("invoice"); }); it("should handle user group selection", () => { // Test all user group options cy.get('select[name="user_restrictions.user_group"]').select("new"); cy.get('select[name="user_restrictions.user_group"]').should( "have.value", "new" ); cy.get('select[name="user_restrictions.user_group"]').select("loyal"); cy.get('select[name="user_restrictions.user_group"]').should( "have.value", "loyal" ); cy.get('select[name="user_restrictions.user_group"]').select("all"); cy.get('select[name="user_restrictions.user_group"]').should( "have.value", "all" ); }); it("should handle purchase count restrictions", () => { cy.get('input[name="user_restrictions.min_purchase_count"]').type("2"); cy.get('input[name="user_restrictions.max_purchase_count"]').type("10"); cy.get('input[name="user_restrictions.referrer_user_id"]').type("456"); cy.get('button[type="submit"]').click(); cy.url().should("include", "/discount-codes"); cy.contains("کد تخفیف با موفقیت ایجاد شد").should("be.visible"); }); it("should warn about conflicting user restrictions", () => { // Check both new users only and loyal users only cy.get('input[name="user_restrictions.new_users_only"]').check(); cy.get('input[name="user_restrictions.loyal_users_only"]').check(); // Warning should be visible cy.contains( "new_users_only و loyal_users_only نمی‌توانند همزمان فعال باشند" ).should("be.visible"); // Uncheck one cy.get('input[name="user_restrictions.new_users_only"]').uncheck(); cy.get('button[type="submit"]').click(); cy.url().should("include", "/discount-codes"); }); }); describe("Application Levels", () => { beforeEach(() => { cy.get('[title="کد تخفیف جدید"]').click(); cy.get('input[name="code"]').type("APPTEST"); cy.get('input[name="name"]').type("Application Test"); cy.get('input[name="value"]').type("100"); cy.get('select[name="status"]').select("active"); }); it("should handle product fee application with fee percentage type", () => { cy.get('select[name="type"]').select("fee_percentage"); cy.get('select[name="application_level"]').select("product_fee"); cy.get('button[type="submit"]').click(); cy.url().should("include", "/discount-codes"); cy.contains("کد تخفیف با موفقیت ایجاد شد").should("be.visible"); }); it("should test all application level combinations", () => { const types = ["percentage", "fixed", "fee_percentage"]; const applications = [ "invoice", "category", "product", "shipping", "product_fee", ]; types.forEach((type, typeIndex) => { applications.forEach((app, appIndex) => { if (typeIndex > 0 || appIndex > 0) { // Generate unique code for each combination cy.get('input[name="code"]') .clear() .type(`TEST${typeIndex}${appIndex}`); } cy.get('select[name="type"]').select(type); cy.get('select[name="application_level"]').select(app); // For fee_percentage, use smaller values if (type === "fee_percentage") { cy.get('input[name="value"]').clear().type("5"); } else if (type === "percentage") { cy.get('input[name="value"]').clear().type("10"); } else { cy.get('input[name="value"]').clear().type("1000"); } cy.get('button[type="submit"]').click(); cy.url().should("include", "/discount-codes"); // Go back to create page for next iteration (except last) if ( !( typeIndex === types.length - 1 && appIndex === applications.length - 1 ) ) { cy.get('[title="کد تخفیف جدید"]').click(); cy.get('input[name="name"]').type("Application Test"); cy.get('select[name="status"]').select("active"); } }); }); }); }); describe("Meta Information", () => { it("should handle meta fields properly", () => { cy.get('[title="کد تخفیف جدید"]').click(); cy.get('input[name="code"]').type("METATEST"); cy.get('input[name="name"]').type("Meta Test"); cy.get('select[name="type"]').select("percentage"); cy.get('input[name="value"]').type("20"); cy.get('select[name="status"]').select("active"); cy.get('select[name="application_level"]').select("invoice"); // Set meta fields cy.get('input[name="meta.campaign"]').type("winter_sale_2024"); cy.get('input[name="meta.category"]').type("seasonal_promotion"); cy.get('button[type="submit"]').click(); cy.url().should("include", "/discount-codes"); cy.contains("کد تخفیف با موفقیت ایجاد شد").should("be.visible"); // Verify meta fields are preserved in edit cy.contains("METATEST") .parent() .parent() .within(() => { cy.get('[title="ویرایش"]').click(); }); cy.get('input[name="meta.campaign"]').should( "have.value", "winter_sale_2024" ); cy.get('input[name="meta.category"]').should( "have.value", "seasonal_promotion" ); }); }); describe("List Page Features", () => { it("should display correct value format based on type", () => { // Create different types of discounts to test display const testCodes = [ { code: "DISPLAYPERCENT", type: "percentage", value: "25" }, { code: "DISPLAYFIXED", type: "fixed", value: "50000" }, { code: "DISPLAYFEE", type: "fee_percentage", value: "5" }, ]; testCodes.forEach((testCode) => { cy.get('[title="کد تخفیف جدید"]').click(); cy.get('input[name="code"]').type(testCode.code); cy.get('input[name="name"]').type(`Display Test ${testCode.type}`); cy.get('select[name="type"]').select(testCode.type); cy.get('input[name="value"]').type(testCode.value); cy.get('select[name="status"]').select("active"); cy.get('select[name="application_level"]').select( testCode.type === "fee_percentage" ? "product_fee" : "invoice" ); cy.get('button[type="submit"]').click(); cy.url().should("include", "/discount-codes"); }); // Check display formats cy.contains("DISPLAYPERCENT") .parent() .parent() .within(() => { cy.contains("25%").should("be.visible"); }); cy.contains("DISPLAYFIXED") .parent() .parent() .within(() => { cy.contains("50000 تومان").should("be.visible"); }); cy.contains("DISPLAYFEE") .parent() .parent() .within(() => { cy.contains("5%").should("be.visible"); }); }); it("should handle pagination properly", () => { // This test assumes there are enough items to paginate // Check if pagination exists cy.get('nav[aria-label="Pagination Navigation"]').should("exist"); // Test pagination controls if they exist cy.get('nav[aria-label="Pagination Navigation"]').within(() => { cy.get("button").should("have.length.greaterThan", 0); }); }); it("should sort columns when sortable", () => { // Click on sortable column headers cy.get("th").contains("کد").click(); cy.wait(500); cy.get("th").contains("نام").click(); cy.wait(500); // Verify table content changes (basic check) cy.get("table tbody tr").should("have.length.greaterThan", 0); }); }); describe("Error Handling", () => { it("should handle network errors gracefully", () => { // Intercept network requests and simulate errors cy.intercept("POST", "**/discount/", { statusCode: 500 }).as( "createError" ); cy.get('[title="کد تخفیف جدید"]').click(); cy.get('input[name="code"]').type("ERRORTEST"); cy.get('input[name="name"]').type("Error Test"); cy.get('select[name="type"]').select("percentage"); cy.get('input[name="value"]').type("10"); cy.get('select[name="status"]').select("active"); cy.get('select[name="application_level"]').select("invoice"); cy.get('button[type="submit"]').click(); cy.wait("@createError"); cy.contains("خطا در ایجاد کد تخفیف").should("be.visible"); }); it("should handle loading states", () => { cy.get('[title="کد تخفیف جدید"]').click(); // Intercept with delay to see loading state cy.intercept("POST", "**/discount/", { delay: 2000, statusCode: 200 }).as( "createSlow" ); cy.get('input[name="code"]').type("LOADTEST"); cy.get('input[name="name"]').type("Load Test"); cy.get('select[name="type"]').select("percentage"); cy.get('input[name="value"]').type("10"); cy.get('select[name="status"]').select("active"); cy.get('select[name="application_level"]').select("invoice"); cy.get('button[type="submit"]').click(); // Check loading state cy.get('button[type="submit"]').should("be.disabled"); cy.get(".animate-spin").should("be.visible"); cy.wait("@createSlow"); }); }); describe("Responsive Design", () => { it("should work on mobile viewport", () => { cy.viewport("iphone-6"); cy.get('[title="کد تخفیف جدید"]').should("be.visible"); cy.get('[title="کد تخفیف جدید"]').click(); cy.contains("ایجاد کد تخفیف").should("be.visible"); // Form should be usable on mobile cy.get('input[name="code"]').type("MOBILETEST"); cy.get('input[name="name"]').type("Mobile Test"); cy.get('select[name="type"]').select("percentage"); cy.get('input[name="value"]').type("10"); cy.get('select[name="status"]').select("active"); cy.get('select[name="application_level"]').select("invoice"); cy.get('button[type="submit"]').should("be.visible").click(); cy.url().should("include", "/discount-codes"); }); it("should work on tablet viewport", () => { cy.viewport("ipad-2"); cy.get('[title="کد تخفیف جدید"]').should("be.visible"); cy.get("table").should("be.visible"); // Test form on tablet cy.get('[title="کد تخفیف جدید"]').click(); cy.get(".grid").should("be.visible"); // Grid layout should work }); }); });