Laravel Console Testing Issue On Confirmation's Exit Code - laravel

When I run my command, I want to ask for a confirmation to proceed unless APP_ENV is testing. Command side is easy, but I couldn't make its test work.
// MyConsoleCommand.php
public function handle()
{
if ($this->isTerminated()) return;
}
public function isTerminated()
{
return env('APP_ENV') != 'testing'
? !$this->confirm("my confirmation message")
: false;
}
// MyConsoleCommandTest.php
public function test_run()
{
$_ENV['APP_ENV'] = 'something';
config()->set('app.env', 'something');
$this->artisan('mycommand')
->expectsConfirmation("my confirmation message", false)
->assertExitCode(0);
$this->artisan('mycommand')
->expectsConfirmation("my confirmation message", true)
->assertExitCode(1);
}
The test with assertExitCode(1) always fails regardless of the answer of the confirmation. How can I amke it work correctly?
Thanks in advance.

Related

How to turn off ConfirmableTrait in Laravel 5?

I need to switch off ConfirmableTrait in Laravel 5.
On my production server I have many jobs, some of them prompt alert "Do you really wish to run this command?" and for that reason job is failed.
Thanks in advance.
edit ConfirmableTrait like this
public function confirmToProceed($warning = 'Application In Production!', $callback = null)
{
return true;
}
second way override confirmToProceed method add in your job or create new trait file and use them
public function confirmToProceed($warning = 'Application In Production!', $callback = null)
{
return true;
}

Laravel custom error page if authorization fails

I am trying to show a custom 403 file in laravel when authorization fails in my edit request.
I tried forbiddenResponse() but as it turns out it has been eliminated.
Then I tried failedauthorization() but this does not redirect as well and allows me to edit.
here is my request file
public function authorize()
{
$job_posting_id = $this->route('id');
$job_posting = Job_postings::where('id', $job_posting_id)->where('user_id', user()->id)->exists();
if($job_posting){
return true;
}
return false;
}
public function failedAuthorization()
{
return redirect('errors.dashboard.parent.403');
}
I have a folder called errors and inside there I have dashboard folder and parent where the error file is located.
How can I redirect to that page if authorization fails?
return abort('403')
Laravel documentation:
https://laravel.com/docs/5.4/errors#http-exceptions
if you make everything like in docs, you'll achieve:
url will stay the same.
template resources/views/errors/403.blade.php will be shown.
aslo response will have Status Code:403 Forbidden
do you want change url into http://www.examlpe.com/error403 ?
return abort('403') doesn't make redirect. It just shows a client that error has occured.
In your case it is easier to show different content in single script, than different scripts. Try to leave single error script as an "entry point". And in that script change output for different users. Imagine that 403.blade.php is a layout for a number of 403 error pages.
In your laravel folder open app/Exceptions/Handler.php paste the following code. That will return custom error page for 403 and 500 error.
public function render($request, Exception $exception)
{
if ($exception instanceof CustomException) {
return response()->view('errors.custom_all', [], 500);
}
if ($exception instanceof \Spatie\Permission\Exceptions\UnauthorizedException) {
return response()->view('errors.custom', [], 403);
}
return parent::render($request, $exception);
}
public function authorize()
{
$job_posting_id = $this->route('id');
$job_posting = Job_postings::where('id', $job_posting_id)->where('user_id', user()->id)->exists();
if($job_posting){
return true;
}
return redirect('/error');
}
public function failedAuthorization()
{
return view('errors.dashboard.parent.403');
}
In your route
Route::get('error', 'YourController#failedAuthorization');
Go to the file Exceptions/Handler.php's report method.
public function report(Exception $e)
{
if(!Auth::check())
{
// Do whatever you want - redirect or return something
}
if($e instanceof HttpException && $e->getStatusCode() == 403)
{
// Do whatever you want - redirect or return something
}
return parent::report($e);
}
And wherever your authorisation failed, just write abort(403)
Hope this will help :)

How to 'unset' session save handler?

For some reason I have to initialize session with default save handler.
Previous code explicitly sets custom handler with session_set_save_handler().
Changing previous code is not a realistic option in my situation, so does anyone know how to restore handler to default eg is there session_restore_save_handler or session_unset_save_handler functions or equivalents?
As of PHP 5.4 you can revert to the default session handler by instantiating the SessionHandler class directly:
session_set_save_handler(new SessionHandler(), true);
Here I have to answer on my own question since no one said anything:
First, there is no session_restore_save_handler or session_unset_save_handler given from PHP and (by so far) no native way to get things back as they were before. For some reason, PHP team didn't give us option to juggle with session handlers in this way.
Second, native session mechanism can be emulated with following code
class FileSessionHandler
{
private $savePath;
function open($savePath, $sessionName)
{
$this->savePath = $savePath;
if (!is_dir($this->savePath)) {
mkdir($this->savePath, 0777);
}
return true;
}
function close()
{
return true;
}
function read($id)
{
return (string)#file_get_contents("$this->savePath/sess_$id");
}
function write($id, $data)
{
return file_put_contents("$this->savePath/sess_$id", $data) === false ? false : true;
}
function destroy($id)
{
$file = "$this->savePath/sess_$id";
if (file_exists($file)) {
unlink($file);
}
return true;
}
function gc($maxlifetime)
{
foreach (glob("$this->savePath/sess_*") as $file) {
if (filemtime($file) + $maxlifetime < time() && file_exists($file)) {
unlink($file);
}
}
return true;
}
}
$handler = new FileSessionHandler();
session_set_save_handler(
array($handler, 'open'),
array($handler, 'close'),
array($handler, 'read'),
array($handler, 'write'),
array($handler, 'destroy'),
array($handler, 'gc')
);
register_shutdown_function('session_write_close');
This logic is closest to PHP's native session dealing one, but with , of course, unpredictable behavior in different circumstances. All I can right now conclude is that basic session operations is full covered with it.

