upskill-event-manager/tests/data/TestDataManager.js
Ben 7c9ca65cf2
Some checks are pending
HVAC Plugin CI/CD Pipeline / Security Analysis (push) Waiting to run
HVAC Plugin CI/CD Pipeline / Code Quality & Standards (push) Waiting to run
HVAC Plugin CI/CD Pipeline / Unit Tests (push) Waiting to run
HVAC Plugin CI/CD Pipeline / Integration Tests (push) Waiting to run
HVAC Plugin CI/CD Pipeline / Deploy to Staging (push) Blocked by required conditions
HVAC Plugin CI/CD Pipeline / Deploy to Production (push) Blocked by required conditions
HVAC Plugin CI/CD Pipeline / Notification (push) Blocked by required conditions
Security Monitoring & Compliance / Dependency Vulnerability Scan (push) Waiting to run
Security Monitoring & Compliance / Secrets & Credential Scan (push) Waiting to run
Security Monitoring & Compliance / WordPress Security Analysis (push) Waiting to run
Security Monitoring & Compliance / Static Code Security Analysis (push) Waiting to run
Security Monitoring & Compliance / Security Compliance Validation (push) Waiting to run
Security Monitoring & Compliance / Security Summary Report (push) Blocked by required conditions
Security Monitoring & Compliance / Security Team Notification (push) Blocked by required conditions
feat: add comprehensive test framework and test files
- Add 90+ test files including E2E, unit, and integration tests
- Implement Page Object Model (POM) architecture
- Add Docker testing environment with comprehensive services
- Include modernized test framework with error recovery
- Add specialized test suites for master trainer and trainer workflows
- Update .gitignore to properly track test infrastructure

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-29 23:23:26 -03:00

540 lines
No EOL
20 KiB
JavaScript

