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

Bug fix: Reset Route arguments for each call #2431

Merged
merged 2 commits into from
Aug 4, 2018
Merged

Bug fix: Reset Route arguments for each call #2431

merged 2 commits into from
Aug 4, 2018

Conversation

mathmarques
Copy link
Contributor

@mathmarques mathmarques commented Apr 27, 2018

Route arguments weren't reset for each call of App::process and if the route had optional arguments on the url this could cause unexpected behaviors.

This Fix #2430

@coveralls
Copy link

Coverage Status

Coverage increased (+0.007%) to 97.088% when pulling 95585bd on mathmarques:fix-route-arguments into e84150b on slimphp:3.x.

@mathmarques mathmarques changed the title Reset Route arguments for each call [WIP] Reset Route arguments for each call Apr 27, 2018
@mathmarques mathmarques changed the title [WIP] Reset Route arguments for each call Reset Route arguments for each call Apr 27, 2018
@akrabat
Copy link
Member

akrabat commented May 7, 2018

Why is process() called more than once for a given route?

@mathmarques
Copy link
Contributor Author

mathmarques commented May 7, 2018

@akrabat It's not more than once for a given route, but process can be invoked more than once for a single Slim's instance. And if one route is matched more than once, this problem will occur.
An use case: #1688

@geggleto geggleto requested review from akrabat and geggleto May 15, 2018 14:15
@fiskWasTaken
Copy link

This is indeed a problem you will run into if you try to use Slim under PPM/ReactPHP, so this would be appreciated

However spellcheck Proccess in your unit test method names, or consider shorter names (testOptionalArgTransience, testOptionalArgTransienceWithSetArguments)

Copy link
Member

@akrabat akrabat left a comment

Choose a reason for hiding this comment

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

If I call setArguments(), then $savedArguments needs resetting I think?

@akrabat akrabat added the pending response Waiting on a response from the original poster label Jun 24, 2018
@mathmarques
Copy link
Contributor Author

I don't think so @akrabat .
After app initialization the only way to call setArguments() is after the route is matched, and I think if you use setArguments() at this time it's only for that one request.

@akrabat
Copy link
Member

akrabat commented Jun 26, 2018

This test fails:

    public function testInvokeSequentialProccessAfterAddingAnotherRouteArgument()
    {
        $app = new App();
        $route = $app->get('/foo[/{bar}]', function ($req, $res, $args) {
            return $res->write(count($args));
        })->setArgument('baz', 'quux');

        // Prepare request and response objects
        $env = Environment::mock([
            'SCRIPT_NAME' => '/index.php',
            'REQUEST_URI' => '/foo/bar',
            'REQUEST_METHOD' => 'GET',
        ]);
        $uri = Uri::createFromEnvironment($env);
        $headers = Headers::createFromEnvironment($env);
        $cookies = [];
        $serverParams = $env->all();
        $body = new RequestBody();
        $req = new Request('GET', $uri, $headers, $cookies, $serverParams, $body);
        $res = new Response();

        // Invoke process with optional arg
        $resOut = $app->process($req, $res);

        $this->assertInstanceOf('\Psr\Http\Message\ResponseInterface', $resOut);
        $this->assertEquals('2', (string)$resOut->getBody());

        // Prepare request and response objects
        $env = Environment::mock([
            'SCRIPT_NAME' => '/index.php',
            'REQUEST_URI' => '/foo/bar',
            'REQUEST_METHOD' => 'GET',
        ]);
        $uri = Uri::createFromEnvironment($env);
        $headers = Headers::createFromEnvironment($env);
        $cookies = [];
        $serverParams = $env->all();
        $body = new RequestBody();
        $req = new Request('GET', $uri, $headers, $cookies, $serverParams, $body);
        $res = new Response();

        // add another argument
        $route->setArgument('one', '1');

        // Invoke process with optional arg
        $resOut2 = $app->process($req, $res);

        $this->assertInstanceOf('\Psr\Http\Message\ResponseInterface', $resOut2);
        $this->assertEquals('3', (string)$resOut2->getBody());
    }

Arguably, it's unlikely to happen, but this test works with 3.x today.

@mathmarques
Copy link
Contributor Author

This change should fix it.
Couldn't think another way to solve it. Any better solution?

@akrabat akrabat removed the pending response Waiting on a response from the original poster label Jul 23, 2018
@akrabat akrabat merged commit 6d7dff9 into slimphp:3.x Aug 4, 2018
@akrabat
Copy link
Member

akrabat commented Aug 4, 2018

Couldn't think another way to solve it. Any better solution?

Seems reasonable to me. I've renamed the variable to make it a bit clearer though.

@akrabat akrabat added this to the 3.10.1 milestone Aug 4, 2018
@akrabat akrabat changed the title Reset Route arguments for each call Bug fix: Reset Route arguments for each call Aug 4, 2018
@mathmarques
Copy link
Contributor Author

@akrabat Should I patch this on 4.x? Or maybe raise an issue for review every change on 3.x tests since 4.x was created and add them to 4.x and fix it?

@akrabat
Copy link
Member

akrabat commented Oct 5, 2018

@mathmarques Good point - this needs to go to 4.x too.

A proportion of them have been ported forward, but it'd be good to go through and check.

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.

5 participants