Laravel 5 and PHPUnit view test fails - headers already sent - laravel-5

I have a freshly set up Laravel 5 project with a working site on "/". When I try to run the provided feature test tests/Feature/ExampleTest.php with PHPUnit 5.7.21 I receive status code 500.
1) Tests\Feature\ExampleTest::testBasicTest
Expected status code 200 but received 500.
Failed asserting that false is true.
The test class is as provided.
<?php
namespace Tests\Feature;
use Tests\TestCase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class ExampleTest extends TestCase
{
/**
* A basic test example.
*
* #return void
*/
public function testBasicTest()
{
$response = $this->get('/');
$response->assertStatus(200);
}
}
The returned page as being part of $response states the following error.
ini_set(): Cannot change zlib.output_compression - headers already sent
I did not change any value in the provided PHPUnit config file.
In my middleware I use the compression to ensure a compressed output of the website.
<?php
namespace App\Http\Middleware;
use Closure;
class AfterMiddleware {
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next) {
ini_set('zlib.output_compression', 'On');
return $next($request);
}
}
When I uncomment the ini_set line, all goes well. What can I do to enable compression and be able to run PHPUnit?
Thanks a lot for your help in advance.

Set your ini_set('zlib.output_compression', 'On'); Edit the php.ini file , then it will be available globaly your application.
zlib.output_compression = On
If you use php --ini you will get list of used ini files and its path used

Related

How do I block certain routes when not in Debug Mode in Laravel?

Is there a way to make a route APP_DEBUG exclusive in Laravel 8?
I can set routes in the PreventRequestsDuringMaintenance middleware exception list.
But that is only for when maintenance mode is on.
I know I can simply do an abort(403) on a Route if Debug mode is on but I'm using Laravel Web Console library which communicates with it's own route when executing commands. So I need to strictly block any requests to that route when in Debug mode.
I want to block certain routes when not in Debug mode. Does Laravel come with such option or do I need a third party library?
As James suggested it, I tinkered with middlewares and registered a global middleware to abort 403 if any uri matches one from a blacklist.
protected $middleware = [
...
// allows blocking some requests when debug mode is off
\App\Http\Middleware\PreventRequestsDuringProduction::class,
];
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
class PreventRequestsDuringProduction
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle(Request $request, Closure $next)
{
$blacklist = [
'console',
'laravelwebconsole/execute'
];
$uri = Route::getRoutes()->match($request)->uri;
if(\in_array($uri, $blacklist) && !env('APP_DEBUG')) {
abort(403);
}
return $next($request);
}
}

Laravel 6 - Conditionally enable debug page on production mode

I used to run debug true in production when needed with Laravel 5 the following way:
'debug' => env('APP_DEBUG', $_SERVER['REMOTE_ADDR'] == 'myipaddress' ? true : false),
However Laravel 6 doesn't let me use it, when I do artisan config:cache, artisan complains that:
variable $_server['REMOTE_ADDR'] is not defined and exists.
Is there another way someone has found out to be working to do this with Laravel 6?
You can't cache dynamic configs. there is no request and no $_server when Laravel tries to cache your configs.
You must disable your debug on production (APP_DEBUG = false) and check the log for any errors.
But if you insist to enable app debug dynamically, you can use middleware:
Create a new middleware using Artisan command:
php artisan make:middleware EnableDebug
This command will place a new EnableDebug class within your app/Http/Middleware directory. Modify it like this:
<?php
namespace App\Http\Middleware;
use Closure;
class EnableDebug
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
config(['app.debug' => $request->ip() === 'myipaddress']);
return $next($request);
}
}
List your middleware class at the end of the $middleware property of your app/Http/Kernel.php class:
protected $middleware = [
//...
\App\Http\Middleware\EnableDebug::class,
];

Unable to access to Auth user info on Laravel

