diff --git a/app/Audit/ConcreteFormatters/SummitAccessLevelTypeAuditLogFormatter.php b/app/Audit/ConcreteFormatters/SummitAccessLevelTypeAuditLogFormatter.php new file mode 100644 index 000000000..82623fcc4 --- /dev/null +++ b/app/Audit/ConcreteFormatters/SummitAccessLevelTypeAuditLogFormatter.php @@ -0,0 +1,73 @@ +getName() ?? 'Unknown Access Level Type'; + $id = $subject->getId() ?? 'unknown'; + $summit = $subject->getSummit(); + $summit_name = $summit ? ($summit->getName() ?? 'Unknown Summit') : 'Unknown Summit'; + + switch ($this->event_type) { + case IAuditStrategy::EVENT_ENTITY_CREATION: + return sprintf( + "Access Level Type '%s' (%s) created in Summit '%s' by user %s", + $name, + $id, + $summit_name, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_UPDATE: + $change_details = $this->buildChangeDetails($change_set); + return sprintf( + "Access Level Type '%s' (%s) in Summit '%s' updated: %s by user %s", + $name, + $id, + $summit_name, + $change_details, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_DELETION: + return sprintf( + "Access Level Type '%s' (%s) from Summit '%s' was deleted by user %s", + $name, + $id, + $summit_name, + $this->getUserInfo() + ); + } + } catch (\Exception $ex) { + Log::warning("SummitAccessLevelTypeAuditLogFormatter error: " . $ex->getMessage()); + } + + return null; + } +} diff --git a/app/Audit/ConcreteFormatters/SummitBadgeFeatureTypeAuditLogFormatter.php b/app/Audit/ConcreteFormatters/SummitBadgeFeatureTypeAuditLogFormatter.php new file mode 100644 index 000000000..2f6515528 --- /dev/null +++ b/app/Audit/ConcreteFormatters/SummitBadgeFeatureTypeAuditLogFormatter.php @@ -0,0 +1,73 @@ +getName() ?? 'Unknown Badge Feature Type'; + $id = $subject->getId() ?? 'unknown'; + $summit = $subject->getSummit(); + $summit_name = $summit ? ($summit->getName() ?? 'Unknown Summit') : 'Unknown Summit'; + + switch ($this->event_type) { + case IAuditStrategy::EVENT_ENTITY_CREATION: + return sprintf( + "Badge Feature Type '%s' (%s) created in Summit '%s' by user %s", + $name, + $id, + $summit_name, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_UPDATE: + $change_details = $this->buildChangeDetails($change_set); + return sprintf( + "Badge Feature Type '%s' (%s) in Summit '%s' updated: %s by user %s", + $name, + $id, + $summit_name, + $change_details, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_DELETION: + return sprintf( + "Badge Feature Type '%s' (%s) from Summit '%s' was deleted by user %s", + $name, + $id, + $summit_name, + $this->getUserInfo() + ); + } + } catch (\Exception $ex) { + Log::warning("SummitBadgeFeatureTypeAuditLogFormatter error: " . $ex->getMessage()); + } + + return null; + } +} diff --git a/app/Audit/ConcreteFormatters/SummitBadgeTypeAuditLogFormatter.php b/app/Audit/ConcreteFormatters/SummitBadgeTypeAuditLogFormatter.php new file mode 100644 index 000000000..ab85cdf60 --- /dev/null +++ b/app/Audit/ConcreteFormatters/SummitBadgeTypeAuditLogFormatter.php @@ -0,0 +1,73 @@ +getName() ?? 'Unknown Badge Type'; + $id = $subject->getId() ?? 'unknown'; + $summit = $subject->getSummit(); + $summit_name = $summit ? ($summit->getName() ?? 'Unknown Summit') : 'Unknown Summit'; + + switch ($this->event_type) { + case IAuditStrategy::EVENT_ENTITY_CREATION: + return sprintf( + "Badge Type '%s' (%s) created in Summit '%s' by user %s", + $name, + $id, + $summit_name, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_UPDATE: + $change_details = $this->buildChangeDetails($change_set); + return sprintf( + "Badge Type '%s' (%s) in Summit '%s' updated: %s by user %s", + $name, + $id, + $summit_name, + $change_details, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_DELETION: + return sprintf( + "Badge Type '%s' (%s) from Summit '%s' was deleted by user %s", + $name, + $id, + $summit_name, + $this->getUserInfo() + ); + } + } catch (\Exception $ex) { + Log::warning("SummitBadgeTypeAuditLogFormatter error: " . $ex->getMessage()); + } + + return null; + } +} diff --git a/app/Audit/ConcreteFormatters/SummitBadgeViewTypeAuditLogFormatter.php b/app/Audit/ConcreteFormatters/SummitBadgeViewTypeAuditLogFormatter.php new file mode 100644 index 000000000..a0811acf7 --- /dev/null +++ b/app/Audit/ConcreteFormatters/SummitBadgeViewTypeAuditLogFormatter.php @@ -0,0 +1,73 @@ +getName() ?? 'Unknown Badge View Type'; + $id = $subject->getId() ?? 'unknown'; + $summit = $subject->getSummit(); + $summit_name = $summit ? ($summit->getName() ?? 'Unknown Summit') : 'Unknown Summit'; + + switch ($this->event_type) { + case IAuditStrategy::EVENT_ENTITY_CREATION: + return sprintf( + "Badge View Type '%s' (%s) created in Summit '%s' by user %s", + $name, + $id, + $summit_name, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_UPDATE: + $change_details = $this->buildChangeDetails($change_set); + return sprintf( + "Badge View Type '%s' (%s) in Summit '%s' updated: %s by user %s", + $name, + $id, + $summit_name, + $change_details, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_DELETION: + return sprintf( + "Badge View Type '%s' (%s) from Summit '%s' was deleted by user %s", + $name, + $id, + $summit_name, + $this->getUserInfo() + ); + } + } catch (\Exception $ex) { + Log::warning("SummitBadgeViewTypeAuditLogFormatter error: " . $ex->getMessage()); + } + + return null; + } +} diff --git a/tests/OpenTelemetry/Formatters/SummitAccessLevelTypeAuditLogFormatterTest.php b/tests/OpenTelemetry/Formatters/SummitAccessLevelTypeAuditLogFormatterTest.php new file mode 100644 index 000000000..72292c652 --- /dev/null +++ b/tests/OpenTelemetry/Formatters/SummitAccessLevelTypeAuditLogFormatterTest.php @@ -0,0 +1,148 @@ +formatter_creation = new SummitAccessLevelTypeAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_CREATION); + $this->formatter_update = new SummitAccessLevelTypeAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_UPDATE); + $this->formatter_deletion = new SummitAccessLevelTypeAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_DELETION); + + $this->audit_context = new AuditContext( + userId: self::USER_ID, + userEmail: self::USER_EMAIL, + userFirstName: self::USER_FIRST_NAME, + userLastName: self::USER_LAST_NAME + ); + } + + protected function tearDown(): void + { + Mockery::close(); + parent::tearDown(); + } + + public function testFormatCreationEvent(): void + { + $access_level = $this->createMockAccessLevelType('In-Person Access', 1); + + $this->formatter_creation->setContext($this->audit_context); + $result = $this->formatter_creation->format($access_level, []); + + $this->assertNotNull($result); + $this->assertStringContainsString("In-Person Access", $result); + $this->assertStringContainsString("(1)", $result); + $this->assertStringContainsString("created", $result); + $this->assertStringContainsString("Test Summit", $result); + } + + public function testFormatUpdateEvent(): void + { + $access_level = $this->createMockAccessLevelType('Virtual Access', 2); + + $this->formatter_update->setContext($this->audit_context); + $result = $this->formatter_update->format($access_level, [ + 'name' => ['In-Person Access', 'Virtual Access'], + 'description' => ['For in-person attendees', 'For virtual attendees'] + ]); + + $this->assertNotNull($result); + $this->assertStringContainsString("Virtual Access", $result); + $this->assertStringContainsString("(2)", $result); + $this->assertStringContainsString("updated", $result); + } + + public function testFormatDeletionEvent(): void + { + $access_level = $this->createMockAccessLevelType('Chat Access', 3); + + $this->formatter_deletion->setContext($this->audit_context); + $result = $this->formatter_deletion->format($access_level, []); + + $this->assertNotNull($result); + $this->assertStringContainsString("Chat Access", $result); + $this->assertStringContainsString("(3)", $result); + $this->assertStringContainsString("deleted", $result); + } + + public function testFormatInvalidSubject(): void + { + $invalid_subject = new \stdClass(); + + $result = $this->formatter_creation->format($invalid_subject, []); + + $this->assertNull($result); + } + + public function testFormatterHandlesEmptyChangeSet(): void + { + $access_level = $this->createMockAccessLevelType('Test Access', 5); + + $this->formatter_update->setContext($this->audit_context); + $result = $this->formatter_update->format($access_level, []); + + $this->assertNotNull($result); + $this->assertStringContainsString("Test Access", $result); + $this->assertStringContainsString("updated", $result); + } + + public function testPropertiesExist(): void + { + $access_level = $this->createMockAccessLevelType('Verify Access', 6); + + $this->formatter_creation->setContext($this->audit_context); + + $this->assertTrue(method_exists($access_level, 'getId')); + $this->assertTrue(method_exists($access_level, 'getName')); + $this->assertTrue(method_exists($access_level, 'getSummit')); + } + + private function createMockAccessLevelType(string $name, int $id): object + { + $mock = Mockery::mock(SummitAccessLevelType::class); + $mock->shouldReceive('getName')->andReturn($name); + $mock->shouldReceive('getId')->andReturn($id); + + $summit = Mockery::mock(\models\summit\Summit::class); + $summit->shouldReceive('getName')->andReturn(self::SUMMIT_NAME); + $mock->shouldReceive('getSummit')->andReturn($summit); + + return $mock; + } +} diff --git a/tests/OpenTelemetry/Formatters/SummitBadgeFeatureTypeAuditLogFormatterTest.php b/tests/OpenTelemetry/Formatters/SummitBadgeFeatureTypeAuditLogFormatterTest.php new file mode 100644 index 000000000..7cad39ecc --- /dev/null +++ b/tests/OpenTelemetry/Formatters/SummitBadgeFeatureTypeAuditLogFormatterTest.php @@ -0,0 +1,148 @@ +formatter_creation = new SummitBadgeFeatureTypeAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_CREATION); + $this->formatter_update = new SummitBadgeFeatureTypeAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_UPDATE); + $this->formatter_deletion = new SummitBadgeFeatureTypeAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_DELETION); + + $this->audit_context = new AuditContext( + userId: self::USER_ID, + userEmail: self::USER_EMAIL, + userFirstName: self::USER_FIRST_NAME, + userLastName: self::USER_LAST_NAME + ); + } + + protected function tearDown(): void + { + Mockery::close(); + parent::tearDown(); + } + + public function testFormatCreationEvent(): void + { + $badge_feature = $this->createMockBadgeFeatureType('VIP Badge Feature', 1); + + $this->formatter_creation->setContext($this->audit_context); + $result = $this->formatter_creation->format($badge_feature, []); + + $this->assertNotNull($result); + $this->assertStringContainsString("VIP Badge Feature", $result); + $this->assertStringContainsString("(1)", $result); + $this->assertStringContainsString("created", $result); + $this->assertStringContainsString("Test Summit", $result); + } + + public function testFormatUpdateEvent(): void + { + $badge_feature = $this->createMockBadgeFeatureType('Networking Feature', 2); + + $this->formatter_update->setContext($this->audit_context); + $result = $this->formatter_update->format($badge_feature, [ + 'name' => ['VIP Badge Feature', 'Networking Feature'], + 'description' => ['For VIP attendees', 'For networking participants'] + ]); + + $this->assertNotNull($result); + $this->assertStringContainsString("Networking Feature", $result); + $this->assertStringContainsString("(2)", $result); + $this->assertStringContainsString("updated", $result); + } + + public function testFormatDeletionEvent(): void + { + $badge_feature = $this->createMockBadgeFeatureType('Speaker Feature', 3); + + $this->formatter_deletion->setContext($this->audit_context); + $result = $this->formatter_deletion->format($badge_feature, []); + + $this->assertNotNull($result); + $this->assertStringContainsString("Speaker Feature", $result); + $this->assertStringContainsString("(3)", $result); + $this->assertStringContainsString("deleted", $result); + } + + public function testFormatInvalidSubject(): void + { + $invalid_subject = new \stdClass(); + + $result = $this->formatter_creation->format($invalid_subject, []); + + $this->assertNull($result); + } + + public function testFormatterHandlesEmptyChangeSet(): void + { + $badge_feature = $this->createMockBadgeFeatureType('Test Feature', 5); + + $this->formatter_update->setContext($this->audit_context); + $result = $this->formatter_update->format($badge_feature, []); + + $this->assertNotNull($result); + $this->assertStringContainsString("Test Feature", $result); + $this->assertStringContainsString("updated", $result); + } + + public function testPropertiesExist(): void + { + $badge_feature = $this->createMockBadgeFeatureType('Verify Feature', 6); + + $this->formatter_creation->setContext($this->audit_context); + + $this->assertTrue(method_exists($badge_feature, 'getId')); + $this->assertTrue(method_exists($badge_feature, 'getName')); + $this->assertTrue(method_exists($badge_feature, 'getSummit')); + } + + private function createMockBadgeFeatureType(string $name, int $id): object + { + $mock = Mockery::mock(SummitBadgeFeatureType::class); + $mock->shouldReceive('getName')->andReturn($name); + $mock->shouldReceive('getId')->andReturn($id); + + $summit = Mockery::mock(\models\summit\Summit::class); + $summit->shouldReceive('getName')->andReturn(self::SUMMIT_NAME); + $mock->shouldReceive('getSummit')->andReturn($summit); + + return $mock; + } +} diff --git a/tests/OpenTelemetry/Formatters/SummitBadgeTypeAuditLogFormatterTest.php b/tests/OpenTelemetry/Formatters/SummitBadgeTypeAuditLogFormatterTest.php new file mode 100644 index 000000000..65d5773d2 --- /dev/null +++ b/tests/OpenTelemetry/Formatters/SummitBadgeTypeAuditLogFormatterTest.php @@ -0,0 +1,149 @@ +formatter_creation = new SummitBadgeTypeAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_CREATION); + $this->formatter_update = new SummitBadgeTypeAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_UPDATE); + $this->formatter_deletion = new SummitBadgeTypeAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_DELETION); + + $this->audit_context = new AuditContext( + userId: self::USER_ID, + userEmail: self::USER_EMAIL, + userFirstName: self::USER_FIRST_NAME, + userLastName: self::USER_LAST_NAME + ); + } + + protected function tearDown(): void + { + Mockery::close(); + parent::tearDown(); + } + + public function testFormatCreationEvent(): void + { + $badge_type = $this->createMockBadgeType('Standard Badge Type', 1); + + $this->formatter_creation->setContext($this->audit_context); + $result = $this->formatter_creation->format($badge_type, []); + + $this->assertNotNull($result); + $this->assertStringContainsString("Standard Badge Type", $result); + $this->assertStringContainsString("(1)", $result); + $this->assertStringContainsString("created", $result); + $this->assertStringContainsString("Test Summit", $result); + } + + public function testFormatUpdateEvent(): void + { + $badge_type = $this->createMockBadgeType('Premium Badge Type', 2); + + $this->formatter_update->setContext($this->audit_context); + $result = $this->formatter_update->format($badge_type, [ + 'name' => ['Standard Badge Type', 'Premium Badge Type'], + 'description' => ['Standard badges', 'Premium badges'], + 'is_default' => [false, true] + ]); + + $this->assertNotNull($result); + $this->assertStringContainsString("Premium Badge Type", $result); + $this->assertStringContainsString("(2)", $result); + $this->assertStringContainsString("updated", $result); + } + + public function testFormatDeletionEvent(): void + { + $badge_type = $this->createMockBadgeType('Legacy Badge Type', 3); + + $this->formatter_deletion->setContext($this->audit_context); + $result = $this->formatter_deletion->format($badge_type, []); + + $this->assertNotNull($result); + $this->assertStringContainsString("Legacy Badge Type", $result); + $this->assertStringContainsString("(3)", $result); + $this->assertStringContainsString("deleted", $result); + } + + public function testFormatInvalidSubject(): void + { + $invalid_subject = new \stdClass(); + + $result = $this->formatter_creation->format($invalid_subject, []); + + $this->assertNull($result); + } + + public function testFormatterHandlesEmptyChangeSet(): void + { + $badge_type = $this->createMockBadgeType('Test Badge Type', 5); + + $this->formatter_update->setContext($this->audit_context); + $result = $this->formatter_update->format($badge_type, []); + + $this->assertNotNull($result); + $this->assertStringContainsString("Test Badge Type", $result); + $this->assertStringContainsString("updated", $result); + } + + public function testPropertiesExist(): void + { + $badge_type = $this->createMockBadgeType('Verify Badge Type', 6); + + $this->formatter_creation->setContext($this->audit_context); + + $this->assertTrue(method_exists($badge_type, 'getId')); + $this->assertTrue(method_exists($badge_type, 'getName')); + $this->assertTrue(method_exists($badge_type, 'getSummit')); + } + + private function createMockBadgeType(string $name, int $id): object + { + $mock = Mockery::mock(SummitBadgeType::class); + $mock->shouldReceive('getName')->andReturn($name); + $mock->shouldReceive('getId')->andReturn($id); + + $summit = Mockery::mock(\models\summit\Summit::class); + $summit->shouldReceive('getName')->andReturn(self::SUMMIT_NAME); + $mock->shouldReceive('getSummit')->andReturn($summit); + + return $mock; + } +} diff --git a/tests/OpenTelemetry/Formatters/SummitBadgeViewTypeAuditLogFormatterTest.php b/tests/OpenTelemetry/Formatters/SummitBadgeViewTypeAuditLogFormatterTest.php new file mode 100644 index 000000000..bf2bf876d --- /dev/null +++ b/tests/OpenTelemetry/Formatters/SummitBadgeViewTypeAuditLogFormatterTest.php @@ -0,0 +1,148 @@ +formatter_creation = new SummitBadgeViewTypeAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_CREATION); + $this->formatter_update = new SummitBadgeViewTypeAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_UPDATE); + $this->formatter_deletion = new SummitBadgeViewTypeAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_DELETION); + + $this->audit_context = new AuditContext( + userId: self::USER_ID, + userEmail: self::USER_EMAIL, + userFirstName: self::USER_FIRST_NAME, + userLastName: self::USER_LAST_NAME + ); + } + + protected function tearDown(): void + { + Mockery::close(); + parent::tearDown(); + } + + public function testFormatCreationEvent(): void + { + $badge_view = $this->createMockBadgeViewType('Standard Badge', 1); + + $this->formatter_creation->setContext($this->audit_context); + $result = $this->formatter_creation->format($badge_view, []); + + $this->assertNotNull($result); + $this->assertStringContainsString("Standard Badge", $result); + $this->assertStringContainsString("(1)", $result); + $this->assertStringContainsString("created", $result); + $this->assertStringContainsString("Test Summit", $result); + } + + public function testFormatUpdateEvent(): void + { + $badge_view = $this->createMockBadgeViewType('Premium Badge', 2); + + $this->formatter_update->setContext($this->audit_context); + $result = $this->formatter_update->format($badge_view, [ + 'name' => ['Standard Badge', 'Premium Badge'], + 'description' => ['Standard', 'Premium'] + ]); + + $this->assertNotNull($result); + $this->assertStringContainsString("Premium Badge", $result); + $this->assertStringContainsString("(2)", $result); + $this->assertStringContainsString("updated", $result); + } + + public function testFormatDeletionEvent(): void + { + $badge_view = $this->createMockBadgeViewType('Archived Badge', 3); + + $this->formatter_deletion->setContext($this->audit_context); + $result = $this->formatter_deletion->format($badge_view, []); + + $this->assertNotNull($result); + $this->assertStringContainsString("Archived Badge", $result); + $this->assertStringContainsString("(3)", $result); + $this->assertStringContainsString("deleted", $result); + } + + public function testFormatInvalidSubject(): void + { + $invalid_subject = new \stdClass(); + + $result = $this->formatter_creation->format($invalid_subject, []); + + $this->assertNull($result); + } + + public function testFormatterHandlesEmptyChangeSet(): void + { + $badge_view = $this->createMockBadgeViewType('Test Badge', 5); + + $this->formatter_update->setContext($this->audit_context); + $result = $this->formatter_update->format($badge_view, []); + + $this->assertNotNull($result); + $this->assertStringContainsString("Test Badge", $result); + $this->assertStringContainsString("updated", $result); + } + + public function testPropertiesExist(): void + { + $badge_view = $this->createMockBadgeViewType('Verify Badge', 6); + + $this->formatter_creation->setContext($this->audit_context); + + $this->assertTrue(method_exists($badge_view, 'getId')); + $this->assertTrue(method_exists($badge_view, 'getName')); + $this->assertTrue(method_exists($badge_view, 'getSummit')); + } + + private function createMockBadgeViewType(string $name, int $id): object + { + $mock = Mockery::mock(SummitBadgeViewType::class); + $mock->shouldReceive('getName')->andReturn($name); + $mock->shouldReceive('getId')->andReturn($id); + + $summit = Mockery::mock(\models\summit\Summit::class); + $summit->shouldReceive('getName')->andReturn(self::SUMMIT_NAME); + $mock->shouldReceive('getSummit')->andReturn($summit); + + return $mock; + } +}