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

fix: filters are executed when controller does not exist with Auto Routing (Legacy). #7925

Merged
merged 20 commits into from
Oct 28, 2023

Conversation

ping-yee
Copy link
Contributor

@ping-yee ping-yee commented Sep 11, 2023

Description
See #7205

Checklist:

  • Securely signed commits
  • Component(s) with PHPDoc blocks, only if necessary or adds value
  • Unit testing, with >80% coverage
  • User guide updated
  • Conforms to style guide

@kenjis kenjis added breaking change Pull requests that may break existing functionalities bug Verified issues on the current code behavior or pull requests that will fix them labels Sep 11, 2023
@kenjis kenjis changed the title fix: Fix the filters are executed when controller does not exist with Auto Routing (Legacy). fix: filters are executed when controller does not exist with Auto Routing (Legacy). Sep 11, 2023
@kenjis
Copy link
Member

kenjis commented Sep 11, 2023

@ping-yee The commit f2f9638 does not add any feature.
The commit message prefix should be test: .

@ping-yee
Copy link
Contributor Author

@kenjis Got it and I have modified that.

@kenjis
Copy link
Member

kenjis commented Sep 12, 2023

@ping-yee I think AutoRouter::getRoute() should throw PageNotFoundException when the controller is not found.
It already throws PageNotFoundException to invalid name:

if (! $this->isValidSegment($controllerName)) {
throw new PageNotFoundException($this->controller . ' is not a valid controller name');
}

@kenjis kenjis added the docs needed Pull requests needing documentation write-ups and/or revisions. label Sep 12, 2023
@ping-yee
Copy link
Contributor Author

ping-yee commented Sep 12, 2023

@kenjis Seems that it will have some problem occur after add the pageNotFoundException into AutoRouter::getRoute().

@kenjis
Copy link
Member

kenjis commented Sep 12, 2023

Do you mean the following PHPUnit errors?
It is a breaking change, so some existing tests fail.
This change is a bug fix but not urgent. It may be better to go to 4.5 because of the impact.

There were 16 errors:

1) CodeIgniter\Router\RouteCollectionTest::testAutoRoutesControllerNameReturnsFQCN with data set "with \ prefix" ('\App\Controllers')
CodeIgniter\Exceptions\PageNotFoundException: Controller or its method is not found: \App\Controllers\Product::index

/home/runner/work/CodeIgniter4/CodeIgniter4/system/Router/AutoRouter.php:179
/home/runner/work/CodeIgniter4/CodeIgniter4/system/Router/Router.php:514
/home/runner/work/CodeIgniter4/CodeIgniter4/system/Router/Router.php:210
/home/runner/work/CodeIgniter4/CodeIgniter4/tests/system/Router/RouteCollectionTest.php:1684
phpvfscomposer:///home/runner/work/CodeIgniter4/CodeIgniter4/vendor/phpunit/phpunit/phpunit:106

2) CodeIgniter\Router\RouteCollectionTest::testAutoRoutesControllerNameReturnsFQCN with data set "without \ prefix" ('App\Controllers')
CodeIgniter\Exceptions\PageNotFoundException: Controller or its method is not found: \App\Controllers\Product::index

/home/runner/work/CodeIgniter4/CodeIgniter4/system/Router/AutoRouter.php:179
/home/runner/work/CodeIgniter4/CodeIgniter4/system/Router/Router.php:514
/home/runner/work/CodeIgniter4/CodeIgniter4/system/Router/Router.php:210
/home/runner/work/CodeIgniter4/CodeIgniter4/tests/system/Router/RouteCollectionTest.php:1684
phpvfscomposer:///home/runner/work/CodeIgniter4/CodeIgniter4/vendor/phpunit/phpunit/phpunit:106

3) CodeIgniter\Router\RouterTest::testAutoRouteFindsDefaultControllerAndMethod
CodeIgniter\Exceptions\PageNotFoundException: Controller or its method is not found: Test::test

/home/runner/work/CodeIgniter4/CodeIgniter4/system/Router/AutoRouter.php:179
/home/runner/work/CodeIgniter4/CodeIgniter4/system/Router/Router.php:514
/home/runner/work/CodeIgniter4/CodeIgniter4/tests/system/Router/RouterTest.php:204
phpvfscomposer:///home/runner/work/CodeIgniter4/CodeIgniter4/vendor/phpunit/phpunit/phpunit:106

4) CodeIgniter\Router\RouterTest::testAutoRouteFindsControllerWithFileAndMethod
CodeIgniter\Exceptions\PageNotFoundException: Controller or its method is not found: MyController::someMethod

