Summer Sale! All accounts are 50% off this week.

davy_yg's avatar
Level 27

AdsTest > input slider data Expected response status code [200] but received 302.

Hello,

I get an error on this part of the phpunit test:

AdsTest.php

	 public function test_input_slider_data()
    {

    $type = "slider";
    $imagePath = UploadedFile::fake()->image('image.jpeg',1366,345)->size(100);
    
    // Storage::fake('avatars');
    
    $user = User::first();
    
    $response = $this->actingAs($user)
                    ->post('cpages/ads/'.$type,[
                        'ad_title'=>'slider 1',
                        'ad_caption'=>'slider 1',
                        'ad_url'=>'https://localhost/axe-backend-mg/public/home',// ok
                        'images'=>$imagePath
                    ],[
                        'content-type'=>'multipart/form-data'
                    ]);

    $response->assertStatus(200);

    }

AdsController.php

		    public function store(Request $request, $type)
		{

    if($type == 'slider')
        {
        $count = Advertisement::where('ad_type', 'slider')->count();
        
            if($count == 1){
                Session::flash('error', 'Tidak dapat menambah slider lebih dari 1');    
            return redirect()->back();  // this appears for response 302 response
            }
                            
        }
    elseif($type == 'featured_index')
        {
        $count = Advertisement::where('ad_type', 'featured_index')->count();
        
            if($count == 3){
                Session::flash('error', 'Tidak dapat menambah featured_index lebih dari 3');    
            
            return redirect()->back();
            }
                            
        }
    elseif($type == 'banner_ads')
        {
        $count = Advertisement::where('ad_type', 'banner_ads')->count();
        
            if($count == 1){
                Session::flash('error', 'Tidak dapat menambah banner_ads lebih dari 1');    
            
            return redirect()->back();
            }
                            
        }

        // $type = "slider";

    if($type == "slider") {//fokus ke slider ini kan ya? iya
                     
         $this->validate($request, [
              'ad_title' => 'required',
              'ad_caption' => 'required',
              'ad_url' => 'required',
              'images' => 'required|dimensions:min_width=1360,min_height=345, max_width=1370,max_height=400'
         ]);   

         $dir_location = 'slider'; 
         $dir = 'ads/slider/';  

    }elseif($type == "featured_index") {

         $this->validate($request, [
              'ad_title' => 'required',
              'ad_caption' => 'required',
              'ad_url' => 'required',
              'images' => 'required|dimensions:min_width=400,min_height=225, max_width=415,max_height=230'
         ]); 

         $dir_location = 'featured_index';

         $dir = 'ads/featured_index/';  

    }elseif($type== "banner_ads") {

        $this->validate($request, [
              'ad_title' => 'required',
              'ad_caption' => 'required',
              'ad_url' => 'required',
              'images' => 'required|dimensions:min_width=1360,min_height=420, max_width=1370,max_height=425'
         ]); 

        $dir_location = 'banner_ads';
        $dir = 'ads/banner_ads/';
    }


    $ads = new Advertisement;

    $ads->ad_type = $type;
    $ads->ad_title = $request->ad_title;
    $ads->ad_caption = $request->ad_caption;
    $ads->ad_url = $request->ad_url;
        
        // Mengelola nama

        $extension = $request->file('images')->extension();
        $name_wo_extension = pathinfo($request->file('images')->getClientOriginalName(), PATHINFO_FILENAME);

        // memberi dash kalo ada spasi namanya
        $slug = Str::slug($name_wo_extension, '-');

        $name = $slug . '.' . $extension;

        // check the existance of old file
        $count = count(Advertisement::where('ad_img_url', $dir.$name)->get());

        while($count != 0)
            {
                $slug = $slug . '-copy';
            }     


    $ads->ad_img_url = $dir . $name;    
    
    Storage::putFileAs($dir_location, $request->file('images'), $name);

    $ads->save();

    Session::flash('flash', 'Ads type :'. $type . ' created');


    return redirect()->back();
	}

ref: https://laracasts.com/discuss/channels/testing/expected-status-code-200-but-received-302

Any clue why the error appears?

0 likes
17 replies
Sinnbeck's avatar

Btw. One suggestion. Refractor the method to several. One for each type. The method is very messy and hard to follow

davy_yg's avatar
Level 27

Do you mean the controller or the the testing method?

davy_yg's avatar
Level 27

Method App\Http\Requests\CreateAdsForm::CreateAdsForm does not exist.

