#!/usr/bin/env node /** * Test script for checkout shipping cost calculation * Creates a checkout via API and verifies totalPrice includes shipping */ const SALEOR_API_URL = process.env.NEXT_PUBLIC_SALEOR_API_URL || 'https://api.manoonoils.com/graphql/'; // Test data const TEST_VARIANT_ID = 'UHJvZHVjdFZhcmlhbnQ6Mjk0'; // Replace with actual variant ID const TEST_EMAIL = 'test@example.com'; const TEST_SHIPPING_ADDRESS = { firstName: 'Test', lastName: 'User', streetAddress1: '123 Test Street', city: 'Belgrade', postalCode: '11000', country: 'RS', phone: '+38160123456' }; async function saleorFetch(query, variables = {}, token = null) { const headers = { 'Content-Type': 'application/json', }; if (token) { headers['Authorization'] = `JWT ${token}`; } const response = await fetch(SALEOR_API_URL, { method: 'POST', headers, body: JSON.stringify({ query, variables }), }); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const result = await response.json(); if (result.errors) { throw new Error(`GraphQL errors: ${JSON.stringify(result.errors)}`); } return result.data; } async function testCheckoutWithShipping() { console.log('๐Ÿงช Testing checkout shipping cost calculation...\n'); try { // Step 1: Create checkout console.log('Step 1: Creating checkout...'); const checkoutCreateMutation = ` mutation CheckoutCreate($input: CheckoutCreateInput!) { checkoutCreate(input: $input) { checkout { id token totalPrice { gross { amount currency } } subtotalPrice { gross { amount currency } } } errors { field message } } } `; const checkoutResult = await saleorFetch(checkoutCreateMutation, { input: { channel: 'default-channel', email: TEST_EMAIL, lines: [], languageCode: 'SR' } }); if (checkoutResult.checkoutCreate.errors?.length > 0) { throw new Error(`Checkout creation failed: ${checkoutResult.checkoutCreate.errors[0].message}`); } const checkout = checkoutResult.checkoutCreate.checkout; console.log(`โœ… Checkout created: ${checkout.id}`); console.log(` Token: ${checkout.token}`); console.log(` Initial total: ${checkout.totalPrice.gross.amount} ${checkout.totalPrice.gross.currency}\n`); // Step 2: Add product to checkout console.log('Step 2: Adding product to checkout...'); const linesAddMutation = ` mutation CheckoutLinesAdd($checkoutId: ID!, $lines: [CheckoutLineInput!]!) { checkoutLinesAdd(checkoutId: $checkoutId, lines: $lines) { checkout { id totalPrice { gross { amount currency } } subtotalPrice { gross { amount currency } } lines { id quantity totalPrice { gross { amount } } } } errors { field message } } } `; // First, let's query for available products to get a real variant ID console.log(' Querying available products...'); const productsQuery = ` query Products { products(channel: "default-channel", first: 1) { edges { node { id name variants { id name } } } } } `; const productsResult = await saleorFetch(productsQuery); const product = productsResult.products.edges[0]?.node; if (!product || !product.variants?.[0]) { throw new Error('No products found in store'); } const variantId = product.variants[0].id; console.log(` Product: ${product.name}, Variant: ${product.variants[0].name}`); const linesResult = await saleorFetch(linesAddMutation, { checkoutId: checkout.id, lines: [{ variantId, quantity: 1 }] }); if (linesResult.checkoutLinesAdd.errors?.length > 0) { throw new Error(`Adding lines failed: ${linesResult.checkoutLinesAdd.errors[0].message}`); } const checkoutWithLines = linesResult.checkoutLinesAdd.checkout; const productTotal = checkoutWithLines.totalPrice.gross.amount; console.log(`โœ… Product added (qty: 1)`); console.log(` Product total: ${productTotal} RSD\n`); // Step 3: Set shipping address console.log('Step 3: Setting shipping address...'); const shippingAddressMutation = ` mutation CheckoutShippingAddressUpdate($checkoutId: ID!, $shippingAddress: AddressInput!) { checkoutShippingAddressUpdate(checkoutId: $checkoutId, shippingAddress: $shippingAddress) { checkout { id shippingMethods { id name price { amount currency } } } errors { field message } } } `; const shippingResult = await saleorFetch(shippingAddressMutation, { checkoutId: checkout.id, shippingAddress: TEST_SHIPPING_ADDRESS }); if (shippingResult.checkoutShippingAddressUpdate.errors?.length > 0) { throw new Error(`Setting shipping address failed: ${shippingResult.checkoutShippingAddressUpdate.errors[0].message}`); } const availableMethods = shippingResult.checkoutShippingAddressUpdate.checkout.shippingMethods; console.log(`โœ… Shipping address set`); console.log(` Available shipping methods: ${availableMethods.length}`); if (availableMethods.length === 0) { console.log(' โš ๏ธ No shipping methods available for this address/region'); return; } availableMethods.forEach((method, i) => { console.log(` [${i + 1}] ${method.name}: ${method.price.amount} ${method.price.currency}`); }); console.log(''); // Step 4: Set shipping method const selectedMethod = availableMethods[0]; console.log(`Step 4: Selecting shipping method: ${selectedMethod.name} (${selectedMethod.price.amount} RSD)...`); const shippingMethodMutation = ` mutation CheckoutShippingMethodUpdate($checkoutId: ID!, $shippingMethodId: ID!) { checkoutShippingMethodUpdate(checkoutId: $checkoutId, shippingMethodId: $shippingMethodId) { checkout { id totalPrice { gross { amount currency } } subtotalPrice { gross { amount currency } } shippingPrice { gross { amount currency } } } errors { field message } } } `; const methodResult = await saleorFetch(shippingMethodMutation, { checkoutId: checkout.id, shippingMethodId: selectedMethod.id }); if (methodResult.checkoutShippingMethodUpdate.errors?.length > 0) { throw new Error(`Setting shipping method failed: ${methodResult.checkoutShippingMethodUpdate.errors[0].message}`); } const finalCheckout = methodResult.checkoutShippingMethodUpdate.checkout; const subtotal = finalCheckout.subtotalPrice.gross.amount; const shipping = finalCheckout.shippingPrice.gross.amount; const finalTotal = finalCheckout.totalPrice.gross.amount; const expectedTotal = subtotal + shipping; console.log(`โœ… Shipping method set`); console.log(` Subtotal: ${subtotal} RSD`); console.log(` Shipping: ${shipping} RSD`); console.log(` Total: ${finalTotal} RSD`); console.log(` Expected: ${expectedTotal} RSD`); console.log(''); // Verification console.log('๐Ÿ“Š VERIFICATION:'); if (finalTotal === expectedTotal) { console.log('โœ… PASS: Total includes shipping cost correctly'); console.log(` ${subtotal} + ${shipping} = ${finalTotal}`); } else { console.log('โŒ FAIL: Total does NOT include shipping cost'); console.log(` Expected: ${expectedTotal}, Got: ${finalTotal}`); console.log(` Difference: ${expectedTotal - finalTotal}`); } // Cleanup - delete checkout console.log('\n๐Ÿงน Cleaning up test checkout...'); // Note: Checkout deletion requires admin permissions console.log(` Checkout ID for manual cleanup: ${checkout.id}`); } catch (error) { console.error('\nโŒ Test failed:', error.message); process.exit(1); } } // Run the test testCheckoutWithShipping();