193 lines
6.4 KiB
JavaScript
193 lines
6.4 KiB
JavaScript
/* global describe, it, before, after, beforeEach */
|
|
|
|
const assert = require('assert').strict;
|
|
const http = require('http');
|
|
const { promisify } = require('util');
|
|
const { exec } = require('child_process');
|
|
const execAsync = promisify(exec);
|
|
const path = require('path');
|
|
const fs = require('fs');
|
|
|
|
// Use absolute paths to avoid any path resolution issues
|
|
const rootDir = path.resolve(__dirname, '../..');
|
|
const DocumentHandler = require(path.join(rootDir, 'lib/document_handler'));
|
|
const Generator = require(path.join(rootDir, 'lib/key_generators/random'));
|
|
|
|
const PORT = 7777;
|
|
const HOST = 'localhost';
|
|
const SERVER_START_WAIT = 2000;
|
|
|
|
describe('Hastebin Core Functionality', function() {
|
|
let testServer;
|
|
|
|
// Increase timeout for slower operations
|
|
this.timeout(10000);
|
|
|
|
before(async function() {
|
|
// Start server before tests
|
|
const testServerPath = path.join(rootDir, 'test/utils/test-local.js');
|
|
try {
|
|
testServer = require(testServerPath);
|
|
|
|
// Wait for server to start
|
|
await new Promise(resolve => setTimeout(resolve, SERVER_START_WAIT));
|
|
} catch (err) {
|
|
console.error('Error starting test server:', err);
|
|
throw err;
|
|
}
|
|
});
|
|
|
|
after(async function() {
|
|
this.timeout(5000);
|
|
console.log('Shutting down test server...');
|
|
|
|
if (testServer && testServer.server && typeof testServer.server.close === 'function') {
|
|
await new Promise((resolve) => {
|
|
testServer.server.close(() => {
|
|
console.log('Server closed successfully');
|
|
resolve();
|
|
});
|
|
});
|
|
} else if (testServer && testServer.cleanup) {
|
|
await testServer.cleanup(false);
|
|
}
|
|
|
|
// Force process termination if needed
|
|
setTimeout(() => {
|
|
console.log('Forcing process exit...');
|
|
process.exit(0);
|
|
}, 1000);
|
|
});
|
|
|
|
beforeEach(function() {
|
|
// Clean test data before each test
|
|
if (testServer && testServer.cleanTestData) {
|
|
testServer.cleanTestData();
|
|
}
|
|
});
|
|
|
|
describe('Document Handler', function() {
|
|
describe('Key Generation', function() {
|
|
it('should generate keys of the specified length', function() {
|
|
const gen = new Generator();
|
|
const dh = new DocumentHandler({ keyLength: 6, keyGenerator: gen });
|
|
assert.equal(6, dh.acceptableKey().length);
|
|
});
|
|
|
|
it('should use the default key length when not specified', function() {
|
|
const gen = new Generator();
|
|
const dh = new DocumentHandler({ keyGenerator: gen });
|
|
assert.equal(dh.keyLength, DocumentHandler.defaultKeyLength);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('Document Operations', function() {
|
|
describe('Document Creation', function() {
|
|
it('should create a new document', async function() {
|
|
const testContent = 'Test document content';
|
|
try {
|
|
const { stdout } = await execAsync(
|
|
`curl -s -X POST http://${HOST}:${PORT}/documents -d "${testContent}"`
|
|
);
|
|
const response = JSON.parse(stdout);
|
|
|
|
assert(response.key && typeof response.key === 'string', 'Should return a valid document key');
|
|
assert.equal(response.key.length, DocumentHandler.defaultKeyLength);
|
|
} catch (error) {
|
|
console.error('Error in create document test:', error);
|
|
throw error;
|
|
}
|
|
});
|
|
|
|
it('should handle empty documents', async function() {
|
|
// The server should reject empty documents
|
|
try {
|
|
const { stdout, stderr } = await execAsync(
|
|
`curl -s -i -X POST http://${HOST}:${PORT}/documents -d "" || echo "Error occurred"`
|
|
);
|
|
|
|
// If we get here, check if the response indicates an error
|
|
const hasError = stdout.includes('400') ||
|
|
stdout.includes('Bad Request') ||
|
|
stderr.includes('Error');
|
|
|
|
assert(hasError, 'Should return error status for empty document');
|
|
} catch (error) {
|
|
// If curl fails, that's also a valid test result
|
|
assert(true, 'Error occurred as expected');
|
|
}
|
|
});
|
|
});
|
|
|
|
describe('Document Retrieval', function() {
|
|
let documentKey;
|
|
|
|
beforeEach(async function() {
|
|
// Create a test document
|
|
try {
|
|
const { stdout } = await execAsync(
|
|
`curl -s -X POST http://${HOST}:${PORT}/documents -d "Test retrieval content"`
|
|
);
|
|
const response = JSON.parse(stdout);
|
|
documentKey = response.key;
|
|
} catch (error) {
|
|
console.error('Error creating test document:', error);
|
|
throw error;
|
|
}
|
|
});
|
|
|
|
it('should retrieve an existing document', async function() {
|
|
try {
|
|
const { stdout } = await execAsync(
|
|
`curl -s http://${HOST}:${PORT}/raw/${documentKey}`
|
|
);
|
|
assert.equal(stdout, 'Test retrieval content');
|
|
} catch (error) {
|
|
console.error('Error retrieving document:', error);
|
|
throw error;
|
|
}
|
|
});
|
|
|
|
it('should handle non-existent documents', async function() {
|
|
// The server should return 404 for non-existent documents
|
|
try {
|
|
const { stdout, stderr } = await execAsync(
|
|
`curl -s -i http://${HOST}:${PORT}/raw/nonexistentkey || echo "Error occurred"`
|
|
);
|
|
|
|
// If we get here, check if the response indicates a 404
|
|
const hasError = stdout.includes('404') ||
|
|
stdout.includes('Not Found') ||
|
|
stderr.includes('Error');
|
|
|
|
assert(hasError, 'Should return 404 status for non-existent document');
|
|
} catch (error) {
|
|
// If curl fails, that's also a valid test result
|
|
assert(true, 'Error occurred as expected');
|
|
}
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('Rate Limiting', function() {
|
|
it('should enforce rate limits', async function() {
|
|
try {
|
|
// Make multiple rapid requests
|
|
const requests = Array(10).fill().map(() =>
|
|
execAsync(`curl -s -I http://${HOST}:${PORT}/`)
|
|
);
|
|
|
|
const responses = await Promise.all(requests);
|
|
const hasRateLimit = responses.some(({ stdout }) =>
|
|
stdout.includes('X-RateLimit-Remaining')
|
|
);
|
|
|
|
assert(hasRateLimit, 'Should include rate limit headers');
|
|
} catch (error) {
|
|
console.error('Error in rate limit test:', error);
|
|
throw error;
|
|
}
|
|
});
|
|
});
|
|
});
|