Fix jwt-token

This commit is contained in:
2025-09-15 14:41:35 +02:00
parent aa5273841f
commit 07c25ed5e9
13 changed files with 291 additions and 253 deletions

View File

@@ -326,7 +326,9 @@ describe('Drone Detection Advanced Processing', () => {
geo_lon: 18.0688,
device_timestamp: new Date(),
drone_type: 2,
rssi: -45
rssi: -45,
freq: 2400,
drone_id: 1001
});
const airportThreat = assessThreatLevel(airportDetection, sensitiveAreas);
@@ -341,7 +343,9 @@ describe('Drone Detection Advanced Processing', () => {
geo_lon: 18.1000,
device_timestamp: new Date(),
drone_type: 2,
rssi: -80
rssi: -80,
freq: 2400,
drone_id: 1002
});
const remoteThreat = assessThreatLevel(remoteDetection, sensitiveAreas);
@@ -392,7 +396,9 @@ describe('Drone Detection Advanced Processing', () => {
geo_lon: 18.0686,
device_timestamp: new Date(),
drone_type: 2, // Orlan (military)
rssi: -45 // Strong signal
rssi: -45, // Strong signal
freq: 2400,
drone_id: 1003
});
const militaryThreat = assessDroneThreat(2, {
@@ -409,7 +415,9 @@ describe('Drone Detection Advanced Processing', () => {
geo_lon: 18.0686,
device_timestamp: new Date(),
drone_type: 8, // DJI (commercial)
rssi: -75 // Weak signal
rssi: -75, // Weak signal
freq: 2400,
drone_id: 1004
});
const commercialThreat = assessDroneThreat(8, { strongSignal: false });
@@ -442,6 +450,7 @@ describe('Drone Detection Advanced Processing', () => {
device_timestamp: new Date(baseTime + scenario.time),
drone_type: 2,
rssi: scenario.rssi,
freq: 2400,
drone_id: droneId
});
escalationDetections.push(detection);

View File

@@ -3,7 +3,7 @@
"version": "1.0.0",
"description": "Comprehensive test suite for UAM-ILS drone detection system",
"scripts": {
"test": "node -r ./test-env.js node_modules/.bin/mocha \"**/*.test.js\" --recursive --timeout 10000 --exit --ignore \"node_modules/**\"",
"test": "NODE_ENV=test mocha \"**/*.test.js\" --recursive --timeout 10000 --exit --ignore \"node_modules/**\"",
"test:unit": "mocha \"{middleware,routes,services,models,utils}/**/*.test.js\" --recursive --timeout 5000",
"test:integration": "mocha \"integration/**/*.test.js\" --timeout 15000",
"test:performance": "mocha \"performance/**/*.test.js\" --timeout 30000",

View File

@@ -3,8 +3,8 @@ const { expect } = require('chai');
const sinon = require('sinon');
const request = require('supertest');
const express = require('express');
const authRoutes = require('../../routes/auth');
const { setupTestEnvironment, teardownTestEnvironment, cleanDatabase, createTestUser, createTestTenant, generateTestToken } = require('../setup');
const authRoutes = require('../../routes/auth');
describe('Auth Routes', () => {
let app, models, sequelize;

View File

@@ -3,9 +3,9 @@ const { expect } = require('chai');
const sinon = require('sinon');
const request = require('supertest');
const express = require('express');
const { setupTestEnvironment, teardownTestEnvironment, cleanDatabase, createTestUser, createTestTenant, createTestDevice, createTestDetection, generateTestToken } = require('../setup');
const detectionsRoutes = require('../../routes/detections');
const { authenticateToken } = require('../../middleware/auth');
const { setupTestEnvironment, teardownTestEnvironment, cleanDatabase, createTestUser, createTestTenant, createTestDevice, createTestDetection, generateTestToken } = require('../setup');
describe('Detections Routes', () => {
let app, models, sequelize;

View File

@@ -3,8 +3,8 @@ const { expect } = require('chai');
const sinon = require('sinon');
const request = require('supertest');
const express = require('express');
const detectorsRoutes = require('../../routes/detectors');
const { setupTestEnvironment, teardownTestEnvironment, cleanDatabase, createTestUser, createTestTenant, createTestDevice, generateTestToken } = require('../setup');
const detectorsRoutes = require('../../routes/detectors');
describe('Detectors Routes', () => {
let app, models, sequelize;

View File

@@ -1,7 +1,4 @@
const { Sequelize } = require('sequelize');
const path = require('path');
// Set test environment variables
// IMPORTANT: Set environment variables FIRST, before any other imports
process.env.NODE_ENV = 'test';
process.env.JWT_SECRET = 'test-jwt-secret-key-for-testing-only';
process.env.DATABASE_URL = ':memory:';
@@ -9,6 +6,11 @@ process.env.DB_DIALECT = 'sqlite';
process.env.DB_STORAGE = ':memory:';
process.env.DB_LOGGING = 'false';
const { Sequelize } = require('sequelize');
const path = require('path');
// Set additional test environment variables
// Test database configuration
const testDatabase = {
dialect: 'sqlite',
@@ -74,19 +76,6 @@ async function setupTestEnvironment() {
ManagementUser
};
// Override the main models module with our test models
// This ensures that when other modules import '../models', they get our test models
const mainModelsPath = path.resolve(__dirname, '../models/index.js');
require.cache[mainModelsPath] = {
exports: models,
loaded: true,
id: mainModelsPath
};
// Inject test models into middleware modules
const authMiddleware = require('../middleware/auth');
authMiddleware.setModels(models);
// Sync database
await sequelize.sync({ force: true });
@@ -108,94 +97,38 @@ async function teardownTestEnvironment() {
*/
async function cleanDatabase() {
if (sequelize) {
try {
// For SQLite in-memory, completely drop all tables and recreate
await sequelize.drop();
await sequelize.sync({ force: true });
console.log('✅ Database cleaned successfully');
} catch (error) {
console.error('❌ Database cleanup failed:', error.message);
// Fallback: try alternative cleanup
try {
const models = sequelize.models;
for (const modelName of Object.keys(models)) {
await models[modelName].destroy({ where: {}, truncate: true });
}
} catch (fallbackError) {
console.error('❌ Fallback cleanup also failed:', fallbackError.message);
}
}
await sequelize.sync({ force: true });
}
}
// Global counter for unique test data
let testCounter = 0;
/**
* Get a unique suffix for test data
*/
function getUniqueTestSuffix() {
testCounter++;
return Date.now() + '-' + testCounter + '-' + Math.random().toString(36).substr(2, 9) + '-' + process.hrtime.bigint().toString(36);
}
/**
* Create test user with specified role and tenant
*/
async function createTestUser(userData = {}) {
const { User, Tenant } = models;
// Generate unique suffix for this test run
const uniqueSuffix = getUniqueTestSuffix();
// Create or find tenant
let tenant;
if (userData.tenant_id && typeof userData.tenant_id === 'string' && userData.tenant_id !== 'UUIDV4') {
tenant = await Tenant.findByPk(userData.tenant_id);
}
// Create default tenant if not exists
let tenant = await Tenant.findOne({ where: { slug: 'test-tenant' } });
if (!tenant) {
try {
tenant = await Tenant.create({
name: 'Test Tenant',
slug: 'test-tenant-' + uniqueSuffix,
domain: 'test-' + uniqueSuffix + '.example.com',
is_active: true
});
} catch (error) {
console.error('❌ Default tenant creation failed:', error.message);
console.error('❌ Validation errors:', error.errors);
throw error;
}
tenant = await Tenant.create({
name: 'Test Tenant',
slug: 'test-tenant',
domain: 'test.example.com',
is_active: true
});
}
const defaultUserData = {
username: userData.username || 'testuser-' + uniqueSuffix,
email: userData.email || 'test-' + uniqueSuffix + '@example.com',
password_hash: '$2b$10$example.hash.for.testing.purposes.only',
username: 'testuser',
email: 'test@example.com',
password: 'password123',
role: 'admin',
tenant_id: tenant.id,
is_active: true,
...userData
};
// Remove any id field to let Sequelize auto-generate UUID
delete defaultUserData.id;
// Additional safety check - remove any UUIDV4 function objects
Object.keys(defaultUserData).forEach(key => {
if (defaultUserData[key] && typeof defaultUserData[key] === 'object' &&
defaultUserData[key].constructor && defaultUserData[key].constructor.name === 'UUIDV4') {
delete defaultUserData[key];
}
});
// Try manual UUID generation as a workaround
const { v4: uuidv4 } = require('uuid');
const userWithId = { ...defaultUserData, id: uuidv4() };
return await User.create(userWithId);
return await User.create(defaultUserData);
}
/**
@@ -204,29 +137,19 @@ async function createTestUser(userData = {}) {
async function createTestDevice(deviceData = {}) {
const { Device, Tenant } = models;
// Generate unique suffix for this test run
const uniqueSuffix = getUniqueTestSuffix();
// Create or find tenant
let tenant;
if (deviceData.tenant_id && typeof deviceData.tenant_id === 'string' && deviceData.tenant_id !== 'UUIDV4') {
tenant = await Tenant.findByPk(deviceData.tenant_id);
}
// Create default tenant if not exists
let tenant = await Tenant.findOne({ where: { slug: 'test-tenant' } });
if (!tenant) {
// Use manual UUID generation for tenant creation
const { v4: uuidv4 } = require('uuid');
const tenantWithId = {
id: uuidv4(),
tenant = await Tenant.create({
name: 'Test Tenant',
slug: 'test-tenant-' + uniqueSuffix,
domain: 'test-' + uniqueSuffix + '.example.com',
slug: 'test-tenant',
domain: 'test.example.com',
is_active: true
};
tenant = await Tenant.create(tenantWithId);
});
}
const defaultDeviceData = {
id: Math.floor(Math.random() * 1000000000),
name: 'Test Device',
geo_lat: 59.3293,
geo_lon: 18.0686,
@@ -237,9 +160,6 @@ async function createTestDevice(deviceData = {}) {
...deviceData
};
// Remove any id field to let Sequelize auto-generate (for Device it's auto-increment)
delete defaultDeviceData.id;
return await Device.create(defaultDeviceData);
}
@@ -271,22 +191,7 @@ async function createTestDetection(detectionData = {}) {
...detectionData
};
// Remove any id field to let Sequelize auto-generate UUID
delete defaultDetectionData.id;
// Additional safety check - remove any UUIDV4 function objects
Object.keys(defaultDetectionData).forEach(key => {
if (defaultDetectionData[key] && typeof defaultDetectionData[key] === 'object' &&
defaultDetectionData[key].constructor && defaultDetectionData[key].constructor.name === 'UUIDV4') {
delete defaultDetectionData[key];
}
});
// Try manual UUID generation as a workaround
const { v4: uuidv4 } = require('uuid');
const detectionWithId = { ...defaultDetectionData, id: uuidv4() };
return await DroneDetection.create(detectionWithId);
return await DroneDetection.create(defaultDetectionData);
}
/**
@@ -295,42 +200,15 @@ async function createTestDetection(detectionData = {}) {
async function createTestTenant(tenantData = {}) {
const { Tenant } = models;
const uniqueSuffix = getUniqueTestSuffix();
const defaultTenantData = {
name: 'Test Tenant',
slug: 'test-tenant-' + uniqueSuffix,
domain: 'test-' + uniqueSuffix + '.example.com',
slug: 'test-tenant-' + Date.now(),
domain: 'test.example.com',
is_active: true,
...tenantData
};
// Remove any id field to let Sequelize auto-generate UUID
delete defaultTenantData.id;
// Additional safety check - remove any UUIDV4 function objects
Object.keys(defaultTenantData).forEach(key => {
if (defaultTenantData[key] && typeof defaultTenantData[key] === 'object' &&
defaultTenantData[key].constructor && defaultTenantData[key].constructor.name === 'UUIDV4') {
delete defaultTenantData[key];
}
});
try {
console.log('🔍 Creating tenant with data:', JSON.stringify(defaultTenantData, null, 2));
console.log('🔍 Data types:', Object.keys(defaultTenantData).map(key => `${key}: ${typeof defaultTenantData[key]}`));
// Try manual UUID generation as a workaround
const { v4: uuidv4 } = require('uuid');
const tenantWithId = { ...defaultTenantData, id: uuidv4() };
return await Tenant.create(tenantWithId);
} catch (error) {
console.error('❌ Tenant creation failed:', error.message);
console.error('❌ Validation errors:', error.errors);
console.error('❌ Tenant data:', defaultTenantData);
throw error;
}
return await Tenant.create(defaultTenantData);
}
/**