/** * 使用者資料管理流程端到端場景 * * 此模組提供完整的使用者資料管理流程場景,組合多個 API 場景形成業務流程。 * * 使用方式: * import { getAndUpdateProfileFlow, emailVerificationFlow, phoneVerificationFlow, passwordChangeFlow } from './scenarios/e2e/user-profile-flow.js'; */ import * as auth from '../apis/auth.js'; import * as user from '../apis/user.js'; import { sleep } from 'k6'; /** * 取得並更新個人資料流程 * @param {Object} options - 配置選項 * @param {string} options.baseUrl - API 基礎 URL * @param {string} options.accessToken - Access Token * @param {Object} options.updateData - 要更新的資料 * @param {Object} options.customMetrics - 自定義指標對象(可選) * @returns {Object} 流程結果 */ export function getAndUpdateProfileFlow(options = {}) { const { baseUrl = __ENV.BASE_URL || 'https://localhost:8888', accessToken, updateData = { nickname: `TestUser_${Date.now()}`, preferred_language: 'zh-tw', }, customMetrics = null, } = options; if (!accessToken) { throw new Error('accessToken is required'); } // 步驟 1: 取得使用者資訊 const getInfoResult = user.getUserInfo({ baseUrl, accessToken, customMetrics, }); if (!getInfoResult.success) { return { success: false, step: 'get_info', error: 'Get user info failed', getInfoResult, }; } // 短暫等待 sleep(1); // 步驟 2: 更新使用者資訊 const updateInfoResult = user.updateUserInfo({ baseUrl, accessToken, updateData, customMetrics, }); if (!updateInfoResult.success) { return { success: false, step: 'update_info', error: 'Update user info failed', getInfoResult, updateInfoResult, }; } return { success: true, getInfoResult, updateInfoResult, originalData: getInfoResult.response, updatedData: updateInfoResult.response, }; } /** * 完整 Email 驗證流程(請求 → 提交) * @param {Object} options - 配置選項 * @param {string} options.baseUrl - API 基礎 URL * @param {string} options.accessToken - Access Token * @param {string} options.verifyCode - 驗證碼(在實際測試中可能需要從外部獲取) * @returns {Object} 流程結果 */ export function emailVerificationFlow(options = {}) { const { baseUrl = __ENV.BASE_URL || 'https://localhost:8888', accessToken, verifyCode, } = options; if (!accessToken) { throw new Error('accessToken is required'); } // 步驟 1: 請求 Email 驗證碼 const requestResult = user.requestVerificationCode({ baseUrl, accessToken, purpose: 'email_verification', }); if (!requestResult.success) { return { success: false, step: 'request', error: 'Request email verification code failed', requestResult, }; } // 短暫等待,模擬用戶收到驗證碼的時間 sleep(2); // 步驟 2: 提交驗證碼 if (!verifyCode) { return { success: false, step: 'submit', error: 'verifyCode is required but not provided', requestResult, note: 'In real testing, verifyCode should be retrieved from external source (DB, email service, etc.)', }; } const submitResult = user.submitVerificationCode({ baseUrl, accessToken, purpose: 'email_verification', verifyCode, }); if (!submitResult.success) { return { success: false, step: 'submit', error: 'Submit email verification code failed', requestResult, submitResult, }; } return { success: true, requestResult, submitResult, }; } /** * 完整手機驗證流程(請求 → 提交) * @param {Object} options - 配置選項 * @param {string} options.baseUrl - API 基礎 URL * @param {string} options.accessToken - Access Token * @param {string} options.verifyCode - 驗證碼(在實際測試中可能需要從外部獲取) * @returns {Object} 流程結果 */ export function phoneVerificationFlow(options = {}) { const { baseUrl = __ENV.BASE_URL || 'https://localhost:8888', accessToken, verifyCode, } = options; if (!accessToken) { throw new Error('accessToken is required'); } // 步驟 1: 請求手機驗證碼 const requestResult = user.requestVerificationCode({ baseUrl, accessToken, purpose: 'phone_verification', }); if (!requestResult.success) { return { success: false, step: 'request', error: 'Request phone verification code failed', requestResult, }; } // 短暫等待,模擬用戶收到驗證碼的時間 sleep(2); // 步驟 2: 提交驗證碼 if (!verifyCode) { return { success: false, step: 'submit', error: 'verifyCode is required but not provided', requestResult, note: 'In real testing, verifyCode should be retrieved from external source (DB, SMS service, etc.)', }; } const submitResult = user.submitVerificationCode({ baseUrl, accessToken, purpose: 'phone_verification', verifyCode, }); if (!submitResult.success) { return { success: false, step: 'submit', error: 'Submit phone verification code failed', requestResult, submitResult, }; } return { success: true, requestResult, submitResult, }; } /** * 登入狀態下修改密碼流程 * @param {Object} options - 配置選項 * @param {string} options.baseUrl - API 基礎 URL * @param {string} options.accessToken - Access Token * @param {string} options.currentPassword - 當前密碼 * @param {string} options.newPassword - 新密碼 * @returns {Object} 流程結果 */ export function passwordChangeFlow(options = {}) { const { baseUrl = __ENV.BASE_URL || 'https://localhost:8888', accessToken, currentPassword, newPassword = 'NewPassword123!', } = options; if (!accessToken || !currentPassword) { throw new Error('accessToken and currentPassword are required'); } // 步驟 1: 修改密碼 const updatePasswordResult = user.updatePassword({ baseUrl, accessToken, currentPassword, newPassword, }); if (!updatePasswordResult.success) { return { success: false, step: 'update_password', error: 'Update password failed', updatePasswordResult, }; } // 短暫等待 sleep(1); // 步驟 2: 使用新密碼登入驗證(可選) // 注意:這需要知道 loginId,可能需要從 getUserInfo 獲取 // 這裡僅作為示例,實際使用時可能需要調整 return { success: true, updatePasswordResult, }; } /** * 完整的使用者資料初始化流程(註冊 → 登入 → 取得資訊 → 更新資訊) * @param {Object} options - 配置選項 * @param {string} options.baseUrl - API 基礎 URL * @param {string} options.loginId - 登入 ID * @param {string} options.password - 密碼 * @param {Object} options.updateData - 要更新的資料 * @param {Object} options.customMetrics - 自定義指標對象(可選) * @returns {Object} 流程結果 */ export function userProfileInitializationFlow(options = {}) { const { baseUrl = __ENV.BASE_URL || 'https://localhost:8888', loginId = `test_${Date.now()}@example.com`, password = 'Test123456!', updateData = { nickname: `TestUser_${Date.now()}`, preferred_language: 'zh-tw', currency: 'TWD', }, customMetrics = null, } = options; // 步驟 1: 註冊 const registerResult = auth.registerWithCredentials({ baseUrl, loginId, password, customMetrics, }); if (!registerResult.success || !registerResult.tokens) { return { success: false, step: 'register', error: 'Registration failed', registerResult, }; } sleep(1); // 步驟 2: 取得使用者資訊 const getInfoResult = user.getUserInfo({ baseUrl, accessToken: registerResult.tokens.accessToken, customMetrics, }); if (!getInfoResult.success) { return { success: false, step: 'get_info', error: 'Get user info failed', registerResult, getInfoResult, }; } sleep(1); // 步驟 3: 更新使用者資訊 const updateInfoResult = user.updateUserInfo({ baseUrl, accessToken: registerResult.tokens.accessToken, updateData, customMetrics, }); if (!updateInfoResult.success) { return { success: false, step: 'update_info', error: 'Update user info failed', registerResult, getInfoResult, updateInfoResult, }; } return { success: true, registerResult, getInfoResult, updateInfoResult, tokens: registerResult.tokens, }; }