reupload
This commit is contained in:
243
tests/Feature/Api/V1/OrderTest.php
Normal file
243
tests/Feature/Api/V1/OrderTest.php
Normal file
@@ -0,0 +1,243 @@
|
||||
<?php
|
||||
|
||||
use App\Models\Ecommerce\Channel\Channel;
|
||||
use App\Models\Ecommerce\Product\Cart\CartItem;
|
||||
use App\Models\Ecommerce\Product\Order\Order;
|
||||
use App\Models\Ecommerce\Product\Order\Payment\OrderPayment;
|
||||
use App\Models\Ecommerce\Product\Order\Shipping\OrderShipping;
|
||||
use App\Models\Ecommerce\Product\Order\Status\OrderStatus;
|
||||
use App\Models\Ecommerce\Product\Product\Product;
|
||||
use App\Models\System\Settings\Location\Region;
|
||||
use App\Models\System\Settings\Payments\PaymentType;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\Config;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
uses(RefreshDatabase::class);
|
||||
|
||||
beforeEach(function () {
|
||||
Config::set('ecommerce.api.token', 'test-token');
|
||||
|
||||
$this->user = User::factory()->create([
|
||||
'password' => 'password',
|
||||
'phone_number' => 61929248,
|
||||
]);
|
||||
|
||||
// Create tmpost channel required by OrderRepository
|
||||
if (Channel::where('slug', 'tmpost')->doesntExist()) {
|
||||
Channel::create(['slug' => 'tmpost', 'name' => 'TM Post']);
|
||||
}
|
||||
|
||||
// Mock default payment type for OrderPayment::default()
|
||||
if (PaymentType::count() === 0) {
|
||||
$paymentType = new PaymentType();
|
||||
$paymentType->forceFill([
|
||||
'id' => 1,
|
||||
'code' => 'cash',
|
||||
'name' => ['en' => 'Cash'],
|
||||
'tax' => 0,
|
||||
'is_enabled' => true,
|
||||
]);
|
||||
$paymentType->save();
|
||||
}
|
||||
});
|
||||
|
||||
test('authenticated user can list their orders', function () {
|
||||
$order = new Order();
|
||||
$order->forceFill([
|
||||
'user_id' => $this->user->id,
|
||||
'number' => 'ORD-123',
|
||||
'customer_name' => 'John Doe',
|
||||
'customer_phone' => 61929248,
|
||||
'customer_address' => 'Test Address',
|
||||
'shipping_method' => OrderShipping::STANDART,
|
||||
'shipping_price' => 20,
|
||||
'payment_type_id' => 1, // Assuming ID 1 exists or mocked
|
||||
'region' => Region::AG,
|
||||
'delivery_at' => now(),
|
||||
'status' => OrderStatus::PENDING,
|
||||
]);
|
||||
$order->save();
|
||||
|
||||
$response = $this->actingAs($this->user, 'sanctum')
|
||||
->withHeaders(['Api-Token' => 'test-token'])
|
||||
->getJson('/api/v1/orders');
|
||||
|
||||
$response->assertOk()
|
||||
->assertJsonStructure([
|
||||
'data' => [
|
||||
'*' => [
|
||||
'id',
|
||||
'number',
|
||||
// Add other fields from OrderIndexResource
|
||||
]
|
||||
]
|
||||
]);
|
||||
});
|
||||
|
||||
test('unauthenticated user cannot list orders', function () {
|
||||
$this->withHeaders(['Api-Token' => 'test-token'])
|
||||
->getJson('/api/v1/orders')
|
||||
->assertUnauthorized();
|
||||
});
|
||||
|
||||
test('can place an order', function () {
|
||||
// Setup prerequisites
|
||||
$product = Product::create([
|
||||
'name' => 'Test Product',
|
||||
'slug' => 'test-product',
|
||||
'price_amount' => 100,
|
||||
'cost_amount' => 80,
|
||||
'stock' => 10,
|
||||
'is_visible' => true,
|
||||
]);
|
||||
|
||||
// Add item to cart
|
||||
CartItem::create([
|
||||
'user_id' => $this->user->id,
|
||||
'product_id' => $product->id,
|
||||
'product_quantity' => 2,
|
||||
]);
|
||||
|
||||
// Mock PaymentType if needed (OrderPayment::values() uses DB)
|
||||
PaymentType::create([
|
||||
'code' => 'card',
|
||||
'name' => ['en' => 'Card'],
|
||||
'tax' => 0,
|
||||
'is_enabled' => true,
|
||||
]);
|
||||
$paymentTypeId = PaymentType::where('code', 'card')->first()->id;
|
||||
|
||||
$response = $this->actingAs($this->user, 'sanctum')
|
||||
->withHeaders(['Api-Token' => 'test-token'])
|
||||
->postJson('/api/v1/orders', [
|
||||
'customer_name' => 'John Doe',
|
||||
'customer_phone' => 61929248,
|
||||
'customer_address' => '123 Main St',
|
||||
'shipping_method' => OrderShipping::STANDART,
|
||||
'payment_type_id' => $paymentTypeId,
|
||||
'region' => Region::AG,
|
||||
'notes' => 'Test order',
|
||||
]);
|
||||
|
||||
$response->assertCreated()
|
||||
->assertJsonStructure(['data' => ['order_id']]);
|
||||
|
||||
// Verify order created
|
||||
$this->assertDatabaseHas('orders', [
|
||||
'user_id' => $this->user->id,
|
||||
'customer_name' => 'John Doe',
|
||||
'notes' => 'Test order',
|
||||
]);
|
||||
|
||||
// Verify cart cleared
|
||||
$this->assertDatabaseMissing('cart_items', [
|
||||
'user_id' => $this->user->id,
|
||||
]);
|
||||
|
||||
// Verify stock reduced
|
||||
$this->assertEquals(8, $product->fresh()->stock);
|
||||
});
|
||||
|
||||
test('cannot place order with empty cart', function () {
|
||||
// Ensure cart is empty
|
||||
$this->user->carts()->delete();
|
||||
|
||||
// Mock PaymentType
|
||||
PaymentType::create([
|
||||
'code' => 'online', // unique code
|
||||
'name' => ['en' => 'Online'],
|
||||
'tax' => 0,
|
||||
'is_enabled' => true,
|
||||
]);
|
||||
$paymentTypeId = PaymentType::where('code', 'online')->first()->id;
|
||||
|
||||
$response = $this->actingAs($this->user, 'sanctum')
|
||||
->withHeaders(['Api-Token' => 'test-token'])
|
||||
->postJson('/api/v1/orders', [
|
||||
'customer_name' => 'John Doe',
|
||||
'customer_phone' => 61929248,
|
||||
'customer_address' => '123 Main St',
|
||||
'shipping_method' => OrderShipping::STANDART,
|
||||
'payment_type_id' => $paymentTypeId,
|
||||
'region' => Region::AG,
|
||||
]);
|
||||
|
||||
// The validation 'user_without_product_in_cart' should fail
|
||||
$response->assertStatus(422)
|
||||
->assertJsonValidationErrors(['user_without_product_in_cart']);
|
||||
});
|
||||
|
||||
test('order validation fails with invalid data', function () {
|
||||
// Add item to cart to pass that check
|
||||
$product = Product::create(['name' => 'P', 'slug' => 'p', 'stock' => 1]);
|
||||
CartItem::create(['user_id' => $this->user->id, 'product_id' => $product->id, 'product_quantity' => 1]);
|
||||
|
||||
$response = $this->actingAs($this->user, 'sanctum')
|
||||
->withHeaders(['Api-Token' => 'test-token'])
|
||||
->postJson('/api/v1/orders', [
|
||||
'customer_name' => '', // Required
|
||||
'shipping_method' => 'invalid_method', // Invalid enum
|
||||
]);
|
||||
|
||||
$response->assertStatus(422)
|
||||
->assertJsonValidationErrors(['customer_name', 'shipping_method']);
|
||||
});
|
||||
|
||||
test('can show specific order', function () {
|
||||
$order = new Order();
|
||||
$order->forceFill([
|
||||
'user_id' => $this->user->id,
|
||||
'number' => 'ORD-SHOW',
|
||||
'customer_name' => 'John Doe',
|
||||
'customer_phone' => 61929248,
|
||||
'customer_address' => 'Address',
|
||||
'shipping_method' => OrderShipping::STANDART,
|
||||
'shipping_price' => 20,
|
||||
'payment_type_id' => 1,
|
||||
'region' => Region::AG,
|
||||
'delivery_at' => now(),
|
||||
'status' => OrderStatus::PENDING,
|
||||
]);
|
||||
$order->save();
|
||||
|
||||
$response = $this->actingAs($this->user, 'sanctum')
|
||||
->withHeaders(['Api-Token' => 'test-token'])
|
||||
->getJson("/api/v1/orders/{$order->id}");
|
||||
|
||||
$response->assertOk()
|
||||
->assertJsonPath('data.id', $order->id)
|
||||
->assertJsonPath('data.number', 'ORD-SHOW');
|
||||
});
|
||||
|
||||
test('can delete order (if allowed)', function () {
|
||||
// Note: The controller destroy method is basically empty: return response()->rest();
|
||||
// But the route exists. Let's test it returns 200 at least.
|
||||
|
||||
$order = new Order();
|
||||
$order->forceFill([
|
||||
'user_id' => $this->user->id,
|
||||
'number' => 'ORD-DEL',
|
||||
'customer_name' => 'John Doe',
|
||||
'customer_phone' => 61929248,
|
||||
'customer_address' => 'Address',
|
||||
'shipping_method' => OrderShipping::STANDART,
|
||||
'shipping_price' => 20,
|
||||
'payment_type_id' => 1,
|
||||
'region' => Region::AG,
|
||||
'delivery_at' => now(),
|
||||
'status' => OrderStatus::PENDING,
|
||||
]);
|
||||
$order->save();
|
||||
|
||||
$response = $this->actingAs($this->user, 'sanctum')
|
||||
->withHeaders(['Api-Token' => 'test-token'])
|
||||
->deleteJson("/api/v1/orders/{$order->id}");
|
||||
|
||||
$response->assertOk();
|
||||
|
||||
$this->assertSoftDeleted('orders', [
|
||||
'id' => $order->id,
|
||||
]);
|
||||
});
|
||||
Reference in New Issue
Block a user