Skip to content
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

Refactor createTemplateService and add a few automated tests #507

Merged
merged 7 commits into from
Sep 15, 2021

Conversation

anarute
Copy link
Member

@anarute anarute commented Aug 24, 2021

This PR should be read as a proposal for a bigger architectural refactor.

Since I need to work on a big feature, I really want us to cover the project with automated tests but to achieve this goal we need to do some refactoring.

I used the createTemplateService as the first gnea pig since I have worked a bit with it and it is a bit independent.

I'm still not 100% happy with the name TemplateService and even if it should be inside the services folder, but for now maybe it's enough.

My idea is to slowly try to apply DDD in the project, but I want to be conservative for now to avoid breaking things by mistake.

In summary in this PR:

  • Remove the test folder and all the existing tests (they didn't seem to be testing anything really)
  • Refactor createTemplatesService to call a new class TemplateService that tries to break down a bit how we are parsing the template creation request
  • Add 2 initial tests to test the TemplateService class
  • Introduce namespace to the projects (I'm still learning so I know it can be better hehe )

@jaragunde
Copy link
Member

Hi Ana, thanks for this hard work. I need to set aside some time to go through your proposal, but I have one comment.

Could the new autoload setup be used to simplify the usage of require/include we do in the codebase? If you take a look, you will find that any user-facing PHP pages define this constant pointing to the root directory:

define('PHPREPORT_ROOT', __DIR__ . '/../../');

Then, every include uses it like:

include_once(PHPREPORT_ROOT . '/model/vo/TemplateVO.php');

So, with autoload and namespaces, could we stop using PHPREPORT_ROOT? Notice I'm a bit lost about modern PHP practices, too :-)

@anarute
Copy link
Member Author

anarute commented Aug 25, 2021

Hi Ana, thanks for this hard work. I need to set aside some time to go through your proposal, but I have one comment.

Could the new autoload setup be used to simplify the usage of require/include we do in the codebase? If you take a look, you will find that any user-facing PHP pages define this constant pointing to the root directory:

define('PHPREPORT_ROOT', __DIR__ . '/../../');

Then, every include uses it like:

include_once(PHPREPORT_ROOT . '/model/vo/TemplateVO.php');

So, with autoload and namespaces, could we stop using PHPREPORT_ROOT? Notice I'm a bit lost about modern PHP practices, too :-)

That's a good point, I'll create an autoload file and use it instead of the one generated by composer so we don't need to use compose to deploy to production yet, only to run the automated tests locally. This will be enough for us to clean up these include lines :) I'll work on it next week (I'll be off for a few days)

@anarute
Copy link
Member Author

anarute commented Aug 25, 2021

And yes we'll be able to stop using PHPREPORT_ROOT 🎉

Copy link
Member

@jaragunde jaragunde left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with the general direction in this PR, and I'm eager to see how we can share more code between different services, add more tests, etc.

I just have a few comments below:

private \LoginManager $loginManager;

public function __construct(
\TemplateVO $templateVO,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The TemplateVO is a Value Object, just a representation of the data for a template in an object form. It's a bit confusing to have one TemplateVO attached to the TemplateService and reuse it, I would create a new object for every template we parse.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will create an object every time, but now it is created outside the class. The idea is to use dependency injection to make the class more independent and easier to isolate and test.

But for TemplateVo you are probably right that I don't need to do this since it's very isolated already, I'll change this and pass only the LoginManager.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been reading about dependency injection and, while I can see the advantage of injecting the LoginManager, I'm not sure about the TemplateVO. I wonder what's the usual procedure: inject all classes, decide case-by-case... The main difference for me is that, while LoginManager provides a service, TemplateVO acts more like a basic data type.

This will create an object every time, but now it is created outside the class.

I see, now I realize the template create operation only supports creating one template for every operation. But, I wonder how DI could be achieved if the service supported creating several at the same time, like the task create service does.

$createTemplates = [];
do {
if ($parser->name == "template") {
$templatesVO = $this->templateVO;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just create a new TemplateVO every time.

.gitignore Outdated
@@ -18,3 +18,5 @@ config/config.defaults
#minified JS and source maps
*.min.js
*.min.js.map

vendor
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can commit this as it is now, but could you please configure your editor to add newline characters at the end of the file?

"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file is huge and contains lots of dependencies... Where do they come from? Are they all really needed?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes :/ they are all sub dependencies of phpunit/phpunit.
Note that for production there are no dependencies needed, only for dev (under packages-dev line 9)

class TemplateService
{
private \TemplateVO $templateVO;
private \LoginManager $loginManager;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At first, I didn't understand why you were storing an instance of LoginManager instead of using it in a static way :)

Maybe add a comment explaining that this allows to fake the login manager for testing?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, will do! I'll try to break this down into smaller commits

@jaragunde
Copy link
Member

That's a good point, I'll create an autoload file and use it instead of the one generated by composer so we don't need to use compose to deploy to production yet, only to run the automated tests locally. This will be enough for us to clean up these include lines :) I'll work on it next week (I'll be off for a few days)

I finally understood what you meant when I read the last commit (I hadn't noticed it when I wrote the review above).

If I understand correctly, it's a temporary solution to prevent composer from being compulsory, right? If that's the case, I would even prefer to start using composer and the improved autoload at the same time and skip the temporary situation.

@anarute
Copy link
Member Author

anarute commented Aug 31, 2021

That's a good point, I'll create an autoload file and use it instead of the one generated by composer so we don't need to use compose to deploy to production yet, only to run the automated tests locally. This will be enough for us to clean up these include lines :) I'll work on it next week (I'll be off for a few days)

I finally understood what you meant when I read the last commit (I hadn't noticed it when I wrote the review above).

If I understand correctly, it's a temporary solution to prevent composer from being compulsory, right? If that's the case, I would even prefer to start using composer and the improved autoload at the same time and skip the temporary situation.

Yes, it would be an intermediate step, ok I'll remove this commit and keep composer :)

Tests is more used and intuitive since it stores all the tests not
just one. Also the existing test files weren't working and only had
tests for getters and setters (probably auto generated tests).
The createTemplateService will just receive a request and return
whatever the TemplateService parses and executes from it.

The goal is to start splitting what handles the requests and what
processes the data and business logic.
Add parseTemplates that is a pure function that receives a XMLReader
and returns an array of TemplateVO with the parsed values from
the XML.
Use depedency injection to decouple TemplateService from
LoginManager. This will make TemplateService more isolated and
easier to test, since with this change we are able to mock
LoginManager instead of instanciating it.
Add initial set of tests for the TemplateService: one for testing
the parserTemplates method and another to check if user can't
create a template if there's no active section
@anarute
Copy link
Member Author

anarute commented Aug 31, 2021

@jaragunde I broke down the commits trying to make the change in steps for a better review. Can you review the whole PR again please?

Sorry for making it confusing the first time 😅

About the usage of PHPREPORT_ROOT, we'll be able to replace all the requires and includes by namespace and use and do a unique include require PHPREPORT_ROOT . "vendor/autoload.php"; in some strategic files, but this would require to modify almost every file in the repository, that's why I haven't done yet. I think it's better if we start using composer and make sure this patch works in beta and prod, then I can do for the rest of the project.

@jaragunde
Copy link
Member

I think it's better if we start using composer and make sure this patch works in beta and prod, then I can do for the rest of the project.

I agree, let's take small steps.

Copy link
Member

@jaragunde jaragunde left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow, you really walked the extra mile to reorganize and tidy up the commits! I wouldn't have dared to ask that much 😄

Everything looks great now!


Step 6: Running automated tests
===========================

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make help complains this underline is too short. There's no need to go back to the list of commits and fix this, let's amend it later.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh my bad, I didn't notice it had to match the amount of characters of the title

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't know, either! I thought it was enough with three. But this is not actually Markdown syntax so 🤷

@jaragunde
Copy link
Member

Note (to self): composer is packaged in Fedora and Debian (probably Ubuntu, I guess), the package name is composer. We probably could mention that in the instructions, like we mention package names for other dependencies. I can do that later.

On the other hand, we might just distribute the phpreport releases with the autoload already generated and dependencies included and mention composer only as a development dependency. Let's figure this out later, when we discuss future releases... Maybe it's not even worth to keep doing them!

@jaragunde
Copy link
Member

On the other hand, we might just distribute the phpreport releases with the autoload already generated and dependencies included and mention composer only as a development dependency. Let's figure this out later, when we discuss future releases... Maybe it's not even worth to keep doing them!

I did one last release without the composer dependency, in the old style. I think that, in the future, it's not worth to keep doing these releases, they are a lot of manual, error-prone work. I've opened #511 to discuss that.

@jaragunde jaragunde merged commit 37ee590 into Igalia:main Sep 15, 2021
@anarute anarute deleted the add-first-unit-test branch September 15, 2021 11:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants