Files
filezzy-staging/backend/scripts/test-guest-config-api.ts
2026-02-04 14:16:04 +01:00

105 lines
4.6 KiB
TypeScript
Raw 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.
#!/usr/bin/env ts-node
/**
* Test: Guest API responses vs runtime config (DB).
* Calls public config and guest-facing endpoints, then compares guest limits
* and feature flags with the values from GET /api/v1/config (runtime config we configured).
* Run: npx ts-node scripts/test-guest-config-api.ts
* API_URL=http://127.0.0.1:4000 npx ts-node scripts/test-guest-config-api.ts
*/
import axios from 'axios';
const BASE_URL = process.env.API_URL || 'http://127.0.0.1:4000';
type PublicConfig = Record<string, unknown>;
interface GuestLimitsResponse {
tier: string;
limits: { maxFileSizeMb: number; maxFilesPerBatch: number; maxBatchSizeMb: number };
opsLimit: number | null;
opsUsedToday: number | null;
nextReset: string | null;
}
function assert(condition: boolean, message: string): void {
if (!condition) {
throw new Error(message);
}
}
async function main(): Promise<void> {
console.log('\n=== Guest API vs Runtime Config (DB) ===\n');
console.log('Base URL:', BASE_URL);
// 1. Fetch public runtime config (from DB - what we configured)
const configRes = await axios.get<PublicConfig>(`${BASE_URL}/api/v1/config`, {
validateStatus: () => true,
timeout: 10000,
});
assert(configRes.status === 200, `GET /api/v1/config failed: ${configRes.status}`);
const config = configRes.data;
console.log(' GET /api/v1/config: 200 OK');
// 2. Fetch guest limits (no auth = guest)
const limitsRes = await axios.get<GuestLimitsResponse>(`${BASE_URL}/api/v1/user/limits`, {
validateStatus: () => true,
timeout: 10000,
});
assert(limitsRes.status === 200, `GET /api/v1/user/limits failed: ${limitsRes.status}`);
const guest = limitsRes.data;
console.log(' GET /api/v1/user/limits (no auth): 200 OK');
// 3. Assert guest tier
assert(guest.tier === 'GUEST', `Expected tier GUEST, got ${guest.tier}`);
console.log(' Tier: GUEST');
// 4. Compare guest limits with runtime config (DB)
const maxFileMb = Number(config.max_file_size_mb_guest);
const maxFilesBatch = Number(config.max_files_per_batch_guest);
const maxBatchMb = Number(config.max_batch_size_mb_guest);
const maxOpsDay = Number(config.max_ops_per_day_guest);
assert(!Number.isNaN(maxFileMb), 'max_file_size_mb_guest missing or invalid in config');
assert(guest.limits.maxFileSizeMb === maxFileMb, `maxFileSizeMb: API=${guest.limits.maxFileSizeMb}, config(DB)=${maxFileMb}`);
console.log(` limits.maxFileSizeMb: ${guest.limits.maxFileSizeMb} (matches config)`);
assert(!Number.isNaN(maxFilesBatch), 'max_files_per_batch_guest missing or invalid in config');
assert(guest.limits.maxFilesPerBatch === maxFilesBatch, `maxFilesPerBatch: API=${guest.limits.maxFilesPerBatch}, config(DB)=${maxFilesBatch}`);
console.log(` limits.maxFilesPerBatch: ${guest.limits.maxFilesPerBatch} (matches config)`);
assert(!Number.isNaN(maxBatchMb), 'max_batch_size_mb_guest missing or invalid in config');
assert(guest.limits.maxBatchSizeMb === maxBatchMb, `maxBatchSizeMb: API=${guest.limits.maxBatchSizeMb}, config(DB)=${maxBatchMb}`);
console.log(` limits.maxBatchSizeMb: ${guest.limits.maxBatchSizeMb} (matches config)`);
assert(!Number.isNaN(maxOpsDay), 'max_ops_per_day_guest missing or invalid in config');
assert(guest.opsLimit === maxOpsDay, `opsLimit: API=${guest.opsLimit}, config(DB)=${maxOpsDay}`);
console.log(` opsLimit: ${guest.opsLimit} (matches config)`);
// 5. Guest-relevant feature flags from config (for reference)
const adsEnabled = config.ads_enabled === true || config.ads_enabled === 'true';
const registrationOpen = config.registration_open === true || config.registration_open === 'true';
const maintenanceMode = config.maintenance_mode === true || config.maintenance_mode === 'true';
console.log('\n Feature flags (from config):');
console.log(` ads_enabled: ${adsEnabled}`);
console.log(` registration_open: ${registrationOpen}`);
console.log(` maintenance_mode: ${maintenanceMode}`);
// 6. Optional: GET /api/v1/config/pricing guest section (still from env in many setups; we just log)
const pricingRes = await axios.get(`${BASE_URL}/api/v1/config/pricing`, {
validateStatus: () => true,
timeout: 10000,
});
if (pricingRes.status === 200 && pricingRes.data?.limits?.guest) {
const pricingGuest = pricingRes.data.limits.guest;
console.log('\n GET /api/v1/config/pricing guest limits (may be env-driven):');
console.log(` maxFileSizeMb: ${pricingGuest.maxFileSizeMb}, maxOpsPerDay: ${pricingGuest.maxOpsPerDay}`);
}
console.log('\n=== All guest vs config checks passed ===\n');
}
main().catch((err) => {
console.error('\nFAIL:', err.message);
process.exit(1);
});