MaxSpl's avatar

PHPUnit tests: request sent on the same url responds with method not allowed

Hello, I've run across a problem that I haven't been able to solve for quite some time.

I've got two tests that create a page with two different flags, which define the position that will be assigned to the newly created page. Having a couple of those flags I naturally want to test each of them so the test is making a request to the same url with the same data but different flags (in practice it's an ajax request from the frontend using axios). The first test passes successfully but the second one fails. When I dump the response of the second test it's message says: The POST method is not supported for route cms/pages/store. Supported methods: GET, HEAD.

The problem is that the route DOES definetly support that method as you can see in the routes file. Another interesting thing is that when I run only the second test it passes. So it fails only when both of the test are run. I'm quite new to testing so I think I might be not seeing something obvious here. So my question is what could be the problem? I'm providing the relevant code below. Let me know if I should post any more of it or provide additional information. Thank you very much.

cms.php (the file with routes)

Route::prefix('cms')->middleware('auth')->group(function () {
    Route::prefix('pages')->group(function () {
        Route::post('store', [PageController::class, 'store']);
    });
});

PageController.php

class PageController extends Controller
{
    public function store(StorePageRequest $request, StorePageAction $storePageAction): JsonResponse
    {
        $page = $storePageAction->execute($request);

        return response()->json([
            'status' => 'success',
            'page' => $page,
        ], 201);
    }
}

PageTest.php

class PageTest extends TestCase
{
    use RefreshDatabase;

    protected User $user;
    protected Page $callerPage;

    protected function setUp(): void
    {
        parent::setUp();

        $this->user = User::factory()->create();
        $this->callerPage = Page::factory()->create();
    }

    public function test_page_is_created_with_up_flag()
    {
        $response = $this->actingAs($this->user)->post('/cms/pages/store', [
            'page_flag' => 'up',
            'target' => 'lorem-ipsum',
            'parent_id' => $this->callerPage->id,
            'position' => 0,
            'title' => 'Lorem',
            'description' => 'Ipsum dolor sit amet',
        ], [
            'Accept' => 'application/json'
        ]);

        $this->assertDatabaseCount('pages', 2);
        $response->assertStatus(201);
    }

    public function test_page_is_created_with_down_flag()
    {
        $response = $this->actingAs($this->user)->post('/cms/pages/store', [
            'page_flag' => 'down',
            'target' => 'lorem-ipsum',
            'parent_id' => $this->callerPage->id,
            'position' => 0,
            'title' => 'Lorem',
            'description' => 'Ipsum dolor sit amet',
        ], [
            'Accept' => 'application/json'
        ]);

        $this->assertDatabaseCount('pages', 2);
        $response->assertStatus(201);
    }
}
0 likes
7 replies
MaxSpl's avatar

@krisi_gjika it's in routes/cms.php, I have separate files for web routes and cms-related routes

tykus's avatar

@MaxSpl why do you only show us the POST /cms/products/store route, and not the pages one - is there a /cms/pages/store Route?

Route::prefix('cms')->middleware('auth')->group(function () {
    Route::prefix('pages')->group(function () {
        Route::post('store', [PageController::class, 'store']);
    });
});
1 like
MaxSpl's avatar

@tykus You're right, I've deleted the rest of the routes from the code snippet to reduce visual clutter and mistakenly left the product route instead of the page one. I'll edit the snippet at the top. Thanks for pointing this out

tykus's avatar

@MaxSpl okay, have tried to reproduce your issue without success. What Laravel and PHP versions are you using?

Please or to participate in this conversation.