209 lines
6.9 KiB
JavaScript
209 lines
6.9 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 ShopifyService Integration", () => {
|
|
let mockShopifyService;
|
|
let mockProductService;
|
|
let mockProgressService;
|
|
|
|
beforeEach(() => {
|
|
// Reset all mocks
|
|
jest.clearAllMocks();
|
|
|
|
// Create mock ShopifyService instance
|
|
mockShopifyService = {
|
|
testConnection: jest.fn(),
|
|
getApiCallLimit: 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(),
|
|
};
|
|
|
|
// Create mock ProgressService instance
|
|
mockProgressService = {
|
|
logOperationStart: jest.fn(),
|
|
logProductUpdate: jest.fn(),
|
|
logCompletionSummary: jest.fn(),
|
|
};
|
|
|
|
// Mock the service constructors
|
|
ShopifyService.mockImplementation(() => mockShopifyService);
|
|
ProductService.mockImplementation(() => mockProductService);
|
|
ProgressService.mockImplementation(() => mockProgressService);
|
|
});
|
|
|
|
describe("Service Integration", () => {
|
|
test("should create ShopifyService instance", () => {
|
|
const service = new ShopifyService();
|
|
expect(service).toBeDefined();
|
|
expect(service.testConnection).toBeDefined();
|
|
expect(service.executeQuery).toBeDefined();
|
|
expect(service.executeMutation).toBeDefined();
|
|
});
|
|
|
|
test("should test connection through ShopifyService", async () => {
|
|
mockShopifyService.testConnection.mockResolvedValue(true);
|
|
|
|
const service = new ShopifyService();
|
|
const isConnected = await service.testConnection();
|
|
|
|
expect(mockShopifyService.testConnection).toHaveBeenCalled();
|
|
expect(isConnected).toBe(true);
|
|
});
|
|
|
|
test("should handle connection test failures", async () => {
|
|
mockShopifyService.testConnection.mockRejectedValue(
|
|
new Error("Connection failed")
|
|
);
|
|
|
|
const service = new ShopifyService();
|
|
|
|
await expect(service.testConnection()).rejects.toThrow(
|
|
"Connection failed"
|
|
);
|
|
});
|
|
|
|
test("should execute GraphQL queries through ShopifyService", async () => {
|
|
const mockResponse = { data: { shop: { name: "Test Shop" } } };
|
|
mockShopifyService.executeQuery.mockResolvedValue(mockResponse);
|
|
|
|
const service = new ShopifyService();
|
|
const query = "query { shop { name } }";
|
|
const variables = { test: "value" };
|
|
const result = await service.executeQuery(query, variables);
|
|
|
|
expect(mockShopifyService.executeQuery).toHaveBeenCalledWith(
|
|
query,
|
|
variables
|
|
);
|
|
expect(result).toEqual(mockResponse);
|
|
});
|
|
|
|
test("should execute GraphQL mutations through ShopifyService", async () => {
|
|
const mockResponse = { data: { productUpdate: { id: "123" } } };
|
|
mockShopifyService.executeMutation.mockResolvedValue(mockResponse);
|
|
|
|
const service = new ShopifyService();
|
|
const mutation = "mutation { productUpdate(input: {}) { id } }";
|
|
const variables = { input: { id: "123" } };
|
|
const result = await service.executeMutation(mutation, variables);
|
|
|
|
expect(mockShopifyService.executeMutation).toHaveBeenCalledWith(
|
|
mutation,
|
|
variables
|
|
);
|
|
expect(result).toEqual(mockResponse);
|
|
});
|
|
|
|
test("should execute operations with retry logic", async () => {
|
|
const mockOperation = jest.fn().mockResolvedValue("success");
|
|
const mockLogger = { log: jest.fn() };
|
|
mockShopifyService.executeWithRetry.mockResolvedValue("success");
|
|
|
|
const service = new ShopifyService();
|
|
const result = await service.executeWithRetry(mockOperation, mockLogger);
|
|
|
|
expect(mockShopifyService.executeWithRetry).toHaveBeenCalledWith(
|
|
mockOperation,
|
|
mockLogger
|
|
);
|
|
expect(result).toBe("success");
|
|
});
|
|
|
|
test("should get API call limit information", async () => {
|
|
const mockLimitInfo = {
|
|
requestedQueryCost: 10,
|
|
actualQueryCost: 8,
|
|
throttleStatus: { maximumAvailable: 1000, currentlyAvailable: 992 },
|
|
};
|
|
mockShopifyService.getApiCallLimit.mockResolvedValue(mockLimitInfo);
|
|
|
|
const service = new ShopifyService();
|
|
const limitInfo = await service.getApiCallLimit();
|
|
|
|
expect(mockShopifyService.getApiCallLimit).toHaveBeenCalled();
|
|
expect(limitInfo).toEqual(mockLimitInfo);
|
|
});
|
|
|
|
test("should handle API call limit retrieval errors gracefully", async () => {
|
|
mockShopifyService.getApiCallLimit.mockRejectedValue(
|
|
new Error("API limit error")
|
|
);
|
|
|
|
const service = new ShopifyService();
|
|
|
|
await expect(service.getApiCallLimit()).rejects.toThrow(
|
|
"API limit error"
|
|
);
|
|
});
|
|
});
|
|
|
|
describe("Service Method Integration", () => {
|
|
test("should integrate all service methods correctly", () => {
|
|
const shopifyService = new ShopifyService();
|
|
const productService = new ProductService();
|
|
const progressService = new ProgressService();
|
|
|
|
// Verify all services are created
|
|
expect(shopifyService).toBeDefined();
|
|
expect(productService).toBeDefined();
|
|
expect(progressService).toBeDefined();
|
|
|
|
// Verify ShopifyService methods
|
|
expect(typeof shopifyService.testConnection).toBe("function");
|
|
expect(typeof shopifyService.executeQuery).toBe("function");
|
|
expect(typeof shopifyService.executeMutation).toBe("function");
|
|
expect(typeof shopifyService.executeWithRetry).toBe("function");
|
|
expect(typeof shopifyService.getApiCallLimit).toBe("function");
|
|
|
|
// Verify ProductService methods
|
|
expect(typeof productService.fetchProductsByTag).toBe("function");
|
|
expect(typeof productService.updateProductPrices).toBe("function");
|
|
expect(typeof productService.rollbackProductPrices).toBe("function");
|
|
|
|
// Verify ProgressService methods
|
|
expect(typeof progressService.logOperationStart).toBe("function");
|
|
expect(typeof progressService.logProductUpdate).toBe("function");
|
|
expect(typeof progressService.logCompletionSummary).toBe("function");
|
|
});
|
|
|
|
test("should maintain service API compatibility", async () => {
|
|
// Test that services maintain their expected API
|
|
mockShopifyService.testConnection.mockResolvedValue(true);
|
|
mockProductService.fetchProductsByTag.mockResolvedValue([]);
|
|
mockProgressService.logOperationStart.mockResolvedValue();
|
|
|
|
const shopifyService = new ShopifyService();
|
|
const productService = new ProductService();
|
|
const progressService = new ProgressService();
|
|
|
|
// Test ShopifyService API
|
|
const connectionResult = await shopifyService.testConnection();
|
|
expect(connectionResult).toBe(true);
|
|
|
|
// Test ProductService API
|
|
const products = await productService.fetchProductsByTag("test-tag");
|
|
expect(Array.isArray(products)).toBe(true);
|
|
|
|
// Test ProgressService API
|
|
await progressService.logOperationStart({ targetTag: "test" });
|
|
expect(mockProgressService.logOperationStart).toHaveBeenCalledWith({
|
|
targetTag: "test",
|
|
});
|
|
});
|
|
});
|
|
});
|