Error Handling & Edge Cases Test Suite

cgen-9d6eda8f5a484a5d824f9c7b7baa98b9
This commit is contained in:
Builder.io 2025-11-08 01:59:21 +00:00
parent 06f8f37d11
commit ca0362f53e

View file

@ -0,0 +1,446 @@
/**
* Error Handling & Edge Cases Test Suite
* Phase 3: Testing & Validation
*/
interface TestResult {
name: string;
passed: boolean;
expectedStatus: number;
actualStatus: number;
message: string;
}
const results: TestResult[] = [];
const BASE_URL = "http://localhost:5173";
const test = (
name: string,
passed: boolean,
expectedStatus: number,
actualStatus: number,
message: string
) => {
results.push({ name, passed, expectedStatus, actualStatus, message });
const symbol = passed ? "✓" : "✗";
console.log(
`${symbol} ${name.padEnd(50)} | Expected: ${expectedStatus}, Got: ${actualStatus}`
);
};
async function runErrorTests() {
console.log("🛡️ Error Handling & Edge Cases Test Suite\n");
// ERROR CATEGORY 1: Validation Errors
console.log("\n🔴 Category 1: Input Validation Errors");
console.log("=".repeat(70));
// Test missing required fields
let res = await fetch(`${BASE_URL}/api/creators`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ username: "testuser" }), // Missing user_id
});
test(
"Create creator - missing user_id",
res.status === 400,
400,
res.status,
"Should require user_id"
);
res = await fetch(`${BASE_URL}/api/creators`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ user_id: "user123" }), // Missing username
});
test(
"Create creator - missing username",
res.status === 400,
400,
res.status,
"Should require username"
);
res = await fetch(`${BASE_URL}/api/opportunities`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ user_id: "user123" }), // Missing title
});
test(
"Create opportunity - missing title",
res.status === 400,
400,
res.status,
"Should require title"
);
res = await fetch(`${BASE_URL}/api/applications`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ user_id: "user123" }), // Missing opportunity_id
});
test(
"Submit application - missing opportunity_id",
res.status === 400,
400,
res.status,
"Should require opportunity_id"
);
// ERROR CATEGORY 2: Not Found Errors
console.log("\n🔴 Category 2: Resource Not Found Errors");
console.log("=".repeat(70));
res = await fetch(`${BASE_URL}/api/creators/nonexistent_user_12345`);
test(
"Get creator - non-existent username",
res.status === 404,
404,
res.status,
"Should return 404 for non-existent creator"
);
res = await fetch(`${BASE_URL}/api/opportunities/fake-opp-id-99999`);
test(
"Get opportunity - non-existent ID",
res.status === 404,
404,
res.status,
"Should return 404 for non-existent opportunity"
);
res = await fetch(`${BASE_URL}/api/applications?user_id=nonexistent-user`);
test(
"Get applications - non-existent creator",
res.status === 404,
404,
res.status,
"Should return 404 when creator doesn't exist"
);
// ERROR CATEGORY 3: Authorization/Ownership Errors
console.log("\n🔴 Category 3: Authorization & Ownership Errors");
console.log("=".repeat(70));
// Create a fake creator for testing
const testCreator = {
id: `error-test-${Date.now()}`,
username: `error_test_${Date.now()}`,
};
let creatorRes = await fetch(`${BASE_URL}/api/creators`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
user_id: testCreator.id,
username: testCreator.username,
bio: "Test creator",
experience_level: "junior",
}),
});
if (creatorRes.ok) {
// Try to update someone else's profile
res = await fetch(`${BASE_URL}/api/creators/fake-id`, {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
bio: "Hacked bio",
}),
});
test(
"Update creator - invalid creator ID",
res.status === 500 || res.status === 404,
404,
res.status,
"Should reject invalid creator ID"
);
}
// ERROR CATEGORY 4: Duplicate/Conflict Errors
console.log("\n🔴 Category 4: Duplicate & Conflict Errors");
console.log("=".repeat(70));
// Create duplicate creator
const dupUsername = `dup_test_${Date.now()}`;
await fetch(`${BASE_URL}/api/creators`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
user_id: `dup-user-1`,
username: dupUsername,
experience_level: "junior",
}),
});
res = await fetch(`${BASE_URL}/api/creators`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
user_id: `dup-user-2`,
username: dupUsername, // Same username
experience_level: "junior",
}),
});
test(
"Create creator - duplicate username",
res.status === 400,
400,
res.status,
"Should prevent duplicate usernames"
);
// Test duplicate application (create opportunity first)
const oppCreatorId = `opp-creator-${Date.now()}`;
const oppCreatorUsername = `opp_creator_${Date.now()}`;
const appCreatorId = `app-creator-${Date.now()}`;
const appCreatorUsername = `app_creator_${Date.now()}`;
let oppRes = await fetch(`${BASE_URL}/api/creators`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
user_id: oppCreatorId,
username: oppCreatorUsername,
experience_level: "senior",
}),
});
let appCreatorRes = await fetch(`${BASE_URL}/api/creators`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
user_id: appCreatorId,
username: appCreatorUsername,
experience_level: "junior",
}),
});
if (oppRes.ok && appCreatorRes.ok) {
// Create opportunity
let createOppRes = await fetch(`${BASE_URL}/api/opportunities`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
user_id: oppCreatorId,
title: "Test Opportunity",
description: "Test",
job_type: "full-time",
}),
});
if (createOppRes.ok) {
const oppData = await createOppRes.json();
const oppId = oppData.id;
// First application
await fetch(`${BASE_URL}/api/applications`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
user_id: appCreatorId,
opportunity_id: oppId,
cover_letter: "First application",
}),
});
// Duplicate application
res = await fetch(`${BASE_URL}/api/applications`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
user_id: appCreatorId,
opportunity_id: oppId,
cover_letter: "Duplicate application",
}),
});
test(
"Apply to opportunity - duplicate application",
res.status === 400,
400,
res.status,
"Should prevent duplicate applications"
);
}
}
// ERROR CATEGORY 5: Missing Required Relationships
console.log("\n🔴 Category 5: Missing Required Relationships");
console.log("=".repeat(70));
res = await fetch(`${BASE_URL}/api/opportunities`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
user_id: `nonexistent-creator-user`,
title: "Opportunity",
description: "Test",
}),
});
test(
"Create opportunity - creator doesn't exist",
res.status === 404,
404,
res.status,
"Should require existing creator profile"
);
res = await fetch(`${BASE_URL}/api/applications`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
user_id: `nonexistent-app-creator`,
opportunity_id: "fake-opp-id",
}),
});
test(
"Submit application - creator doesn't exist",
res.status === 404,
404,
res.status,
"Should require existing creator profile"
);
// ERROR CATEGORY 6: Invalid Query Parameters
console.log("\n🔴 Category 6: Invalid Query Parameters");
console.log("=".repeat(70));
res = await fetch(`${BASE_URL}/api/creators?page=invalid&limit=20`);
const pageData = await res.json();
test(
"Get creators - invalid page parameter",
res.ok, // Should still work with default pagination
200,
res.status,
"Should handle invalid page gracefully"
);
res = await fetch(`${BASE_URL}/api/opportunities?limit=999999`);
test(
"Get opportunities - limit too large",
res.ok, // Should cap the limit
200,
res.status,
"Should cap maximum limit"
);
res = await fetch(`${BASE_URL}/api/creators?arm=invalid_arm`);
const armData = await res.json();
test(
"Get creators - invalid arm filter",
res.ok && Array.isArray(armData.data),
200,
res.status,
"Should return empty results or handle gracefully"
);
// ERROR CATEGORY 7: Empty/Null Values
console.log("\n🔴 Category 7: Empty & Null Values");
console.log("=".repeat(70));
res = await fetch(`${BASE_URL}/api/creators`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
user_id: "",
username: "",
}),
});
test(
"Create creator - empty user_id",
res.status === 400,
400,
res.status,
"Should reject empty user_id"
);
res = await fetch(`${BASE_URL}/api/creators?search=`);
test(
"Search creators - empty search string",
res.ok,
200,
res.status,
"Should handle empty search gracefully"
);
// ERROR CATEGORY 8: Missing DevConnect Parameters
console.log("\n🔴 Category 8: DevConnect Linking Errors");
console.log("=".repeat(70));
res = await fetch(`${BASE_URL}/api/devconnect/link`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ devconnect_username: "user" }), // Missing user_id
});
test(
"Link DevConnect - missing user_id",
res.status === 400,
400,
res.status,
"Should require user_id"
);
res = await fetch(`${BASE_URL}/api/devconnect/link`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ user_id: "user123" }), // Missing devconnect_username
});
test(
"Link DevConnect - missing devconnect_username",
res.status === 400,
400,
res.status,
"Should require devconnect_username"
);
res = await fetch(`${BASE_URL}/api/devconnect/link`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
user_id: "nonexistent-user",
devconnect_username: "dev_user",
}),
});
test(
"Link DevConnect - creator doesn't exist",
res.status === 404,
404,
res.status,
"Should require existing creator profile"
);
// Summary
console.log("\n" + "=".repeat(70));
const passed = results.filter((r) => r.passed).length;
const failed = results.filter((r) => !r.passed).length;
console.log(`\n📊 Error Handling Test Summary:`);
console.log(` ✓ Passed: ${passed}`);
console.log(` ✗ Failed: ${failed}`);
console.log(` Total: ${results.length}`);
if (failed > 0) {
console.log("\n❌ Failed Tests:");
results
.filter((r) => !r.passed)
.forEach((r) => {
console.log(` - ${r.name}`);
console.log(` Expected ${r.expectedStatus}, got ${r.actualStatus}: ${r.message}`);
});
} else {
console.log("\n✅ All error handling tests passed!");
}
console.log("\n" + "=".repeat(70));
return { passed, failed, total: results.length };
}
runErrorTests()
.then((summary) => {
process.exit(summary.failed > 0 ? 1 : 0);
})
.catch((error) => {
console.error("Test suite failed:", error);
process.exit(1);
});