/** * WalkGuide — Synthetic Test Data Generator * Menghasilkan data dummy yang realistis untuk semua skenario load test. */ import { uuidv4 } from "https://jslib.k6.io/k6-utils/1.4.0/index.js"; // ── Alphabet untuk uniqueUserId (12 char alphanumeric) ────────────────────── const ALPHANUM = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; function randomString(len, chars = ALPHANUM) { let out = ""; for (let i = 0; i < len; i++) { out += chars[Math.floor(Math.random() * chars.length)]; } return out; } function randomInt(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; } function randomFloat(min, max, decimals = 6) { return parseFloat((Math.random() * (max - min) + min).toFixed(decimals)); } function randomElement(arr) { return arr[Math.floor(Math.random() * arr.length)]; } // ── Koordinat realistis: sekitar Surabaya ─────────────────────────────────── const SURABAYA_CENTER = { lat: -7.2575, lng: 112.7521 }; export function randomSurabayaCoord(radiusDegrees = 0.05) { return { lat: SURABAYA_CENTER.lat + randomFloat(-radiusDegrees, radiusDegrees), lng: SURABAYA_CENTER.lng + randomFloat(-radiusDegrees, radiusDegrees), }; } // ── User / Guardian data ───────────────────────────────────────────────────── /** * Generate payload untuk register GUARDIAN */ export function guardianRegisterPayload(suffix = "") { const uid = suffix || randomString(8); return { email: `guardian_${uid}@walkguide-test.com`, password: `Pass@${randomString(6)}!`, displayName: `Guardian ${uid}`, role: "ROLE_GUARDIAN", }; } /** * Generate payload untuk register USER (tunanetra) */ export function userRegisterPayload(suffix = "") { const uid = suffix || randomString(8); return { email: `user_${uid}@walkguide-test.com`, password: `Pass@${randomString(6)}!`, displayName: `User ${uid}`, role: "ROLE_USER", }; } // ── Location data ──────────────────────────────────────────────────────────── const DIRECTION_LABELS = [ "NORTH", "NORTHEAST", "EAST", "SOUTHEAST", "SOUTH", "SOUTHWEST", "WEST", "NORTHWEST", ]; /** * Generate satu location update payload (simulasi GPS setiap 5 detik) */ export function locationUpdatePayload( baseLat = SURABAYA_CENTER.lat, baseLng = SURABAYA_CENTER.lng, ) { return { lat: baseLat + randomFloat(-0.001, 0.001), lng: baseLng + randomFloat(-0.001, 0.001), accuracy: randomFloat(3.0, 15.0, 1), speed: randomFloat(0.5, 2.5, 2), // walking speed m/s heading: randomFloat(0.0, 359.9, 1), }; } /** * Generate array of location updates (simulasi walking path) */ export function walkingPath( steps = 10, startLat = SURABAYA_CENTER.lat, startLng = SURABAYA_CENTER.lng, ) { const path = []; let lat = startLat, lng = startLng; for (let i = 0; i < steps; i++) { lat += randomFloat(-0.0002, 0.0002); lng += randomFloat(-0.0002, 0.0002); path.push({ lat, lng, accuracy: randomFloat(3, 10, 1), speed: randomFloat(0.8, 1.8, 2), heading: randomFloat(0, 360, 1), }); } return path; } // ── Obstacle data ──────────────────────────────────────────────────────────── const YOLO_LABELS = [ "person", "car", "motorcycle", "bicycle", "truck", "bus", "traffic light", "stop sign", "bench", "chair", "potted plant", "fire hydrant", "parking meter", "dog", "cat", "suitcase", ]; const OBSTACLE_DIRECTIONS = ["LEFT", "CENTER", "RIGHT"]; const OBSTACLE_DISTANCES = ["Very Close", "Close", "Medium", "Far"]; /** * Generate satu obstacle log payload (output YOLO detection) */ export function obstacleLogPayload() { const coord = randomSurabayaCoord(0.02); return { label: randomElement(YOLO_LABELS), confidence: randomFloat(0.5, 0.99, 4), direction: randomElement(OBSTACLE_DIRECTIONS), estimatedDist: randomElement(OBSTACLE_DISTANCES), lat: coord.lat, lng: coord.lng, }; } /** * Generate burst obstacle logs (simulasi: 5 FPS deteksi selama beberapa detik) */ export function obstacleLogBurst(count = 5) { return Array.from({ length: count }, () => obstacleLogPayload()); } // ── SOS data ───────────────────────────────────────────────────────────────── const SOS_TRIGGER_TYPES = ["VOICE_COMMAND", "BUTTON", "MANUAL"]; export function sosPayload() { const coord = randomSurabayaCoord(0.03); return { triggerType: randomElement(SOS_TRIGGER_TYPES), lat: coord.lat, lng: coord.lng, }; } // ── Notification data ───────────────────────────────────────────────────────── const NOTIFICATION_MESSAGES = [ "Hati-hati ada kendaraan di depan!", "Sudah sampai tujuan belum?", "Minta kabar, kamu baik-baik saja?", "Ada yang bisa dibantu?", "Jangan lupa berhati-hati di jalan.", "Aku pantau dari sini ya.", "Sudah mau hujan, cari tempat teduh.", "Ada mobil di sebelah kanan!", "Tolong berhenti dulu.", "Aman ya? Jawab kalau dengar.", ]; export function sendNotificationPayload() { return { notifType: "TEXT", content: randomElement(NOTIFICATION_MESSAGES), }; } // ── AI Config data ──────────────────────────────────────────────────────────── export function aiConfigPayload() { return { confidenceThreshold: randomFloat(0.3, 0.8, 2), alertDistanceClose: randomFloat(1.0, 2.5, 1), alertDistanceMedium: randomFloat(2.5, 5.0, 1), maxInferenceFps: randomInt(3, 10), enabledLabels: "ALL", }; } // ── User Settings data ──────────────────────────────────────────────────────── export function userSettingsPayload() { return { ttsLanguage: randomElement(["id-ID", "en-US"]), ttsPitch: randomFloat(0.8, 1.5, 1), ttsSpeed: randomFloat(0.7, 1.3, 1), warnNoGuardian: true, hapticEnabled: true, }; } // ── Geofence Config data ────────────────────────────────────────────────────── export function geofenceConfigPayload() { const coord = randomSurabayaCoord(0.01); return { centerLat: coord.lat, centerLng: coord.lng, radiusMeters: randomFloat(200, 1000, 0), enabled: true, }; } // ── Unique user id (mirror dari backend logic) ─────────────────────────────── export function fakeUniqueUserId() { return randomString(12); } // ── Generic helpers ─────────────────────────────────────────────────────────── export const testData = { guardianRegisterPayload, userRegisterPayload, locationUpdatePayload, walkingPath, obstacleLogPayload, obstacleLogBurst, sosPayload, sendNotificationPayload, aiConfigPayload, userSettingsPayload, geofenceConfigPayload, fakeUniqueUserId, randomSurabayaCoord, randomElement, randomInt, randomFloat, };