From 43f17a37b57c4001d79f3b07854a12c663c53ee0 Mon Sep 17 00:00:00 2001 From: Jose Andres Tejerina Date: Tue, 10 Feb 2026 16:07:06 -0300 Subject: [PATCH] feat: add new formatters for PurchaseOrders --- ...xtraQuestionTypeValueAuditLogFormatter.php | 52 ++++++++ .../SummitOrderAuditLogFormatter.php | 55 ++++++++ ...rderExtraQuestionTypeAuditLogFormatter.php | 53 ++++++++ config/audit_log.php | 12 ++ ...QuestionTypeValueAuditLogFormatterTest.php | 99 +++++++++++++++ ...mmitAttendeeBadgeAuditLogFormatterTest.php | 105 ++++++++++++++++ ...ummitAttendeeNoteAuditLogFormatterTest.php | 103 +++++++++++++++ ...mitAttendeeTicketAuditLogFormatterTest.php | 118 ++++++++++++++++++ .../SummitOrderAuditLogFormatterTest.php | 105 ++++++++++++++++ ...ExtraQuestionTypeAuditLogFormatterTest.php | 100 +++++++++++++++ 10 files changed, 802 insertions(+) create mode 100644 app/Audit/ConcreteFormatters/ExtraQuestionTypeValueAuditLogFormatter.php create mode 100644 app/Audit/ConcreteFormatters/SummitOrderAuditLogFormatter.php create mode 100644 app/Audit/ConcreteFormatters/SummitOrderExtraQuestionTypeAuditLogFormatter.php create mode 100644 tests/OpenTelemetry/Formatters/ExtraQuestionTypeValueAuditLogFormatterTest.php create mode 100644 tests/OpenTelemetry/Formatters/SummitAttendeeBadgeAuditLogFormatterTest.php create mode 100644 tests/OpenTelemetry/Formatters/SummitAttendeeNoteAuditLogFormatterTest.php create mode 100644 tests/OpenTelemetry/Formatters/SummitAttendeeTicketAuditLogFormatterTest.php create mode 100644 tests/OpenTelemetry/Formatters/SummitOrderAuditLogFormatterTest.php create mode 100644 tests/OpenTelemetry/Formatters/SummitOrderExtraQuestionTypeAuditLogFormatterTest.php diff --git a/app/Audit/ConcreteFormatters/ExtraQuestionTypeValueAuditLogFormatter.php b/app/Audit/ConcreteFormatters/ExtraQuestionTypeValueAuditLogFormatter.php new file mode 100644 index 000000000..20db9203a --- /dev/null +++ b/app/Audit/ConcreteFormatters/ExtraQuestionTypeValueAuditLogFormatter.php @@ -0,0 +1,52 @@ +getId() ?? 'unknown'; + $label = $subject->getLabel() ?? 'Unknown Value'; + $question = $subject->getQuestion(); + $question_label = $question ? ($question->getLabel() ?? 'Unknown Question') : 'Unknown Question'; + + switch ($this->event_type) { + case IAuditStrategy::EVENT_ENTITY_CREATION: + return sprintf("Extra Question Value '%s' (%s) for Question '%s' created by user %s", $label, $id, $question_label, $this->getUserInfo()); + case IAuditStrategy::EVENT_ENTITY_UPDATE: + $details = $this->buildChangeDetails($change_set); + return sprintf("Extra Question Value '%s' (%s) for Question '%s' updated: %s by user %s", $label, $id, $question_label, $details, $this->getUserInfo()); + case IAuditStrategy::EVENT_ENTITY_DELETION: + return sprintf("Extra Question Value '%s' (%s) for Question '%s' deleted by user %s", $label, $id, $question_label, $this->getUserInfo()); + } + } catch (\Exception $ex) { + Log::warning("ExtraQuestionTypeValueAuditLogFormatter error: " . $ex->getMessage()); + } + + return null; + } +} diff --git a/app/Audit/ConcreteFormatters/SummitOrderAuditLogFormatter.php b/app/Audit/ConcreteFormatters/SummitOrderAuditLogFormatter.php new file mode 100644 index 000000000..0640a3489 --- /dev/null +++ b/app/Audit/ConcreteFormatters/SummitOrderAuditLogFormatter.php @@ -0,0 +1,55 @@ +getId() ?? 'unknown'; + $order_number = $subject->getNumber() ?? 'Unknown Order'; + $status = $subject->getStatus() ?? 'Unknown'; + $summit = $subject->getSummit(); + $summit_name = $summit ? ($summit->getName() ?? 'Unknown Summit') : 'Unknown Summit'; + $owner = $subject->getOwner(); + $owner_email = $owner ? ($owner->getEmail() ?? 'Unknown Owner') : 'No Owner'; + + switch ($this->event_type) { + case IAuditStrategy::EVENT_ENTITY_CREATION: + return sprintf("Order '%s' (%s) created for '%s' in Summit '%s' with status '%s' by user %s", $order_number, $id, $owner_email, $summit_name, $status, $this->getUserInfo()); + case IAuditStrategy::EVENT_ENTITY_UPDATE: + $details = $this->buildChangeDetails($change_set); + return sprintf("Order '%s' (%s) in Summit '%s' updated: %s by user %s", $order_number, $id, $summit_name, $details, $this->getUserInfo()); + case IAuditStrategy::EVENT_ENTITY_DELETION: + return sprintf("Order '%s' (%s) in Summit '%s' deleted by user %s", $order_number, $id, $summit_name, $this->getUserInfo()); + } + } catch (\Exception $ex) { + Log::warning("SummitOrderAuditLogFormatter error: " . $ex->getMessage()); + } + + return null; + } +} diff --git a/app/Audit/ConcreteFormatters/SummitOrderExtraQuestionTypeAuditLogFormatter.php b/app/Audit/ConcreteFormatters/SummitOrderExtraQuestionTypeAuditLogFormatter.php new file mode 100644 index 000000000..fa3d22aa3 --- /dev/null +++ b/app/Audit/ConcreteFormatters/SummitOrderExtraQuestionTypeAuditLogFormatter.php @@ -0,0 +1,53 @@ +getId() ?? 'unknown'; + $label = $subject->getLabel() ?? 'Unknown Question'; + $question_type = $subject->getType() ?? 'Unknown Type'; + $summit = $subject->getSummit(); + $summit_name = $summit ? ($summit->getName() ?? 'Unknown Summit') : 'Unknown Summit'; + + switch ($this->event_type) { + case IAuditStrategy::EVENT_ENTITY_CREATION: + return sprintf("Order Extra Question '%s' (%s) of type '%s' created in Summit '%s' by user %s", $label, $id, $question_type, $summit_name, $this->getUserInfo()); + case IAuditStrategy::EVENT_ENTITY_UPDATE: + $details = $this->buildChangeDetails($change_set); + return sprintf("Order Extra Question '%s' (%s) in Summit '%s' updated: %s by user %s", $label, $id, $summit_name, $details, $this->getUserInfo()); + case IAuditStrategy::EVENT_ENTITY_DELETION: + return sprintf("Order Extra Question '%s' (%s) in Summit '%s' deleted by user %s", $label, $id, $summit_name, $this->getUserInfo()); + } + } catch (\Exception $ex) { + Log::warning("SummitOrderExtraQuestionTypeAuditLogFormatter error: " . $ex->getMessage()); + } + + return null; + } +} diff --git a/config/audit_log.php b/config/audit_log.php index cd204dd5e..2e416a283 100644 --- a/config/audit_log.php +++ b/config/audit_log.php @@ -228,5 +228,17 @@ 'enabled' => true, 'strategy' => \App\Audit\ConcreteFormatters\PresentationAttendeeVoteAuditLogFormatter::class, ], + \models\summit\SummitOrder::class => [ + 'enabled' => true, + 'strategy' => \App\Audit\ConcreteFormatters\SummitOrderAuditLogFormatter::class, + ], + \models\summit\SummitOrderExtraQuestionType::class => [ + 'enabled' => true, + 'strategy' => \App\Audit\ConcreteFormatters\SummitOrderExtraQuestionTypeAuditLogFormatter::class, + ], + \App\Models\Foundation\ExtraQuestions\ExtraQuestionTypeValue::class => [ + 'enabled' => true, + 'strategy' => \App\Audit\ConcreteFormatters\ExtraQuestionTypeValueAuditLogFormatter::class, + ], ] ]; diff --git a/tests/OpenTelemetry/Formatters/ExtraQuestionTypeValueAuditLogFormatterTest.php b/tests/OpenTelemetry/Formatters/ExtraQuestionTypeValueAuditLogFormatterTest.php new file mode 100644 index 000000000..23e2e671e --- /dev/null +++ b/tests/OpenTelemetry/Formatters/ExtraQuestionTypeValueAuditLogFormatterTest.php @@ -0,0 +1,99 @@ +mockSubject = $this->createMockSubject(); + } + + protected function tearDown(): void + { + Mockery::close(); + parent::tearDown(); + } + + private function createMockSubject(): mixed + { + $mockQuestion = Mockery::mock('App\Models\Foundation\ExtraQuestions\ExtraQuestionType'); + $mockQuestion->shouldReceive('getLabel')->andReturn(self::QUESTION_LABEL); + + $mock = Mockery::mock('App\Models\Foundation\ExtraQuestions\ExtraQuestionTypeValue'); + $mock->shouldReceive('getId')->andReturn(self::VALUE_ID); + $mock->shouldReceive('getLabel')->andReturn(self::VALUE_LABEL); + $mock->shouldReceive('getValue')->andReturn(self::VALUE_VALUE); + $mock->shouldReceive('getQuestion')->andReturn($mockQuestion); + + return $mock; + } + + public function testSubjectCreationAuditMessage(): void + { + $formatter = new ExtraQuestionTypeValueAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_CREATION); + $formatter->setContext(AuditContextBuilder::default()->build()); + $result = $formatter->format($this->mockSubject, []); + + $this->assertNotNull($result); + $this->assertStringContainsString('created', $result); + $this->assertStringContainsString(self::VALUE_LABEL, $result); + $this->assertStringContainsString((string)self::VALUE_ID, $result); + } + + public function testSubjectUpdateAuditMessage(): void + { + $formatter = new ExtraQuestionTypeValueAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_UPDATE); + $formatter->setContext(AuditContextBuilder::default()->build()); + $changeSet = ['label' => [self::VALUE_LABEL, self::CHANGED_LABEL]]; + + $result = $formatter->format($this->mockSubject, $changeSet); + + $this->assertNotNull($result); + $this->assertStringContainsString('updated', $result); + } + + public function testSubjectDeletionAuditMessage(): void + { + $formatter = new ExtraQuestionTypeValueAuditLogFormatter(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 ExtraQuestionTypeValueAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_CREATION); + $formatter->setContext(AuditContextBuilder::default()->build()); + $result = $formatter->format(new \stdClass(), []); + + $this->assertNull($result); + } + + public function testFormatterHandlesEmptyChangeSet(): void + { + $formatter = new ExtraQuestionTypeValueAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_UPDATE); + $formatter->setContext(AuditContextBuilder::default()->build()); + $result = $formatter->format($this->mockSubject, []); + + $this->assertNotNull($result); + $this->assertStringContainsString('updated', $result); + } +} diff --git a/tests/OpenTelemetry/Formatters/SummitAttendeeBadgeAuditLogFormatterTest.php b/tests/OpenTelemetry/Formatters/SummitAttendeeBadgeAuditLogFormatterTest.php new file mode 100644 index 000000000..553845c36 --- /dev/null +++ b/tests/OpenTelemetry/Formatters/SummitAttendeeBadgeAuditLogFormatterTest.php @@ -0,0 +1,105 @@ +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(self::SUMMIT_NAME); + + $mockOrder = Mockery::mock('models\summit\SummitOrder'); + $mockOrder->shouldReceive('getSummit')->andReturn($mockSummit); + + $mockTicket = Mockery::mock('models\summit\SummitAttendeeTicket'); + $mockTicket->shouldReceive('getId')->andReturn(self::TICKET_ID); + $mockTicket->shouldReceive('getNumber')->andReturn(self::TICKET_NUMBER); + $mockTicket->shouldReceive('getOrder')->andReturn($mockOrder); + + $mock = Mockery::mock('models\summit\SummitAttendeeBadge'); + $mock->shouldReceive('getId')->andReturn(self::BADGE_ID); + $mock->shouldReceive('isVoid')->andReturn(false); + $mock->shouldReceive('getTicket')->andReturn($mockTicket); + + return $mock; + } + + public function testSubjectCreationAuditMessage(): void + { + $formatter = new SummitAttendeeBadgeAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_CREATION); + $formatter->setContext(AuditContextBuilder::default()->build()); + $result = $formatter->format($this->mockSubject, []); + + $this->assertNotNull($result); + $this->assertStringContainsString('created', $result); + $this->assertStringContainsString(self::TICKET_NUMBER, $result); + $this->assertStringContainsString((string)self::TICKET_ID, $result); + } + + public function testSubjectUpdateAuditMessage(): void + { + $formatter = new SummitAttendeeBadgeAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_UPDATE); + $formatter->setContext(AuditContextBuilder::default()->build()); + $changeSet = ['is_void' => [false, true]]; + + $result = $formatter->format($this->mockSubject, $changeSet); + + $this->assertNotNull($result); + $this->assertStringContainsString('updated', $result); + } + + public function testSubjectDeletionAuditMessage(): void + { + $formatter = new SummitAttendeeBadgeAuditLogFormatter(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 SummitAttendeeBadgeAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_CREATION); + $formatter->setContext(AuditContextBuilder::default()->build()); + $result = $formatter->format(new \stdClass(), []); + + $this->assertNull($result); + } + + public function testFormatterHandlesEmptyChangeSet(): void + { + $formatter = new SummitAttendeeBadgeAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_UPDATE); + $formatter->setContext(AuditContextBuilder::default()->build()); + $result = $formatter->format($this->mockSubject, []); + + $this->assertNotNull($result); + $this->assertStringContainsString('updated', $result); + } +} diff --git a/tests/OpenTelemetry/Formatters/SummitAttendeeNoteAuditLogFormatterTest.php b/tests/OpenTelemetry/Formatters/SummitAttendeeNoteAuditLogFormatterTest.php new file mode 100644 index 000000000..a00196d02 --- /dev/null +++ b/tests/OpenTelemetry/Formatters/SummitAttendeeNoteAuditLogFormatterTest.php @@ -0,0 +1,103 @@ +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(self::SUMMIT_NAME); + + $mockAttendee = Mockery::mock('models\summit\SummitAttendee'); + $mockAttendee->shouldReceive('getId')->andReturn(self::ATTENDEE_ID); + $mockAttendee->shouldReceive('getEmail')->andReturn(self::ATTENDEE_EMAIL); + $mockAttendee->shouldReceive('getSummit')->andReturn($mockSummit); + + $mock = Mockery::mock('models\summit\SummitAttendeeNote'); + $mock->shouldReceive('getId')->andReturn(self::NOTE_ID); + $mock->shouldReceive('getContent')->andReturn(self::NOTE_CONTENT); + $mock->shouldReceive('getOwner')->andReturn($mockAttendee); + + return $mock; + } + + public function testSubjectCreationAuditMessage(): void + { + $formatter = new SummitAttendeeNoteAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_CREATION); + $formatter->setContext(AuditContextBuilder::default()->build()); + $result = $formatter->format($this->mockSubject, []); + + $this->assertNotNull($result); + $this->assertStringContainsString('created', $result); + $this->assertStringContainsString(self::ATTENDEE_EMAIL, $result); + $this->assertStringContainsString((string)self::ATTENDEE_ID, $result); + } + + public function testSubjectUpdateAuditMessage(): void + { + $formatter = new SummitAttendeeNoteAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_UPDATE); + $formatter->setContext(AuditContextBuilder::default()->build()); + $changeSet = ['content' => ['Old content', 'New content']]; + + $result = $formatter->format($this->mockSubject, $changeSet); + + $this->assertNotNull($result); + $this->assertStringContainsString('updated', $result); + } + + public function testSubjectDeletionAuditMessage(): void + { + $formatter = new SummitAttendeeNoteAuditLogFormatter(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 SummitAttendeeNoteAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_CREATION); + $formatter->setContext(AuditContextBuilder::default()->build()); + $result = $formatter->format(new \stdClass(), []); + + $this->assertNull($result); + } + + public function testFormatterHandlesEmptyChangeSet(): void + { + $formatter = new SummitAttendeeNoteAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_UPDATE); + $formatter->setContext(AuditContextBuilder::default()->build()); + $result = $formatter->format($this->mockSubject, []); + + $this->assertNotNull($result); + $this->assertStringContainsString('updated', $result); + } +} diff --git a/tests/OpenTelemetry/Formatters/SummitAttendeeTicketAuditLogFormatterTest.php b/tests/OpenTelemetry/Formatters/SummitAttendeeTicketAuditLogFormatterTest.php new file mode 100644 index 000000000..30b634f74 --- /dev/null +++ b/tests/OpenTelemetry/Formatters/SummitAttendeeTicketAuditLogFormatterTest.php @@ -0,0 +1,118 @@ +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(self::SUMMIT_NAME); + + $mockOwner = Mockery::mock('models\main\Member'); + $mockOwner->shouldReceive('getEmail')->andReturn(self::OWNER_EMAIL); + + $mockOrder = Mockery::mock('models\summit\SummitOrder'); + $mockOrder->shouldReceive('getId')->andReturn(self::ORDER_ID); + $mockOrder->shouldReceive('getNumber')->andReturn(self::ORDER_NUMBER); + $mockOrder->shouldReceive('getSummit')->andReturn($mockSummit); + $mockOrder->shouldReceive('getOwner')->andReturn($mockOwner); + + $mockTicketType = Mockery::mock('models\summit\SummitTicketType'); + $mockTicketType->shouldReceive('getName')->andReturn(self::TICKET_TYPE); + + $mock = Mockery::mock('models\summit\SummitAttendeeTicket'); + $mock->shouldReceive('getId')->andReturn(self::TICKET_ID); + $mock->shouldReceive('getNumber')->andReturn(self::TICKET_NUMBER); + $mock->shouldReceive('getOrder')->andReturn($mockOrder); + $mock->shouldReceive('getTicketType')->andReturn($mockTicketType); + $mock->shouldReceive('getStatus')->andReturn(self::TICKET_STATUS); + + return $mock; + } + + public function testSubjectCreationAuditMessage(): void + { + $formatter = new SummitAttendeeTicketAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_CREATION); + $formatter->setContext(AuditContextBuilder::default()->build()); + $result = $formatter->format($this->mockSubject, []); + + $this->assertNotNull($result); + $this->assertStringContainsString('created', $result); + $this->assertStringContainsString(self::TICKET_NUMBER, $result); + $this->assertStringContainsString((string)self::TICKET_ID, $result); + $this->assertStringContainsString(self::TICKET_TYPE, $result); + $this->assertStringContainsString(self::ORDER_NUMBER, $result); + } + + public function testSubjectUpdateAuditMessage(): void + { + $formatter = new SummitAttendeeTicketAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_UPDATE); + $formatter->setContext(AuditContextBuilder::default()->build()); + $changeSet = ['status' => [self::TICKET_STATUS, self::NEW_STATUS]]; + + $result = $formatter->format($this->mockSubject, $changeSet); + + $this->assertNotNull($result); + $this->assertStringContainsString('updated', $result); + } + + public function testSubjectDeletionAuditMessage(): void + { + $formatter = new SummitAttendeeTicketAuditLogFormatter(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 SummitAttendeeTicketAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_CREATION); + $formatter->setContext(AuditContextBuilder::default()->build()); + $result = $formatter->format(new \stdClass(), []); + + $this->assertNull($result); + } + + public function testFormatterHandlesEmptyChangeSet(): void + { + $formatter = new SummitAttendeeTicketAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_UPDATE); + $formatter->setContext(AuditContextBuilder::default()->build()); + $result = $formatter->format($this->mockSubject, []); + + $this->assertNotNull($result); + $this->assertStringContainsString('updated', $result); + } +} diff --git a/tests/OpenTelemetry/Formatters/SummitOrderAuditLogFormatterTest.php b/tests/OpenTelemetry/Formatters/SummitOrderAuditLogFormatterTest.php new file mode 100644 index 000000000..139bd4598 --- /dev/null +++ b/tests/OpenTelemetry/Formatters/SummitOrderAuditLogFormatterTest.php @@ -0,0 +1,105 @@ +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(self::SUMMIT_NAME); + + $mockOwner = Mockery::mock('models\main\Member'); + $mockOwner->shouldReceive('getEmail')->andReturn(self::OWNER_EMAIL); + + $mock = Mockery::mock('models\summit\SummitOrder'); + $mock->shouldReceive('getId')->andReturn(self::ORDER_ID); + $mock->shouldReceive('getNumber')->andReturn(self::ORDER_NUMBER); + $mock->shouldReceive('getStatus')->andReturn(self::ORDER_STATUS); + $mock->shouldReceive('getSummit')->andReturn($mockSummit); + $mock->shouldReceive('getOwner')->andReturn($mockOwner); + + return $mock; + } + + public function testSubjectCreationAuditMessage(): void + { + $formatter = new SummitOrderAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_CREATION); + $formatter->setContext(AuditContextBuilder::default()->build()); + $result = $formatter->format($this->mockSubject, []); + + $this->assertNotNull($result); + $this->assertStringContainsString('created', $result); + $this->assertStringContainsString(self::ORDER_NUMBER, $result); + $this->assertStringContainsString((string)self::ORDER_ID, $result); + $this->assertStringContainsString(self::ORDER_STATUS, $result); + } + + public function testSubjectUpdateAuditMessage(): void + { + $formatter = new SummitOrderAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_UPDATE); + $formatter->setContext(AuditContextBuilder::default()->build()); + $changeSet = ['status' => [self::ORDER_STATUS, self::NEW_STATUS]]; + + $result = $formatter->format($this->mockSubject, $changeSet); + + $this->assertNotNull($result); + $this->assertStringContainsString('updated', $result); + } + + public function testSubjectDeletionAuditMessage(): void + { + $formatter = new SummitOrderAuditLogFormatter(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 SummitOrderAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_CREATION); + $formatter->setContext(AuditContextBuilder::default()->build()); + $result = $formatter->format(new \stdClass(), []); + + $this->assertNull($result); + } + + public function testFormatterHandlesEmptyChangeSet(): void + { + $formatter = new SummitOrderAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_UPDATE); + $formatter->setContext(AuditContextBuilder::default()->build()); + $result = $formatter->format($this->mockSubject, []); + + $this->assertNotNull($result); + $this->assertStringContainsString('updated', $result); + } +} diff --git a/tests/OpenTelemetry/Formatters/SummitOrderExtraQuestionTypeAuditLogFormatterTest.php b/tests/OpenTelemetry/Formatters/SummitOrderExtraQuestionTypeAuditLogFormatterTest.php new file mode 100644 index 000000000..c5ba74a4b --- /dev/null +++ b/tests/OpenTelemetry/Formatters/SummitOrderExtraQuestionTypeAuditLogFormatterTest.php @@ -0,0 +1,100 @@ +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(self::SUMMIT_NAME); + + $mock = Mockery::mock('models\summit\SummitOrderExtraQuestionType'); + $mock->shouldReceive('getId')->andReturn(self::QUESTION_ID); + $mock->shouldReceive('getLabel')->andReturn(self::QUESTION_LABEL); + $mock->shouldReceive('getType')->andReturn(self::QUESTION_TYPE); + $mock->shouldReceive('getSummit')->andReturn($mockSummit); + + return $mock; + } + + public function testSubjectCreationAuditMessage(): void + { + $formatter = new SummitOrderExtraQuestionTypeAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_CREATION); + $formatter->setContext(AuditContextBuilder::default()->build()); + $result = $formatter->format($this->mockSubject, []); + + $this->assertNotNull($result); + $this->assertStringContainsString('created', $result); + $this->assertStringContainsString(self::QUESTION_LABEL, $result); + $this->assertStringContainsString((string)self::QUESTION_ID, $result); + $this->assertStringContainsString(self::QUESTION_TYPE, $result); + } + + public function testSubjectUpdateAuditMessage(): void + { + $formatter = new SummitOrderExtraQuestionTypeAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_UPDATE); + $formatter->setContext(AuditContextBuilder::default()->build()); + $changeSet = ['label' => [self::QUESTION_LABEL, self::NEW_LABEL]]; + + $result = $formatter->format($this->mockSubject, $changeSet); + + $this->assertNotNull($result); + $this->assertStringContainsString('updated', $result); + } + + public function testSubjectDeletionAuditMessage(): void + { + $formatter = new SummitOrderExtraQuestionTypeAuditLogFormatter(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 SummitOrderExtraQuestionTypeAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_CREATION); + $formatter->setContext(AuditContextBuilder::default()->build()); + $result = $formatter->format(new \stdClass(), []); + + $this->assertNull($result); + } + + public function testFormatterHandlesEmptyChangeSet(): void + { + $formatter = new SummitOrderExtraQuestionTypeAuditLogFormatter(IAuditStrategy::EVENT_ENTITY_UPDATE); + $formatter->setContext(AuditContextBuilder::default()->build()); + $result = $formatter->format($this->mockSubject, []); + + $this->assertNotNull($result); + $this->assertStringContainsString('updated', $result); + } +}