How to dispatch url with subdomain in Zend PHPUnit Controller test? - zend-framework

I want to test my controller which works on subdomain www.username.domain.com
The problem is when I dispatch in ControllerTestCase it throws Zend_Controller_Dispatcher_Exception
routes.php:
$userRouter = new Zend_Controller_Router_Route_Hostname(':user.domain.com'));
$router->addRoute('user', $userRouter->chain(new Zend_Controller_Router_Route('',
array('controller' => 'user'))));
UserControllerTest:
require_once 'AbstarctControllerTestCase.php';
class UserControllerTest extends AbstarctControllerTestCase
{
public function setUp()
{
$this->cleardb();
parent::setUp();
}
public function testRoute()
{
$this->dispatch('www.username.domain.com');
$this->assertController('user');
}
}
AbstarctControllerTestCase:
abstract class AbstarctControllerTestCase extends Zend_Test_PHPUnit_ControllerTestCase
{
public function setUp()
{
$this->bootstrap = array($this, 'appBootstrap');
parent::setUp();
}
public function appBootstrap()
{
chdir(dirname(dirname(dirname(dirname(__FILE__)))));
require 'application/test/controllerunit/routes.php';
Zend_Session::start();
}
(...)
}
Result:
PHPUnit 3.3.17 by Sebastian Bergmann.
F
Time: 1 second
There was 1 failure:
1) testRoute(UserControllerTest)
Failed asserting last controller used was "user"
When I dispatch normal URI like /login it work well but the problem is dispatching URLs with hostnames.
Any ideas?
Thank you all.

Did you try setting the $_SERVER variable in setup?
e.g.
$_SERVER['SERVER_NAME'] = 'www.username.domain.com';
and then call dispatch as per usual.
See - http://php.net/manual/en/reserved.variables.server.php

Define $_SERVER['HTTP_HOST'] before calling dispatch() .
There is already a ticket with the same concern under http://framework.zend.com/issues/browse/ZF-11680

Related

Codeigniter 3 SimpleSAMLPHP integration - Session Probelm

