From 4943e68606ff932b80e01414b413e0198cc85b62 Mon Sep 17 00:00:00 2001 From: ncoronel Date: Wed, 1 Jul 2026 15:38:12 -0300 Subject: [PATCH] feat: implement multi-tenant cart functionality and add image validation helper --- .../Cart/Resources/CartItemResource.php | 1 + .../Shared/Rules/ImageOrBase64Rule.php | 4 + bootstrap/app.php | 4 +- test_out.txt | Bin 772 -> 0 bytes tests/Feature/Cart/CartControllerTest.php | 77 ++++++++++++++---- 5 files changed, 69 insertions(+), 17 deletions(-) delete mode 100644 test_out.txt diff --git a/app/Domains/Cart/Resources/CartItemResource.php b/app/Domains/Cart/Resources/CartItemResource.php index e8cc166..c768d43 100644 --- a/app/Domains/Cart/Resources/CartItemResource.php +++ b/app/Domains/Cart/Resources/CartItemResource.php @@ -48,6 +48,7 @@ class CartItemResource extends JsonResource 'cantidad' => $this->cantidad, 'precio_unitario' => $this->formatMoney($product?->precio), 'product_id' => $product?->id, + 'product_variant_id' => $this->producto_variante_id, 'product' => $product === null ? null : [ 'nombre' => $productName, 'imagen' => $imageUrl, diff --git a/app/Domains/Shared/Rules/ImageOrBase64Rule.php b/app/Domains/Shared/Rules/ImageOrBase64Rule.php index f2b7771..61b2458 100644 --- a/app/Domains/Shared/Rules/ImageOrBase64Rule.php +++ b/app/Domains/Shared/Rules/ImageOrBase64Rule.php @@ -21,6 +21,10 @@ class ImageOrBase64Rule implements ValidationRule if (is_string($value)) { $payload = trim($value); + if (\Illuminate\Support\Str::isUuid($payload)) { + return; + } + if ($payload === '') { $fail("The :attribute must not be empty."); return; diff --git a/bootstrap/app.php b/bootstrap/app.php index 4b327d2..8a4fa0e 100644 --- a/bootstrap/app.php +++ b/bootstrap/app.php @@ -13,7 +13,9 @@ return Application::configure(basePath: dirname(__DIR__)) health: '/up', ) ->withMiddleware(function (Middleware $middleware): void { - // + $middleware->encryptCookies(except: [ + 'guest_token', + ]); }) ->withExceptions(function (Exceptions $exceptions): void { $exceptions->shouldRenderJsonWhen( diff --git a/test_out.txt b/test_out.txt deleted file mode 100644 index 051891222ebfe937f80fa9f38462e44a5b67203b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 772 zcmbu7%}T>i5QWcL@ExRUEm}da+lmh$y0UVqP5MLABqUJ~@zvFDW|G>ygxh9j&YW{* zZhpQ$HBzUFr{HbMskPy}snnLrNavhJxmt3CXAHH{f_gzd>oJ{UI&j8w<$X1%mM2hC zU3zxNHLz__F8iKauV&~p^bNJ7eP5qw0`EkD%Rx1CH+?k}|FQ{ZIV|BbTsu(@M6B7K-p$mk4p4xZ?^dy_lCH0 zFFSZDI4$!)rY4G>P^o>M3%#Pe)Xs6ktbzOg{>G@<7Z~#tD4I)~=UO-Zh3wsHi-&bz kv0JqLoYA+?2QyXtXT)3l+i$6NGRBr^4BMApIHx+%FXY6G^Z)<= diff --git a/tests/Feature/Cart/CartControllerTest.php b/tests/Feature/Cart/CartControllerTest.php index ae20141..ce8e769 100644 --- a/tests/Feature/Cart/CartControllerTest.php +++ b/tests/Feature/Cart/CartControllerTest.php @@ -72,7 +72,7 @@ class CartControllerTest extends TestCase $this->assertDatabaseHas('carritos', [ 'tenant_codigo' => 'acme', - 'guest_token' => $response->getCookie('guest_token')?->getValue(), + 'guest_token' => $response->getCookie('guest_token', false)?->getValue(), 'status' => 'active', ]); @@ -96,13 +96,22 @@ class CartControllerTest extends TestCase 'cantidad' => 2, ]); - $guestToken = $firstResponse->getCookie('guest_token')?->getValue(); + $guestToken = $firstResponse->getCookie('guest_token', false)?->getValue(); - $this->withCookie('guest_token', $guestToken) - ->postJson('/api/tenants/acme/cart/items', [ + $response = $this->call( + 'POST', + '/api/tenants/acme/cart/items', + [], + ['guest_token' => $guestToken], + [], + ['HTTP_Accept' => 'application/json', 'CONTENT_TYPE' => 'application/json'], + json_encode([ 'product_variant_id' => $variant->id, 'cantidad' => 3, ]) + ); + + $response ->assertOk() ->assertJsonPath('data.items.0.cantidad', 5) ->assertJsonPath('data.subtotal', '125.00'); @@ -128,12 +137,21 @@ class CartControllerTest extends TestCase 'cantidad' => 2, ]); - $guestToken = $createResponse->getCookie('guest_token')?->getValue(); + $guestToken = $createResponse->getCookie('guest_token', false)?->getValue(); - $this->withCookie('guest_token', $guestToken) - ->patchJson("/api/tenants/acme/cart/items/{$variant->id}", [ + $response = $this->call( + 'PATCH', + "/api/tenants/acme/cart/items/{$variant->id}", + [], + ['guest_token' => $guestToken], + [], + ['HTTP_Accept' => 'application/json', 'CONTENT_TYPE' => 'application/json'], + json_encode([ 'cantidad' => 5, ]) + ); + + $response ->assertOk() ->assertJsonPath('data.items.0.cantidad', 5) ->assertJsonPath('data.subtotal', '75.00'); @@ -157,10 +175,18 @@ class CartControllerTest extends TestCase 'cantidad' => 4, ]); - $guestToken = $createResponse->getCookie('guest_token')?->getValue(); + $guestToken = $createResponse->getCookie('guest_token', false)?->getValue(); - $this->withCookie('guest_token', $guestToken) - ->deleteJson("/api/tenants/acme/cart/items/{$variant->id}") + $response = $this->call( + 'DELETE', + "/api/tenants/acme/cart/items/{$variant->id}", + [], + ['guest_token' => $guestToken], + [], + ['HTTP_Accept' => 'application/json', 'CONTENT_TYPE' => 'application/json'] + ); + + $response ->assertOk() ->assertJsonPath('data.items', []) ->assertJsonPath('data.subtotal', '0.00'); @@ -249,20 +275,38 @@ class CartControllerTest extends TestCase 'cantidad' => 2, ]); - $guestToken = $response->getCookie('guest_token')?->getValue(); + $guestToken = $response->getCookie('guest_token', false)?->getValue(); - $this->withCookie('guest_token', $guestToken) - ->postJson('/api/tenants/acme/cart/items', [ + $response1 = $this->call( + 'POST', + '/api/tenants/acme/cart/items', + [], + ['guest_token' => $guestToken], + [], + ['HTTP_Accept' => 'application/json', 'CONTENT_TYPE' => 'application/json'], + json_encode([ 'product_variant_id' => $variant->id, 'cantidad' => 1, ]) + ); + + $response1 ->assertUnprocessable() ->assertJsonValidationErrors(['cantidad']); - $this->withCookie('guest_token', $guestToken) - ->patchJson("/api/tenants/acme/cart/items/{$variant->id}", [ + $response2 = $this->call( + 'PATCH', + "/api/tenants/acme/cart/items/{$variant->id}", + [], + ['guest_token' => $guestToken], + [], + ['HTTP_Accept' => 'application/json', 'CONTENT_TYPE' => 'application/json'], + json_encode([ 'cantidad' => 3, ]) + ); + + $response2 ->assertUnprocessable() ->assertJsonValidationErrors(['cantidad']); } @@ -330,7 +374,8 @@ class CartControllerTest extends TestCase 'secondary_color' => '#222222', 'danger_color' => '#333333', 'success_color' => '#28a745', - 'header_footer_bg_color' => '#444444', + 'header_bg_color' => '#444444', + 'footer_bg_color' => '#444444', 'header_logo_id' => $headerAttachment->id, 'footer_logo_id' => $footerAttachment->id, ]);