Some checks failed
Build and Deploy / build (push) Has been cancelled
- Add RybbitService for tracking e-commerce events - Update useAnalytics hook to track with both OpenPanel and Rybbit - Add Rybbit script to layout for page view tracking - Track all applicable store events: product views, cart, checkout, orders, search, etc.
311 lines
8.9 KiB
JavaScript
311 lines
8.9 KiB
JavaScript
#!/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();
|