When integrating SimpeSAMLPHP with Codeigniter 3, they recommand to stop the sp-application session and set the default session handler for SimpleSAMLPHP. I have added the following configuration which works without infinite redirect loop. Previous to this issue it was looping between Idp and sp infitnitely.
//Session library loaded in autoload.php
session_write_close();
session_set_save_handler(new SessionHandler(), true);
require_once $this->config->item("saml_dir").'lib/_autoload.php';
$as = new \SimpleSAML\Auth\Simple('default-sp');
$as->requireAuth();
$session = \SimpleSAML\Session::getSessionFromRequest();
$session->cleanup();
session_write_close();
$this->session->__construct();
$this->session->set_userdata("display_name","Pamira");
print_r($_SESSION);
redirect("main/dashbaord","refresh);
The above print display the sessions values correctly
However, in main controller it does not display the configured session.
class Main extends CI_Controller {
public function __construct() {
parent::__construct();
print_r($_SESSION);
}
public function dashboard()
{
//Dashboard Page
}
}
Now when redirecting to another controller, the session data are gone. Would be great if anyone could help regarding.
Printing the result before redirect, shows all session data but after redirect only the {"__ci_last_regenerate":1665334265} remains.

Behat functional test stop Symfony HttpKernal redirects

I'm using Behat to test a REST API my team has developed. When a particular resource is created the API returns a 201 and a Location header in the response.
The API was developed using using Symfony5 and it's using the Symfony HttpKernel as the client:
$kernel->handle($request);
I would like to assert through my behat test that it returns a 201 and the headers contains the Location. However the client is automatically following the Location header and as such I can't verify that.
Is there a way to turn off following redirects using the existing kernel component? I've not been able to find a way to do this.
You can create your own context and check the Response
<?php declare(strict_types=1);
namespace App\Tests\Features\Context;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Kernel;
final class HttpContext
{
private Kernel $kernel;
private Response $response;
public function __construct(Kernel $kernel)
{
$this->kernel = $kernel;
}
/**
* #When I request :method to :uri
*/
public function iRequest(string $method, string $uri): void
{
$this->request($method, $uri);
}
/**
* #Then the location header should be :location
*/
public function assertLocationHeader(string $location): void
{
// make your assertion
dd($this->response->headers->get('location'), $location);
}
private function request(string $method, string $uri): void
{
$request = Request::create($uri, $method, [], [], [], [], null);
$this->response = $this->kernel->handle($request);
$this->kernel->terminate($request, $this->response);
}
}

Zend framework: how to pass creation options to services

When registering a service in module.config.php like
'service_manager' => [
'factories' => [
\Path\To\Your\Service\AService => \Path\To\Your\Service\Factory\AServiceFactory,
]
]
I can't pass in creation options when calling the service factory neither in ZF2 (when the factory implements MutableCreationOptionsInterface) nor in ZF3 (via $container->get(\Path\To\Your\Service\AService::class, $options).
Could anyone tell me how to pass the creation options to the services?
MutableOptions is currently only available on plugin manager instances; the service manager does not implement it. This is why you see the discrepancy.
Références : https://github.com/zendframework/zend-servicemanager/issues/7
Sample : https://samsonasik.wordpress.com/2014/08/14/zend-framework-2-using-creationoptions-in-pluginmanager/
COMPLEMENT
My solution is to add a method with a fluent pattern to the AService class :
class AService
{
public function __construct(...)
{
//your code, you can inject variables from $container by AServiceFactory
}
public function setOptions($options)
{
// your setting from $options
...
// fluent pattern
return $this;
}
}
To use your service :
$container->get(\Path\To\Your\Service\Aservice::class)->setOptions($options);

How to make POST call using FOSRestBundle

I am trying to setup a RESTFUL web service using FOSRestBunble, but I have some problem making POST calls, here's my setup:
app/config/routing.yml
rest:
type: rest
resource: "routing_rest.yml"
prefix: /api
app/config/routing_rest.yml
Rest_User:
type: rest
resource: "#AppBundle/Resources/config/routing_rest.yml"
AppBundle/Resources/config/routing_rest.yml
rest_application:
type: rest
resource: "AppBundle:Rest"
name_prefix: api_
AppBundle/Controller/RestController.php
class RestController extends FOSRestController
{
public function testrestAction(Request $request)
{
$r = [
'is' => 'TEST'
];
return $r;
}
public function getArticleAction()
{
$r = [
'is' => 'GET'
];
return $r;
}
public function postArticleAction()
{
$r = [
'is' => 'POST'
];
return $r;
}
}
I also made PUT and DELETE test methods. so when I do some test call
GET /api/testrest
{
"is": "TEST"
}
GET /api/article
{
"is": "GET"
}
POST /api/article
No route found for "POST /api/article": Method Not Allowed (Allow: GET, HEAD) (405 Method Not Allowed)
PUT and DELETE are also fine. Am I missing some configuration?
second problem: if I make a API folder inside Controller folder, I change the namespace for RestController to "namespace AppBundle\Controller\API;" and I update "AppBundle/Resources/config/routing_rest.yml" to
resource: "AppBundle:API:Rest"
then I got this message:
Can't locate "AppBundle:API:Rest" controller in /var/www/ws/app/config/routing_rest.yml (which is being imported from "/var/www/ws/app/config/routing.yml").
any help appreciated
1-option, run app/console debug:router (or bin/console debug:router if v > 2.8), to list generated routes;
2-option, add RouteResource annotation to class (eg. article), rename postArticleAction to postAction and check POST /api/articles is responding or not;
3-option, add article url explicitly with #POST annotation, eg. /** #Post("article") */

How to go back to referer after login failure?

For login success there is a parameter use_referer: true. For login failure there is only failure_path, which isn't what I'm looking for.
Second thing: How to do that and pass error message?
Third thing: How to go back to referrer after logout?
I solved it.
There is solution: How to disable redirection after login_check in Symfony 2
and here is code which solves my problem:
<?php
namespace Acme\MainBundle\Handler;
use Symfony\Component\Security\Http\Logout\LogoutSuccessHandlerInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RedirectResponse;
class AuthenticationHandler implements AuthenticationFailureHandlerInterface, LogoutSuccessHandlerInterface
{
public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
{
$referer = $request->headers->get('referer');
$request->getSession()->setFlash('error', $exception->getMessage());
return new RedirectResponse($referer);
}
public function onLogoutSuccess(Request $request)
{
$referer = $request->headers->get('referer');
return new RedirectResponse($referer);
}
}
to handle events add to security.yml for example:
form_login:
check_path: /access/login_check
login_path: /
use_referer: true
failure_handler: authentication_handler
logout:
path: /access/logout
target: /
success_handler: authentication_handler
and to config.yml:
services:
authentication_handler:
class: Acme\MainBundle\Handler\AuthenticationHandler