185 行
5.7 KiB
TypeScript
185 行
5.7 KiB
TypeScript
import { expect, test } from "@playwright/test";
|
|
|
|
function envelope(data: unknown) {
|
|
return {
|
|
requestId: "mock-request",
|
|
data,
|
|
};
|
|
}
|
|
|
|
test("E2E 企微首次登录:映射缺失时失败关闭且不要求用密码完成绑定", async ({ page }) => {
|
|
await page.addInitScript(() => {
|
|
Object.defineProperty(window.navigator, "userAgent", {
|
|
configurable: true,
|
|
value: "Mozilla/5.0 wxwork/4.1.20 MicroMessenger/7.0.1",
|
|
});
|
|
});
|
|
|
|
await page.route("**/api/auth/sso/providers", async (route) => {
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: "application/json",
|
|
body: JSON.stringify(envelope([])),
|
|
});
|
|
});
|
|
await page.route("**/api/auth/wecom/config", async (route) => {
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: "application/json",
|
|
body: JSON.stringify(
|
|
envelope({
|
|
enabled: true,
|
|
entryEnabled: true,
|
|
oauthEnabled: true,
|
|
corpId: "wx-test-corp",
|
|
agentId: "1000001",
|
|
loginUrl: "/api/auth/wecom/login?returnTo=%2Fmobile",
|
|
bindEnabled: true,
|
|
defaultReturnTo: "/mobile",
|
|
status: "ready",
|
|
statusReasons: [],
|
|
}),
|
|
),
|
|
});
|
|
});
|
|
await page.route("**/api/auth/login", async (route) => {
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: "application/json",
|
|
headers: { "set-cookie": "has_session=1; Path=/; SameSite=Lax" },
|
|
body: JSON.stringify(
|
|
envelope({
|
|
accessToken: "wecom-fallback-token",
|
|
expiresIn: 900,
|
|
mustChangePassword: false,
|
|
wecomBindingStatus: "bound",
|
|
}),
|
|
),
|
|
});
|
|
});
|
|
await page.route("**/api/auth/refresh", async (route) => {
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: "application/json",
|
|
headers: { "set-cookie": "has_session=1; Path=/; SameSite=Lax" },
|
|
body: JSON.stringify(
|
|
envelope({
|
|
accessToken: "wecom-fallback-token",
|
|
expiresIn: 900,
|
|
mustChangePassword: false,
|
|
}),
|
|
),
|
|
});
|
|
});
|
|
await page.route("**/api/me", async (route) => {
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: "application/json",
|
|
body: JSON.stringify(
|
|
envelope({
|
|
id: "employee-1",
|
|
employeeNo: "HYD000123",
|
|
name: "张三",
|
|
phone: "13800000001",
|
|
email: "[email protected]",
|
|
departmentId: "dept-1",
|
|
directManagerId: null,
|
|
status: "active",
|
|
notificationPushEnabled: true,
|
|
roleCodes: ["employee"],
|
|
permissions: [],
|
|
profileCompleteness: {
|
|
hasEmergencyContact: true,
|
|
hasBankAccount: false,
|
|
hasAvatar: false,
|
|
hasIdNumber: false,
|
|
score: 25,
|
|
},
|
|
wecomBinding: {
|
|
externalUserId: "wecom-user-1",
|
|
createdAt: "2026-05-04T12:00:00.000Z",
|
|
},
|
|
}),
|
|
),
|
|
});
|
|
});
|
|
await page.route("**/api/system/navigation", async (route) => {
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: "application/json",
|
|
body: JSON.stringify(
|
|
envelope({
|
|
workspace: {
|
|
id: "workspace-1",
|
|
persisted: true,
|
|
profile: "small_team_internal",
|
|
orgMode: "single_company",
|
|
primaryEntryMode: "wecom",
|
|
notificationStrategy: "in_app",
|
|
devicePriority: "mobile",
|
|
moduleVisibility: {},
|
|
createdAt: null,
|
|
updatedAt: null,
|
|
updatedBy: null,
|
|
},
|
|
sections: {
|
|
main: [{ key: "portal", href: "/portal", label: "工作台", icon: "home_app_logo", placement: "main", permissionCodes: [], featureFlagKey: null }],
|
|
admin: [],
|
|
backup: [],
|
|
},
|
|
recommendedRolePresets: [],
|
|
}),
|
|
),
|
|
});
|
|
});
|
|
await page.route((url) => url.pathname === "/api/notifications", async (route) => {
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: "application/json",
|
|
body: JSON.stringify(
|
|
envelope({
|
|
page: 1,
|
|
pageSize: 10,
|
|
total: 0,
|
|
unreadOnly: true,
|
|
unreadCount: 0,
|
|
items: [],
|
|
}),
|
|
),
|
|
});
|
|
});
|
|
await page.route("**/api/portal/home", async (route) => {
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: "application/json",
|
|
body: JSON.stringify(
|
|
envelope({
|
|
workspace: { id: "workspace-1", persisted: true, profile: "small_team_internal" },
|
|
greeting: { name: "张三" },
|
|
cards: [],
|
|
pendingTasks: { count: 0, href: "/workflow/tasks" },
|
|
myApplications: [],
|
|
riskSummary: null,
|
|
announcements: [],
|
|
quickLinks: [],
|
|
todayPresence: null,
|
|
teamPresence: null,
|
|
weeklyReport: null,
|
|
weeklySummary: null,
|
|
todoSummary: { openCount: 0, highPriorityCount: 0, href: "/todos" },
|
|
projectSummary: { myCount: 0, overdueMilestonesCount: 0, highPriorityTaskCount: 0, openRiskCount: 0, followUpDueTodayCount: 0, closurePendingProjectCount: 0, href: "/projects" },
|
|
peopleLifecycle: null,
|
|
adoptionSummary: null,
|
|
recentActivities: [],
|
|
teamStatusBoard: [],
|
|
}),
|
|
),
|
|
});
|
|
});
|
|
|
|
await page.goto("/login?redirect=%2Fmobile&wecom=account_mapping_required");
|
|
await expect(page.getByTestId("login-wecom-notice")).toContainText("企业微信账号映射尚未完成");
|
|
await expect(page.getByTestId("login-wecom-notice")).toContainText("请联系管理员核对通讯录同步");
|
|
await expect(page.getByTestId("login-wecom-notice")).not.toContainText("先用账号密码登录");
|
|
});
|