Deploy Ladill Woo Manager / deploy (push) Successful in 38s
Co-authored-by: Cursor <cursoragent@cursor.com>
256 lines
7.9 KiB
PHP
256 lines
7.9 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature;
|
|
|
|
use App\Models\User;
|
|
use App\Models\WooOrder;
|
|
use App\Models\WooStore;
|
|
use App\Services\Woo\InstallTokenService;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Tests\TestCase;
|
|
|
|
class WooWebTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
public function test_guest_is_redirected_to_sso(): void
|
|
{
|
|
$this->get(route('woo.dashboard'))
|
|
->assertRedirect(route('sso.connect', ['redirect' => route('woo.dashboard')]));
|
|
}
|
|
|
|
public function test_authenticated_user_sees_dashboard(): void
|
|
{
|
|
$user = User::factory()->create();
|
|
|
|
$this->actingAs($user)
|
|
->get(route('woo.dashboard'))
|
|
->assertOk()
|
|
->assertSee('Woo Manager');
|
|
}
|
|
|
|
public function test_store_activation_exchanges_install_token(): void
|
|
{
|
|
$user = User::factory()->create();
|
|
$store = WooStore::create([
|
|
'user_id' => $user->id,
|
|
'site_url' => 'https://shop.example.com',
|
|
'site_name' => 'Example Shop',
|
|
'status' => WooStore::STATUS_PENDING,
|
|
]);
|
|
|
|
$token = app(InstallTokenService::class)->issue($store)['token'];
|
|
|
|
$response = $this->postJson('/api/v1/stores/activate', [
|
|
'install_token' => $token,
|
|
'site_url' => 'https://shop.example.com',
|
|
]);
|
|
|
|
$response->assertOk()
|
|
->assertJsonPath('store_id', $store->public_id)
|
|
->assertJsonStructure(['webhook_url', 'webhook_secret', 'plugin_token']);
|
|
|
|
$this->assertSame(WooStore::STATUS_ACTIVE, $store->fresh()->status);
|
|
}
|
|
|
|
public function test_webhook_ingests_order(): void
|
|
{
|
|
$user = User::factory()->create();
|
|
$store = WooStore::create([
|
|
'user_id' => $user->id,
|
|
'site_url' => 'https://shop.example.com',
|
|
'status' => WooStore::STATUS_ACTIVE,
|
|
'connected_at' => now(),
|
|
'plugin_token_hash' => hash('sha256', 'test-token'),
|
|
]);
|
|
|
|
$payload = [
|
|
'id' => 42,
|
|
'number' => '1042',
|
|
'status' => 'processing',
|
|
'currency' => 'GHS',
|
|
'total' => '120.50',
|
|
'billing' => [
|
|
'first_name' => 'Ama',
|
|
'last_name' => 'Mensah',
|
|
'email' => 'ama@example.com',
|
|
'phone' => '0244123456',
|
|
],
|
|
'line_items' => [
|
|
['name' => 'T-shirt', 'quantity' => 2, 'total' => '120.50', 'sku' => 'TS-1'],
|
|
],
|
|
'needs_payment' => false,
|
|
'date_modified_gmt' => now()->utc()->format('Y-m-d H:i:s'),
|
|
];
|
|
|
|
$body = json_encode($payload, JSON_THROW_ON_ERROR);
|
|
$signature = base64_encode(hash_hmac('sha256', $body, (string) $store->webhook_secret, true));
|
|
|
|
$this->call(
|
|
'POST',
|
|
route('woo.webhooks.woocommerce', $store->public_id),
|
|
[],
|
|
[],
|
|
[],
|
|
[
|
|
'CONTENT_TYPE' => 'application/json',
|
|
'HTTP_X_WC_WEBHOOK_SIGNATURE' => $signature,
|
|
'HTTP_X_WC_WEBHOOK_TOPIC' => 'order.updated',
|
|
],
|
|
$body,
|
|
)->assertOk();
|
|
|
|
$order = WooOrder::query()->where('external_order_id', 42)->first();
|
|
$this->assertNotNull($order);
|
|
$this->assertSame('ama@example.com', $order->customer_email);
|
|
$this->assertSame(12050, $order->total_minor);
|
|
}
|
|
|
|
public function test_merchant_can_update_fulfillment_status(): void
|
|
{
|
|
$user = User::factory()->create();
|
|
$store = WooStore::create([
|
|
'user_id' => $user->id,
|
|
'site_url' => 'https://shop.example.com',
|
|
'status' => WooStore::STATUS_ACTIVE,
|
|
]);
|
|
$order = WooOrder::create([
|
|
'woo_store_id' => $store->id,
|
|
'external_order_id' => 7,
|
|
'order_number' => '1007',
|
|
'line_items' => [['name' => 'Item', 'quantity' => 1, 'total_minor' => 1000]],
|
|
'currency' => 'GHS',
|
|
'total_minor' => 1000,
|
|
]);
|
|
|
|
$this->actingAs($user)
|
|
->patch(route('woo.orders.update-status', $order), [
|
|
'fulfillment_status' => WooOrder::FULFILLMENT_PREPARING,
|
|
])
|
|
->assertRedirect();
|
|
|
|
$this->assertSame(WooOrder::FULFILLMENT_PREPARING, $order->fresh()->fulfillment_status);
|
|
}
|
|
|
|
public function test_product_webhook_ingests_product(): void
|
|
{
|
|
$user = User::factory()->create();
|
|
$store = WooStore::create([
|
|
'user_id' => $user->id,
|
|
'site_url' => 'https://shop.example.com',
|
|
'status' => WooStore::STATUS_ACTIVE,
|
|
'connected_at' => now(),
|
|
]);
|
|
|
|
$payload = [
|
|
'id' => 101,
|
|
'name' => 'Hoodie',
|
|
'slug' => 'hoodie',
|
|
'sku' => 'HD-1',
|
|
'status' => 'publish',
|
|
'regular_price' => '150.00',
|
|
'categories' => [['id' => 12, 'name' => 'Apparel']],
|
|
];
|
|
|
|
$body = json_encode($payload, JSON_THROW_ON_ERROR);
|
|
$signature = base64_encode(hash_hmac('sha256', $body, (string) $store->webhook_secret, true));
|
|
|
|
$this->call(
|
|
'POST',
|
|
route('woo.webhooks.woocommerce', $store->public_id),
|
|
[],
|
|
[],
|
|
[],
|
|
[
|
|
'CONTENT_TYPE' => 'application/json',
|
|
'HTTP_X_WC_WEBHOOK_SIGNATURE' => $signature,
|
|
'HTTP_X_WC_WEBHOOK_TOPIC' => 'product.updated',
|
|
],
|
|
$body,
|
|
)->assertOk();
|
|
|
|
$this->assertDatabaseHas('woo_products', [
|
|
'woo_store_id' => $store->id,
|
|
'external_id' => 101,
|
|
'name' => 'Hoodie',
|
|
'sku' => 'HD-1',
|
|
]);
|
|
}
|
|
|
|
public function test_category_webhook_ingests_category(): void
|
|
{
|
|
$user = User::factory()->create();
|
|
$store = WooStore::create([
|
|
'user_id' => $user->id,
|
|
'site_url' => 'https://shop.example.com',
|
|
'status' => WooStore::STATUS_ACTIVE,
|
|
'connected_at' => now(),
|
|
]);
|
|
|
|
$payload = [
|
|
'id' => 12,
|
|
'name' => 'Apparel',
|
|
'slug' => 'apparel',
|
|
'parent' => 0,
|
|
'count' => 4,
|
|
];
|
|
|
|
$body = json_encode($payload, JSON_THROW_ON_ERROR);
|
|
$signature = base64_encode(hash_hmac('sha256', $body, (string) $store->webhook_secret, true));
|
|
|
|
$this->call(
|
|
'POST',
|
|
route('woo.webhooks.woocommerce', $store->public_id),
|
|
[],
|
|
[],
|
|
[],
|
|
[
|
|
'CONTENT_TYPE' => 'application/json',
|
|
'HTTP_X_WC_WEBHOOK_SIGNATURE' => $signature,
|
|
'HTTP_X_WC_WEBHOOK_TOPIC' => 'product_category.created',
|
|
],
|
|
$body,
|
|
)->assertOk();
|
|
|
|
$this->assertDatabaseHas('woo_categories', [
|
|
'woo_store_id' => $store->id,
|
|
'external_id' => 12,
|
|
'name' => 'Apparel',
|
|
]);
|
|
}
|
|
|
|
public function test_authenticated_user_can_view_settings(): void
|
|
{
|
|
$user = User::factory()->create();
|
|
|
|
$this->actingAs($user)
|
|
->get(route('woo.settings'))
|
|
->assertOk()
|
|
->assertSee('Settings')
|
|
->assertSee('Manage connected stores');
|
|
}
|
|
|
|
public function test_merchant_can_view_products_page(): void
|
|
{
|
|
$user = User::factory()->create();
|
|
$store = WooStore::create([
|
|
'user_id' => $user->id,
|
|
'site_url' => 'https://shop.example.com',
|
|
'status' => WooStore::STATUS_ACTIVE,
|
|
]);
|
|
|
|
\App\Models\WooProduct::create([
|
|
'woo_store_id' => $store->id,
|
|
'external_id' => 1,
|
|
'name' => 'Sample Tee',
|
|
'slug' => 'sample-tee',
|
|
'status' => 'publish',
|
|
]);
|
|
|
|
$this->actingAs($user)
|
|
->get(route('woo.products.index'))
|
|
->assertOk()
|
|
->assertSee('Sample Tee');
|
|
}
|
|
}
|