Files
AniKotoAPI/test.js
T
Sʜɪɴᴇɪ Nᴏᴜᴢᴇɴ 100b9f9414 v1.9.0: Full diagnostic sweep - 42 issues fixed
Critical fixes (7):
- Added global Express error handler (returns JSON instead of HTML)
- Removed caching from random endpoint (defeated purpose)
- Renamed share.jpg to share.png (MIME type mismatch)
- Fixed OG image dimensions (630 → 601)
- Fixed manifest.json icon sizes (192x192 → 512x512)
- Fixed implicit global event variable in console
- Added 9 missing endpoints to docs/endpoints.md

High fixes (12):
- Imported version from package.json (no hardcoded drift)
- Added dynamic endpoint count in stats
- Added input sanitization for mapper API (SSRF prevention)
- Added homepage caching (reduced 5 duplicate HTTP requests)
- Added rate limiting (100 requests/minute per IP)
- Added rel="noopener noreferrer" to all target="_blank" links
- Fixed trailing slash inconsistency in console
- Added noindex meta to 404.html
- Fixed docs/architecture.md controller filenames and dependency versions
- Fixed README.md dependency versions
- Added 12 missing endpoint tests

Medium fixes (22):
- Added escapeHtml helper for error messages
- Consistent favicon across all pages
- Added meta descriptions to privacy.html and tos.html
- Added OG/Twitter meta tags to privacy.html and tos.html
- Added aria-label to playground inputs
- Added aria-hidden to decorative SVGs
- Synced Twitter description with OG description
- Fixed robots.txt to disallow /api
- Added PWA fields to manifest.json
- Removed 5 unused imports
- Removed unused cookie-parser dependency
- Fixed inconsistent error handling in extractors
- Fixed resolvedSlug returning numeric ID
- Added /watch endpoint to streaming docs
- Improved test assertions and status code validation
- Deleted orphaned og-image.svg and logo.png

Low fixes (11):
- Removed redundant try/catch from extractPages
- Added max size eviction to cache
- Added cache key sorting in filter controller
- Added author meta tag
- Fixed favicon.svg font

Version bumped to 1.9.0
2026-06-09 06:00:37 +05:30

101 lines
3.2 KiB
JavaScript

/*
* ======= • ======= • ======= • ======= • =======• =======
* AniKotoAPI — test.js
* Repository: https://github.com/Shineii86/AniKotoAPI
*
* @description
* Integration test suite for AniKotoAPI endpoints.
* Tests all major endpoints for correct response format.
*
* @author Shinei Nouzen
* @license MIT
* ======= • ======= • ======= • ======= • =======• =======
*/
const BASE = process.env.API_URL || "https://anikototvapi.vercel.app/api";
const tests = [
{ name: "Home", url: "/" },
{ name: "Search", url: "/search?keyword=naruto" },
{ name: "Info", url: "/info?id=road-of-naruto-ggjw8" },
{ name: "Episodes", url: "/episodes/road-of-naruto-ggjw8" },
{ name: "Suggestions", url: "/suggestions?keyword=naruto" },
{ name: "Spotlight", url: "/spotlight" },
{ name: "Trending", url: "/trending" },
{ name: "Top 10", url: "/top-ten" },
{ name: "Random", url: "/random" },
{ name: "Most Popular", url: "/most-popular" },
{ name: "New Release", url: "/new-release" },
{ name: "Schedule", url: "/schedule" },
{ name: "Genre", url: "/genre/action" },
{ name: "Type", url: "/type/tv" },
{ name: "Status", url: "/status/airing" },
{ name: "Health", url: "/health" },
{ name: "Stats", url: "/stats" },
{ name: "OpenAPI", url: "/openapi" },
{ name: "Watch", url: "/watch?slug=road-of-naruto-ggjw8&ep=1" },
{ name: "Search Suggest", url: "/search/suggest?keyword=naruto" },
{ name: "Episodes Ajax", url: "/episodes-ajax/road-of-naruto-ggjw8" },
{ name: "Newly Added", url: "/newly-added" },
{ name: "Trending Sidebar", url: "/trending-sidebar" },
{ name: "Seasons", url: "/seasons/road-of-naruto-ggjw8" },
{ name: "Watch Order", url: "/watch-order/road-of-naruto-ggjw8" },
{ name: "AZ List", url: "/az-list/a" },
{ name: "Filter", url: "/filter?keyword=&genre[]=1" },
{ name: "Episodes By ID", url: "/episodes/1" },
{ name: "Servers", url: "/servers?ids=1" },
{ name: "Mapper Servers", url: "/mapper-servers?malId=21&slug=one-piece-100&timestamp=1234567890" },
];
let passed = 0;
let failed = 0;
async function runTest(test) {
try {
const res = await fetch(`${BASE}${test.url}`);
if (!res.ok) {
console.log(`❌ ${test.name} - HTTP ${res.status}`);
failed++;
return;
}
const data = await res.json();
if (data.success === true && data.results) {
console.log(`✅ ${test.name}`);
passed++;
} else {
console.log(`❌ ${test.name} - Invalid response format`);
failed++;
}
} catch (error) {
console.log(`❌ ${test.name} - ${error.message}`);
failed++;
}
}
const data = await res.json();
if (data.success === true && data.results) {
console.log(`✅ ${test.name}`);
passed++;
} else {
console.log(`❌ ${test.name} - Invalid response format`);
failed++;
}
} catch (error) {
console.log(`❌ ${test.name} - ${error.message}`);
failed++;
}
}
async function runAll() {
console.log(`\n🧪 Running ${tests.length} tests...\n`);
for (const test of tests) {
await runTest(test);
}
console.log(`\n📊 Results: ${passed} passed, ${failed} failed, ${tests.length} total\n`);
process.exit(failed > 0 ? 1 : 0);
}
runAll();