onPostExecute is getting executed before doInBackground

I am stuck with the following issue. I tried searching for answers but none of the responses could help me so i am asking this question here. Any response will be greatly appreciated!
I am using this below AsyncTask to use the login methods exposed by the Firebase API. However when i invoke new LoginOperation().execute() at the click of login button, i am not seeing the expected results. I am pasting the code below and the Logcat output.
I would like to know why onPostExecute is getting executed before doInBackground? Please note i am using a valid email id & password, so i should have been able to login properly.
Code:
private class LoginOperation extends AsyncTask<Void, Void, Boolean> {
protected Boolean doInBackground(Void... params) {
try{
authClient.loginWithEmail(emailid.getText().toString(),password.getText().toString(), new SimpleLoginAuthenticatedHandler() {
public void authenticated(
com.firebase.simplelogin.enums.Error error, User user) {
if(error != null) {
// There was an error logging into this account
loginStatus=false;
errorMsg=error.name();
Log.d(appName, "Inside if block in doInBackground of LoginOperation");
}
else {
// We are now logged in
loginStatus=true;
Log.d(appName, "Inside else block in doInBackground of LoginOperation");
}
}
});
}
catch (Exception e)
{
e.printStackTrace();
}
return Boolean.valueOf(loginStatus);
}
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
if (result.booleanValue()) {
toastMsg="User logged in successfully";
Log.d(appName, "Inside onPostExecute success of LoginOperation");
}
else
{
toastMsg="Error in login";
Log.d(appName, "Inside onPostExecute failure of LoginOperation");
}
TextView displayStatus = (TextView) findViewById(R.id.displayStatus);
displayStatus.setText(toastMsg);
}
protected void onPreExecute() {
super.onPreExecute();
}
protected void onProgressUpdate(Void... values) {}
}
Code invoked on Login click:
public void onLogin(View arg0)
{
Log.d(appName, " email id is " + emailid.getText().toString());
Log.d(appName, " password is " + password.getText().toString());
try {
Boolean finalStatus= new LoginOperation().execute().get(5000, TimeUnit.MILLISECONDS);
Log.d(appName, " final Status is: " + finalStatus.booleanValue());
}
LogCat:
01-27 17:50:02.054: D/LOGIN(984): email id is abc#gmail.com
01-27 17:50:02.054: D/LOGIN(984): password is abc123
01-27 17:50:02.082: D/LOGIN(984): final Status is: false
01-27 17:50:02.082: D/LOGIN(984): Inside onPostExecute failure of LoginOperation
01-27 17:50:05.502: D/LOGIN(984): Inside else block in doInBackground of LoginOperation
Expected result:
Inside else block in doInBackground of LoginOperation
Inside onPostExecute success of LoginOperation
You don't need your AsyncTask because the class you are using in doInBackground seems to already perform its task in a background thread. Move the code in doInBackground somewhere to the UI thread and move your code from onPostExecute into the SimpleLoginAuthenticationHandler.
Currently, onPostExecuted is called immediately, because it just starts a new background thread and comes back immediately.
Most likely this is because SimpleLoginAuthenticatedHandler.authenticated() is executed asynchronously. It looks you don't need AsyncTask at all.
My guess is that loginWithEmail() runs within a Thread. That means that when you call this method, the thread is indeed run but that doesn't mean it has ended its execution, so maybe it's running paralelly, you get back, finish the doInBackground() method and it joins the onPostExecute() method.
I would remove the AsyncTask if it's that way, it's not necessary.

StackOverFlow Exception, alternatives for my function?

I've created a program that at some point has to log in to some website. If something goes wrong, I want it to wait for some time, say 2 seconds, and then try again. so the function looks something like this:
public void log_in ()
{
try
{
//login code
}
catch
{
Thread.Sleep(2000);
log_in();
}
}
But this code started to give me StackOverFlowExeptions every now and then. Does anyone know how to solve that?
You're getting a stack overflow exception because every time you call log_in() you're adding the function to the stack. This this:
public void log_in ()
{
while (true) {
try
{
//login code
return;
}
catch
{
}
}
}
what's because if code can't login at all it keeps creating new function call each time on the stack. Next code would work:
public void log_in ()
{
while(true) {
try {
//login code
return;
}
catch {
Thread.Sleep(2000);
}
}
}
But overall you shouldn't try to login endlessly, after several time report error to user/admin.

Resources