Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

dajoeberlei's avatar

Persist Session ID in Feature Tests

Hi,

im working on an e-commerce system where i try to make a shopping cart for guest users that are not logged in. In my Feature tests the session id wont persist so when trying to validate if the user can add a shopping cart item because the shopping cart?

$location = Location::first();
$cart = ShoppingCart::currentOrCreate($location);
$sessionId = Session::getId(); 
// dump(sessionId,  cart->session_id) here returns a $sessionId that is equal to $cart->session_id;

$sessionName = Session::getName();


$product = $location->products()->first();

$data = [
    'productId' => $product->id,
    'cartId' => $cart->id
];

$response = $this->withCookies([$sessionName => $sessionId])->post(route('shopping-cart.add-item'), $data); // sessionId() within that controller is different than the one dumped in line 4

$response->assertOk();

$cart->refresh();
$this->assertTrue($cart->items->count() == 1);

Within the static function ShoppingCart::currentOrCreate($location) it creates a new shopping cart model based on session()->getId() and saves it to the shopping carts session_id property.

$cart->session_id = $session()->getId();
$cart->location_id = $location->id;
$cart->save();

Even though im doing $this->withCookies([$sessionName => $sessionId]) my session()->getId() within that request has a different session id then my initial created one at ShoppingCart::currentOrCreate($location).

I cant figure out why and i cant get my test to work since my $response->assertOk() returns a 403 (which it should when the session id is not the same)

0 likes
10 replies
dajoeberlei's avatar

@tykus unfortunately that doesn't work because withSession(['x' => 'y']) can only set a key/value attribute pair of the session but it can't edit the id of the session.

The Session is basically structured like this as far as i understand:

id: string // this id is what i want to change
attributes: array // can be set with withSession()
tykus's avatar

@dajoeberlei

it can't edit the id of the session

Why do you want to modify the Session ID?

dajoeberlei's avatar

@tykus because the session id from the first request in my test is different than the session id of my second request. I want them to be the same session id so that i can test my controller which should only work when the session id is validated as the same from the first request.

dajoeberlei's avatar

@tykus thats true. Sorry, i actually didnt phrase it right i have to admit. Let my simplify my code from above:

public function test_unauthorized_user_can_add_items_to_shopping_cart()
{
    $shoppingCart = ShoppingCart::create([
		// the first time session()->getId() gets called.
		'session_id' => session()->getId(),
	]);
    
	$product = Product::first();

    $data = [
        'productId' => $product->id,
        'cartId' => $shoppingCart->id
    ];

    // this calls my shopping cart controller with session()->getId() again, see code below
    $response = $this->post(route('shopping-cart.add-item'), $data); 

    $response->assertOk();
}

And the following ShoppingCartController is called through the post request above:

public function addItem(Request $request)
{
    // second Time session()->getId() gets called, and here its different then the one before
    if(session()->getId() !== $cart->session_id) { 
         abort(403);
    }

   return response()->ok();
}
tykus's avatar

@dajoeberlei try this:

public function test_unauthorized_user_can_add_items_to_shopping_cart()
{
    $shoppingCart = ShoppingCart::create([
		// the first time session()->getId() gets called.
		'session_id' => $sessionId = session()->getId(),
	]);
    
	$product = Product::first();

    $data = [
        'productId' => $product->id,
        'cartId' => $shoppingCart->id
    ];

    $response = $this->withCookies([
        session()->getName() => $sessionId
    ])->post(route('shopping-cart.add-item'), $data); 

    $response->assertOk();
}
1 like
dajoeberlei's avatar

@tykus thats what i tried but it doesn't work unfortunately. I cant figure out why

tykus's avatar

@dajoeberlei did you set the array value and the $sessionId variable together like this:

'session_id' => $sessionId = session()->getId(),

Otherwise, every time you call session()->getId() outside of a Request (where the session has been properly started) you will get a different value.

Is session_id fillable on the ShoppingCart model?

1 like

Please or to participate in this conversation.