backend/test/scenarios/e2e/authentication-flow.js

243 lines
5.5 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 認證流程端到端場景
*
* 此模組提供完整的認證流程場景,組合多個 API 場景形成業務流程。
*
* 使用方式:
* import { registerAndLoginFlow, loginAndRefreshFlow, passwordResetFlow } from './scenarios/e2e/authentication-flow.js';
*/
import * as auth from '../apis/auth.js';
import { sleep } from 'k6';
/**
* 註冊後立即登入流程
* @param {Object} options - 配置選項
* @param {string} options.baseUrl - API 基礎 URL
* @param {string} options.loginId - 登入 ID
* @param {string} options.password - 密碼
* @param {Object} options.customMetrics - 自定義指標對象(可選)
* @returns {Object} 流程結果
*/
export function registerAndLoginFlow(options = {}) {
const {
baseUrl = __ENV.BASE_URL || 'https://localhost:8888',
loginId = `test_${Date.now()}@example.com`,
password = 'Test123456!',
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 loginResult = auth.loginWithCredentials({
baseUrl,
loginId,
password,
customMetrics,
});
if (!loginResult.success || !loginResult.tokens) {
return {
success: false,
step: 'login',
error: 'Login failed after registration',
registerResult,
loginResult,
};
}
return {
success: true,
registerResult,
loginResult,
tokens: loginResult.tokens,
};
}
/**
* 登入後刷新 Token 流程
* @param {Object} options - 配置選項
* @param {string} options.baseUrl - API 基礎 URL
* @param {string} options.loginId - 登入 ID
* @param {string} options.password - 密碼
* @param {Object} options.customMetrics - 自定義指標對象(可選)
* @returns {Object} 流程結果
*/
export function loginAndRefreshFlow(options = {}) {
const {
baseUrl = __ENV.BASE_URL || 'https://localhost:8888',
loginId,
password,
customMetrics = null,
} = options;
if (!loginId || !password) {
throw new Error('loginId and password are required');
}
// 步驟 1: 登入
const loginResult = auth.loginWithCredentials({
baseUrl,
loginId,
password,
customMetrics,
});
if (!loginResult.success || !loginResult.tokens) {
return {
success: false,
step: 'login',
error: 'Login failed',
loginResult,
};
}
// 短暫等待
sleep(1);
// 步驟 2: 刷新 Token
const refreshResult = auth.refreshToken({
baseUrl,
accessToken: loginResult.tokens.accessToken,
refreshToken: loginResult.tokens.refreshToken,
customMetrics,
});
if (!refreshResult.success || !refreshResult.tokens) {
return {
success: false,
step: 'refresh',
error: 'Token refresh failed',
loginResult,
refreshResult,
};
}
return {
success: true,
loginResult,
refreshResult,
tokens: refreshResult.tokens,
};
}
/**
* 完整密碼重設流程(請求 → 驗證 → 重設)
* @param {Object} options - 配置選項
* @param {string} options.baseUrl - API 基礎 URL
* @param {string} options.identifier - 使用者帳號email 或 phone
* @param {string} options.accountType - 帳號類型email/phone
* @param {string} options.verifyCode - 驗證碼(在實際測試中可能需要從外部獲取)
* @param {string} options.newPassword - 新密碼
* @returns {Object} 流程結果
*/
export function passwordResetFlow(options = {}) {
const {
baseUrl = __ENV.BASE_URL || 'https://localhost:8888',
identifier,
accountType = 'email',
verifyCode,
newPassword = 'NewPassword123!',
} = options;
if (!identifier) {
throw new Error('identifier is required');
}
// 步驟 1: 請求密碼重設驗證碼
const requestResult = auth.requestPasswordReset({
baseUrl,
identifier,
accountType,
});
if (!requestResult.success) {
return {
success: false,
step: 'request',
error: 'Request password reset failed',
requestResult,
};
}
// 短暫等待,模擬用戶收到驗證碼的時間
sleep(2);
// 步驟 2: 驗證密碼重設驗證碼
if (!verifyCode) {
// 在實際測試中,驗證碼可能需要從外部獲取(如測試資料庫、郵件服務等)
return {
success: false,
step: 'verify',
error: 'verifyCode is required but not provided',
requestResult,
note: 'In real testing, verifyCode should be retrieved from external source (DB, email service, etc.)',
};
}
const verifyResult = auth.verifyPasswordResetCode({
baseUrl,
identifier,
verifyCode,
});
if (!verifyResult.success) {
return {
success: false,
step: 'verify',
error: 'Verify password reset code failed',
requestResult,
verifyResult,
};
}
// 短暫等待
sleep(1);
// 步驟 3: 執行密碼重設
const resetResult = auth.resetPassword({
baseUrl,
identifier,
verifyCode,
newPassword,
});
if (!resetResult.success) {
return {
success: false,
step: 'reset',
error: 'Reset password failed',
requestResult,
verifyResult,
resetResult,
};
}
return {
success: true,
requestResult,
verifyResult,
resetResult,
};
}