/home/runner/work/CodeIgniter4/CodeIgniter4/system/Router/AutoRouter.php:179
/home/runner/work/CodeIgniter4/CodeIgniter4/system/Router/Router.php:514
/home/runner/work/CodeIgniter4/CodeIgniter4/tests/system/Router/RouterTest.php:215
phpvfscomposer:///home/runner/work/CodeIgniter4/CodeIgniter4/vendor/phpunit/phpunit/phpunit:106

5) CodeIgniter\Router\RouterTest::testAutoRouteFindsControllerWithFile
ErrorException: file_put_contents(/home/runner/work/CodeIgniter4/CodeIgniter4/app/Controllers/Φ): failed to open stream: Is a directory

/home/runner/work/CodeIgniter4/CodeIgniter4/tests/system/Router/RouterTest.php:342
phpvfscomposer:///home/runner/work/CodeIgniter4/CodeIgniter4/vendor/phpunit/phpunit/phpunit:106

13) CodeIgniter\Router\RouterTest::testTranslateURIDashesForAutoRoute
CodeIgniter\Exceptions\PageNotFoundException: Controller or its method is not found: Admin-user::show-list

/home/runner/work/CodeIgniter4/CodeIgniter4/system/Router/AutoRouter.php:179
/home/runner/work/CodeIgniter4/CodeIgniter4/system/Router/Router.php:514
/home/runner/work/CodeIgniter4/CodeIgniter4/tests/system/Router/RouterTest.php:740
phpvfscomposer:///home/runner/work/CodeIgniter4/CodeIgniter4/vendor/phpunit/phpunit/phpunit:106

14) CodeIgniter\Router\RouterTest::testAutoRouteMatchesZeroParams
CodeIgniter\Exceptions\PageNotFoundException: Controller or its method is not found: MyController::someMethod

/home/runner/work/CodeIgniter4/CodeIgniter4/system/Router/AutoRouter.php:179
/home/runner/work/CodeIgniter4/CodeIgniter4/system/Router/Router.php:514
/home/runner/work/CodeIgniter4/CodeIgniter4/tests/system/Router/RouterTest.php:754
phpvfscomposer:///home/runner/work/CodeIgniter4/CodeIgniter4/vendor/phpunit/phpunit/phpunit:106

15) CodeIgniter\Router\RouterTest::testAutoRouteMethodEmpty
CodeIgniter\Exceptions\PageNotFoundException: Controller or its method is not found: Home::index

/home/runner/work/CodeIgniter4/CodeIgniter4/system/Router/AutoRouter.php:179
/home/runner/work/CodeIgniter4/CodeIgniter4/system/Router/Router.php:514
/home/runner/work/CodeIgniter4/CodeIgniter4/system/Router/Router.php:210
/home/runner/work/CodeIgniter4/CodeIgniter4/tests/system/Router/RouterTest.php:775
phpvfscomposer:///home/runner/work/CodeIgniter4/CodeIgniter4/vendor/phpunit/phpunit/phpunit:106

16) CodeIgniter\Router\RouterTest::testRouterPriorDirectory
CodeIgniter\Exceptions\PageNotFoundException: Controller or its method is not found: Some_controller::some_method

/home/runner/work/CodeIgniter4/CodeIgniter4/system/Router/AutoRouter.php:179
/home/runner/work/CodeIgniter4/CodeIgniter4/system/Router/Router.php:514
/home/runner/work/CodeIgniter4/CodeIgniter4/system/Router/Router.php:210
/home/runner/work/CodeIgniter4/CodeIgniter4/tests/system/Router/RouterTest.php:826
phpvfscomposer:///home/runner/work/CodeIgniter4/CodeIgniter4/vendor/phpunit/phpunit/phpunit:106

--

https://github.com/codeigniter4/CodeIgniter4/actions/runs/6159447007/job/16714289271?pr=7925

@kenjis
Copy link
Member

kenjis commented Sep 12, 2023

For example, see the following test.
In this test, $router->handle() is expected to set controller/method names from the URI path,
even if the controller does not exist.
But I don't see a reason that $router finds controllers that do not exist.

RouteCollectionTest:

    /**
     * @dataProvider provideRouteDefaultNamespace
     *
     * @param mixed $namespace
     */
    public function testAutoRoutesControllerNameReturnsFQCN($namespace): void
    {
        $routes = $this->getCollector();
        $routes->setAutoRoute(true);
        $routes->setDefaultNamespace($namespace);

        $router = new Router($routes, Services::request());
        $router->handle('/product');

        $this->assertSame('\App\\Controllers\\Product', $router->controllerName());
    }

