165 lines
3.5 KiB
TypeScript
165 lines
3.5 KiB
TypeScript
import fs from 'fs';
|
|
import path from 'path';
|
|
|
|
/**
|
|
* Test utilities for scheduler testing
|
|
*/
|
|
|
|
export const testFixtures = {
|
|
/**
|
|
* Create a mock auth.json file with valid Instagram session
|
|
*/
|
|
createMockAuthFile: (filePath: string) => {
|
|
const dir = path.dirname(filePath);
|
|
if (!fs.existsSync(dir)) {
|
|
fs.mkdirSync(dir, { recursive: true });
|
|
}
|
|
|
|
const mockAuth = {
|
|
cookies: [
|
|
{
|
|
name: 'sessionid',
|
|
value: 'mock-session-' + Date.now(),
|
|
domain: '.instagram.com',
|
|
path: '/',
|
|
expires: Math.floor(Date.now() / 1000) + 3600 * 24 * 30,
|
|
httpOnly: true,
|
|
secure: true,
|
|
sameSite: 'Strict'
|
|
},
|
|
{
|
|
name: 'ig_did',
|
|
value: 'mock-did-' + Date.now(),
|
|
domain: '.instagram.com',
|
|
path: '/',
|
|
expires: Math.floor(Date.now() / 1000) + 3600 * 24 * 365,
|
|
httpOnly: false,
|
|
secure: true,
|
|
sameSite: 'Strict'
|
|
}
|
|
],
|
|
origins: [
|
|
{
|
|
origin: 'https://www.instagram.com',
|
|
localStorage: [
|
|
{
|
|
name: 'ig_nrcb',
|
|
value: '1'
|
|
}
|
|
]
|
|
}
|
|
]
|
|
};
|
|
|
|
fs.writeFileSync(filePath, JSON.stringify(mockAuth, null, 2));
|
|
return mockAuth;
|
|
},
|
|
|
|
/**
|
|
* Clean up mock auth files
|
|
*/
|
|
cleanupMockAuthFile: (filePath: string) => {
|
|
if (fs.existsSync(filePath)) {
|
|
fs.unlinkSync(filePath);
|
|
}
|
|
|
|
const dir = path.dirname(filePath);
|
|
if (fs.existsSync(dir) && fs.readdirSync(dir).length === 0) {
|
|
fs.rmdirSync(dir);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Mock environment for scheduler testing
|
|
*/
|
|
setupEnv: (config: Record<string, string | undefined>) => {
|
|
const original: Record<string, string | undefined> = {};
|
|
|
|
for (const [key, value] of Object.entries(config)) {
|
|
original[key] = process.env[key];
|
|
if (value === undefined) {
|
|
delete process.env[key];
|
|
} else {
|
|
process.env[key] = value;
|
|
}
|
|
}
|
|
|
|
return () => {
|
|
// Restore original env
|
|
for (const [key, value] of Object.entries(original)) {
|
|
if (value === undefined) {
|
|
delete process.env[key];
|
|
} else {
|
|
process.env[key] = value;
|
|
}
|
|
}
|
|
};
|
|
},
|
|
|
|
/**
|
|
* Validate auth.json file structure
|
|
*/
|
|
validateAuthFile: (filePath: string): boolean => {
|
|
try {
|
|
const content = JSON.parse(fs.readFileSync(filePath, 'utf-8'));
|
|
|
|
// Check required fields
|
|
if (!Array.isArray(content.cookies)) return false;
|
|
if (!Array.isArray(content.origins)) return false;
|
|
|
|
// Check cookie structure
|
|
for (const cookie of content.cookies) {
|
|
if (!cookie.name || !cookie.value || !cookie.domain) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
} catch {
|
|
return false;
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Get mock browser context for testing
|
|
*/
|
|
createMockBrowserContext: () => {
|
|
return {
|
|
newPage: async () => ({
|
|
goto: async () => {},
|
|
waitForSelector: async () => {},
|
|
evaluate: async () => 'Home',
|
|
close: async () => {},
|
|
screenshot: async () => Buffer.from('mock-image')
|
|
}),
|
|
storageState: async (options: { path: string }) => {
|
|
const mockAuth = {
|
|
cookies: [{ name: 'sessionid', value: 'refreshed', domain: '.instagram.com' }],
|
|
origins: []
|
|
};
|
|
fs.writeFileSync(options.path, JSON.stringify(mockAuth, null, 2));
|
|
},
|
|
close: async () => {}
|
|
};
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Helper to create a spy for interval/timeout functions
|
|
*/
|
|
export const createTimerSpy = () => {
|
|
let timers: NodeJS.Timeout[] = [];
|
|
|
|
return {
|
|
setInterval: (callback: () => void, ms: number) => {
|
|
const timer = setInterval(callback, ms);
|
|
timers.push(timer);
|
|
return timer;
|
|
},
|
|
cleanup: () => {
|
|
timers.forEach((timer) => clearInterval(timer));
|
|
timers = [];
|
|
}
|
|
};
|
|
};
|