{"version":3,"names":["test","expect","describe","beforeEach","page","goto","fill","click","waitForTimeout","waitForLoadState","orderItem","locator","first","ordersExist","isVisible","timeout","catch","skip","messageSection","hasMessages","messageContent","messages","all","msg","text","textContent","includes","not","toMatch","pageText","emailPatterns","pattern","hasEmailDisplay","toBeFalsy","request","loginResponse","post","data","email","password","status","toBe","loginData","json","token","access_token","ordersResponse","get","headers","orders","length","firstOrder","orderId","id","order_id","messagesResponse","messagesData","Array","isArray","toHaveProperty","sender_name","toContain"],"sources":["message-sender-name.spec.js"],"sourcesContent":["import { test, expect } from '@playwright/test'\n\n/**\n * E2E Test: Message System - sender_name Display\n * \n * Tests the bug: 订单留言永远显示邮箱格式，而不是用户名\n * \n * Expected behavior:\n * - Messages should display sender's username (extracted from email)\n * - NOT display raw email addresses like \"test@example.com\"\n * \n * Bug symptom: Messages show \"test@example.com\" instead of \"test\"\n */\n\ntest.describe('Message System - sender_name Display', () => {\n\n  test.beforeEach(async ({ page }) => {\n    // Login\n    await page.goto('/login')\n    await page.fill('input[type=\"email\"]', 'e2e_test_partner@fetch.com')\n    await page.fill('input[type=\"password\"]', 'e2etest123')\n    await page.click('button[type=\"submit\"]')\n    await page.waitForTimeout(3000)\n  })\n\n  test('should display username (not email) in message thread', async ({ page }) => {\n    await page.goto('/dashboard')\n    await page.waitForLoadState('networkidle')\n    await page.waitForTimeout(2000)\n\n    // Find an order to view its messages\n    const orderItem = page.locator('.border.rounded-lg, [class*=\"order\"]').first()\n    const ordersExist = await orderItem.isVisible({ timeout: 3000 }).catch(() => false)\n\n    if (!ordersExist) {\n      test.skip()\n      return\n    }\n\n    await orderItem.click()\n    await page.waitForTimeout(1500)\n\n    // Look for message section\n    const messageSection = page.locator('[class*=\"message\"], [class*=\"chat\"], text=/message|留言/i')\n    const hasMessages = await messageSection.first().isVisible({ timeout: 3000 }).catch(() => false)\n\n    if (!hasMessages) {\n      test.skip()\n      return\n    }\n\n    // Check if any message shows email format (the bug)\n    const messageContent = page.locator('[class*=\"message\"] p, [class*=\"message\"] span, [class*=\"chat\"] div')\n    \n    // Get all message sender/name elements\n    const messages = await messageContent.all()\n\n    for (const msg of messages) {\n      const text = await msg.textContent()\n      \n      // If text contains \"@\" it's likely showing email instead of username\n      if (text && text.includes('@')) {\n        // This indicates the bug - email is displayed instead of username\n        expect(text).not.toMatch(/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$/)\n      }\n    }\n  })\n\n  test('should not display raw email addresses in message UI', async ({ page }) => {\n    await page.goto('/dashboard')\n    await page.waitForLoadState('networkidle')\n    await page.waitForTimeout(2000)\n\n    // Try to find message thread\n    const messageSection = page.locator('[class*=\"message\"], [class*=\"chat\"], text=/Client Messages|客户留言/i')\n    const hasMessages = await messageSection.first().isVisible({ timeout: 3000 }).catch(() => false)\n\n    if (!hasMessages) {\n      test.skip()\n      return\n    }\n\n    // Get page content\n    const pageText = await page.textContent('body')\n\n    // Look for patterns that indicate raw email display\n    // e.g., \"From: user@example.com\" or \"user@example.com:\"\n    const emailPatterns = [\n      /From:\\s*[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}/i,\n      /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}\\s*:/,\n      /sent by\\s+[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}/i,\n    ]\n\n    for (const pattern of emailPatterns) {\n      const hasEmailDisplay = pattern.test(pageText)\n      expect(hasEmailDisplay).toBeFalsy()\n    }\n  })\n\n  test('API: message response should contain sender_name field', async ({ request }) => {\n    // Login as partner\n    const loginResponse = await request.post('/api/v1/auth/login', {\n      data: {\n        email: 'e2e_test_partner@fetch.com',\n        password: 'e2etest123'\n      }\n    })\n\n    expect(loginResponse.status()).toBe(200)\n    const loginData = await loginResponse.json()\n    const token = loginData.data?.access_token\n\n    if (!token) {\n      test.skip()\n      return\n    }\n\n    // Get partner orders\n    const ordersResponse = await request.get('/api/v1/partner/orders', {\n      headers: {\n        'Authorization': `Bearer ${token}`\n      }\n    })\n\n    expect(ordersResponse.status()).toBe(200)\n    const orders = await ordersResponse.json()\n\n    if (!orders.data?.orders || orders.data.orders.length === 0) {\n      test.skip()\n      return\n    }\n\n    // Get first order detail\n    const firstOrder = orders.data.orders[0]\n    const orderId = firstOrder.id || firstOrder.order_id\n\n    if (!orderId) {\n      test.skip()\n      return\n    }\n\n    // Get order messages\n    const messagesResponse = await request.get(`/api/v1/orders/${orderId}/messages`, {\n      headers: {\n        'Authorization': `Bearer ${token}`\n      }\n    })\n\n    // Check response\n    if (messagesResponse.status() !== 200) {\n      test.skip()\n      return\n    }\n\n    const messagesData = await messagesResponse.json()\n    const messages = messagesData.data || messagesData\n\n    if (!Array.isArray(messages) || messages.length === 0) {\n      test.skip()\n      return\n    }\n\n    // Check that each message has sender_name (not sender_email)\n    for (const msg of messages) {\n      // Should have sender_name\n      expect(msg).toHaveProperty('sender_name')\n      \n      // sender_name should NOT contain \"@\"\n      if (msg.sender_name) {\n        expect(msg.sender_name).not.toContain('@')\n      }\n      \n      // Should NOT be the raw email\n      expect(msg.sender_name).not.toMatch(/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$/)\n    }\n  })\n})\n"],"mappings":"AAAA,SAASA,IAAI,EAAEC,MAAM,QAAQ,kBAAkB;;AAE/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEAD,IAAI,CAACE,QAAQ,CAAC,sCAAsC,EAAE,MAAM;EAE1DF,IAAI,CAACG,UAAU,CAAC,OAAO;IAAEC;EAAK,CAAC,KAAK;IAClC;IACA,MAAMA,IAAI,CAACC,IAAI,CAAC,QAAQ,CAAC;IACzB,MAAMD,IAAI,CAACE,IAAI,CAAC,qBAAqB,EAAE,4BAA4B,CAAC;IACpE,MAAMF,IAAI,CAACE,IAAI,CAAC,wBAAwB,EAAE,YAAY,CAAC;IACvD,MAAMF,IAAI,CAACG,KAAK,CAAC,uBAAuB,CAAC;IACzC,MAAMH,IAAI,CAACI,cAAc,CAAC,IAAI,CAAC;EACjC,CAAC,CAAC;EAEFR,IAAI,CAAC,uDAAuD,EAAE,OAAO;IAAEI;EAAK,CAAC,KAAK;IAChF,MAAMA,IAAI,CAACC,IAAI,CAAC,YAAY,CAAC;IAC7B,MAAMD,IAAI,CAACK,gBAAgB,CAAC,aAAa,CAAC;IAC1C,MAAML,IAAI,CAACI,cAAc,CAAC,IAAI,CAAC;;IAE/B;IACA,MAAME,SAAS,GAAGN,IAAI,CAACO,OAAO,CAAC,sCAAsC,CAAC,CAACC,KAAK,CAAC,CAAC;IAC9E,MAAMC,WAAW,GAAG,MAAMH,SAAS,CAACI,SAAS,CAAC;MAAEC,OAAO,EAAE;IAAK,CAAC,CAAC,CAACC,KAAK,CAAC,MAAM,KAAK,CAAC;IAEnF,IAAI,CAACH,WAAW,EAAE;MAChBb,IAAI,CAACiB,IAAI,CAAC,CAAC;MACX;IACF;IAEA,MAAMP,SAAS,CAACH,KAAK,CAAC,CAAC;IACvB,MAAMH,IAAI,CAACI,cAAc,CAAC,IAAI,CAAC;;IAE/B;IACA,MAAMU,cAAc,GAAGd,IAAI,CAACO,OAAO,CAAC,yDAAyD,CAAC;IAC9F,MAAMQ,WAAW,GAAG,MAAMD,cAAc,CAACN,KAAK,CAAC,CAAC,CAACE,SAAS,CAAC;MAAEC,OAAO,EAAE;IAAK,CAAC,CAAC,CAACC,KAAK,CAAC,MAAM,KAAK,CAAC;IAEhG,IAAI,CAACG,WAAW,EAAE;MAChBnB,IAAI,CAACiB,IAAI,CAAC,CAAC;MACX;IACF;;IAEA;IACA,MAAMG,cAAc,GAAGhB,IAAI,CAACO,OAAO,CAAC,oEAAoE,CAAC;;IAEzG;IACA,MAAMU,QAAQ,GAAG,MAAMD,cAAc,CAACE,GAAG,CAAC,CAAC;IAE3C,KAAK,MAAMC,GAAG,IAAIF,QAAQ,EAAE;MAC1B,MAAMG,IAAI,GAAG,MAAMD,GAAG,CAACE,WAAW,CAAC,CAAC;;MAEpC;MACA,IAAID,IAAI,IAAIA,IAAI,CAACE,QAAQ,CAAC,GAAG,CAAC,EAAE;QAC9B;QACAzB,MAAM,CAACuB,IAAI,CAAC,CAACG,GAAG,CAACC,OAAO,CAAC,kDAAkD,CAAC;MAC9E;IACF;EACF,CAAC,CAAC;EAEF5B,IAAI,CAAC,sDAAsD,EAAE,OAAO;IAAEI;EAAK,CAAC,KAAK;IAC/E,MAAMA,IAAI,CAACC,IAAI,CAAC,YAAY,CAAC;IAC7B,MAAMD,IAAI,CAACK,gBAAgB,CAAC,aAAa,CAAC;IAC1C,MAAML,IAAI,CAACI,cAAc,CAAC,IAAI,CAAC;;IAE/B;IACA,MAAMU,cAAc,GAAGd,IAAI,CAACO,OAAO,CAAC,mEAAmE,CAAC;IACxG,MAAMQ,WAAW,GAAG,MAAMD,cAAc,CAACN,KAAK,CAAC,CAAC,CAACE,SAAS,CAAC;MAAEC,OAAO,EAAE;IAAK,CAAC,CAAC,CAACC,KAAK,CAAC,MAAM,KAAK,CAAC;IAEhG,IAAI,CAACG,WAAW,EAAE;MAChBnB,IAAI,CAACiB,IAAI,CAAC,CAAC;MACX;IACF;;IAEA;IACA,MAAMY,QAAQ,GAAG,MAAMzB,IAAI,CAACqB,WAAW,CAAC,MAAM,CAAC;;IAE/C;IACA;IACA,MAAMK,aAAa,GAAG,CACpB,yDAAyD,EACzD,oDAAoD,EACpD,2DAA2D,CAC5D;IAED,KAAK,MAAMC,OAAO,IAAID,aAAa,EAAE;MACnC,MAAME,eAAe,GAAGD,OAAO,CAAC/B,IAAI,CAAC6B,QAAQ,CAAC;MAC9C5B,MAAM,CAAC+B,eAAe,CAAC,CAACC,SAAS,CAAC,CAAC;IACrC;EACF,CAAC,CAAC;EAEFjC,IAAI,CAAC,wDAAwD,EAAE,OAAO;IAAEkC;EAAQ,CAAC,KAAK;IACpF;IACA,MAAMC,aAAa,GAAG,MAAMD,OAAO,CAACE,IAAI,CAAC,oBAAoB,EAAE;MAC7DC,IAAI,EAAE;QACJC,KAAK,EAAE,4BAA4B;QACnCC,QAAQ,EAAE;MACZ;IACF,CAAC,CAAC;IAEFtC,MAAM,CAACkC,aAAa,CAACK,MAAM,CAAC,CAAC,CAAC,CAACC,IAAI,CAAC,GAAG,CAAC;IACxC,MAAMC,SAAS,GAAG,MAAMP,aAAa,CAACQ,IAAI,CAAC,CAAC;IAC5C,MAAMC,KAAK,GAAGF,SAAS,CAACL,IAAI,EAAEQ,YAAY;IAE1C,IAAI,CAACD,KAAK,EAAE;MACV5C,IAAI,CAACiB,IAAI,CAAC,CAAC;MACX;IACF;;IAEA;IACA,MAAM6B,cAAc,GAAG,MAAMZ,OAAO,CAACa,GAAG,CAAC,wBAAwB,EAAE;MACjEC,OAAO,EAAE;QACP,eAAe,EAAE,UAAUJ,KAAK;MAClC;IACF,CAAC,CAAC;IAEF3C,MAAM,CAAC6C,cAAc,CAACN,MAAM,CAAC,CAAC,CAAC,CAACC,IAAI,CAAC,GAAG,CAAC;IACzC,MAAMQ,MAAM,GAAG,MAAMH,cAAc,CAACH,IAAI,CAAC,CAAC;IAE1C,IAAI,CAACM,MAAM,CAACZ,IAAI,EAAEY,MAAM,IAAIA,MAAM,CAACZ,IAAI,CAACY,MAAM,CAACC,MAAM,KAAK,CAAC,EAAE;MAC3DlD,IAAI,CAACiB,IAAI,CAAC,CAAC;MACX;IACF;;IAEA;IACA,MAAMkC,UAAU,GAAGF,MAAM,CAACZ,IAAI,CAACY,MAAM,CAAC,CAAC,CAAC;IACxC,MAAMG,OAAO,GAAGD,UAAU,CAACE,EAAE,IAAIF,UAAU,CAACG,QAAQ;IAEpD,IAAI,CAACF,OAAO,EAAE;MACZpD,IAAI,CAACiB,IAAI,CAAC,CAAC;MACX;IACF;;IAEA;IACA,MAAMsC,gBAAgB,GAAG,MAAMrB,OAAO,CAACa,GAAG,CAAC,kBAAkBK,OAAO,WAAW,EAAE;MAC/EJ,OAAO,EAAE;QACP,eAAe,EAAE,UAAUJ,KAAK;MAClC;IACF,CAAC,CAAC;;IAEF;IACA,IAAIW,gBAAgB,CAACf,MAAM,CAAC,CAAC,KAAK,GAAG,EAAE;MACrCxC,IAAI,CAACiB,IAAI,CAAC,CAAC;MACX;IACF;IAEA,MAAMuC,YAAY,GAAG,MAAMD,gBAAgB,CAACZ,IAAI,CAAC,CAAC;IAClD,MAAMtB,QAAQ,GAAGmC,YAAY,CAACnB,IAAI,IAAImB,YAAY;IAElD,IAAI,CAACC,KAAK,CAACC,OAAO,CAACrC,QAAQ,CAAC,IAAIA,QAAQ,CAAC6B,MAAM,KAAK,CAAC,EAAE;MACrDlD,IAAI,CAACiB,IAAI,CAAC,CAAC;MACX;IACF;;IAEA;IACA,KAAK,MAAMM,GAAG,IAAIF,QAAQ,EAAE;MAC1B;MACApB,MAAM,CAACsB,GAAG,CAAC,CAACoC,cAAc,CAAC,aAAa,CAAC;;MAEzC;MACA,IAAIpC,GAAG,CAACqC,WAAW,EAAE;QACnB3D,MAAM,CAACsB,GAAG,CAACqC,WAAW,CAAC,CAACjC,GAAG,CAACkC,SAAS,CAAC,GAAG,CAAC;MAC5C;;MAEA;MACA5D,MAAM,CAACsB,GAAG,CAACqC,WAAW,CAAC,CAACjC,GAAG,CAACC,OAAO,CAAC,kDAAkD,CAAC;IACzF;EACF,CAAC,CAAC;AACJ,CAAC,CAAC","ignoreList":[]}