ikinci temizlik tamamlandı
This commit is contained in:
@@ -0,0 +1,556 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Unit;
|
||||
|
||||
use Tests\TestCase;
|
||||
use App\Services\WeldLogTriggers\WeldLogTriggerManager;
|
||||
use App\Services\WeldLogTriggers\WeldLogTriggerRegistry;
|
||||
use App\Services\WeldLogTriggers\Contracts\WeldLogTriggerInterface;
|
||||
use App\Models\WeldLog;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
/**
|
||||
* WeldLog Trigger System Integration Test Suite
|
||||
*
|
||||
* COMPREHENSIVE TESTING - Uses PRODUCTION Database for ALL tables
|
||||
*
|
||||
* This test suite validates:
|
||||
* - Trigger registry and structure
|
||||
* - Trigger execution with REAL production data
|
||||
* - Database interactions with actual production tables
|
||||
* - Field dependency logic
|
||||
* - Execution order and results
|
||||
*
|
||||
* IMPORTANT: Uses PRODUCTION database (devstellar_viksa) for ALL tables
|
||||
* - ALL tables use production database (real data)
|
||||
* - Manual transaction management ensures rollback
|
||||
* - 100% SAFE: All changes are rolled back after each test
|
||||
*
|
||||
* Note: Manual transaction management - NO data is persisted
|
||||
*/
|
||||
class WeldLogTriggerSystemTest extends TestCase
|
||||
{
|
||||
|
||||
protected $registry;
|
||||
protected $manager;
|
||||
|
||||
/**
|
||||
* Setup for each test
|
||||
*/
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
// Start transaction on PRODUCTION database (mysql connection)
|
||||
// This ensures ALL changes will be rolled back
|
||||
DB::beginTransaction();
|
||||
|
||||
Log::info("=== TEST STARTED ===", [
|
||||
'database' => DB::getDatabaseName(),
|
||||
'connection' => DB::getDefaultConnection(),
|
||||
'transaction_level' => DB::transactionLevel(),
|
||||
'protection' => 'ENABLED - All changes will be rolled back'
|
||||
]);
|
||||
|
||||
// Initialize trigger system
|
||||
$this->registry = new WeldLogTriggerRegistry();
|
||||
$this->manager = new WeldLogTriggerManager($this->registry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Teardown after each test
|
||||
*/
|
||||
protected function tearDown(): void
|
||||
{
|
||||
// IMPORTANT: Rollback ALL production database changes
|
||||
// This ensures NO changes are persisted
|
||||
if (DB::transactionLevel() > 0) {
|
||||
DB::rollBack();
|
||||
Log::info("=== TEST COMPLETED - ALL CHANGES ROLLED BACK ===", [
|
||||
'database' => DB::getDatabaseName(),
|
||||
'changes_persisted' => 'NO - Everything rolled back'
|
||||
]);
|
||||
}
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// REGISTRY AND STRUCTURE TESTS
|
||||
// ========================================
|
||||
|
||||
/**
|
||||
* Test: Registry registers all triggers correctly
|
||||
*/
|
||||
public function test_registry_registers_all_triggers()
|
||||
{
|
||||
$triggers = $this->registry->getTriggersInOrder();
|
||||
|
||||
$this->assertGreaterThanOrEqual(13, count($triggers), 'Registry should have at least 13 triggers');
|
||||
|
||||
foreach ($triggers as $trigger) {
|
||||
$this->assertInstanceOf(
|
||||
WeldLogTriggerInterface::class,
|
||||
$trigger,
|
||||
'All triggers must implement WeldLogTriggerInterface'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test: Triggers are returned in correct order
|
||||
*/
|
||||
public function test_triggers_are_sorted_by_order()
|
||||
{
|
||||
$triggers = $this->registry->getTriggersInOrder();
|
||||
|
||||
$previousOrder = 0;
|
||||
foreach ($triggers as $trigger) {
|
||||
$currentOrder = $trigger->getOrder();
|
||||
$this->assertGreaterThanOrEqual(
|
||||
$previousOrder,
|
||||
$currentOrder,
|
||||
"Triggers must be sorted by order. {$trigger->getName()} has order {$currentOrder} but previous was {$previousOrder}"
|
||||
);
|
||||
$previousOrder = $currentOrder;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test: Get specific trigger by name
|
||||
*/
|
||||
public function test_get_trigger_by_name()
|
||||
{
|
||||
$trigger = $this->registry->getTrigger('Spool Status Changer');
|
||||
|
||||
$this->assertNotNull($trigger, 'Should find Spool Status Changer trigger');
|
||||
$this->assertEquals('Spool Status Changer', $trigger->getName());
|
||||
$this->assertEquals(1, $trigger->getOrder());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test: All expected triggers are registered
|
||||
*/
|
||||
public function test_all_expected_triggers_are_registered()
|
||||
{
|
||||
$expectedTriggers = [
|
||||
'Spool Status Changer',
|
||||
'Line Lists Update',
|
||||
'NDE Matrix Update',
|
||||
'Request Date Operations',
|
||||
'Repair Logs Update',
|
||||
'NDE Project Update',
|
||||
'Test Package Operations',
|
||||
'Test Pack Sync from WeldLog',
|
||||
'Construction Paint Logs Sync',
|
||||
'Test Pack Base Status Changer',
|
||||
'Paint Follow Ups Sync',
|
||||
'Handovers Sync',
|
||||
'Test Pack Cleanup',
|
||||
'NdtCalculationCacheTrigger',
|
||||
'RegisterCreatorCacheTrigger'
|
||||
];
|
||||
|
||||
$registeredNames = $this->registry->getTriggerNames();
|
||||
|
||||
foreach ($expectedTriggers as $expectedName) {
|
||||
$this->assertContains(
|
||||
$expectedName,
|
||||
$registeredNames,
|
||||
"Expected trigger '{$expectedName}' should be registered"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// FIELD DEPENDENCY TESTS
|
||||
// ========================================
|
||||
|
||||
/**
|
||||
* Test: shouldRun returns true for new records
|
||||
*/
|
||||
public function test_should_run_returns_true_for_new_records()
|
||||
{
|
||||
$trigger = $this->registry->getTrigger('Spool Status Changer');
|
||||
|
||||
$shouldRun = $trigger->shouldRun([], true);
|
||||
|
||||
$this->assertTrue($shouldRun, 'All triggers should run for new records');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test: shouldRun checks dependent fields correctly
|
||||
*/
|
||||
public function test_should_run_checks_dependent_fields()
|
||||
{
|
||||
$trigger = $this->registry->getTrigger('Spool Status Changer');
|
||||
|
||||
// Should run when dependent field changes
|
||||
$shouldRun1 = $trigger->shouldRun(['spool_number'], false);
|
||||
$this->assertTrue($shouldRun1, 'Should run when spool_number changes');
|
||||
|
||||
$shouldRun2 = $trigger->shouldRun(['iso_number'], false);
|
||||
$this->assertTrue($shouldRun2, 'Should run when iso_number changes');
|
||||
|
||||
// Should not run when non-dependent field changes
|
||||
$shouldRun3 = $trigger->shouldRun(['drawing_revision'], false);
|
||||
$this->assertFalse($shouldRun3, 'Should not run when non-dependent field changes');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test: Spool Status Changer dependencies
|
||||
*/
|
||||
public function test_spool_status_changer_dependencies()
|
||||
{
|
||||
$trigger = $this->registry->getTrigger('Spool Status Changer');
|
||||
$dependentFields = $trigger->getDependentFields();
|
||||
|
||||
$this->assertContains('spool_number', $dependentFields);
|
||||
$this->assertContains('iso_number', $dependentFields);
|
||||
$this->assertContains('type_of_joint', $dependentFields);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test: NDE Matrix trigger dependencies
|
||||
*/
|
||||
public function test_nde_matrix_trigger_dependencies()
|
||||
{
|
||||
$trigger = $this->registry->getTrigger('NDE Matrix Update');
|
||||
$dependentFields = $trigger->getDependentFields();
|
||||
|
||||
$this->assertContains('type_of_welds', $dependentFields);
|
||||
$this->assertContains('fluid_code', $dependentFields);
|
||||
$this->assertContains('type_of_joint', $dependentFields);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test: Test Package trigger dependencies
|
||||
*/
|
||||
public function test_test_package_trigger_dependencies()
|
||||
{
|
||||
$trigger = $this->registry->getTrigger('Test Package Operations');
|
||||
$dependentFields = $trigger->getDependentFields();
|
||||
|
||||
$this->assertContains('test_package_no', $dependentFields);
|
||||
$this->assertContains('iso_number', $dependentFields);
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// DATABASE INTERACTION TESTS
|
||||
// ========================================
|
||||
|
||||
/**
|
||||
* Test: Read real weld log record from production
|
||||
*/
|
||||
public function test_read_real_weld_log_record()
|
||||
{
|
||||
// Get first weld log from PRODUCTION database
|
||||
$weldLog = WeldLog::first();
|
||||
|
||||
$this->assertInstanceOf(WeldLog::class, $weldLog);
|
||||
$this->assertNotNull($weldLog->id);
|
||||
|
||||
// Verify we're reading from production
|
||||
$this->assertEquals('mysql', $weldLog->getConnectionName());
|
||||
|
||||
Log::info("Testing with real production weld log", [
|
||||
'id' => $weldLog->id,
|
||||
'spool_number' => $weldLog->spool_number ?? 'N/A',
|
||||
'iso_number' => $weldLog->iso_number ?? 'N/A'
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test: Manager executes triggers with real production data
|
||||
*/
|
||||
public function test_manager_executes_triggers_with_real_data()
|
||||
{
|
||||
// Get real weld log from PRODUCTION
|
||||
$weldLog = WeldLog::first();
|
||||
$this->assertNotNull($weldLog, 'Production database must have at least one weld log');
|
||||
|
||||
// Convert to object format that triggers expect
|
||||
$weldLogData = (object) $weldLog->toArray();
|
||||
|
||||
$results = $this->manager->executeTriggers(
|
||||
$weldLogData,
|
||||
null, // Simulate new record
|
||||
['spool_number', 'iso_number', 'line_number'],
|
||||
true
|
||||
);
|
||||
|
||||
$this->assertIsArray($results);
|
||||
$this->assertNotEmpty($results);
|
||||
|
||||
// Check that we have execution status for each trigger
|
||||
foreach ($results as $triggerName => $result) {
|
||||
$this->assertIsArray($result);
|
||||
$this->assertTrue(
|
||||
isset($result['executed']) || isset($result['skipped']) || isset($result['queued']),
|
||||
"Trigger {$triggerName} must have execution status"
|
||||
);
|
||||
}
|
||||
|
||||
Log::info("Tested triggers with real production data", [
|
||||
'weld_log_id' => $weldLog->id,
|
||||
'triggers_executed' => count($results)
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test: Only relevant triggers execute for specific field changes
|
||||
*/
|
||||
public function test_only_relevant_triggers_execute_for_field_changes()
|
||||
{
|
||||
// Get real weld log from PRODUCTION
|
||||
$weldLog = WeldLog::first();
|
||||
$this->assertNotNull($weldLog);
|
||||
|
||||
// Simulate field change (within transaction - will be rolled back)
|
||||
$beforeData = (object) $weldLog->toArray();
|
||||
|
||||
$originalWelder = $weldLog->welder_1;
|
||||
$weldLog->welder_1 = 'TEST-UPDATED-WELDER';
|
||||
$weldLog->save();
|
||||
|
||||
$afterData = (object) $weldLog->fresh()->toArray();
|
||||
$changedFields = ['welder_1'];
|
||||
|
||||
$results = $this->manager->executeTriggers(
|
||||
$afterData,
|
||||
$beforeData,
|
||||
$changedFields,
|
||||
false
|
||||
);
|
||||
|
||||
// Count skipped vs executed
|
||||
$skippedCount = 0;
|
||||
$executedCount = 0;
|
||||
|
||||
foreach ($results as $result) {
|
||||
if (isset($result['skipped']) && $result['skipped']) {
|
||||
$skippedCount++;
|
||||
} elseif (isset($result['executed']) && $result['executed']) {
|
||||
$executedCount++;
|
||||
}
|
||||
}
|
||||
|
||||
// Most triggers should be skipped since welder_1 is not critical
|
||||
$this->assertGreaterThan(
|
||||
$executedCount,
|
||||
$skippedCount,
|
||||
'Most triggers should be skipped when only welder_1 changes'
|
||||
);
|
||||
|
||||
Log::info("Tested field-specific triggers", [
|
||||
'changed_field' => 'welder_1',
|
||||
'skipped' => $skippedCount,
|
||||
'executed' => $executedCount,
|
||||
'note' => 'Changes rolled back - production data unchanged'
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test: Critical field changes trigger multiple triggers
|
||||
*/
|
||||
public function test_critical_field_changes_trigger_multiple_triggers()
|
||||
{
|
||||
// Get real weld log from PRODUCTION
|
||||
$weldLog = WeldLog::first();
|
||||
$this->assertNotNull($weldLog);
|
||||
|
||||
$beforeData = (object) $weldLog->toArray();
|
||||
|
||||
// Change critical fields (within transaction - will be rolled back)
|
||||
$originalSpool = $weldLog->spool_number;
|
||||
$originalIso = $weldLog->iso_number;
|
||||
$originalTP = $weldLog->test_package_no;
|
||||
|
||||
$weldLog->spool_number = 'TEST-CRITICAL-SPOOL';
|
||||
$weldLog->iso_number = 'TEST-CRITICAL-ISO';
|
||||
$weldLog->test_package_no = 'TEST-CRITICAL-TP';
|
||||
$weldLog->save();
|
||||
|
||||
$afterData = (object) $weldLog->fresh()->toArray();
|
||||
$changedFields = ['spool_number', 'iso_number', 'test_package_no'];
|
||||
|
||||
$results = $this->manager->executeTriggers(
|
||||
$afterData,
|
||||
$beforeData,
|
||||
$changedFields,
|
||||
false
|
||||
);
|
||||
|
||||
// Multiple field changes should trigger multiple triggers
|
||||
$executedCount = 0;
|
||||
foreach ($results as $result) {
|
||||
if (isset($result['executed']) && $result['executed']) {
|
||||
$executedCount++;
|
||||
}
|
||||
}
|
||||
|
||||
$this->assertGreaterThan(
|
||||
2,
|
||||
$executedCount,
|
||||
'Multiple critical field changes should trigger multiple triggers'
|
||||
);
|
||||
|
||||
Log::info("Tested critical field changes", [
|
||||
'changed_fields' => $changedFields,
|
||||
'triggers_executed' => $executedCount,
|
||||
'note' => 'Changes rolled back - production data unchanged'
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test: All triggers execute for new record simulation
|
||||
*/
|
||||
public function test_all_triggers_execute_for_new_record()
|
||||
{
|
||||
// Get real weld log from PRODUCTION to simulate new record
|
||||
$weldLog = WeldLog::first();
|
||||
$this->assertNotNull($weldLog);
|
||||
|
||||
$weldLogData = (object) $weldLog->toArray();
|
||||
|
||||
$results = $this->manager->executeTriggers(
|
||||
$weldLogData,
|
||||
null, // Simulate new record
|
||||
[],
|
||||
true
|
||||
);
|
||||
|
||||
$this->assertNotEmpty($results);
|
||||
|
||||
// For new records, all triggers should at least attempt to run
|
||||
foreach ($results as $triggerName => $result) {
|
||||
$this->assertTrue(
|
||||
isset($result['executed']) || isset($result['skipped']) || isset($result['queued']),
|
||||
"Trigger {$triggerName} must have execution status for new record"
|
||||
);
|
||||
}
|
||||
|
||||
Log::info("Tested new record trigger execution", [
|
||||
'total_triggers' => count($results),
|
||||
'note' => 'Simulated new record with real production data'
|
||||
]);
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// INTERFACE AND STRUCTURE TESTS
|
||||
// ========================================
|
||||
|
||||
/**
|
||||
* Test: Trigger interface methods exist
|
||||
*/
|
||||
public function test_trigger_interface_methods_exist()
|
||||
{
|
||||
$trigger = $this->registry->getTrigger('Spool Status Changer');
|
||||
|
||||
$this->assertTrue(method_exists($trigger, 'getName'));
|
||||
$this->assertTrue(method_exists($trigger, 'getOrder'));
|
||||
$this->assertTrue(method_exists($trigger, 'shouldRun'));
|
||||
$this->assertTrue(method_exists($trigger, 'getDependentFields'));
|
||||
$this->assertTrue(method_exists($trigger, 'execute'));
|
||||
$this->assertTrue(method_exists($trigger, 'isAsync'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test: Dependent fields are properly defined
|
||||
*/
|
||||
public function test_dependent_fields_are_properly_defined()
|
||||
{
|
||||
$triggers = $this->registry->getTriggersInOrder();
|
||||
|
||||
foreach ($triggers as $trigger) {
|
||||
$dependentFields = $trigger->getDependentFields();
|
||||
|
||||
$this->assertIsArray(
|
||||
$dependentFields,
|
||||
"{$trigger->getName()} must return array for getDependentFields()"
|
||||
);
|
||||
|
||||
foreach ($dependentFields as $field) {
|
||||
$this->assertIsString(
|
||||
$field,
|
||||
"Dependent field must be string in {$trigger->getName()}"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test: Trigger async flag returns boolean
|
||||
*/
|
||||
public function test_trigger_async_flag()
|
||||
{
|
||||
$triggers = $this->registry->getTriggersInOrder();
|
||||
|
||||
foreach ($triggers as $trigger) {
|
||||
$isAsync = $trigger->isAsync();
|
||||
$this->assertIsBool(
|
||||
$isAsync,
|
||||
"{$trigger->getName()} isAsync() must return boolean"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test: Manager returns results array
|
||||
*/
|
||||
public function test_manager_returns_results_array()
|
||||
{
|
||||
// Get real weld log from PRODUCTION
|
||||
$weldLog = WeldLog::first();
|
||||
$this->assertNotNull($weldLog);
|
||||
|
||||
$weldLogData = (object) $weldLog->toArray();
|
||||
|
||||
$results = $this->manager->executeTriggers($weldLogData, null, [], true);
|
||||
|
||||
$this->assertIsArray($results);
|
||||
|
||||
foreach ($results as $triggerName => $result) {
|
||||
$this->assertIsString($triggerName);
|
||||
$this->assertIsArray($result);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test: Registry count method
|
||||
*/
|
||||
public function test_registry_count()
|
||||
{
|
||||
$count = $this->registry->count();
|
||||
|
||||
$this->assertIsInt($count);
|
||||
$this->assertGreaterThanOrEqual(13, $count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test: Trigger names are unique
|
||||
*/
|
||||
public function test_trigger_names_are_unique()
|
||||
{
|
||||
$names = $this->registry->getTriggerNames();
|
||||
$uniqueNames = array_unique($names);
|
||||
|
||||
$this->assertEquals(
|
||||
count($names),
|
||||
count($uniqueNames),
|
||||
"All trigger names must be unique"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test: Manager get registry method
|
||||
*/
|
||||
public function test_manager_get_registry()
|
||||
{
|
||||
$registry = $this->manager->getRegistry();
|
||||
|
||||
$this->assertInstanceOf(WeldLogTriggerRegistry::class, $registry);
|
||||
$this->assertSame($this->registry, $registry);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user