Im using Laravel 5.4 i have created the auth system guard using the laravel stuff, i have also created a role based registration form.
At this point all works so far, but for example i want to only certains pages to be available only for admin, so i have created a New User page to allow the admin create users.
My RegisteruserControoller:
namespace App\Http\Controllers;
use App\Proveedor;
use App\RubroProveedor;
use Illuminate\Http\Request;
use App\Http\Requests\StoreProveedor;
use App\Http\Requests\UpdateProveedor;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redirect;
use Alert;
use Exception;
use Auth;
class RegisteruserController extends Controller
{
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct() {
$this->middleware('role:admin');
}
public function index(Request $request)
{
return view('usuarios.registeruser');
}
My problem here is if i use the middleware in construct im always being asked to login again and again, and i need to disable that but keep the guard to allow only admin user create new users.
Im not sure if im clear, im sorry my bad english.
I have created a Middleware called CheckRole:
<?php
namespace App\Http\Middleware;
use Closure;
class CheckRole
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next, $role)
{
if (! $request->user()->hasRole($role)) {
abort(401, 'This action is unauthorized.');
}
return $next($request);
}
}

Laravel Testing Request - Service Provider - Middleware Issue

I have a Laravel 5.5 App where I have a Service Provider which I use to put some stuff in the request->attributes to access it everywhere (simplified):
namespace App\Providers;
use App\Models\Domain;
use Illuminate\Http\Request;
use Illuminate\Support\ServiceProvider;
class GlobalVarsServiceProvider extends ServiceProvider
{
/**
* Register the application services.
*
* #return void
*/
public function register()
{
//
}
/**
* Bootstrap the application services.
*
* #param Request $request
*
* #return void
*/
public function boot(Request $request)
{
$domain = .. get domain with language and some logic and cache because of multiple domains ..
$request->attributes->add(['domain' => $domain]);
}
}
I do this in a Service Provider, because then I can already use it in other Service Providers like my ViewComposerServiceProvider, where I compose some stuff for the Views. I'm able to access $domain everywhere like this:
$this->domain = $request->attributes->get('domain');
It works great. BUT not in testing. When I want to access $domain in a Unit Test in a middleware the $request->attributes are empty (In UnitTests as in DuskTests either).
It looks like the testing environment uses a different Request Lifecycle? If yes, what else is different in the testing environment?
What am I doing wrong?
-- Edit --
Test Example:
namespace Tests\Feature;
use Tests\TestCase;
class ExampleTest extends TestCase
{
/**
* A basic test example.
*
* #return void
*/
public function testBasicTest()
{
$response = $this->get('/');
$response->assertStatus(200);
}
}
TestCase uses trait MakesHttpRequests which has method call. When you use get method in your tests, it's simply a shortcut to this.
In your test you can use it like this:
$this->call('GET', '/url/here', $yourRequestParametersHere);

New registered user to be redirected to the password reset screen

I'm quite new to Laravel and have been stumped on a problem for 2 days - I'd be grateful for some guidance.
I'm using the default out-of-the-box User authentication system with Laravel 5.3. A new user is created automatically behind the scenes by an existing Admin user - I will in time hide the user registration page. I have also successfully set up middleware to check if a user is newly registered (by looking for a null 'last_logged_in_date' that I've added to the migration).
All I want to happen is for a new registered user to be redirected to the password reset screen that ships with Laravel (again, in time I will create a dedicated page). I would like this to happen within the middleware file. So far, my middleware looks like this:
<?php
namespace App\Http\Middleware;
use Closure;
use App\Http\Controllers\Auth;
class CheckIfNewUser
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
$user = $request->user();
if (! is_null($user->last_logged_in_date )) {
return $next($request);
}
// This is where I'm stuck!!!
}
}
I'm not sure what code to enter at the location indicated by the comments above. I've tried sendResetLinkEmail($request); etc and have imported what I though were the correct classes but I always end up with a Call to undefined function App\Http\Middleware\sendResetLinkEmail() message irregardless of what I 'use' at the top of my class.
Where am I going wrong? Thanks!
Well that happens because you have not defined your sendResetLinkEmail($request) function yet. You can do it like this, or you can create a new class with that and then call the class.
Call the trait SendsPasswordResetEmails and then access it with $this since traits are not classes and you cannot access their members directly.
<?php
namespace App\Http\Middleware;
use Closure;
use App\Http\Controllers\Auth;
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
class CheckIfNewUser
{
use SendsPasswordResetEmails;
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
$user = $request->user();
if (! is_null($user->last_logged_in_date )) {
return $next($request);
}
// This is where I'm stuck!!!
//EDIT
//return $this->SendsPasswordResetEmails->sendResetLinkEmail($request);
return $this->sendResetLinkEmail($request);
}
}

Resources