AdsController.php

	use App\Http\Requests\CreateAdsForm;
		
	class AdsController extends Controller
	{
		public function store(Request $request, $type, CreateAdsForm $adsform)
			{
    		...
	    	$adsform->CreateAdsForm($dir_location, $dir, $type);

	    	return redirect()->back();
			}
	

I only wonder why the error appears?

Tray2's avatar

@davy_yg Probably cause your CreateAdsForm class doesn't have a CreateAdsForm.

Make sure that it has and be aware of the case and the spelling.

CreateAdsForm != createAdsForm
1 like
davy_yg's avatar
Level 27

@sinnbeck I don't quite understand how to create the AdsTest, this is what I did:

	public function test_input_slider_data()
	{
    
    $type = "slider";
    $imagePath = UploadedFile::fake()->image('image.jpeg',1366,345)->size(100);
    
    // Storage::fake('avatars');
    
    $user = User::first();
    
    $response = $this->actingAs($user)
                    ->post('cpages/ads/'.$type,[
                        'ad_title'=>'slider 1',
                        'ad_caption'=>'slider 1',
                        'ad_url'=>'https://localhost/axe-backend-mg/public/home',// ok
                        'images'=>$imagePath
                    ],[
                        'content-type'=>'multipart/form-data'
                    ]);

    $url = 'cpages/ads/slider';
    $response->assertRedirect($url);

    $response->assertStatus(200);
	}

CMD RESULT:

	• Tests\Feature\AdsTest > input slider data
	  Failed asserting that two strings are equal.

	  at E:\xampp75\htdocs\axe-backend-mg\tests\Feature\AdsTest.php:87
 		83▕                             'content-type'=>'multipart/form-data'
 		84▕                         ]);
 		85▕
 		86▕         $url = '/cpages/ads/slider';
	 ➜  87▕         $response->assertRedirect($url);
 		88▕
 		89▕
 		90▕         $response->assertStatus(200);
 		91▕
Sinnbeck's avatar

@davy_yg you don't use both of these. Just one. And the response status isn't 200, but 302

And the url is where you will be sent, not where you are

$response->assertRedirect($url);
//or 
    $response->assertStatus(302);
davy_yg's avatar
Level 27

This works: $response->assertStatus(302);

I will be sent to the same page as where I am since it's using return redirect()->back();

So this is truly to test if all the below data can be inputted correctly, true?

	$response = $this->actingAs($user)
                    ->post('cpages/ads/'.$type,[
                        'ad_title'=>'slider 1',
                        'ad_caption'=>'slider 1',
                        'ad_url'=>'https://localhost/axe-backend-mg/public/home',// ok
                        'images'=>$imagePath
                    ],[
                        'content-type'=>'multipart/form-data'
                    ]);

    $response->assertStatus(302);
Tray2's avatar

@davy_yg Your test only asserts that you have been redirected which you would be even if the validation fails. You should do a couple of more assertions to see that the session has no errors and that you have a record in your table.

Consider the code below.

    /**
    * @test
    */
    public function a_valid_book_can_be_stored(): void
    {
        $book = Book::factory()->make()->toArray();
        $this->post('/books', $book)
            ->assertStatus(302)
            ->assertSessionHasNoErrors();
        $this->assertDatabaseCount('books', 1);
    }
davy_yg's avatar
Level 27

See I don't understand how to modify my codes. I want to make sure that all the data are able to be inputted in my form.

			$this->actingAs($user)
                ->post('cpages/ads/'.$type,[
                    'ad_title'=>'slider 1',
                    'ad_caption'=>'slider 1',
                    'ad_url'=>'https://localhost/axe-backend-mg/public/home',// ok
                    'images'=>$imagePath
                ],[
                    'content-type'=>'multipart/form-data'
                ])
				->assertStatus(302)
				->assertSessionHasNoErrors()
				->assertDatabaseCount('advertisements', 1);	

My table's name advertisements in axeshop database.

Should I write it this way?

Tray2's avatar

@davy_yg What is it that you don't understand?

  1. You run the test acting as a created user
  2. You do a post to `cpages/ads/{type}'
  3. You pass along an array of the data you want to insert into your table
  4. You assert that you are redirected
  5. You assert the your session has no errors (Your request passes the validation)
  6. You check that the data has been inserted into the database
davy_yg's avatar
Level 27

ok I tried my codes:

		  • Tests\Feature\AdsTest > input slider data
		BadMethodCallException

		  Call to undefined method Illuminate\Http\RedirectResponse::assertDatabaseCount()

		  at E:\xampp75\htdocs\axe-backend-mg\vendor\laravel\framework\src\Illuminate\Support\Traits\ForwardsCalls.php:50
 			46▕      * @throws \BadMethodCallException
 			47▕      */
 			48▕     protected static function throwBadMethodCallException($method)
 			49▕     {
		➜  50▕         throw new BadMethodCallException(sprintf(
 			51▕             'Call to undefined method %s::%s()', static::class, $method
 			52▕         ));
 			53▕     }
 			54▕ }

		  1   E:\xampp75\htdocs\axe-backend-mg\vendor\laravel\framework\src\Illuminate\Http\RedirectResponse.php:256
  			Illuminate\Http\RedirectResponse::throwBadMethodCallException("assertDatabaseCount")

		  2   E:\xampp75\htdocs\axe-backend-mg\tests\Feature\AdsTest.php:100
  Illuminate\Testing\TestResponse::__call("assertDatabaseCount")


		Tests:  1 failed, 6 passed
		Time:   4.39s

I do have a table called advertisements with 1 row in it.

ref: https://laravel.com/docs/7.x/database-testing

Sinnbeck's avatar

@davy_yg you are chaining on the response, not the test

$this->assertDatabaseCount('advertisements', 1);	 
davy_yg's avatar
Level 27

@Sinnbeck I don't understand. Should I put $this->

behind all of the arrows ?

Please or to participate in this conversation.