diff --git a/app/Audit/ConcreteFormatters/FileAuditLogFormatter.php b/app/Audit/ConcreteFormatters/FileAuditLogFormatter.php new file mode 100644 index 000000000..18983e0b1 --- /dev/null +++ b/app/Audit/ConcreteFormatters/FileAuditLogFormatter.php @@ -0,0 +1,72 @@ +getName() ?? 'Unknown File'; + $id = $subject->getId() ?? 0; + $filename = $subject->getFilename() ?? 'N/A'; + + switch ($this->event_type) { + case IAuditStrategy::EVENT_ENTITY_CREATION: + return sprintf( + "File '%s' (%s) (%d) created by user %s", + $name, + $filename, + $id, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_UPDATE: + $change_details = $this->buildChangeDetails($change_set); + return sprintf( + "File '%s' (%s) (%d) updated: %s by user %s", + $name, + $filename, + $id, + $change_details, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_DELETION: + return sprintf( + "File '%s' (%s) (%d) was deleted by user %s", + $name, + $filename, + $id, + $this->getUserInfo() + ); + } + } catch (\Exception $ex) { + Log::warning("FileAuditLogFormatter error: " . $ex->getMessage()); + } + + return null; + } +} diff --git a/app/Audit/ConcreteFormatters/ScheduledSummitLocationBannerAuditLogFormatter.php b/app/Audit/ConcreteFormatters/ScheduledSummitLocationBannerAuditLogFormatter.php new file mode 100644 index 000000000..0cad8a791 --- /dev/null +++ b/app/Audit/ConcreteFormatters/ScheduledSummitLocationBannerAuditLogFormatter.php @@ -0,0 +1,79 @@ +getTitle() ?? 'Unknown Banner'; + $id = $subject->getId() ?? 0; + + $location = $subject->getLocation(); + $location_name = $location ? ($location->getName() ?? 'Unknown Location') : 'Unknown Location'; + + $summit = $location ? ($location->getSummit() ? ($location->getSummit()->getName() ?? 'Unknown Summit') : 'Unknown Summit') : 'Unknown Summit'; + + switch ($this->event_type) { + case IAuditStrategy::EVENT_ENTITY_CREATION: + return sprintf( + "Scheduled Location Banner '%s' (%d) created for Location '%s' in Summit '%s' by user %s", + $title, + $id, + $location_name, + $summit, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_UPDATE: + $change_details = $this->buildChangeDetails($change_set); + return sprintf( + "Scheduled Location Banner '%s' (%d) for Location '%s' in Summit '%s' updated: %s by user %s", + $title, + $id, + $location_name, + $summit, + $change_details, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_DELETION: + return sprintf( + "Scheduled Location Banner '%s' (%d) for Location '%s' in Summit '%s' was deleted by user %s", + $title, + $id, + $location_name, + $summit, + $this->getUserInfo() + ); + } + } catch (\Exception $ex) { + Log::warning("ScheduledSummitLocationBannerAuditLogFormatter error: " . $ex->getMessage()); + } + + return null; + } +} diff --git a/app/Audit/ConcreteFormatters/SummitBookableVenueRoomAuditLogFormatter.php b/app/Audit/ConcreteFormatters/SummitBookableVenueRoomAuditLogFormatter.php new file mode 100644 index 000000000..a303b548c --- /dev/null +++ b/app/Audit/ConcreteFormatters/SummitBookableVenueRoomAuditLogFormatter.php @@ -0,0 +1,80 @@ +getName() ?? 'Unknown Room'; + $id = $subject->getId() ?? 0; + + $venue = $subject->getVenue(); + $venue_name = $venue ? ($venue->getName() ?? 'Unknown Venue') : 'Unknown Venue'; + + $summit = $subject->getSummit(); + $summit_name = $summit ? ($summit->getName() ?? 'Unknown Summit') : 'Unknown Summit'; + + switch ($this->event_type) { + case IAuditStrategy::EVENT_ENTITY_CREATION: + return sprintf( + "Bookable Venue Room '%s' (%d) created in Venue '%s' for Summit '%s' by user %s", + $name, + $id, + $venue_name, + $summit_name, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_UPDATE: + $change_details = $this->buildChangeDetails($change_set); + return sprintf( + "Bookable Venue Room '%s' (%d) in Venue '%s' for Summit '%s' updated: %s by user %s", + $name, + $id, + $venue_name, + $summit_name, + $change_details, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_DELETION: + return sprintf( + "Bookable Venue Room '%s' (%d) in Venue '%s' for Summit '%s' was deleted by user %s", + $name, + $id, + $venue_name, + $summit_name, + $this->getUserInfo() + ); + } + } catch (\Exception $ex) { + Log::warning("SummitBookableVenueRoomAuditLogFormatter error: " . $ex->getMessage()); + } + + return null; + } +} diff --git a/app/Audit/ConcreteFormatters/SummitLocationBannerAuditLogFormatter.php b/app/Audit/ConcreteFormatters/SummitLocationBannerAuditLogFormatter.php new file mode 100644 index 000000000..97992b291 --- /dev/null +++ b/app/Audit/ConcreteFormatters/SummitLocationBannerAuditLogFormatter.php @@ -0,0 +1,79 @@ +getTitle() ?? 'Unknown Banner'; + $id = $subject->getId() ?? 0; + + $location = $subject->getLocation(); + $location_name = $location ? ($location->getName() ?? 'Unknown Location') : 'Unknown Location'; + + $summit = $location ? ($location->getSummit() ? ($location->getSummit()->getName() ?? 'Unknown Summit') : 'Unknown Summit') : 'Unknown Summit'; + + switch ($this->event_type) { + case IAuditStrategy::EVENT_ENTITY_CREATION: + return sprintf( + "Location Banner '%s' (%d) created for Location '%s' in Summit '%s' by user %s", + $title, + $id, + $location_name, + $summit, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_UPDATE: + $change_details = $this->buildChangeDetails($change_set); + return sprintf( + "Location Banner '%s' (%d) for Location '%s' in Summit '%s' updated: %s by user %s", + $title, + $id, + $location_name, + $summit, + $change_details, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_DELETION: + return sprintf( + "Location Banner '%s' (%d) for Location '%s' in Summit '%s' was deleted by user %s", + $title, + $id, + $location_name, + $summit, + $this->getUserInfo() + ); + } + } catch (\Exception $ex) { + Log::warning("SummitLocationBannerAuditLogFormatter error: " . $ex->getMessage()); + } + + return null; + } +} diff --git a/app/Audit/ConcreteFormatters/SummitLocationImageAuditLogFormatter.php b/app/Audit/ConcreteFormatters/SummitLocationImageAuditLogFormatter.php new file mode 100644 index 000000000..63d34d581 --- /dev/null +++ b/app/Audit/ConcreteFormatters/SummitLocationImageAuditLogFormatter.php @@ -0,0 +1,79 @@ +getName() ?? 'Unknown Image'; + $id = $subject->getId() ?? 0; + + $location = $subject->getLocation(); + $location_name = $location ? ($location->getName() ?? 'Unknown Location') : 'Unknown Location'; + + $summit = $location ? ($location->getSummit() ? ($location->getSummit()->getName() ?? 'Unknown Summit') : 'Unknown Summit') : 'Unknown Summit'; + + switch ($this->event_type) { + case IAuditStrategy::EVENT_ENTITY_CREATION: + return sprintf( + "Location Image '%s' (%d) created for Location '%s' in Summit '%s' by user %s", + $name, + $id, + $location_name, + $summit, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_UPDATE: + $change_details = $this->buildChangeDetails($change_set); + return sprintf( + "Location Image '%s' (%d) for Location '%s' in Summit '%s' updated: %s by user %s", + $name, + $id, + $location_name, + $summit, + $change_details, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_DELETION: + return sprintf( + "Location Image '%s' (%d) for Location '%s' in Summit '%s' was deleted by user %s", + $name, + $id, + $location_name, + $summit, + $this->getUserInfo() + ); + } + } catch (\Exception $ex) { + Log::warning("SummitLocationImageAuditLogFormatter error: " . $ex->getMessage()); + } + + return null; + } +} diff --git a/app/Audit/ConcreteFormatters/SummitVenueFloorAuditLogFormatter.php b/app/Audit/ConcreteFormatters/SummitVenueFloorAuditLogFormatter.php new file mode 100644 index 000000000..31a7a90c1 --- /dev/null +++ b/app/Audit/ConcreteFormatters/SummitVenueFloorAuditLogFormatter.php @@ -0,0 +1,83 @@ +getName() ?? 'Unknown Floor'; + $number = $subject->getNumber() ?? 0; + $id = $subject->getId() ?? 0; + + $venue = $subject->getVenue(); + $venue_name = $venue ? ($venue->getName() ?? 'Unknown Venue') : 'Unknown Venue'; + + $summit = $venue ? ($venue->getSummit() ? ($venue->getSummit()->getName() ?? 'Unknown Summit') : 'Unknown Summit') : 'Unknown Summit'; + + switch ($this->event_type) { + case IAuditStrategy::EVENT_ENTITY_CREATION: + return sprintf( + "Venue Floor '%s' (Floor #%d) (%d) created in Venue '%s' for Summit '%s' by user %s", + $name, + $number, + $id, + $venue_name, + $summit, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_UPDATE: + $change_details = $this->buildChangeDetails($change_set); + return sprintf( + "Venue Floor '%s' (Floor #%d) (%d) in Venue '%s' for Summit '%s' updated: %s by user %s", + $name, + $number, + $id, + $venue_name, + $summit, + $change_details, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_DELETION: + return sprintf( + "Venue Floor '%s' (Floor #%d) (%d) in Venue '%s' for Summit '%s' was deleted by user %s", + $name, + $number, + $id, + $venue_name, + $summit, + $this->getUserInfo() + ); + } + } catch (\Exception $ex) { + Log::warning("SummitVenueFloorAuditLogFormatter error: " . $ex->getMessage()); + } + + return null; + } +} diff --git a/config/audit_log.php b/config/audit_log.php index 4488990f9..904f97674 100644 --- a/config/audit_log.php +++ b/config/audit_log.php @@ -108,6 +108,30 @@ 'enabled' => true, 'strategy' => \App\Audit\ConcreteFormatters\SummitVenueAuditLogFormatter::class, ], + \models\summit\SummitVenueFloor::class => [ + 'enabled' => true, + 'strategy' => \App\Audit\ConcreteFormatters\SummitVenueFloorAuditLogFormatter::class, + ], + \models\main\File::class => [ + 'enabled' => true, + 'strategy' => \App\Audit\ConcreteFormatters\FileAuditLogFormatter::class, + ], + \models\summit\SummitBookableVenueRoom::class => [ + 'enabled' => true, + 'strategy' => \App\Audit\ConcreteFormatters\SummitBookableVenueRoomAuditLogFormatter::class, + ], + \models\summit\SummitLocationImage::class => [ + 'enabled' => true, + 'strategy' => \App\Audit\ConcreteFormatters\SummitLocationImageAuditLogFormatter::class, + ], + \App\Models\Foundation\Summit\Locations\Banners\SummitLocationBanner::class => [ + 'enabled' => true, + 'strategy' => \App\Audit\ConcreteFormatters\SummitLocationBannerAuditLogFormatter::class, + ], + \App\Models\Foundation\Summit\Locations\Banners\ScheduledSummitLocationBanner::class => [ + 'enabled' => true, + 'strategy' => \App\Audit\ConcreteFormatters\ScheduledSummitLocationBannerAuditLogFormatter::class, + ], \models\summit\SummitExternalLocation::class => [ 'enabled' => true, 'strategy' => \App\Audit\ConcreteFormatters\SummitExternalLocationAuditLogFormatter::class, diff --git a/tests/OpenTelemetry/Formatters/FileAuditLogFormatterTest.php b/tests/OpenTelemetry/Formatters/FileAuditLogFormatterTest.php new file mode 100644 index 000000000..12a2fd817 --- /dev/null +++ b/tests/OpenTelemetry/Formatters/FileAuditLogFormatterTest.php @@ -0,0 +1,117 @@ +mockSubject = $this->createMockSubject(); + } + + protected function tearDown(): void + { + Mockery::close(); + parent::tearDown(); + } + + private function createMockSubject(): mixed + { + $mock = Mockery::mock('models\main\File'); + + // Configure return values + $mock->shouldReceive('getId')->andReturn(123); + $mock->shouldReceive('getName')->andReturn('Test Document'); + $mock->shouldReceive('getFilename')->andReturn('test.pdf'); + + return $mock; + } + + public function testSubjectCreationAuditMessage(): void + { + $formatter = new FileAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_CREATION); + $formatter->setContext(AuditContextBuilder::default()->build()); + $result = $formatter->format($this->mockSubject, []); + + $this->assertNotNull($result); + $this->assertStringContainsString('created', $result); + $this->assertStringContainsString('123', $result); + } + + public function testSubjectUpdateAuditMessage(): void + { + $formatter = new FileAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_UPDATE); + $formatter->setContext(AuditContextBuilder::default()->build()); + $changeSet = [ + 'name' => ['Old Name', 'New Name'], + 'filename' => ['old.pdf', 'new.pdf'] + ]; + + $result = $formatter->format($this->mockSubject, $changeSet); + + $this->assertNotNull($result); + $this->assertStringContainsString('updated', $result); + } + + public function testSubjectDeletionAuditMessage(): void + { + $formatter = new FileAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_DELETION); + $formatter->setContext(AuditContextBuilder::default()->build()); + $result = $formatter->format($this->mockSubject, []); + + $this->assertNotNull($result); + $this->assertStringContainsString('deleted', $result); + } + + public function testFormatterReturnsNullForInvalidSubject(): void + { + $formatter = new FileAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_CREATION); + $result = $formatter->format(new \stdClass(), []); + $this->assertNull($result); + } + + public function testFormatterHandlesEmptyChangeSet(): void + { + $formatter = new FileAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_UPDATE); + $formatter->setContext(AuditContextBuilder::default()->build()); + $result = $formatter->format($this->mockSubject, []); + + $this->assertNotNull($result); + $this->assertStringContainsString('updated', $result); + } + + public function testPropertiesExist(): void + { + $formatter = new FileAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_CREATION); + $formatter->setContext(AuditContextBuilder::default()->build()); + + $this->assertTrue(method_exists($this->mockSubject, 'getId')); + $this->assertTrue(method_exists($this->mockSubject, 'getName')); + $this->assertTrue(method_exists($this->mockSubject, 'getFilename')); + + $result = $formatter->format($this->mockSubject, []); + $this->assertNotNull($result); + } +} diff --git a/tests/OpenTelemetry/Formatters/ScheduledSummitLocationBannerAuditLogFormatterTest.php b/tests/OpenTelemetry/Formatters/ScheduledSummitLocationBannerAuditLogFormatterTest.php new file mode 100644 index 000000000..ffb12774a --- /dev/null +++ b/tests/OpenTelemetry/Formatters/ScheduledSummitLocationBannerAuditLogFormatterTest.php @@ -0,0 +1,127 @@ +mockSubject = $this->createMockSubject(); + } + + protected function tearDown(): void + { + Mockery::close(); + parent::tearDown(); + } + + private function createMockSubject(): mixed + { + $mockSummit = Mockery::mock('models\summit\Summit'); + $mockSummit->shouldReceive('getName')->andReturn('OpenStack Summit 2024'); + + $mockLocation = Mockery::mock('models\summit\SummitGeoLocatedLocation'); + $mockLocation->shouldReceive('getName')->andReturn('Keynote Hall'); + $mockLocation->shouldReceive('getSummit')->andReturn($mockSummit); + + $mock = Mockery::mock('App\Models\Foundation\Summit\Locations\Banners\ScheduledSummitLocationBanner'); + + // Configure return values + $mock->shouldReceive('getId')->andReturn(222); + $mock->shouldReceive('getTitle')->andReturn('Live Keynote Banner'); + $mock->shouldReceive('getLocation')->andReturn($mockLocation); + $mock->shouldReceive('getStartDate')->andReturn(new \DateTime('2024-01-01 09:00:00')); + $mock->shouldReceive('getEndDate')->andReturn(new \DateTime('2024-01-01 17:00:00')); + + return $mock; + } + + public function testSubjectCreationAuditMessage(): void + { + $formatter = new ScheduledSummitLocationBannerAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_CREATION); + $formatter->setContext(AuditContextBuilder::default()->build()); + $result = $formatter->format($this->mockSubject, []); + + $this->assertNotNull($result); + $this->assertStringContainsString('created', $result); + $this->assertStringContainsString('Live Keynote Banner', $result); + $this->assertStringContainsString('222', $result); + } + + public function testSubjectUpdateAuditMessage(): void + { + $formatter = new ScheduledSummitLocationBannerAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_UPDATE); + $formatter->setContext(AuditContextBuilder::default()->build()); + $changeSet = ['title' => ['Live Keynote Banner', 'Keynote Session Banner'], 'start_date' => ['2024-01-01 09:00:00', '2024-01-01 10:00:00']]; + + $result = $formatter->format($this->mockSubject, $changeSet); + + $this->assertNotNull($result); + $this->assertStringContainsString('updated', $result); + } + + public function testSubjectDeletionAuditMessage(): void + { + $formatter = new ScheduledSummitLocationBannerAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_DELETION); + $formatter->setContext(AuditContextBuilder::default()->build()); + $result = $formatter->format($this->mockSubject, []); + + $this->assertNotNull($result); + $this->assertStringContainsString('deleted', $result); + } + + public function testFormatterReturnsNullForInvalidSubject(): void + { + $formatter = new ScheduledSummitLocationBannerAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_CREATION); + $formatter->setContext(AuditContextBuilder::default()->build()); + $result = $formatter->format(new \stdClass(), []); + $this->assertNull($result); + } + + public function testFormatterHandlesEmptyChangeSet(): void + { + $formatter = new ScheduledSummitLocationBannerAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_UPDATE); + $formatter->setContext(AuditContextBuilder::default()->build()); + $result = $formatter->format($this->mockSubject, []); + + $this->assertNotNull($result); + $this->assertStringContainsString('updated', $result); + } + + public function testPropertiesExist(): void + { + $formatter = new ScheduledSummitLocationBannerAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_CREATION); + $formatter->setContext(AuditContextBuilder::default()->build()); + + $this->assertTrue(method_exists($this->mockSubject, 'getId')); + $this->assertTrue(method_exists($this->mockSubject, 'getTitle')); + $this->assertTrue(method_exists($this->mockSubject, 'getLocation')); + $this->assertTrue(method_exists($this->mockSubject, 'getStartDate')); + $this->assertTrue(method_exists($this->mockSubject, 'getEndDate')); + + $result = $formatter->format($this->mockSubject, []); + $this->assertNotNull($result); + } +} diff --git a/tests/OpenTelemetry/Formatters/SummitBookableVenueRoomAuditLogFormatterTest.php b/tests/OpenTelemetry/Formatters/SummitBookableVenueRoomAuditLogFormatterTest.php new file mode 100644 index 000000000..c592698c0 --- /dev/null +++ b/tests/OpenTelemetry/Formatters/SummitBookableVenueRoomAuditLogFormatterTest.php @@ -0,0 +1,124 @@ +mockSubject = $this->createMockSubject(); + } + + protected function tearDown(): void + { + Mockery::close(); + parent::tearDown(); + } + + private function createMockSubject(): mixed + { + $mockSummit = Mockery::mock('models\summit\Summit'); + $mockSummit->shouldReceive('getName')->andReturn('OpenStack Summit 2024'); + + $mockVenue = Mockery::mock('models\summit\SummitVenue'); + $mockVenue->shouldReceive('getName')->andReturn('Convention Center'); + $mockVenue->shouldReceive('getSummit')->andReturn($mockSummit); + + $mock = Mockery::mock('models\summit\SummitBookableVenueRoom'); + + // Configure return values + $mock->shouldReceive('getId')->andReturn(789); + $mock->shouldReceive('getName')->andReturn('Ballroom A'); + $mock->shouldReceive('getVenue')->andReturn($mockVenue); + $mock->shouldReceive('getSummit')->andReturn($mockSummit); + + return $mock; + } + + public function testSubjectCreationAuditMessage(): void + { + $formatter = new SummitBookableVenueRoomAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_CREATION); + $formatter->setContext(AuditContextBuilder::default()->build()); + $result = $formatter->format($this->mockSubject, []); + + $this->assertNotNull($result); + $this->assertStringContainsString('created', $result); + $this->assertStringContainsString('Ballroom A', $result); + $this->assertStringContainsString('789', $result); + } + + public function testSubjectUpdateAuditMessage(): void + { + $formatter = new SummitBookableVenueRoomAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_UPDATE); + $formatter->setContext(AuditContextBuilder::default()->build()); + $changeSet = ['name' => ['Ballroom A', 'Ballroom A & B'], 'time_slot_cost' => [1000, 1500]]; + + $result = $formatter->format($this->mockSubject, $changeSet); + + $this->assertNotNull($result); + $this->assertStringContainsString('updated', $result); + } + + public function testSubjectDeletionAuditMessage(): void + { + $formatter = new SummitBookableVenueRoomAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_DELETION); + $formatter->setContext(AuditContextBuilder::default()->build()); + $result = $formatter->format($this->mockSubject, []); + + $this->assertNotNull($result); + $this->assertStringContainsString('deleted', $result); + } + + public function testFormatterReturnsNullForInvalidSubject(): void + { + $formatter = new SummitBookableVenueRoomAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_CREATION); + $formatter->setContext(AuditContextBuilder::default()->build()); + $result = $formatter->format(new \stdClass(), []); + $this->assertNull($result); + } + + public function testFormatterHandlesEmptyChangeSet(): void + { + $formatter = new SummitBookableVenueRoomAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_UPDATE); + $formatter->setContext(AuditContextBuilder::default()->build()); + $result = $formatter->format($this->mockSubject, []); + + $this->assertNotNull($result); + $this->assertStringContainsString('updated', $result); + } + + public function testPropertiesExist(): void + { + $formatter = new SummitBookableVenueRoomAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_CREATION); + $formatter->setContext(AuditContextBuilder::default()->build()); + + $this->assertTrue(method_exists($this->mockSubject, 'getId')); + $this->assertTrue(method_exists($this->mockSubject, 'getName')); + $this->assertTrue(method_exists($this->mockSubject, 'getVenue')); + + $result = $formatter->format($this->mockSubject, []); + $this->assertNotNull($result); + } +} diff --git a/tests/OpenTelemetry/Formatters/SummitLocationBannerAuditLogFormatterTest.php b/tests/OpenTelemetry/Formatters/SummitLocationBannerAuditLogFormatterTest.php new file mode 100644 index 000000000..7a6b829d1 --- /dev/null +++ b/tests/OpenTelemetry/Formatters/SummitLocationBannerAuditLogFormatterTest.php @@ -0,0 +1,123 @@ +mockSubject = $this->createMockSubject(); + } + + protected function tearDown(): void + { + Mockery::close(); + parent::tearDown(); + } + + private function createMockSubject(): mixed + { + $mockSummit = Mockery::mock('models\summit\Summit'); + $mockSummit->shouldReceive('getName')->andReturn('OpenStack Summit 2024'); + + $mockLocation = Mockery::mock('models\summit\SummitGeoLocatedLocation'); + $mockLocation->shouldReceive('getName')->andReturn('Main Hall'); + $mockLocation->shouldReceive('getSummit')->andReturn($mockSummit); + + $mock = Mockery::mock('App\Models\Foundation\Summit\Locations\Banners\SummitLocationBanner'); + + // Configure return values + $mock->shouldReceive('getId')->andReturn(111); + $mock->shouldReceive('getTitle')->andReturn('Welcome Banner'); + $mock->shouldReceive('getLocation')->andReturn($mockLocation); + + return $mock; + } + + public function testSubjectCreationAuditMessage(): void + { + $formatter = new SummitLocationBannerAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_CREATION); + $formatter->setContext(AuditContextBuilder::default()->build()); + $result = $formatter->format($this->mockSubject, []); + + $this->assertNotNull($result); + $this->assertStringContainsString('created', $result); + $this->assertStringContainsString('Welcome Banner', $result); + $this->assertStringContainsString('111', $result); + } + + public function testSubjectUpdateAuditMessage(): void + { + $formatter = new SummitLocationBannerAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_UPDATE); + $formatter->setContext(AuditContextBuilder::default()->build()); + $changeSet = ['title' => ['Welcome Banner', 'Welcome to OpenStack Summit']]; + + $result = $formatter->format($this->mockSubject, $changeSet); + + $this->assertNotNull($result); + $this->assertStringContainsString('updated', $result); + } + + public function testSubjectDeletionAuditMessage(): void + { + $formatter = new SummitLocationBannerAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_DELETION); + $formatter->setContext(AuditContextBuilder::default()->build()); + $result = $formatter->format($this->mockSubject, []); + + $this->assertNotNull($result); + $this->assertStringContainsString('deleted', $result); + } + + public function testFormatterReturnsNullForInvalidSubject(): void + { + $formatter = new SummitLocationBannerAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_CREATION); + $formatter->setContext(AuditContextBuilder::default()->build()); + $result = $formatter->format(new \stdClass(), []); + $this->assertNull($result); + } + + public function testFormatterHandlesEmptyChangeSet(): void + { + $formatter = new SummitLocationBannerAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_UPDATE); + $formatter->setContext(AuditContextBuilder::default()->build()); + $result = $formatter->format($this->mockSubject, []); + + $this->assertNotNull($result); + $this->assertStringContainsString('updated', $result); + } + + public function testPropertiesExist(): void + { + $formatter = new SummitLocationBannerAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_CREATION); + $formatter->setContext(AuditContextBuilder::default()->build()); + + $this->assertTrue(method_exists($this->mockSubject, 'getId')); + $this->assertTrue(method_exists($this->mockSubject, 'getTitle')); + $this->assertTrue(method_exists($this->mockSubject, 'getLocation')); + + $result = $formatter->format($this->mockSubject, []); + $this->assertNotNull($result); + } +} diff --git a/tests/OpenTelemetry/Formatters/SummitLocationImageAuditLogFormatterTest.php b/tests/OpenTelemetry/Formatters/SummitLocationImageAuditLogFormatterTest.php new file mode 100644 index 000000000..4887772f8 --- /dev/null +++ b/tests/OpenTelemetry/Formatters/SummitLocationImageAuditLogFormatterTest.php @@ -0,0 +1,123 @@ +mockSubject = $this->createMockSubject(); + } + + protected function tearDown(): void + { + Mockery::close(); + parent::tearDown(); + } + + private function createMockSubject(): mixed + { + $mockSummit = Mockery::mock('models\summit\Summit'); + $mockSummit->shouldReceive('getName')->andReturn('OpenStack Summit 2024'); + + $mockLocation = Mockery::mock('models\summit\SummitGeoLocatedLocation'); + $mockLocation->shouldReceive('getName')->andReturn('Main Hall'); + $mockLocation->shouldReceive('getSummit')->andReturn($mockSummit); + + $mock = Mockery::mock('models\summit\SummitLocationImage'); + + // Configure return values + $mock->shouldReceive('getId')->andReturn(999); + $mock->shouldReceive('getName')->andReturn('Main Hall Photo'); + $mock->shouldReceive('getLocation')->andReturn($mockLocation); + + return $mock; + } + + public function testSubjectCreationAuditMessage(): void + { + $formatter = new SummitLocationImageAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_CREATION); + $formatter->setContext(AuditContextBuilder::default()->build()); + $result = $formatter->format($this->mockSubject, []); + + $this->assertNotNull($result); + $this->assertStringContainsString('created', $result); + $this->assertStringContainsString('Main Hall Photo', $result); + $this->assertStringContainsString('999', $result); + } + + public function testSubjectUpdateAuditMessage(): void + { + $formatter = new SummitLocationImageAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_UPDATE); + $formatter->setContext(AuditContextBuilder::default()->build()); + $changeSet = ['name' => ['Main Hall Photo', 'Main Hall Photo - Updated']]; + + $result = $formatter->format($this->mockSubject, $changeSet); + + $this->assertNotNull($result); + $this->assertStringContainsString('updated', $result); + } + + public function testSubjectDeletionAuditMessage(): void + { + $formatter = new SummitLocationImageAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_DELETION); + $formatter->setContext(AuditContextBuilder::default()->build()); + $result = $formatter->format($this->mockSubject, []); + + $this->assertNotNull($result); + $this->assertStringContainsString('deleted', $result); + } + + public function testFormatterReturnsNullForInvalidSubject(): void + { + $formatter = new SummitLocationImageAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_CREATION); + $formatter->setContext(AuditContextBuilder::default()->build()); + $result = $formatter->format(new \stdClass(), []); + $this->assertNull($result); + } + + public function testFormatterHandlesEmptyChangeSet(): void + { + $formatter = new SummitLocationImageAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_UPDATE); + $formatter->setContext(AuditContextBuilder::default()->build()); + $result = $formatter->format($this->mockSubject, []); + + $this->assertNotNull($result); + $this->assertStringContainsString('updated', $result); + } + + public function testPropertiesExist(): void + { + $formatter = new SummitLocationImageAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_CREATION); + $formatter->setContext(AuditContextBuilder::default()->build()); + + $this->assertTrue(method_exists($this->mockSubject, 'getId')); + $this->assertTrue(method_exists($this->mockSubject, 'getName')); + $this->assertTrue(method_exists($this->mockSubject, 'getLocation')); + + $result = $formatter->format($this->mockSubject, []); + $this->assertNotNull($result); + } +} diff --git a/tests/OpenTelemetry/Formatters/SummitVenueFloorAuditLogFormatterTest.php b/tests/OpenTelemetry/Formatters/SummitVenueFloorAuditLogFormatterTest.php new file mode 100644 index 000000000..3c6d3a7bf --- /dev/null +++ b/tests/OpenTelemetry/Formatters/SummitVenueFloorAuditLogFormatterTest.php @@ -0,0 +1,125 @@ +mockSubject = $this->createMockSubject(); + } + + protected function tearDown(): void + { + Mockery::close(); + parent::tearDown(); + } + + private function createMockSubject(): mixed + { + $mockSummit = Mockery::mock('models\summit\Summit'); + $mockSummit->shouldReceive('getName')->andReturn('OpenStack Summit 2024'); + + $mockVenue = Mockery::mock('models\summit\SummitVenue'); + $mockVenue->shouldReceive('getName')->andReturn('Convention Center'); + $mockVenue->shouldReceive('getSummit')->andReturn($mockSummit); + + $mock = Mockery::mock('models\summit\SummitVenueFloor'); + + // Configure return values + $mock->shouldReceive('getId')->andReturn(456); + $mock->shouldReceive('getName')->andReturn('Ground Floor'); + $mock->shouldReceive('getNumber')->andReturn(0); + $mock->shouldReceive('getVenue')->andReturn($mockVenue); + + return $mock; + } + + public function testSubjectCreationAuditMessage(): void + { + $formatter = new SummitVenueFloorAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_CREATION); + $formatter->setContext(AuditContextBuilder::default()->build()); + $result = $formatter->format($this->mockSubject, []); + + $this->assertNotNull($result); + $this->assertStringContainsString('created', $result); + $this->assertStringContainsString('Ground Floor', $result); + $this->assertStringContainsString('456', $result); + } + + public function testSubjectUpdateAuditMessage(): void + { + $formatter = new SummitVenueFloorAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_UPDATE); + $formatter->setContext(AuditContextBuilder::default()->build()); + $changeSet = ['name' => ['Ground Floor', 'First Floor'], 'number' => [0, 1]]; + + $result = $formatter->format($this->mockSubject, $changeSet); + + $this->assertNotNull($result); + $this->assertStringContainsString('updated', $result); + } + + public function testSubjectDeletionAuditMessage(): void + { + $formatter = new SummitVenueFloorAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_DELETION); + $formatter->setContext(AuditContextBuilder::default()->build()); + $result = $formatter->format($this->mockSubject, []); + + $this->assertNotNull($result); + $this->assertStringContainsString('deleted', $result); + } + + public function testFormatterReturnsNullForInvalidSubject(): void + { + $formatter = new SummitVenueFloorAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_CREATION); + $formatter->setContext(AuditContextBuilder::default()->build()); + $result = $formatter->format(new \stdClass(), []); + $this->assertNull($result); + } + + public function testFormatterHandlesEmptyChangeSet(): void + { + $formatter = new SummitVenueFloorAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_UPDATE); + $formatter->setContext(AuditContextBuilder::default()->build()); + $result = $formatter->format($this->mockSubject, []); + + $this->assertNotNull($result); + $this->assertStringContainsString('updated', $result); + } + + public function testPropertiesExist(): void + { + $formatter = new SummitVenueFloorAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_CREATION); + $formatter->setContext(AuditContextBuilder::default()->build()); + + $this->assertTrue(method_exists($this->mockSubject, 'getId')); + $this->assertTrue(method_exists($this->mockSubject, 'getName')); + $this->assertTrue(method_exists($this->mockSubject, 'getNumber')); + $this->assertTrue(method_exists($this->mockSubject, 'getVenue')); + + $result = $formatter->format($this->mockSubject, []); + $this->assertNotNull($result); + } +}