-
Notifications
You must be signed in to change notification settings - Fork 9.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactored Source For ImportExport module, related to #7469 #9480
Refactored Source For ImportExport module, related to #7469 #9480
Conversation
…CSV parser implementation
…bjectManager for test harness
…entations as depracated
…ort-empty-row-support
Hey IvanChepurnyi, thanks for incorporating the fix for my reported issue. Just wanted to let you know in case you might run into a similiar problem |
@koenner01 did you checked it with "null" option passed into CSV Parser Factory and then used this as an empty value for a special price? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My main concerns for this Pull Request:
- Incorrect following of Backward Compatibility policies (new Interfaces should be added independently to legacy code). No need to mix up legacy and new implementation in one class.
- Not proper work with Exceptions. Sometimes Exceptions substituted with FALSE value and vice versa.
- Not proper Object design for factories and parser instantiation
- Re-implemented some core functions responsible for work with filesystem
- Lot of public getters are introduced just for testing purposes (violating object encapsulation)
- All existing Unit tests are actually Integration ones, in terms of Magento 2
* @param $data | ||
* @return array | ||
*/ | ||
protected function getSourceAdapterOptions($data) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we don't recommend to use Inheritance Based API, so all the methods should be whether public or private
* | ||
* @return array | ||
*/ | ||
protected function getSourceAdapterOptions() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we don't recommend to use Inheritance Based API, so all the methods should be whether public or private
/** @var FileFactory */ | ||
private $fileSourceFactory; | ||
|
||
public function __construct(FileFactory $fileSourceFactory) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
doc block absent for this constructor
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you see as a comment for a constructor?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DocBlock is not just comment, but specification of all input types.
@@ -25,29 +38,12 @@ class Adapter | |||
* @return AbstractSource | |||
* | |||
* @throws \Magento\Framework\Exception\LocalizedException | |||
* @deprecated | |||
* @see Adapter::createSourceByPath() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's better to avoid mixing up Deprecated logic and Newly created one in one class.
Thus, we recommend to introduce new Factory entity and mark it with @ api.
Current class to mark as @ deprecated.
Inject newly created factory as DI injection to Adapter class.
And make current class to proxy calls to newly created API
/** @var FileFactory */ | ||
private $fileSourceFactory; | ||
|
||
public function __construct(FileFactory $fileSourceFactory) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Violation of BC policies, all the parameters should be optional (nullable)
$fileFactory->createFromFilePath('test.csv'); | ||
} | ||
|
||
public function testGivenParserFactoryConfiguredWhenSourceIsCreatedByPathThenRightInstanceIsCreated() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's not so easy to read this method name.
It's like 10 years ago when SMS cost a lot, you try to save space (140 symbols) for text not using spaces at all.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Method name looks like this because "_" are prohibited by Magento code style guideline. Previous versions had "_" as space.
use Magento\ImportExport\Model\Import\Source\FileParser\ParserFactoryInterface; | ||
use Magento\ImportExport\Model\Import\Source\FileParser\UnsupportedPathException; | ||
|
||
class FakeParserFactory implements ParserFactoryInterface |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have so many Fake objects here, and we need to update their code updating code of the real objects as well
Currently, we don't use this approach for Unit testing. And definitely it needs separate approval from AC
Because for now we introduced additional entities to maintain. But why do we need that if we already have Integration tests?
@@ -0,0 +1 @@ | |||
column1|;column2;|column3 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do we need to use CSV files for Unit testing?
Integration tests are made for these purposes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are no component level integration tests in Magento 2 repository and the one you are referring to requires to work with real database and other components enabled. However, this test case is quite isolated and does not leave any side effects visible to other test cases. Unit scope for this one is parsing a ZIP file, but integration test is more about testing integration of components versus just I/O operation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would love to get an advice how to overcome a problem of running fast "integration" test witout bootstrapping all database and other components.
namespace Magento\ImportExport\Model\Import\Source\FileParser; | ||
|
||
/** | ||
* File Parser Composite |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should be marked as @ api , because used as an Extension Point
$resolvedArguments[] = $arguments[$parameter->getName()] ?? $parameter->getDefaultValue(); | ||
} | ||
|
||
return $resolvedArguments; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
when we provide an implementation of Fake objects, who and how will test this implementation?
For example, current function is 10 lines of code. How can we make sure that this code is safe to rely upon?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will add a test case for it, and also probably move it into framework, as FakeObjectManager must be available for other factory instantiation in the test harness as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My main concerns for this Pull Request:
- Violation of Backward compatibility policies. No need to mix up the legacy (deprecated) code with newly created APIs. It's better to segregate classes.
- There are many public getters added just for testing purposes and not used in code of business logic (violation of object encapsulation)
- Not proper work with exceptions. Some of the exceptions are substituted with FALSE, and vice versa
- Not proper Object Oriented design for ParserFactory instantiation
- Some core functions for working with Filesystem are re-implemented on PHP level. Which is incorrect
- All Unit tests looks like Integration tests in terms of Magento 2
- Lot of Fake objects are introduced. These fake objects contain business logic, which is not covered with any kind of test. These fake objects should be also maintained in future
@IvanChepurnyi @maghamed |
@IvanChepurnyi @maghamed I am closing this PR for now due to inactivity. Please reopen if you wish to continue work on it. |
Hi @IvanChepurnyi, we are talking about this PR in the Magento2 Slack Channel. Is it possible to join this channel and join the channel #import_export. Thanks! |
Description
The following pull request provides a refactored Import/Export source file parsing.
These are the major new features of this pull requests:
\Magento\ImportExport\Model\Import\Source\FileParser\ParserInterface
\Magento\ImportExport\Model\Import\Source\FileParser\ParserFactoryInterface
and add it to\Magento\ImportExport\Model\Import\Source\FileParser\CompositeParserFactory
as an argument indi.xml
Fixed Issues
#7468: CatalogImportExport doesn't support empty row values
* Added possiblity to specify "null" option for CsvParser, but this option must be passed into file creation factory
* Added extension points
\Magento\ImportExport\Controller\Adminhtml\Import\Validate::getSourceAdapterOptions()
and to\Magento\ImportExport\Model\Import::getSourceAdapterOptions()
for override by thirdparty, as it is not yet possible to completely replace current creation logic without breaking code that is not covered with tests.Manual testing scenarios
Contribution checklist