diff --git a/dev/tests/unit/Magento/FunctionalTestFramework/Allure/AllureHelperTest.php b/dev/tests/unit/Magento/FunctionalTestFramework/Allure/AllureHelperTest.php index 048c6f7de..b7eafaead 100644 --- a/dev/tests/unit/Magento/FunctionalTestFramework/Allure/AllureHelperTest.php +++ b/dev/tests/unit/Magento/FunctionalTestFramework/Allure/AllureHelperTest.php @@ -6,6 +6,7 @@ namespace Tests\unit\Magento\FunctionalTestingFramework\Allure; use Magento\FunctionalTestingFramework\Allure\AllureHelper; +use Magento\FunctionalTestingFramework\Allure\Event\AddUniqueAttachmentEvent; use Yandex\Allure\Adapter\Allure; use Yandex\Allure\Adapter\Event\AddAttachmentEvent; use Yandex\Allure\Adapter\Event\StepFinishedEvent; @@ -24,6 +25,7 @@ class AllureHelperTest extends TestCase public function tearDown() { Allure::setDefaultLifecycle(); + AspectMock::clean(); } /** @@ -85,13 +87,48 @@ public function testAddAttachmentToLastStep() } /** - * Mock file system manipulation function + * AddAttachment actions should have files with different attachment names + * @throws \Yandex\Allure\Adapter\AllureException + */ + public function testAddAttachementUniqueName() + { + $this->mockCopyFile(); + $expectedData = "string"; + $expectedCaption = "caption"; + + //Prepare Allure lifecycle + Allure::lifecycle()->fire(new StepStartedEvent('firstStep')); + + //Call function twice + AllureHelper::addAttachmentToCurrentStep($expectedData, $expectedCaption); + AllureHelper::addAttachmentToCurrentStep($expectedData, $expectedCaption); + + // Assert file names for both attachments are not the same. + $step = Allure::lifecycle()->getStepStorage()->pollLast(); + $attachmentOne = $step->getAttachments()[0]->getSource(); + $attachmentTwo = $step->getAttachments()[1]->getSource(); + $this->assertNotEquals($attachmentOne, $attachmentTwo); + } + + /** + * Mock entire attachment writing mechanisms * @throws \Exception */ public function mockAttachmentWriteEvent() { - AspectMock::double(AddAttachmentEvent::class, [ + AspectMock::double(AddUniqueAttachmentEvent::class, [ "getAttachmentFileName" => self::MOCK_FILENAME ]); } + + /** + * Mock only file writing mechanism + * @throws \Exception + */ + public function mockCopyFile() + { + AspectMock::double(AddUniqueAttachmentEvent::class, [ + "copyFile" => true + ]); + } } diff --git a/src/Magento/FunctionalTestingFramework/Allure/AllureHelper.php b/src/Magento/FunctionalTestingFramework/Allure/AllureHelper.php index d8f1c63d8..e1d871781 100644 --- a/src/Magento/FunctionalTestingFramework/Allure/AllureHelper.php +++ b/src/Magento/FunctionalTestingFramework/Allure/AllureHelper.php @@ -5,6 +5,7 @@ */ namespace Magento\FunctionalTestingFramework\Allure; +use Magento\FunctionalTestingFramework\Allure\Event\AddUniqueAttachmentEvent; use Yandex\Allure\Adapter\Allure; use Yandex\Allure\Adapter\Event\AddAttachmentEvent; @@ -19,7 +20,7 @@ class AllureHelper */ public static function addAttachmentToCurrentStep($data, $caption) { - Allure::lifecycle()->fire(new AddAttachmentEvent($data, $caption)); + Allure::lifecycle()->fire(new AddUniqueAttachmentEvent($data, $caption)); } /** @@ -34,7 +35,7 @@ public static function addAttachmentToLastStep($data, $caption) $rootStep = Allure::lifecycle()->getStepStorage()->getLast(); $trueLastStep = array_last($rootStep->getSteps()); - $attachmentEvent = new AddAttachmentEvent($data, $caption); + $attachmentEvent = new AddUniqueAttachmentEvent($data, $caption); $attachmentEvent->process($trueLastStep); } } diff --git a/src/Magento/FunctionalTestingFramework/Allure/Event/AddUniqueAttachmentEvent.php b/src/Magento/FunctionalTestingFramework/Allure/Event/AddUniqueAttachmentEvent.php new file mode 100644 index 000000000..fc4ff64c2 --- /dev/null +++ b/src/Magento/FunctionalTestingFramework/Allure/Event/AddUniqueAttachmentEvent.php @@ -0,0 +1,107 @@ +guessFileMimeType($filePath); + $this->type = $type; + } + + $fileExtension = $this->guessFileExtension($type); + + $fileSha1 = uniqid(sha1_file($filePath)); + $outputPath = parent::getOutputPath($fileSha1, $fileExtension); + if (!$this->copyFile($filePath, $outputPath)) { + throw new AllureException("Failed to copy attachment from $filePath to $outputPath."); + } + + return $this->getOutputFileName($fileSha1, $fileExtension); + } + + /** + * Copies file from one path to another. Wrapper for mocking in unit test. + * @param string $filePath + * @param string $outputPath + * @return boolean + */ + private function copyFile($filePath, $outputPath) + { + return copy($filePath, $outputPath); + } + + /** + * Copy of parent private function + * @param string $filePath + * @return string + */ + private function guessFileMimeType($filePath) + { + $type = MimeTypeGuesser::getInstance()->guess($filePath); + if (!isset($type)) { + return DEFAULT_MIME_TYPE; + } + return $type; + } + + /** + * Copy of parent private function + * @param string $mimeType + * @return string + */ + private function guessFileExtension($mimeType) + { + $candidate = ExtensionGuesser::getInstance()->guess($mimeType); + if (!isset($candidate)) { + return DEFAULT_FILE_EXTENSION; + } + return $candidate; + } + + /** + * Copy of parent private function + * @param string $sha1 + * @param string $extension + * @return string + */ + public function getOutputFileName($sha1, $extension) + { + return $sha1 . '-attachment.' . $extension; + } +} diff --git a/src/Magento/FunctionalTestingFramework/DataGenerator/Persist/CurlHandler.php b/src/Magento/FunctionalTestingFramework/DataGenerator/Persist/CurlHandler.php index 691ce3606..16584e7a3 100644 --- a/src/Magento/FunctionalTestingFramework/DataGenerator/Persist/CurlHandler.php +++ b/src/Magento/FunctionalTestingFramework/DataGenerator/Persist/CurlHandler.php @@ -123,6 +123,8 @@ public function executeRequest($dependentEntities) $returnRegex = $this->operationDefinition->getReturnRegex(); $returnIndex = $this->operationDefinition->getReturnIndex(); $method = $this->operationDefinition->getApiMethod(); + AllureHelper::addAttachmentToLastStep($apiUrl, 'API Endpoint'); + AllureHelper::addAttachmentToLastStep(json_encode($headers, JSON_PRETTY_PRINT), 'Request Headers'); $operationDataResolver = new OperationDataArrayResolver($dependentEntities); $this->requestData = $operationDataResolver->resolveOperationDataArray(