Skip to main content
Glama

SFCC Development MCP Server

by taurgis
testing-patterns.mdc15.1 kB
--- description: SFCC testing patterns and test automation globs: "**/test/**/*.js" alwaysApply: false --- # SFCC Testing Patterns Use this rule when creating tests for SFCC components. ## Mandatory MCP Tools Sequence for Testing **BEFORE writing ANY SFCC tests:** 1. `mcp_sfcc-dev_search_best_practices` with query: "testing" 2. `mcp_sfcc-dev_get_best_practice_guide` with guideName: relevant guide for component under test 3. `mcp_sfcc-dev_search_sfcc_classes` with query: classes being tested 4. `mcp_sfcc-dev_get_sfcc_class_info` with className: specific classes under test ## MCP-Guided Testing Development Process ### Step 1: Research Testing Best Practices ``` Use: mcp_sfcc-dev_search_best_practices with query: "testing" Purpose: Get SFCC-specific testing patterns and guidelines ``` ### Step 2: Understand Component Being Tested ``` Use: mcp_sfcc-dev_get_best_practice_guide with guideName: [relevant guide] Purpose: Get implementation patterns for the component type being tested ``` ### Step 3: Research SFCC Classes Under Test ``` Use: mcp_sfcc-dev_search_sfcc_classes with query: [component domain] Use: mcp_sfcc-dev_get_sfcc_class_info with className: [specific class] Purpose: Understand the SFCC APIs and methods being tested ``` ## MCP-Enhanced Test Template Pattern ```javascript 'use strict'; /** * Test Suite: [Component Name] * Purpose: Test [component functionality] * * Implementation based on: * - mcp_sfcc-dev_search_best_practices with query: "testing" * - mcp_sfcc-dev_get_best_practice_guide with guideName: "[relevant guide]" * - mcp_sfcc-dev_search_sfcc_classes with query: "[domain]" */ var assert = require('chai').assert; var proxyquire = require('proxyquire').noCallThru().noPreserveCache(); describe('ComponentName', function () { var ComponentName; var mockDependencies; var mockLogger; beforeEach(function () { // Mock SFCC dependencies (patterns from MCP testing best practices) mockLogger = { error: sinon.spy(), warn: sinon.spy(), info: sinon.spy(), debug: sinon.spy() }; mockDependencies = { 'dw/system/Logger': { getLogger: function () { return mockLogger; } }, 'dw/system/Transaction': { wrap: function (callback) { return callback(); } }, // Add other SFCC mocks based on MCP class research }; ComponentName = proxyquire('../../../cartridge/scripts/ComponentName', mockDependencies); }); describe('Happy Path Tests', function () { it('should handle valid input correctly', function () { // Arrange (use patterns from MCP best practices) var validInput = 'valid-test-input'; // Act var result = ComponentName.methodName(validInput); // Assert (comprehensive validation from MCP testing patterns) assert.isTrue(result.success, 'Operation should succeed'); assert.isDefined(result.data, 'Result data should be defined'); assert.isString(result.data.someProperty, 'Property should be string'); }); it('should process multiple valid inputs', function () { var inputs = ['input1', 'input2', 'input3']; var results = inputs.map(function(input) { return ComponentName.methodName(input); }); results.forEach(function(result, index) { assert.isTrue(result.success, 'Input ' + index + ' should succeed'); assert.isDefined(result.data, 'Result ' + index + ' should have data'); }); }); }); describe('Error Handling Tests', function () { it('should handle null input gracefully', function () { // Test null input (critical pattern from MCP testing practices) var result = ComponentName.methodName(null); assert.isFalse(result.success, 'Null input should fail gracefully'); assert.isDefined(result.error, 'Error message should be provided'); assert.equal(result.error, 'INVALID_INPUT', 'Should return expected error code'); }); it('should handle undefined input gracefully', function () { var result = ComponentName.methodName(undefined); assert.isFalse(result.success, 'Undefined input should fail gracefully'); assert.isDefined(result.error, 'Error message should be provided'); }); it('should handle invalid input types', function () { var invalidInputs = [123, {}, [], true]; invalidInputs.forEach(function(invalidInput) { var result = ComponentName.methodName(invalidInput); assert.isFalse(result.success, 'Invalid input type should fail'); assert.isDefined(result.error, 'Error should be defined for invalid input'); }); }); it('should handle errors from dependencies', function () { // Mock dependency error (from MCP error handling patterns) var errorDependencies = Object.assign({}, mockDependencies, { 'dw/system/SomeManager': { getObject: function() { throw new Error('Dependency error'); } } }); var ComponentWithError = proxyquire('../../../cartridge/scripts/ComponentName', errorDependencies); var result = ComponentWithError.methodName('validInput'); assert.isFalse(result.success, 'Should handle dependency errors'); assert.isDefined(result.error, 'Error message should be provided'); assert.isTrue(mockLogger.error.called, 'Should log errors'); }); }); describe('Edge Cases and Boundary Tests', function () { it('should handle empty string input', function () { var result = ComponentName.methodName(''); assert.isFalse(result.success, 'Empty string should be rejected'); assert.equal(result.error, 'EMPTY_INPUT', 'Should identify empty input'); }); it('should handle very long input strings', function () { var longInput = 'a'.repeat(10000); var result = ComponentName.methodName(longInput); // Validate based on expected behavior from MCP patterns if (result.success) { assert.isDefined(result.data, 'Long input processing should provide data'); } else { assert.equal(result.error, 'INPUT_TOO_LONG', 'Should handle length limits'); } }); it('should handle special characters in input', function () { var specialChars = ['<script>', '&amp;', '"quotes"', "'single'"]; specialChars.forEach(function(input) { var result = ComponentName.methodName(input); // Validate security handling (from MCP security patterns) if (result.success) { // Ensure output is sanitized assert.notInclude(result.data.toString(), '<script>', 'Should sanitize script tags'); } }); }); }); describe('Security Tests (from MCP Security Patterns)', function () { it('should sanitize XSS attempts', function () { var xssAttempts = [ '<script>alert("xss")</script>', 'javascript:void(0)', 'onload="alert(1)"' ]; xssAttempts.forEach(function(xssInput) { var result = ComponentName.methodName(xssInput); if (result.success) { // Ensure XSS is neutralized (pattern from MCP security guide) assert.notInclude(result.data.toString().toLowerCase(), 'script', 'Should remove script tags'); assert.notInclude(result.data.toString().toLowerCase(), 'javascript:', 'Should remove javascript protocol'); } }); }); it('should prevent SQL injection patterns', function () { var sqlAttempts = [ "'; DROP TABLE users; --", "' OR '1'='1", "UNION SELECT * FROM admin" ]; sqlAttempts.forEach(function(sqlInput) { var result = ComponentName.methodName(sqlInput); // Should either reject or sanitize (based on MCP security patterns) assert.isDefined(result, 'Should handle SQL injection attempts'); }); }); }); describe('Performance Tests', function () { it('should complete within reasonable time', function () { this.timeout(5000); // 5 second timeout var startTime = Date.now(); var result = ComponentName.methodName('performance-test-input'); var duration = Date.now() - startTime; assert.isBelow(duration, 1000, 'Should complete within 1 second'); assert.isDefined(result, 'Should return result within time limit'); }); it('should handle multiple concurrent operations', function () { var promises = []; var concurrentCount = 10; for (var i = 0; i < concurrentCount; i++) { promises.push( new Promise(function(resolve) { var result = ComponentName.methodName('concurrent-test-' + i); resolve(result); }) ); } return Promise.all(promises).then(function(results) { assert.equal(results.length, concurrentCount, 'All operations should complete'); results.forEach(function(result, index) { assert.isDefined(result, 'Result ' + index + ' should be defined'); }); }); }); }); }); ``` ## Mock Patterns for SFCC Objects (from MCP Research) ```javascript /** * Mock SFCC objects based on MCP system object research */ // Mock Product (use structure from MCP system object definitions) var mockProduct = { ID: 'test-product-id', name: 'Test Product', online: true, custom: { customAttribute: 'test-value', customSize: 'Medium', customColor: 'Blue' }, getPriceModel: function () { return { getPrice: function () { return { value: 99.99, currencyCode: 'USD' }; } }; }, getAvailabilityModel: function() { return { isInStock: function() { return true; }, getInventoryRecord: function() { return { allocation: { value: 100 } }; } }; } }; // Mock Customer (use structure from MCP customer object research) var mockCustomer = { authenticated: true, profile: { customerNo: 'test-customer-123', email: 'test@example.com', firstName: 'Test', lastName: 'User', custom: { loyaltyTier: 'Gold', customField: 'test-value' } }, addressBook: { addresses: [] } }; // Mock Order (use structure from MCP order object research) var mockOrder = { orderNo: 'TEST-ORDER-001', totalGrossPrice: { value: 199.99, currencyCode: 'USD' }, productLineItems: [], customer: mockCustomer, custom: { orderSource: 'web', customOrderField: 'test-value' } }; // Mock Site (for site preferences from MCP) var mockSite = { current: { getCustomPreferenceValue: function(prefName) { var preferences = { 'maxOrderQuantity': 10, 'enableFeature': true, 'customSetting': 'test-value' }; return preferences[prefName] || null; } } }; ``` ## Testing Checklist (MCP-Verified) Before writing tests, verify with MCP: - [ ] `mcp_sfcc-dev_search_best_practices` with query: "testing" - Get testing patterns - [ ] `mcp_sfcc-dev_get_best_practice_guide` - Get implementation patterns for component - [ ] `mcp_sfcc-dev_search_sfcc_classes` - Research classes being tested Test coverage verification: - [ ] Test both success and failure scenarios - [ ] Mock external dependencies consistently - [ ] Use descriptive test names that explain behavior - [ ] Test error handling and edge cases - [ ] Validate both positive and negative outcomes - [ ] Include integration tests for complete workflows - [ ] Test security validations and input sanitization - [ ] Performance tests for critical operations - [ ] Test with realistic SFCC object structures ## Advanced Testing Patterns (from MCP Best Practices) ```javascript // Integration test pattern for SFCC workflows describe('Integration: Complete Customer Journey', function() { it('should handle complete purchase flow', function() { // Test complete workflow using MCP-researched SFCC patterns var customerResult = ComponentName.authenticateCustomer(mockCustomer); assert.isTrue(customerResult.success, 'Customer authentication should succeed'); var cartResult = ComponentName.addToCart(mockProduct, 2); assert.isTrue(cartResult.success, 'Add to cart should succeed'); var orderResult = ComponentName.createOrder(cartResult.cart); assert.isTrue(orderResult.success, 'Order creation should succeed'); assert.isDefined(orderResult.orderNo, 'Order number should be generated'); }); }); // Transaction testing pattern (from MCP transaction patterns) describe('Transaction Handling', function() { it('should handle transaction rollback on error', function() { var transactionRolledBack = false; mockDependencies['dw/system/Transaction'] = { wrap: function(callback) { try { return callback(); } catch (e) { transactionRolledBack = true; throw e; } } }; // Test that triggers transaction rollback var ComponentWithTransaction = proxyquire('../../../cartridge/scripts/ComponentName', mockDependencies); assert.throws(function() { ComponentWithTransaction.methodThatShouldFail('error-input'); }); assert.isTrue(transactionRolledBack, 'Transaction should be rolled back on error'); }); }); ``` ## NEVER Write Tests Without MCP - ❌ Don't write tests without understanding patterns - use `mcp_sfcc-dev_search_best_practices` - ❌ Don't mock SFCC objects without research - use `mcp_sfcc-dev_get_system_object_definitions` - ❌ Don't test components without understanding implementation - use relevant MCP guides - ❌ Don't assume SFCC class behavior - use `mcp_sfcc-dev_get_sfcc_class_info`

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/taurgis/sfcc-dev-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server