@github-actions github-actions bot added the stale Pull requests with conflicts label Sep 20, 2023
@github-actions
Copy link

👋 Hi, @ping-yee!

We detected conflicts in your PR against the base branch 🙊
You may want to sync 🔄 your branch with upstream!

Ref: Syncing Your Branch

@kenjis kenjis removed the stale Pull requests with conflicts label Sep 20, 2023
@ping-yee ping-yee force-pushed the 230910_filter branch 2 times, most recently from f3aadcc to a1f2c50 Compare September 22, 2023 04:09
@ping-yee
Copy link
Contributor Author

In this test, $router->handle() is expected to set controller/method names from the URI path,
even if the controller does not exist.
But I don't see a reason that $router finds controllers that do not exist.

I am also feel confused about this and I wonder how these test cases work as we expect, like this case as below.

public function testAutoRouteFindsControllerWithSubfolder(): void
    {
        $this->collection->setAutoRoute(true);

        $router = new Router($this->collection, $this->request);

        mkdir(APPPATH . 'Controllers/Subfolder');

        $router->autoRoute('subfolder/myController/someMethod');

        rmdir(APPPATH . 'Controllers/Subfolder');

        $this->assertSame('MyController', $router->controllerName());
        $this->assertSame('someMethod', $router->methodName());
    }

It make a Subfolder folder but doesn't make a myController file and someMethod.
So what we expect is it only will throw the PageNotFound exception for now?

@kenjis
Copy link
Member

kenjis commented Sep 22, 2023

That is a test to find the controller in a subfolder, so the controller should be present.
The test method is AutoRouteFindsControllerWithSubfolder.

In the test code, the controller file that should be prepared is not created because the test passes without a controller file.

@ping-yee ping-yee changed the base branch from develop to 4.5 September 28, 2023 06:29
@ping-yee
Copy link
Contributor Author

In the test code, the controller file that should be prepared is not created because the test passes without a controller file.

Yes. And I also find that the testing used controllers has been prepared in the same directory.

https://github.com/codeigniter4/CodeIgniter4/tree/develop/tests/system/Router

But I think the controllers aren't being used because it's different method name between the test case and mock controller.

Or I have some misunderstandings.

public function testAutoRouteFindsControllerWithSubfolder(): void
    {
        $this->collection->setAutoRoute(true);

        $router = new Router($this->collection, $this->request);

        mkdir(APPPATH . 'Controllers/Subfolder');

        $router->autoRoute('subfolder/myController/someMethod');

        rmdir(APPPATH . 'Controllers/Subfolder');

        $this->assertSame('MyController', $router->controllerName());
        $this->assertSame('someMethod', $router->methodName());
    }
namespace CodeIgniter\Router\Controllers\Subfolder;

use CodeIgniter\Controller;

class Mycontroller extends Controller
{
    public function getSomemethod(): void
    {
    }
}

@ping-yee
Copy link
Contributor Author

ping-yee commented Oct 9, 2023

@kenjis I fix the problem that the controller isn't exist into few test cases at the latest commit, please review.
If the change is feasible, I will apply the change into the other test cases.

@kenjis
Copy link
Member

kenjis commented Oct 10, 2023

Yes. And I also find that the testing used controllers has been prepared in the same directory.
https://github.com/codeigniter4/CodeIgniter4/tree/develop/tests/system/Router
But I think the controllers aren't being used because it's different method name between the test case and mock controller.

Yes, these controllers are for testing Auto Routing Improved.
But they can be used for Auto Routing Legacy as you wrote test code.

@kenjis
Copy link
Member

kenjis commented Oct 10, 2023

@ping-yee Thank you. Your way seems to be okay.

It is better not to copy files during testing, but the Auto Routing Legacy has hard coded APPPATH . 'Controllers/',
so we must copy the controllers to app/Controllers now.

@kenjis kenjis removed the docs needed Pull requests needing documentation write-ups and/or revisions. label Oct 24, 2023
Copy link
Member

@kenjis kenjis left a comment

Choose a reason for hiding this comment

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

Thank you!

@kenjis kenjis merged commit f45040b into codeigniter4:4.5 Oct 28, 2023
46 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
4.5 breaking change Pull requests that may break existing functionalities bug Verified issues on the current code behavior or pull requests that will fix them
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants