437 lines
12 KiB
JavaScript
437 lines
12 KiB
JavaScript
const ShopifyService = require("../../../src/services/shopify");
|
|
const ProductService = require("../../../src/services/product");
|
|
const ProgressService = require("../../../src/services/progress");
|
|
|
|
// Mock the services to avoid actual API calls during testing
|
|
jest.mock("../../../src/services/shopify");
|
|
jest.mock("../../../src/services/product");
|
|
jest.mock("../../../src/services/progress");
|
|
|
|
describe("TUI ProductService and ProgressService Integration", () => {
|
|
let mockShopifyService;
|
|
let mockProductService;
|
|
let mockProgressService;
|
|
|
|
beforeEach(() => {
|
|
// Reset all mocks
|
|
jest.clearAllMocks();
|
|
|
|
// Create mock ShopifyService instance
|
|
mockShopifyService = {
|
|
testConnection: jest.fn(),
|
|
executeQuery: jest.fn(),
|
|
executeMutation: jest.fn(),
|
|
executeWithRetry: jest.fn(),
|
|
};
|
|
|
|
// Create mock ProductService instance
|
|
mockProductService = {
|
|
fetchProductsByTag: jest.fn(),
|
|
updateProductPrices: jest.fn(),
|
|
rollbackProductPrices: jest.fn(),
|
|
validateProducts: jest.fn(),
|
|
validateProductsForRollback: jest.fn(),
|
|
getProductSummary: jest.fn(),
|
|
};
|
|
|
|
// Create mock ProgressService instance
|
|
mockProgressService = {
|
|
logOperationStart: jest.fn(),
|
|
logRollbackStart: jest.fn(),
|
|
logProductUpdate: jest.fn(),
|
|
logRollbackUpdate: jest.fn(),
|
|
logError: jest.fn(),
|
|
logCompletionSummary: jest.fn(),
|
|
logRollbackSummary: jest.fn(),
|
|
};
|
|
|
|
// Mock the service constructors
|
|
ShopifyService.mockImplementation(() => mockShopifyService);
|
|
ProductService.mockImplementation(() => mockProductService);
|
|
ProgressService.mockImplementation(() => mockProgressService);
|
|
});
|
|
|
|
describe("ProductService Integration", () => {
|
|
test("should fetch products by tag", async () => {
|
|
const mockProducts = [
|
|
{
|
|
id: "product1",
|
|
title: "Test Product 1",
|
|
variants: [{ id: "variant1", price: 10.0 }],
|
|
},
|
|
];
|
|
mockProductService.fetchProductsByTag.mockResolvedValue(mockProducts);
|
|
|
|
const service = new ProductService();
|
|
const products = await service.fetchProductsByTag("test-tag");
|
|
|
|
expect(mockProductService.fetchProductsByTag).toHaveBeenCalledWith(
|
|
"test-tag"
|
|
);
|
|
expect(products).toEqual(mockProducts);
|
|
});
|
|
|
|
test("should update product prices", async () => {
|
|
const mockProducts = [
|
|
{
|
|
id: "product1",
|
|
title: "Test Product 1",
|
|
variants: [{ id: "variant1", price: 10.0 }],
|
|
},
|
|
];
|
|
const mockResults = {
|
|
totalProducts: 1,
|
|
totalVariants: 1,
|
|
successfulUpdates: 1,
|
|
failedUpdates: 0,
|
|
errors: [],
|
|
};
|
|
mockProductService.updateProductPrices.mockResolvedValue(mockResults);
|
|
|
|
const service = new ProductService();
|
|
const results = await service.updateProductPrices(mockProducts, 10);
|
|
|
|
expect(mockProductService.updateProductPrices).toHaveBeenCalledWith(
|
|
mockProducts,
|
|
10
|
|
);
|
|
expect(results).toEqual(mockResults);
|
|
});
|
|
|
|
test("should rollback product prices", async () => {
|
|
const mockProducts = [
|
|
{
|
|
id: "product1",
|
|
title: "Test Product 1",
|
|
variants: [{ id: "variant1", price: 11.0, compareAtPrice: 10.0 }],
|
|
},
|
|
];
|
|
const mockResults = {
|
|
totalProducts: 1,
|
|
totalVariants: 1,
|
|
successfulRollbacks: 1,
|
|
failedRollbacks: 0,
|
|
skippedVariants: 0,
|
|
errors: [],
|
|
};
|
|
mockProductService.rollbackProductPrices.mockResolvedValue(mockResults);
|
|
|
|
const service = new ProductService();
|
|
const results = await service.rollbackProductPrices(mockProducts);
|
|
|
|
expect(mockProductService.rollbackProductPrices).toHaveBeenCalledWith(
|
|
mockProducts
|
|
);
|
|
expect(results).toEqual(mockResults);
|
|
});
|
|
|
|
test("should validate products", async () => {
|
|
const mockProducts = [
|
|
{
|
|
id: "product1",
|
|
title: "Test Product 1",
|
|
variants: [{ id: "variant1", price: 10.0 }],
|
|
},
|
|
];
|
|
mockProductService.validateProducts.mockResolvedValue(mockProducts);
|
|
|
|
const service = new ProductService();
|
|
const validProducts = await service.validateProducts(mockProducts);
|
|
|
|
expect(mockProductService.validateProducts).toHaveBeenCalledWith(
|
|
mockProducts
|
|
);
|
|
expect(validProducts).toEqual(mockProducts);
|
|
});
|
|
|
|
test("should validate products for rollback", async () => {
|
|
const mockProducts = [
|
|
{
|
|
id: "product1",
|
|
title: "Test Product 1",
|
|
variants: [{ id: "variant1", price: 11.0, compareAtPrice: 10.0 }],
|
|
},
|
|
];
|
|
mockProductService.validateProductsForRollback.mockResolvedValue(
|
|
mockProducts
|
|
);
|
|
|
|
const service = new ProductService();
|
|
const validProducts = await service.validateProductsForRollback(
|
|
mockProducts
|
|
);
|
|
|
|
expect(
|
|
mockProductService.validateProductsForRollback
|
|
).toHaveBeenCalledWith(mockProducts);
|
|
expect(validProducts).toEqual(mockProducts);
|
|
});
|
|
|
|
test("should get product summary", () => {
|
|
const mockProducts = [
|
|
{
|
|
id: "product1",
|
|
title: "Test Product 1",
|
|
variants: [{ id: "variant1", price: 10.0 }],
|
|
},
|
|
];
|
|
const mockSummary = {
|
|
totalProducts: 1,
|
|
totalVariants: 1,
|
|
priceRange: { min: 10.0, max: 10.0 },
|
|
};
|
|
mockProductService.getProductSummary.mockReturnValue(mockSummary);
|
|
|
|
const service = new ProductService();
|
|
const summary = service.getProductSummary(mockProducts);
|
|
|
|
expect(mockProductService.getProductSummary).toHaveBeenCalledWith(
|
|
mockProducts
|
|
);
|
|
expect(summary).toEqual(mockSummary);
|
|
});
|
|
});
|
|
|
|
describe("ProgressService Integration", () => {
|
|
test("should log operation start", async () => {
|
|
const mockConfig = {
|
|
targetTag: "test-tag",
|
|
priceAdjustmentPercentage: 10,
|
|
};
|
|
mockProgressService.logOperationStart.mockResolvedValue();
|
|
|
|
const service = new ProgressService();
|
|
await service.logOperationStart(mockConfig);
|
|
|
|
expect(mockProgressService.logOperationStart).toHaveBeenCalledWith(
|
|
mockConfig
|
|
);
|
|
});
|
|
|
|
test("should log rollback start", async () => {
|
|
const mockConfig = { targetTag: "test-tag" };
|
|
mockProgressService.logRollbackStart.mockResolvedValue();
|
|
|
|
const service = new ProgressService();
|
|
await service.logRollbackStart(mockConfig);
|
|
|
|
expect(mockProgressService.logRollbackStart).toHaveBeenCalledWith(
|
|
mockConfig
|
|
);
|
|
});
|
|
|
|
test("should log product update", async () => {
|
|
const mockEntry = {
|
|
productId: "product1",
|
|
productTitle: "Test Product",
|
|
variantId: "variant1",
|
|
oldPrice: 10.0,
|
|
newPrice: 11.0,
|
|
compareAtPrice: 10.0,
|
|
};
|
|
mockProgressService.logProductUpdate.mockResolvedValue();
|
|
|
|
const service = new ProgressService();
|
|
await service.logProductUpdate(mockEntry);
|
|
|
|
expect(mockProgressService.logProductUpdate).toHaveBeenCalledWith(
|
|
mockEntry
|
|
);
|
|
});
|
|
|
|
test("should log rollback update", async () => {
|
|
const mockEntry = {
|
|
productId: "product1",
|
|
productTitle: "Test Product",
|
|
variantId: "variant1",
|
|
oldPrice: 11.0,
|
|
newPrice: 10.0,
|
|
compareAtPrice: 10.0,
|
|
};
|
|
mockProgressService.logRollbackUpdate.mockResolvedValue();
|
|
|
|
const service = new ProgressService();
|
|
await service.logRollbackUpdate(mockEntry);
|
|
|
|
expect(mockProgressService.logRollbackUpdate).toHaveBeenCalledWith(
|
|
mockEntry
|
|
);
|
|
});
|
|
|
|
test("should log error", async () => {
|
|
const mockEntry = {
|
|
productId: "product1",
|
|
productTitle: "Test Product",
|
|
variantId: "variant1",
|
|
errorMessage: "Test error",
|
|
};
|
|
mockProgressService.logError.mockResolvedValue();
|
|
|
|
const service = new ProgressService();
|
|
await service.logError(mockEntry);
|
|
|
|
expect(mockProgressService.logError).toHaveBeenCalledWith(mockEntry);
|
|
});
|
|
|
|
test("should log completion summary", async () => {
|
|
const mockSummary = {
|
|
totalProducts: 1,
|
|
successfulUpdates: 1,
|
|
failedUpdates: 0,
|
|
startTime: new Date(),
|
|
};
|
|
mockProgressService.logCompletionSummary.mockResolvedValue();
|
|
|
|
const service = new ProgressService();
|
|
await service.logCompletionSummary(mockSummary);
|
|
|
|
expect(mockProgressService.logCompletionSummary).toHaveBeenCalledWith(
|
|
mockSummary
|
|
);
|
|
});
|
|
|
|
test("should log rollback summary", async () => {
|
|
const mockSummary = {
|
|
totalProducts: 1,
|
|
totalVariants: 1,
|
|
successfulRollbacks: 1,
|
|
failedRollbacks: 0,
|
|
skippedVariants: 0,
|
|
startTime: new Date(),
|
|
};
|
|
mockProgressService.logRollbackSummary.mockResolvedValue();
|
|
|
|
const service = new ProgressService();
|
|
await service.logRollbackSummary(mockSummary);
|
|
|
|
expect(mockProgressService.logRollbackSummary).toHaveBeenCalledWith(
|
|
mockSummary
|
|
);
|
|
});
|
|
});
|
|
|
|
describe("Service Integration Workflow", () => {
|
|
test("should support complete update workflow", async () => {
|
|
// Mock the complete workflow
|
|
const mockProducts = [
|
|
{
|
|
id: "product1",
|
|
title: "Test Product 1",
|
|
variants: [{ id: "variant1", price: 10.0 }],
|
|
},
|
|
];
|
|
const mockConfig = {
|
|
targetTag: "test-tag",
|
|
priceAdjustmentPercentage: 10,
|
|
};
|
|
const mockResults = {
|
|
totalProducts: 1,
|
|
totalVariants: 1,
|
|
successfulUpdates: 1,
|
|
failedUpdates: 0,
|
|
errors: [],
|
|
};
|
|
|
|
mockProductService.fetchProductsByTag.mockResolvedValue(mockProducts);
|
|
mockProductService.validateProducts.mockResolvedValue(mockProducts);
|
|
mockProductService.updateProductPrices.mockResolvedValue(mockResults);
|
|
mockProgressService.logOperationStart.mockResolvedValue();
|
|
mockProgressService.logCompletionSummary.mockResolvedValue();
|
|
|
|
const productService = new ProductService();
|
|
const progressService = new ProgressService();
|
|
|
|
// Execute workflow
|
|
await progressService.logOperationStart(mockConfig);
|
|
const fetchedProducts = await productService.fetchProductsByTag(
|
|
mockConfig.targetTag
|
|
);
|
|
const validProducts = await productService.validateProducts(
|
|
fetchedProducts
|
|
);
|
|
const results = await productService.updateProductPrices(
|
|
validProducts,
|
|
mockConfig.priceAdjustmentPercentage
|
|
);
|
|
await progressService.logCompletionSummary(results);
|
|
|
|
// Verify workflow execution
|
|
expect(mockProgressService.logOperationStart).toHaveBeenCalledWith(
|
|
mockConfig
|
|
);
|
|
expect(mockProductService.fetchProductsByTag).toHaveBeenCalledWith(
|
|
mockConfig.targetTag
|
|
);
|
|
expect(mockProductService.validateProducts).toHaveBeenCalledWith(
|
|
mockProducts
|
|
);
|
|
expect(mockProductService.updateProductPrices).toHaveBeenCalledWith(
|
|
mockProducts,
|
|
mockConfig.priceAdjustmentPercentage
|
|
);
|
|
expect(mockProgressService.logCompletionSummary).toHaveBeenCalledWith(
|
|
mockResults
|
|
);
|
|
});
|
|
|
|
test("should support complete rollback workflow", async () => {
|
|
// Mock the complete rollback workflow
|
|
const mockProducts = [
|
|
{
|
|
id: "product1",
|
|
title: "Test Product 1",
|
|
variants: [{ id: "variant1", price: 11.0, compareAtPrice: 10.0 }],
|
|
},
|
|
];
|
|
const mockConfig = { targetTag: "test-tag" };
|
|
const mockResults = {
|
|
totalProducts: 1,
|
|
totalVariants: 1,
|
|
successfulRollbacks: 1,
|
|
failedRollbacks: 0,
|
|
skippedVariants: 0,
|
|
errors: [],
|
|
};
|
|
|
|
mockProductService.fetchProductsByTag.mockResolvedValue(mockProducts);
|
|
mockProductService.validateProductsForRollback.mockResolvedValue(
|
|
mockProducts
|
|
);
|
|
mockProductService.rollbackProductPrices.mockResolvedValue(mockResults);
|
|
mockProgressService.logRollbackStart.mockResolvedValue();
|
|
mockProgressService.logRollbackSummary.mockResolvedValue();
|
|
|
|
const productService = new ProductService();
|
|
const progressService = new ProgressService();
|
|
|
|
// Execute rollback workflow
|
|
await progressService.logRollbackStart(mockConfig);
|
|
const fetchedProducts = await productService.fetchProductsByTag(
|
|
mockConfig.targetTag
|
|
);
|
|
const validProducts = await productService.validateProductsForRollback(
|
|
fetchedProducts
|
|
);
|
|
const results = await productService.rollbackProductPrices(validProducts);
|
|
await progressService.logRollbackSummary(results);
|
|
|
|
// Verify rollback workflow execution
|
|
expect(mockProgressService.logRollbackStart).toHaveBeenCalledWith(
|
|
mockConfig
|
|
);
|
|
expect(mockProductService.fetchProductsByTag).toHaveBeenCalledWith(
|
|
mockConfig.targetTag
|
|
);
|
|
expect(
|
|
mockProductService.validateProductsForRollback
|
|
).toHaveBeenCalledWith(mockProducts);
|
|
expect(mockProductService.rollbackProductPrices).toHaveBeenCalledWith(
|
|
mockProducts
|
|
);
|
|
expect(mockProgressService.logRollbackSummary).toHaveBeenCalledWith(
|
|
mockResults
|
|
);
|
|
});
|
|
});
|
|
});
|