/**
* Test Data Manager
* Centralized test data management for HVAC testing framework
*/
const fs = require('fs').promises;
const path = require('path');
class TestDataManager {
constructor(environment = 'staging') {
this.environment = environment;
this.dataCache = new Map();
this.fixturesPath = path.join(__dirname, 'fixtures');
this.accounts = null;
this.testData = null;
}
/**
* Initialize test data manager
* @returns {Promise<void>}
*/
async initialize() {
await this.loadTestAccounts();
await this.loadTestData();
await this.loadFixtures();
}
/**
* Load test accounts for different environments
* @returns {Promise<void>}
*/
async loadTestAccounts() {
this.accounts = {
staging: {
masterTrainer: {
username: 'test_master',
password: 'TestMaster123!',
email: 'test_master@example.com',
role: 'master_trainer',
displayName: 'Test Master Trainer',
capabilities: ['manage_events', 'manage_trainers', 'view_announcements']
},
alternateMasterTrainer: {
username: 'JoeMedosch@gmail.com',
password: 'JoeTrainer2025@',
email: 'JoeMedosch@gmail.com',
role: 'master_trainer',
displayName: 'Joe Medosch',
capabilities: ['manage_events', 'manage_trainers', 'view_announcements']
},
trainer: {
username: 'test_trainer',
password: 'TestTrainer123!',
email: 'test_trainer@example.com',
role: 'hvac_trainer',
displayName: 'Test Trainer',
capabilities: ['create_events', 'manage_profile', 'view_leads']
},
admin: {
username: process.env.STAGING_ADMIN_USER || 'admin',
password: process.env.STAGING_ADMIN_PASSWORD || 'admin_password',
email: 'admin@example.com',
role: 'administrator',
displayName: 'Site Administrator',
capabilities: ['manage_options', 'manage_users', 'manage_plugins']
}
},
production: {
masterTrainer: {
username: process.env.PROD_MASTER_USERNAME,
password: process.env.PROD_MASTER_PASSWORD,
email: process.env.PROD_MASTER_EMAIL,
role: 'master_trainer',
displayName: 'Production Master Trainer',
capabilities: ['manage_events', 'manage_trainers', 'view_announcements']
},
trainer: {
username: process.env.PROD_TRAINER_USERNAME,
password: process.env.PROD_TRAINER_PASSWORD,
email: process.env.PROD_TRAINER_EMAIL,
role: 'hvac_trainer',
displayName: 'Production Trainer',
capabilities: ['create_events', 'manage_profile', 'view_leads']
}
},
local: {
masterTrainer: {
username: 'master_local',
password: 'MasterLocal123!',
email: 'master@localhost.dev',
role: 'master_trainer',
displayName: 'Local Master Trainer',
capabilities: ['manage_events', 'manage_trainers', 'view_announcements']
},
trainer: {
username: 'trainer_local',
password: 'TrainerLocal123!',
email: 'trainer@localhost.dev',
role: 'hvac_trainer',
displayName: 'Local Trainer',
capabilities: ['create_events', 'manage_profile', 'view_leads']
},
admin: {
username: 'admin',
password: 'admin123',
email: 'admin@localhost.dev',
role: 'administrator',
displayName: 'Local Admin',
capabilities: ['manage_options', 'manage_users', 'manage_plugins']
}
}
};
}
/**
* Load test data for different scenarios
* @returns {Promise<void>}
*/
async loadTestData() {
this.testData = {
events: {
basicEvent: {
title: 'Test HVAC Training Event',
description: 'This is a test event for HVAC training purposes.',
startDate: this.getFutureDate(7), // 7 days from now
endDate: this.getFutureDate(8), // 8 days from now
startTime: '09:00:00',
endTime: '17:00:00',
location: 'Test Training Center',
address: '123 Test Street, Test City, TS 12345',
capacity: 20,
status: 'published',
eventType: 'training',
categories: ['hvac', 'training', 'test']
},
fullEvent: {
title: 'Comprehensive HVAC Certification Course',
description: 'Complete HVAC certification training with hands-on experience.',
startDate: this.getFutureDate(14),
endDate: this.getFutureDate(16),
startTime: '08:30:00',
endTime: '18:00:00',
location: 'Advanced Training Facility',
address: '456 Training Avenue, Education City, ED 54321',
capacity: 15,
price: 299.99,
instructorNotes: 'Bring work clothes and safety equipment',
prerequisites: 'Basic electrical knowledge required',
materials: 'All materials provided',
certification: 'EPA 608 Certification',
status: 'published',
eventType: 'certification',
categories: ['hvac', 'certification', 'advanced']
},
pastEvent: {
title: 'Past HVAC Workshop',
description: 'This event has already occurred.',
startDate: this.getPastDate(30),
endDate: this.getPastDate(30),
startTime: '10:00:00',
endTime: '16:00:00',
location: 'Past Event Venue',
address: '789 Past Street, History City, HI 98765',
capacity: 12,
status: 'completed',
eventType: 'workshop'
}
},
venues: {
basicVenue: {
name: 'Test Training Center',
address: '123 Test Street',
city: 'Test City',
state: 'TS',
zipCode: '12345',
phone: '555-TEST-001',
email: 'contact@testcenter.com',
capacity: 25,
facilities: ['parking', 'wifi', 'projector'],
notes: 'Accessible venue with modern facilities'
},
advancedVenue: {
name: 'Advanced Training Facility',
address: '456 Training Avenue',
city: 'Education City',
state: 'ED',
zipCode: '54321',
phone: '555-ADV-002',
email: 'info@advancedtraining.com',
website: 'https://advancedtraining.com',
capacity: 30,
facilities: ['parking', 'wifi', 'projector', 'lab_equipment', 'tools'],
notes: 'Full HVAC lab with latest equipment'
}
},
organizers: {
testOrganizer: {
name: 'Test Training Organization',
contactName: 'Jane Organizer',
email: 'jane@testorg.com',
phone: '555-ORG-001',
website: 'https://testorg.com',
address: '123 Organization Street, Org City, OG 12345',
notes: 'Primary test organizer for training events'
},
corporateOrganizer: {
name: 'Corporate HVAC Training',
contactName: 'John Corporate',
email: 'john@corporate-hvac.com',
phone: '555-CORP-002',
website: 'https://corporate-hvac.com',
address: '789 Corporate Plaza, Business City, BC 67890',
taxId: '12-3456789',
notes: 'Large scale training provider'
}
},
announcements: {
generalAnnouncement: {
title: 'Test General Announcement',
content: 'This is a test announcement for general information.',
priority: 'normal',
targetAudience: 'all',
startDate: this.getCurrentDate(),
endDate: this.getFutureDate(30),
status: 'published',
author: 'Test Master Trainer'
},
urgentAnnouncement: {
title: 'Urgent: Test Emergency Announcement',
content: 'This is an urgent test announcement that requires immediate attention.',
priority: 'high',
targetAudience: 'trainers',
startDate: this.getCurrentDate(),
endDate: this.getFutureDate(7),
status: 'published',
urgent: true,
emailNotification: true
}
},
forms: {
eventRegistration: {
firstName: 'Test',
lastName: 'Participant',
email: 'test.participant@example.com',
phone: '555-PART-001',
company: 'Test Company LLC',
experience: 'beginner',
specialRequirements: 'None',
emergencyContact: 'Emergency Contact',
emergencyPhone: '555-EMRG-001'
},
trainerProfile: {
firstName: 'Test',
lastName: 'Trainer',
email: 'test.trainer@example.com',
phone: '555-TRAIN-001',
company: 'HVAC Training Pro',
experience: '5-10 years',
certifications: ['EPA 608', 'NATE Certified'],
specialties: ['Installation', 'Maintenance', 'Troubleshooting'],
bio: 'Experienced HVAC professional with focus on training.',
website: 'https://hvactrainingpro.com',
linkedIn: 'https://linkedin.com/in/testtrainer'
}
}
};
}
/**
* Load fixtures from JSON files
* @returns {Promise<void>}
*/
async loadFixtures() {
try {
// Ensure fixtures directory exists
await fs.mkdir(this.fixturesPath, { recursive: true });
// Load existing fixtures or create defaults
await this.loadOrCreateFixture('users.json', this.accounts[this.environment] || this.accounts.staging);
await this.loadOrCreateFixture('events.json', this.testData.events);
await this.loadOrCreateFixture('venues.json', this.testData.venues);
await this.loadOrCreateFixture('organizers.json', this.testData.organizers);
await this.loadOrCreateFixture('announcements.json', this.testData.announcements);
} catch (error) {
console.warn(`Failed to load fixtures: ${error.message}`);
}
}
/**
* Load fixture file or create with default data
* @param {string} filename - Fixture filename
* @param {Object} defaultData - Default data if file doesn't exist
* @returns {Promise<Object>}
*/
async loadOrCreateFixture(filename, defaultData) {
const filePath = path.join(this.fixturesPath, filename);
try {
const content = await fs.readFile(filePath, 'utf8');
const data = JSON.parse(content);
this.dataCache.set(filename, data);
return data;
} catch (error) {
// File doesn't exist, create with default data
await fs.writeFile(filePath, JSON.stringify(defaultData, null, 2));
this.dataCache.set(filename, defaultData);
return defaultData;
}
}
/**
* Get test account by role
* @param {string} role - User role (masterTrainer, trainer, admin, etc.)
* @returns {Object|null}
*/
getTestAccount(role) {
const envAccounts = this.accounts[this.environment] || this.accounts.staging;
return envAccounts[role] || null;
}
/**
* Get all test accounts for current environment
* @returns {Object}
*/
getAllTestAccounts() {
return this.accounts[this.environment] || this.accounts.staging;
}
/**
* Get test data by category and type
* @param {string} category - Data category (events, venues, etc.)
* @param {string} type - Data type (basicEvent, fullEvent, etc.)
* @returns {Object|null}
*/
getTestData(category, type) {
if (!this.testData[category]) return null;
return this.testData[category][type] || null;
}
/**
* Get all test data for a category
* @param {string} category - Data category
* @returns {Object|null}
*/
getTestDataCategory(category) {
return this.testData[category] || null;
}
/**
* Generate unique test data
* @param {string} category - Data category
* @param {string} type - Data type
* @param {Object} overrides - Properties to override
* @returns {Object}
*/
generateUniqueTestData(category, type, overrides = {}) {
const baseData = this.getTestData(category, type);
if (!baseData) return null;
const uniqueData = { ...baseData };
const timestamp = Date.now();
// Add unique identifiers
if (uniqueData.title) {
uniqueData.title = `${uniqueData.title} - ${timestamp}`;
}
if (uniqueData.name) {
uniqueData.name = `${uniqueData.name} - ${timestamp}`;
}
if (uniqueData.email) {
uniqueData.email = uniqueData.email.replace('@', `+${timestamp}@`);
}
// Apply overrides
Object.assign(uniqueData, overrides);
return uniqueData;
}
/**
* Create test event data with random variations
* @param {Object} overrides - Properties to override
* @returns {Object}
*/
createRandomEventData(overrides = {}) {
const eventTypes = ['training', 'workshop', 'certification', 'seminar'];
const locations = ['Training Center A', 'Workshop Venue B', 'Conference Hall C'];
const cities = ['Training City', 'Workshop Town', 'Education Village'];
const randomEvent = {
title: `${this.getRandomElement(['Advanced', 'Basic', 'Intermediate'])} HVAC ${this.getRandomElement(['Training', 'Workshop', 'Course'])}`,
description: 'Comprehensive HVAC training with hands-on experience.',
startDate: this.getFutureDate(Math.floor(Math.random() * 30) + 1),
endDate: this.getFutureDate(Math.floor(Math.random() * 30) + 2),
startTime: '09:00:00',
endTime: '17:00:00',
location: this.getRandomElement(locations),
address: `${Math.floor(Math.random() * 999) + 100} ${this.getRandomElement(['Main', 'Training', 'Education'])} Street, ${this.getRandomElement(cities)}, TC 12345`,
capacity: Math.floor(Math.random() * 30) + 10,
eventType: this.getRandomElement(eventTypes),
status: 'published'
};
return { ...randomEvent, ...overrides };
}
/**
* Get protected URLs for security testing
* @returns {string[]}
*/
getProtectedUrls() {
return [
'/trainer/dashboard/',
'/trainer/venue/list/',
'/trainer/venue/manage/',
'/trainer/organizer/manage/',
'/trainer/profile/training-leads/',
'/master-trainer/master-dashboard/',
'/master-trainer/events/',
'/master-trainer/google-sheets/',
'/master-trainer/announcements/',
'/master-trainer/pending-approvals/',
'/master-trainer/trainers/',
'/master-trainer/communication-templates/'
];
}
/**
* Get role-based access test scenarios
* @returns {Array}
*/
getRoleAccessTestScenarios() {
const masterTrainer = this.getTestAccount('masterTrainer');
const trainer = this.getTestAccount('trainer');
return [
// Master trainer should have access to master trainer pages
{ user: masterTrainer, url: '/master-trainer/master-dashboard/', expectedAccess: true },
{ user: masterTrainer, url: '/master-trainer/events/', expectedAccess: true },
{ user: masterTrainer, url: '/master-trainer/trainers/', expectedAccess: true },
// Regular trainer should NOT have access to master trainer pages
{ user: trainer, url: '/master-trainer/master-dashboard/', expectedAccess: false },
{ user: trainer, url: '/master-trainer/events/', expectedAccess: false },
{ user: trainer, url: '/master-trainer/trainers/', expectedAccess: false },
// Regular trainer should have access to trainer pages
{ user: trainer, url: '/trainer/dashboard/', expectedAccess: true },
{ user: trainer, url: '/trainer/venue/manage/', expectedAccess: true },
{ user: trainer, url: '/trainer/organizer/manage/', expectedAccess: true }
];
}
/**
* Get current date in YYYY-MM-DD format
* @returns {string}
*/
getCurrentDate() {
return new Date().toISOString().split('T')[0];
}
/**
* Get future date in YYYY-MM-DD format
* @param {number} daysFromNow - Days in the future
* @returns {string}
*/
getFutureDate(daysFromNow) {
const date = new Date();
date.setDate(date.getDate() + daysFromNow);
return date.toISOString().split('T')[0];
}
/**
* Get past date in YYYY-MM-DD format
* @param {number} daysAgo - Days in the past
* @returns {string}
*/
getPastDate(daysAgo) {
const date = new Date();
date.setDate(date.getDate() - daysAgo);
return date.toISOString().split('T')[0];
}
/**
* Get random element from array
* @param {Array} array - Array to select from
* @returns {*}
* @private
*/
getRandomElement(array) {
return array[Math.floor(Math.random() * array.length)];
}
/**
* Save test data to fixture file
* @param {string} filename - Fixture filename
* @param {Object} data - Data to save
* @returns {Promise<void>}
*/
async saveFixture(filename, data) {
const filePath = path.join(this.fixturesPath, filename);
await fs.writeFile(filePath, JSON.stringify(data, null, 2));
this.dataCache.set(filename, data);
}
/**
* Clear all cached test data
* @returns {void}
*/
clearCache() {
this.dataCache.clear();
}
/**
* Get fixture data
* @param {string} filename - Fixture filename
* @returns {Object|null}
*/
getFixture(filename) {
return this.dataCache.get(filename) || null;
}
}
// Singleton instance
let testDataManager = null;
/**
* Get singleton TestDataManager instance
* @param {string} environment - Environment name
* @returns {TestDataManager}
*/
function getTestDataManager(environment = 'staging') {
if (!testDataManager || testDataManager.environment !== environment) {
testDataManager = new TestDataManager(environment);
}
return testDataManager;
}
module.exports = { TestDataManager, getTestDataManager };