mirror of
https://github.com/vega-org/vega-providers.git
synced 2026-04-17 15:41:45 +00:00
refactor: streamline provider testing utility and remove deprecated test configurations
This commit is contained in:
@@ -8,10 +8,8 @@
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "node test-providers.js",
|
||||
"test:single": "node test-providers.js",
|
||||
"test:provider": "node test-provider.js",
|
||||
"test:provider:build": "npm run build && node test-provider.js",
|
||||
"test:interactive": "npm run build && node interactive-test.js",
|
||||
"test:quick": "npm run build && node quick-test.js",
|
||||
"test:ui": "npm run test:interactive",
|
||||
"build": "node build-simple.js",
|
||||
"build:dev": "cross-env SKIP_MINIFY=true node build-simple.js",
|
||||
|
||||
111
test-config.js
111
test-config.js
@@ -1,111 +0,0 @@
|
||||
// Common test configurations
|
||||
// You can customize these and run them quickly
|
||||
|
||||
const testConfigs = {
|
||||
// UHD Tests
|
||||
uhdMeta: {
|
||||
provider: "uhd",
|
||||
module: "meta",
|
||||
function: "getMeta",
|
||||
params: {
|
||||
link: "https://uhdmovies.email/download-squid-game-season-2-hindi-1080p-2160p-4k/",
|
||||
},
|
||||
},
|
||||
|
||||
// LuxMovies Tests
|
||||
luxPosts: {
|
||||
provider: "luxMovies",
|
||||
module: "posts",
|
||||
function: "getPosts",
|
||||
params: {
|
||||
url: "https://rogmovies.sbs/page/1/?s=pan",
|
||||
},
|
||||
},
|
||||
|
||||
// PrimeMirror Tests
|
||||
primeMirrorEpisodes: {
|
||||
provider: "primeMirror",
|
||||
module: "episodes",
|
||||
function: "getEpisodes",
|
||||
params: {
|
||||
url: "0KMA7H0RHEPJA51SUBXKN9V6VA",
|
||||
},
|
||||
},
|
||||
|
||||
primeMirrorMeta: {
|
||||
provider: "primeMirror",
|
||||
module: "meta",
|
||||
function: "getMeta",
|
||||
params: {
|
||||
link: "https://www.netflixmirror.com/title/82020512",
|
||||
},
|
||||
},
|
||||
|
||||
primeMirrorSearch: {
|
||||
provider: "primeMirror",
|
||||
module: "posts",
|
||||
function: "getSearchPosts",
|
||||
params: {
|
||||
searchQuery: "breaking",
|
||||
page: 1,
|
||||
providerValue: "primeMirror",
|
||||
},
|
||||
},
|
||||
|
||||
// CinemaLuxe Tests
|
||||
cinemaLuxeEpisodes: {
|
||||
provider: "cinemaLuxe",
|
||||
module: "episodes",
|
||||
function: "getEpisodes",
|
||||
params: {
|
||||
url: "https://cinemalux.net/?88fdac61e5=cVQxdnNXeGRIRXlZTEQ0bTZSZlFsT09qclNlQzExOUNwVk5JZ05JK1ZjbzVxSWt1SHZSZjdZUm5vVnZEOEd1QXlrdXhPdnNETHRHTnpPUUNFN3k3VVdpY0J0OW5rem10c1ZlZ2xRcjI2YjFWRm9Uc3FEeEd0aWZlNFBpOHJ6bms=",
|
||||
},
|
||||
},
|
||||
|
||||
// Add more test configurations here as needed
|
||||
// Template:
|
||||
// yourTestName: {
|
||||
// provider: 'providerName',
|
||||
// module: 'moduleName',
|
||||
// function: 'functionName',
|
||||
// params: {
|
||||
// // your parameters here
|
||||
// }
|
||||
// }
|
||||
};
|
||||
|
||||
// Predefined test batches
|
||||
const testBatches = {
|
||||
// Test all meta functions
|
||||
allMeta: [
|
||||
testConfigs.uhdMeta,
|
||||
testConfigs.primeMirrorMeta,
|
||||
// Add more meta tests
|
||||
],
|
||||
|
||||
// Test all posts/search functions
|
||||
allPosts: [
|
||||
testConfigs.luxPosts,
|
||||
testConfigs.primeMirrorSearch,
|
||||
// Add more posts tests
|
||||
],
|
||||
|
||||
// Test all episode functions
|
||||
allEpisodes: [
|
||||
testConfigs.primeMirrorEpisodes,
|
||||
testConfigs.cinemaLuxeEpisodes,
|
||||
// Add more episode tests
|
||||
],
|
||||
|
||||
// Quick smoke test - test one function from each major provider
|
||||
smokeTest: [
|
||||
testConfigs.uhdMeta,
|
||||
testConfigs.luxPosts,
|
||||
testConfigs.primeMirrorSearch,
|
||||
],
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
testConfigs,
|
||||
testBatches,
|
||||
};
|
||||
@@ -1,188 +1,590 @@
|
||||
const axios = require("axios");
|
||||
const cheerio = require("cheerio");
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
|
||||
// Load extractors and utilities
|
||||
let providerContext;
|
||||
try {
|
||||
const { getBaseUrl } = require("./dist/getBaseUrl.js");
|
||||
const { hubcloudExtracter } = require("./dist/hubcloudExtractor.js");
|
||||
const { gofileExtracter } = require("./dist/gofileExtracter.js");
|
||||
const { superVideoExtractor } = require("./dist/superVideoExtractor.js");
|
||||
const { gdFlixExtracter } = require("./dist/gdFlixExtractor.js");
|
||||
|
||||
providerContext = {
|
||||
axios,
|
||||
cheerio,
|
||||
getBaseUrl,
|
||||
commonHeaders: {
|
||||
"User-Agent":
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
|
||||
},
|
||||
extractors: {
|
||||
hubcloudExtracter,
|
||||
gofileExtracter,
|
||||
superVideoExtractor,
|
||||
gdFlixExtracter,
|
||||
},
|
||||
Crypto: {},
|
||||
};
|
||||
} catch (error) {
|
||||
console.log(
|
||||
"⚠️ Could not load provider context. Run 'npm run build' first."
|
||||
);
|
||||
providerContext = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provider testing utility
|
||||
* Helper to pick random items from array
|
||||
*/
|
||||
function pickRandom(arr, count = 1) {
|
||||
const shuffled = [...arr].sort(() => Math.random() - 0.5);
|
||||
return count === 1 ? shuffled[0] : shuffled.slice(0, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sleep helper
|
||||
*/
|
||||
function sleep(ms) {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
/**
|
||||
* Provider testing utility - Full integration test
|
||||
*/
|
||||
class ProviderTester {
|
||||
constructor(serverUrl = "http://localhost:3001") {
|
||||
this.serverUrl = serverUrl;
|
||||
this.axios = axios.create({
|
||||
baseURL: serverUrl,
|
||||
timeout: 10000,
|
||||
});
|
||||
constructor(options = {}) {
|
||||
this.timeout = options.timeout || 30000;
|
||||
this.postsToTest = options.postsToTest || 2;
|
||||
this.linksToTest = options.linksToTest || 2;
|
||||
this.signal = new AbortController().signal;
|
||||
this.results = {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Test server connectivity
|
||||
* Load provider module
|
||||
*/
|
||||
async testConnection() {
|
||||
loadModule(providerName, moduleName) {
|
||||
try {
|
||||
const response = await this.axios.get("/health");
|
||||
console.log("✅ Server connection OK");
|
||||
return true;
|
||||
const modulePath = `./dist/${providerName}/${moduleName}.js`;
|
||||
// Clear cache to get fresh module
|
||||
delete require.cache[require.resolve(modulePath)];
|
||||
return require(modulePath);
|
||||
} catch (error) {
|
||||
console.error("❌ Server connection failed:", error.message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test manifest endpoint
|
||||
*/
|
||||
async testManifest() {
|
||||
try {
|
||||
const response = await this.axios.get("/manifest.json");
|
||||
const providers = response.data;
|
||||
|
||||
console.log(`✅ Manifest OK - Found ${providers.length} providers:`);
|
||||
providers.forEach((p) => {
|
||||
console.log(` 📦 ${p.display_name} (${p.value}) v${p.version}`);
|
||||
});
|
||||
|
||||
return providers;
|
||||
} catch (error) {
|
||||
console.error("❌ Manifest test failed:", error.message);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test individual provider modules
|
||||
* Load manifest to get enabled providers
|
||||
*/
|
||||
loadManifest() {
|
||||
try {
|
||||
const manifestPath = path.join(__dirname, "manifest.json");
|
||||
if (!fs.existsSync(manifestPath)) {
|
||||
console.log("⚠️ manifest.json not found");
|
||||
return [];
|
||||
}
|
||||
const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf-8"));
|
||||
return manifest;
|
||||
} catch (error) {
|
||||
console.log("⚠️ Failed to load manifest:", error.message);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get available providers from dist folder (excluding disabled ones)
|
||||
*/
|
||||
getAvailableProviders() {
|
||||
const distPath = path.join(__dirname, "dist");
|
||||
if (!fs.existsSync(distPath)) {
|
||||
console.log("❌ dist folder not found. Run 'npm run build' first.");
|
||||
return [];
|
||||
}
|
||||
|
||||
// Load manifest to check for disabled providers
|
||||
const manifest = this.loadManifest();
|
||||
const disabledProviders = manifest
|
||||
.filter((p) => p.disabled === true)
|
||||
.map((p) => p.value);
|
||||
|
||||
if (disabledProviders.length > 0) {
|
||||
console.log(
|
||||
`\n⏭️ Skipping disabled providers: ${disabledProviders.join(", ")}`
|
||||
);
|
||||
}
|
||||
|
||||
const providers = fs
|
||||
.readdirSync(distPath, { withFileTypes: true })
|
||||
.filter((dirent) => dirent.isDirectory())
|
||||
.map((dirent) => dirent.name)
|
||||
.filter((name) => {
|
||||
// Skip disabled providers
|
||||
if (disabledProviders.includes(name)) {
|
||||
return false;
|
||||
}
|
||||
// Check if it has required modules
|
||||
const hasRequired = [
|
||||
"catalog.js",
|
||||
"posts.js",
|
||||
"meta.js",
|
||||
"stream.js",
|
||||
].every((file) => fs.existsSync(path.join(distPath, name, file)));
|
||||
return hasRequired;
|
||||
});
|
||||
|
||||
return providers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test a single provider with full flow
|
||||
*/
|
||||
async testProvider(providerName) {
|
||||
console.log(`\n🧪 Testing provider: ${providerName}`);
|
||||
console.log(`\n${"=".repeat(60)}`);
|
||||
console.log(`🧪 Testing Provider: ${providerName}`);
|
||||
console.log("=".repeat(60));
|
||||
|
||||
const modules = ["catalog", "posts", "meta", "stream", "episodes"];
|
||||
const results = {};
|
||||
const result = {
|
||||
provider: providerName,
|
||||
catalog: { success: false, data: null, error: null },
|
||||
posts: { success: false, data: null, error: null },
|
||||
meta: { success: false, data: null, error: null },
|
||||
episodes: { success: false, data: null, error: null, skipped: false },
|
||||
stream: { success: false, data: null, error: null, skipped: false },
|
||||
summary: { passed: 0, failed: 0, skipped: 0 },
|
||||
};
|
||||
|
||||
for (const module of modules) {
|
||||
try {
|
||||
const response = await this.axios.get(
|
||||
`/dist/${providerName}/${module}.js`
|
||||
try {
|
||||
// Step 1: Load and test catalog
|
||||
console.log("\n📂 Step 1: Loading Catalog...");
|
||||
const catalogModule = this.loadModule(providerName, "catalog");
|
||||
if (!catalogModule) {
|
||||
throw new Error("Catalog module not found");
|
||||
}
|
||||
|
||||
const catalog = catalogModule.catalog || [];
|
||||
// const genres = catalogModule.genres || [];
|
||||
const allFilters = [...catalog];
|
||||
|
||||
if (allFilters.length === 0) {
|
||||
throw new Error("No filters found in catalog");
|
||||
}
|
||||
|
||||
result.catalog.success = true;
|
||||
result.catalog.data = {
|
||||
catalogCount: catalog.length,
|
||||
};
|
||||
console.log(` ✅ Found ${catalog.length} catalog items`);
|
||||
|
||||
// Pick a random filter
|
||||
const randomFilter = pickRandom(allFilters);
|
||||
console.log(
|
||||
` 🎲 Selected random filter: "${randomFilter.title}" (${randomFilter.filter})`
|
||||
);
|
||||
|
||||
// Step 2: Test getPosts with random filter
|
||||
console.log("\n📝 Step 2: Testing getPosts...");
|
||||
const postsModule = this.loadModule(providerName, "posts");
|
||||
if (!postsModule || !postsModule.getPosts) {
|
||||
throw new Error("getPosts function not found");
|
||||
}
|
||||
|
||||
const posts = await postsModule.getPosts({
|
||||
filter: randomFilter.filter,
|
||||
page: 1,
|
||||
providerValue: providerName,
|
||||
signal: this.signal,
|
||||
providerContext,
|
||||
});
|
||||
|
||||
if (!Array.isArray(posts) || posts.length === 0) {
|
||||
throw new Error("getPosts returned empty or invalid result");
|
||||
}
|
||||
|
||||
result.posts.success = true;
|
||||
result.posts.data = { count: posts.length };
|
||||
console.log(` ✅ Got ${posts.length} posts`);
|
||||
|
||||
// Pick random posts to test
|
||||
const postsToTest = pickRandom(
|
||||
posts,
|
||||
Math.min(this.postsToTest, posts.length)
|
||||
);
|
||||
console.log(
|
||||
` 🎲 Selected ${postsToTest.length} random posts for meta testing`
|
||||
);
|
||||
|
||||
// Step 3: Test getMeta with random posts
|
||||
console.log("\n📋 Step 3: Testing getMeta...");
|
||||
const metaModule = this.loadModule(providerName, "meta");
|
||||
if (!metaModule || !metaModule.getMeta) {
|
||||
throw new Error("getMeta function not found");
|
||||
}
|
||||
|
||||
const metaResults = [];
|
||||
for (const post of postsToTest) {
|
||||
console.log(`\n 📌 Testing: "${post.title.substring(0, 50)}..."`);
|
||||
console.log(` Link: ${post.link}`);
|
||||
|
||||
try {
|
||||
await sleep(500); // Small delay between requests
|
||||
const meta = await metaModule.getMeta({
|
||||
link: post.link,
|
||||
providerContext,
|
||||
});
|
||||
|
||||
if (!meta || !meta.linkList) {
|
||||
console.log(
|
||||
` ⚠️ Meta returned but linkList is empty/missing`
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
metaResults.push({ post, meta });
|
||||
console.log(
|
||||
` ✅ Got meta: type=${meta.type}, links=${meta.linkList.length}`
|
||||
);
|
||||
|
||||
// Show link structure
|
||||
meta.linkList.forEach((link, i) => {
|
||||
const hasEpisodes = !!link.episodesLink;
|
||||
const hasDirectLinks =
|
||||
link.directLinks && link.directLinks.length > 0;
|
||||
console.log(
|
||||
` [${i + 1}] ${link.title.substring(0, 30)} - ${
|
||||
hasEpisodes ? "📺 Episodes" : ""
|
||||
}${hasDirectLinks ? "🎬 Direct" : ""}`
|
||||
);
|
||||
});
|
||||
} catch (err) {
|
||||
console.log(` ❌ Error: ${err.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (metaResults.length === 0) {
|
||||
throw new Error("No valid meta data retrieved");
|
||||
}
|
||||
|
||||
result.meta.success = true;
|
||||
result.meta.data = { testedCount: metaResults.length };
|
||||
|
||||
// Step 4: Test episodes OR stream based on meta content
|
||||
console.log("\n🔗 Step 4: Testing Episodes/Stream...");
|
||||
|
||||
// Find links with episodes
|
||||
const episodeLinks = [];
|
||||
const directLinks = [];
|
||||
|
||||
for (const { meta } of metaResults) {
|
||||
for (const link of meta.linkList) {
|
||||
if (link.episodesLink) {
|
||||
episodeLinks.push({ meta, link });
|
||||
}
|
||||
if (link.directLinks && link.directLinks.length > 0) {
|
||||
directLinks.push({ meta, link });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test episodes if available
|
||||
if (episodeLinks.length > 0) {
|
||||
console.log(`\n 📺 Found ${episodeLinks.length} episode links`);
|
||||
const episodesModule = this.loadModule(providerName, "episodes");
|
||||
|
||||
if (episodesModule && episodesModule.getEpisodes) {
|
||||
const testEpisodeLink = pickRandom(episodeLinks);
|
||||
console.log(
|
||||
` 🎲 Testing episodes from: ${testEpisodeLink.link.title}`
|
||||
);
|
||||
console.log(` URL: ${testEpisodeLink.link.episodesLink}`);
|
||||
|
||||
try {
|
||||
const episodes = await episodesModule.getEpisodes({
|
||||
url: testEpisodeLink.link.episodesLink,
|
||||
providerContext,
|
||||
});
|
||||
|
||||
if (Array.isArray(episodes) && episodes.length > 0) {
|
||||
result.episodes.success = true;
|
||||
result.episodes.data = { count: episodes.length };
|
||||
console.log(` ✅ Got ${episodes.length} episodes`);
|
||||
|
||||
// Show first few episodes
|
||||
episodes.slice(0, 3).forEach((ep, i) => {
|
||||
console.log(` [${i + 1}] ${ep.title}`);
|
||||
});
|
||||
|
||||
// Test stream with random episode
|
||||
console.log(`\n 🎬 Testing stream with random episode...`);
|
||||
const randomEpisode = pickRandom(episodes);
|
||||
console.log(` Episode: ${randomEpisode.title}`);
|
||||
|
||||
try {
|
||||
const streamModule = this.loadModule(providerName, "stream");
|
||||
if (streamModule && streamModule.getStream) {
|
||||
const streams = await streamModule.getStream({
|
||||
link: randomEpisode.link,
|
||||
type: "series",
|
||||
signal: this.signal,
|
||||
providerContext,
|
||||
});
|
||||
|
||||
if (Array.isArray(streams) && streams.length > 0) {
|
||||
result.stream.success = true;
|
||||
result.stream.data = {
|
||||
count: streams.length,
|
||||
type: "series",
|
||||
};
|
||||
console.log(` ✅ Got ${streams.length} stream(s)`);
|
||||
streams.forEach((s, i) => {
|
||||
console.log(
|
||||
` [${i + 1}] ${s.server} - ${
|
||||
s.quality || "unknown"
|
||||
} quality`
|
||||
);
|
||||
});
|
||||
} else {
|
||||
console.log(` ⚠️ No streams returned`);
|
||||
result.stream.error = "No streams returned";
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.log(` ❌ Stream error: ${err.message}`);
|
||||
result.stream.error = err.message;
|
||||
}
|
||||
} else {
|
||||
console.log(` ⚠️ No episodes returned`);
|
||||
result.episodes.error = "No episodes returned";
|
||||
}
|
||||
} catch (err) {
|
||||
console.log(` ❌ Episodes error: ${err.message}`);
|
||||
result.episodes.error = err.message;
|
||||
}
|
||||
} else {
|
||||
console.log(` ⚠️ getEpisodes function not found`);
|
||||
result.episodes.skipped = true;
|
||||
result.episodes.error = "Function not available";
|
||||
}
|
||||
} else {
|
||||
result.episodes.skipped = true;
|
||||
console.log(` ℹ️ No episode links found, skipping episodes test`);
|
||||
}
|
||||
|
||||
// Test direct links/stream if episodes not tested or no episode links
|
||||
if (directLinks.length > 0 && !result.stream.success) {
|
||||
console.log(`\n 🎬 Found ${directLinks.length} direct link entries`);
|
||||
|
||||
const testDirectLink = pickRandom(directLinks);
|
||||
const linksToTest = pickRandom(
|
||||
testDirectLink.link.directLinks,
|
||||
Math.min(this.linksToTest, testDirectLink.link.directLinks.length)
|
||||
);
|
||||
results[module] = {
|
||||
success: true,
|
||||
size: response.data.length,
|
||||
hasExports: response.data.includes("exports."),
|
||||
};
|
||||
console.log(` ✅ ${module}.js (${results[module].size} bytes)`);
|
||||
} catch (error) {
|
||||
results[module] = {
|
||||
success: false,
|
||||
error: error.response?.status === 404 ? "Not found" : error.message,
|
||||
};
|
||||
const isOptional = module === "episodes";
|
||||
const icon = isOptional ? "⚠️ " : "❌";
|
||||
|
||||
console.log(
|
||||
` ${icon} ${module}.js - ${results[module].error}${
|
||||
isOptional ? " (optional)" : ""
|
||||
}`
|
||||
` 🎲 Testing ${linksToTest.length} random direct link(s)`
|
||||
);
|
||||
|
||||
const streamModule = this.loadModule(providerName, "stream");
|
||||
if (streamModule && streamModule.getStream) {
|
||||
for (const directLink of Array.isArray(linksToTest)
|
||||
? linksToTest
|
||||
: [linksToTest]) {
|
||||
console.log(`\n Testing: ${directLink.title}`);
|
||||
console.log(` Link: ${directLink.link}`);
|
||||
|
||||
try {
|
||||
await sleep(500);
|
||||
const streams = await streamModule.getStream({
|
||||
link: directLink.link,
|
||||
type: directLink.type || "movie",
|
||||
signal: this.signal,
|
||||
providerContext,
|
||||
});
|
||||
|
||||
if (Array.isArray(streams) && streams.length > 0) {
|
||||
result.stream.success = true;
|
||||
result.stream.data = {
|
||||
count: streams.length,
|
||||
type: directLink.type || "movie",
|
||||
};
|
||||
console.log(` ✅ Got ${streams.length} stream(s)`);
|
||||
streams.forEach((s, i) => {
|
||||
console.log(
|
||||
` [${i + 1}] ${s.server} - ${
|
||||
s.quality || "unknown"
|
||||
} quality`
|
||||
);
|
||||
});
|
||||
break; // One success is enough
|
||||
} else {
|
||||
console.log(` ⚠️ No streams returned`);
|
||||
}
|
||||
} catch (err) {
|
||||
console.log(` ❌ Stream error: ${err.message}`);
|
||||
result.stream.error = err.message;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.log(` ❌ getStream function not found`);
|
||||
result.stream.error = "Function not available";
|
||||
}
|
||||
} else if (
|
||||
!result.stream.success &&
|
||||
directLinks.length === 0 &&
|
||||
episodeLinks.length === 0
|
||||
) {
|
||||
result.stream.skipped = true;
|
||||
console.log(` ℹ️ No links to test stream with`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(`\n❌ Test failed: ${error.message}`);
|
||||
|
||||
// Determine which step failed
|
||||
if (!result.catalog.success) {
|
||||
result.catalog.error = error.message;
|
||||
} else if (!result.posts.success) {
|
||||
result.posts.error = error.message;
|
||||
} else if (!result.meta.success) {
|
||||
result.meta.error = error.message;
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
// Calculate summary
|
||||
const steps = ["catalog", "posts", "meta", "episodes", "stream"];
|
||||
for (const step of steps) {
|
||||
if (result[step].success) {
|
||||
result.summary.passed++;
|
||||
} else if (result[step].skipped) {
|
||||
result.summary.skipped++;
|
||||
} else if (result[step].error) {
|
||||
result.summary.failed++;
|
||||
}
|
||||
}
|
||||
|
||||
// Print summary
|
||||
console.log(`\n${"─".repeat(60)}`);
|
||||
console.log(`📊 Provider Summary: ${providerName}`);
|
||||
console.log("─".repeat(60));
|
||||
console.log(` ✅ Passed: ${result.summary.passed}`);
|
||||
console.log(` ❌ Failed: ${result.summary.failed}`);
|
||||
console.log(` ⏭️ Skipped: ${result.summary.skipped}`);
|
||||
|
||||
// List which steps passed/failed/skipped
|
||||
console.log("\n Step Results:");
|
||||
for (const step of steps) {
|
||||
if (result[step].success) {
|
||||
console.log(` ✅ ${step}`);
|
||||
} else if (result[step].skipped) {
|
||||
console.log(` ⏭️ ${step} (skipped)`);
|
||||
} else if (result[step].error) {
|
||||
console.log(` ❌ ${step}: ${result[step].error}`);
|
||||
} else {
|
||||
console.log(` ⚪ ${step} (not tested)`);
|
||||
}
|
||||
}
|
||||
|
||||
const statusIcon = result.summary.failed === 0 ? "✅" : "❌";
|
||||
console.log(
|
||||
`\n ${statusIcon} Overall: ${
|
||||
result.summary.failed === 0 ? "PASSED" : "FAILED"
|
||||
}`
|
||||
);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test all providers
|
||||
*/
|
||||
async testAllProviders() {
|
||||
console.log("🚀 Starting comprehensive provider test...\n");
|
||||
console.log("🚀 Starting comprehensive provider tests...\n");
|
||||
|
||||
// Test connection
|
||||
const connected = await this.testConnection();
|
||||
if (!connected) return;
|
||||
|
||||
// Test manifest
|
||||
const providers = await this.testManifest();
|
||||
if (!providers) return;
|
||||
|
||||
// Test each provider
|
||||
const results = {};
|
||||
for (const provider of providers) {
|
||||
results[provider.value] = await this.testProvider(provider.value);
|
||||
}
|
||||
|
||||
// Summary
|
||||
console.log("\n📊 Test Summary:");
|
||||
console.log("=".repeat(50));
|
||||
|
||||
let totalProviders = 0;
|
||||
let passedProviders = 0;
|
||||
|
||||
for (const [providerName, modules] of Object.entries(results)) {
|
||||
totalProviders++;
|
||||
const requiredModules = ["catalog", "posts", "meta", "stream"];
|
||||
const passedRequired = requiredModules.every(
|
||||
(mod) => modules[mod]?.success
|
||||
);
|
||||
|
||||
if (passedRequired) {
|
||||
passedProviders++;
|
||||
console.log(`✅ ${providerName} - All required modules OK`);
|
||||
} else {
|
||||
console.log(`❌ ${providerName} - Missing required modules`);
|
||||
}
|
||||
}
|
||||
|
||||
console.log(
|
||||
`\n📈 Results: ${passedProviders}/${totalProviders} providers passed`
|
||||
);
|
||||
|
||||
if (passedProviders === totalProviders) {
|
||||
console.log("🎉 All providers are ready for testing!");
|
||||
} else {
|
||||
console.log("⚠️ Some providers need attention before testing.");
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger rebuild on server
|
||||
*/
|
||||
async rebuild() {
|
||||
try {
|
||||
console.log("🔨 Triggering rebuild...");
|
||||
const response = await this.axios.post("/build");
|
||||
console.log("✅ Rebuild completed");
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error(
|
||||
"❌ Rebuild failed:",
|
||||
error.response?.data?.error || error.message
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get server status
|
||||
*/
|
||||
async getStatus() {
|
||||
try {
|
||||
const response = await this.axios.get("/status");
|
||||
const status = response.data;
|
||||
|
||||
console.log("📊 Server Status:");
|
||||
console.log(` 🟢 Status: ${status.status}`);
|
||||
console.log(` 🔌 Port: ${status.port}`);
|
||||
console.log(` 📦 Providers: ${status.providers}`);
|
||||
console.log(` 🕐 Last Build: ${status.buildTime || "Never"}`);
|
||||
|
||||
if (status.providerList.length > 0) {
|
||||
console.log(" 📋 Available Providers:");
|
||||
status.providerList.forEach((p) => console.log(` • ${p}`));
|
||||
}
|
||||
|
||||
return status;
|
||||
} catch (error) {
|
||||
console.error("❌ Failed to get status:", error.message);
|
||||
if (!providerContext) {
|
||||
console.log("❌ Provider context not loaded. Run 'npm run build' first.");
|
||||
return null;
|
||||
}
|
||||
|
||||
const providers = this.getAvailableProviders();
|
||||
if (providers.length === 0) {
|
||||
console.log("❌ No providers found.");
|
||||
return null;
|
||||
}
|
||||
|
||||
console.log(`📦 Found ${providers.length} providers to test:`);
|
||||
providers.forEach((p) => console.log(` • ${p}`));
|
||||
|
||||
const results = {};
|
||||
let passed = 0;
|
||||
let failed = 0;
|
||||
|
||||
for (const provider of providers) {
|
||||
try {
|
||||
results[provider] = await this.testProvider(provider);
|
||||
if (results[provider].summary.failed === 0) {
|
||||
passed++;
|
||||
} else {
|
||||
failed++;
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(
|
||||
`\n❌ Critical error testing ${provider}: ${error.message}`
|
||||
);
|
||||
failed++;
|
||||
results[provider] = { error: error.message };
|
||||
}
|
||||
|
||||
// Small delay between providers
|
||||
await sleep(1000);
|
||||
}
|
||||
|
||||
// Final summary
|
||||
console.log(`\n${"═".repeat(60)}`);
|
||||
console.log("📊 FINAL TEST SUMMARY");
|
||||
console.log("═".repeat(60));
|
||||
console.log(` Total Providers: ${providers.length}`);
|
||||
console.log(` ✅ Passed: ${passed}`);
|
||||
console.log(` ❌ Failed: ${failed}`);
|
||||
|
||||
// List failed providers with details
|
||||
if (failed > 0) {
|
||||
console.log(`\n${"─".repeat(60)}`);
|
||||
console.log("❌ FAILED PROVIDERS:");
|
||||
console.log("─".repeat(60));
|
||||
|
||||
for (const [name, result] of Object.entries(results)) {
|
||||
if (result.error) {
|
||||
// Critical error
|
||||
console.log(`\n ❌ ${name}`);
|
||||
console.log(` Error: ${result.error}`);
|
||||
} else if (result.summary?.failed > 0) {
|
||||
// Step failures
|
||||
console.log(`\n ❌ ${name}`);
|
||||
const steps = ["catalog", "posts", "meta", "episodes", "stream"];
|
||||
for (const step of steps) {
|
||||
if (result[step]?.error && !result[step]?.skipped) {
|
||||
console.log(` • ${step}: ${result[step].error}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// List passed providers
|
||||
if (passed > 0) {
|
||||
console.log(`\n${"─".repeat(60)}`);
|
||||
console.log("✅ PASSED PROVIDERS:");
|
||||
console.log("─".repeat(60));
|
||||
const passedProviders = Object.entries(results)
|
||||
.filter(([_, result]) => result.summary?.failed === 0 && !result.error)
|
||||
.map(([name]) => name);
|
||||
console.log(` ${passedProviders.join(", ")}`);
|
||||
}
|
||||
|
||||
console.log(`\n${"═".repeat(60)}`);
|
||||
|
||||
return results;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,53 +593,52 @@ class ProviderTester {
|
||||
*/
|
||||
async function main() {
|
||||
const args = process.argv.slice(2);
|
||||
const command = args[0] || "test";
|
||||
const providerName = args[1];
|
||||
const providerName = args[0];
|
||||
|
||||
const tester = new ProviderTester();
|
||||
// Check for options
|
||||
const postsToTest =
|
||||
parseInt(args.find((a) => a.startsWith("--posts="))?.split("=")[1]) || 2;
|
||||
const linksToTest =
|
||||
parseInt(args.find((a) => a.startsWith("--links="))?.split("=")[1]) || 2;
|
||||
|
||||
switch (command) {
|
||||
case "test":
|
||||
if (providerName) {
|
||||
await tester.testProvider(providerName);
|
||||
} else {
|
||||
await tester.testAllProviders();
|
||||
}
|
||||
break;
|
||||
const tester = new ProviderTester({ postsToTest, linksToTest });
|
||||
|
||||
case "status":
|
||||
await tester.getStatus();
|
||||
break;
|
||||
if (args.includes("--help") || args.includes("-h")) {
|
||||
console.log(`
|
||||
🎯 Vega Providers Integration Tester
|
||||
=====================================
|
||||
|
||||
case "rebuild":
|
||||
await tester.rebuild();
|
||||
break;
|
||||
Usage: node test-providers.js [provider] [options]
|
||||
|
||||
case "connection":
|
||||
await tester.testConnection();
|
||||
break;
|
||||
Arguments:
|
||||
provider Name of specific provider to test (optional)
|
||||
If not provided, tests all providers
|
||||
|
||||
case "manifest":
|
||||
await tester.testManifest();
|
||||
break;
|
||||
Options:
|
||||
--posts=N Number of random posts to test (default: 2)
|
||||
--links=N Number of random direct links to test (default: 2)
|
||||
--help, -h Show this help message
|
||||
|
||||
default:
|
||||
console.log(`
|
||||
Usage: node test-providers.js [command] [provider]
|
||||
|
||||
Commands:
|
||||
test [provider] - Test all providers or specific provider
|
||||
status - Show server status
|
||||
rebuild - Trigger rebuild
|
||||
connection - Test server connection
|
||||
manifest - Test manifest endpoint
|
||||
Test Flow:
|
||||
1. Load catalog → pick random filter
|
||||
2. Call getPosts with filter
|
||||
3. Pick random posts → call getMeta
|
||||
4. If episodesLink → call getEpisodes → getStream
|
||||
5. If directLinks → call getStream
|
||||
|
||||
Examples:
|
||||
node test-providers.js # Test all providers
|
||||
node test-providers.js test vega # Test specific provider
|
||||
node test-providers.js status # Show status
|
||||
node test-providers.js rebuild # Rebuild and test
|
||||
`);
|
||||
node test-providers.js # Test all providers
|
||||
node test-providers.js vega # Test only vega provider
|
||||
node test-providers.js mod --posts=3 # Test mod with 3 random posts
|
||||
node test-providers.js --posts=1 --links=1 # Quick test all providers
|
||||
`);
|
||||
return;
|
||||
}
|
||||
|
||||
if (providerName && !providerName.startsWith("--")) {
|
||||
await tester.testProvider(providerName);
|
||||
} else {
|
||||
await tester.testAllProviders();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user