This is page 44 of 61. Use http://codebase.md/taurgis/sfcc-dev-mcp?lines=true&page={x} to view the full context.
# Directory Structure
```
├── .DS_Store
├── .github
│ ├── dependabot.yml
│ ├── instructions
│ │ ├── mcp-node-tests.instructions.md
│ │ └── mcp-yml-tests.instructions.md
│ ├── ISSUE_TEMPLATE
│ │ ├── bug_report.yml
│ │ ├── config.yml
│ │ ├── documentation.yml
│ │ ├── feature_request.yml
│ │ └── question.yml
│ ├── PULL_REQUEST_TEMPLATE
│ │ ├── bug_fix.md
│ │ ├── documentation.md
│ │ └── new_tool.md
│ ├── pull_request_template.md
│ └── workflows
│ ├── ci.yml
│ ├── deploy-pages.yml
│ ├── publish.yml
│ └── update-docs.yml
├── .gitignore
├── .husky
│ └── pre-commit
├── aegis.config.docs-only.json
├── aegis.config.json
├── aegis.config.with-dw.json
├── AGENTS.md
├── ai-instructions
│ ├── claude-desktop
│ │ └── claude_custom_instructions.md
│ ├── cursor
│ │ └── .cursor
│ │ └── rules
│ │ ├── debugging-workflows.mdc
│ │ ├── hooks-development.mdc
│ │ ├── isml-templates.mdc
│ │ ├── job-framework.mdc
│ │ ├── performance-optimization.mdc
│ │ ├── scapi-endpoints.mdc
│ │ ├── security-patterns.mdc
│ │ ├── sfcc-development.mdc
│ │ ├── sfra-controllers.mdc
│ │ ├── sfra-models.mdc
│ │ ├── system-objects.mdc
│ │ └── testing-patterns.mdc
│ └── github-copilot
│ └── copilot-instructions.md
├── CHANGELOG.md
├── CONTRIBUTING.md
├── docs
│ ├── best-practices
│ │ ├── cartridge_creation.md
│ │ ├── isml_templates.md
│ │ ├── job_framework.md
│ │ ├── localserviceregistry.md
│ │ ├── ocapi_hooks.md
│ │ ├── performance.md
│ │ ├── scapi_custom_endpoint.md
│ │ ├── scapi_hooks.md
│ │ ├── security.md
│ │ ├── sfra_client_side_js.md
│ │ ├── sfra_controllers.md
│ │ ├── sfra_models.md
│ │ └── sfra_scss.md
│ ├── dw_campaign
│ │ ├── ABTest.md
│ │ ├── ABTestMgr.md
│ │ ├── ABTestSegment.md
│ │ ├── AmountDiscount.md
│ │ ├── ApproachingDiscount.md
│ │ ├── BonusChoiceDiscount.md
│ │ ├── BonusDiscount.md
│ │ ├── Campaign.md
│ │ ├── CampaignMgr.md
│ │ ├── CampaignStatusCodes.md
│ │ ├── Coupon.md
│ │ ├── CouponMgr.md
│ │ ├── CouponRedemption.md
│ │ ├── CouponStatusCodes.md
│ │ ├── Discount.md
│ │ ├── DiscountPlan.md
│ │ ├── FixedPriceDiscount.md
│ │ ├── FixedPriceShippingDiscount.md
│ │ ├── FreeDiscount.md
│ │ ├── FreeShippingDiscount.md
│ │ ├── PercentageDiscount.md
│ │ ├── PercentageOptionDiscount.md
│ │ ├── PriceBookPriceDiscount.md
│ │ ├── Promotion.md
│ │ ├── PromotionMgr.md
│ │ ├── PromotionPlan.md
│ │ ├── SlotContent.md
│ │ ├── SourceCodeGroup.md
│ │ ├── SourceCodeInfo.md
│ │ ├── SourceCodeStatusCodes.md
│ │ └── TotalFixedPriceDiscount.md
│ ├── dw_catalog
│ │ ├── Catalog.md
│ │ ├── CatalogMgr.md
│ │ ├── Category.md
│ │ ├── CategoryAssignment.md
│ │ ├── CategoryLink.md
│ │ ├── PriceBook.md
│ │ ├── PriceBookMgr.md
│ │ ├── Product.md
│ │ ├── ProductActiveData.md
│ │ ├── ProductAttributeModel.md
│ │ ├── ProductAvailabilityLevels.md
│ │ ├── ProductAvailabilityModel.md
│ │ ├── ProductInventoryList.md
│ │ ├── ProductInventoryMgr.md
│ │ ├── ProductInventoryRecord.md
│ │ ├── ProductLink.md
│ │ ├── ProductMgr.md
│ │ ├── ProductOption.md
│ │ ├── ProductOptionModel.md
│ │ ├── ProductOptionValue.md
│ │ ├── ProductPriceInfo.md
│ │ ├── ProductPriceModel.md
│ │ ├── ProductPriceTable.md
│ │ ├── ProductSearchHit.md
│ │ ├── ProductSearchModel.md
│ │ ├── ProductSearchRefinementDefinition.md
│ │ ├── ProductSearchRefinements.md
│ │ ├── ProductSearchRefinementValue.md
│ │ ├── ProductVariationAttribute.md
│ │ ├── ProductVariationAttributeValue.md
│ │ ├── ProductVariationModel.md
│ │ ├── Recommendation.md
│ │ ├── SearchModel.md
│ │ ├── SearchRefinementDefinition.md
│ │ ├── SearchRefinements.md
│ │ ├── SearchRefinementValue.md
│ │ ├── SortingOption.md
│ │ ├── SortingRule.md
│ │ ├── Store.md
│ │ ├── StoreGroup.md
│ │ ├── StoreInventoryFilter.md
│ │ ├── StoreInventoryFilterValue.md
│ │ ├── StoreMgr.md
│ │ ├── Variant.md
│ │ └── VariationGroup.md
│ ├── dw_content
│ │ ├── Content.md
│ │ ├── ContentMgr.md
│ │ ├── ContentSearchModel.md
│ │ ├── ContentSearchRefinementDefinition.md
│ │ ├── ContentSearchRefinements.md
│ │ ├── ContentSearchRefinementValue.md
│ │ ├── Folder.md
│ │ ├── Library.md
│ │ ├── MarkupText.md
│ │ └── MediaFile.md
│ ├── dw_crypto
│ │ ├── CertificateRef.md
│ │ ├── CertificateUtils.md
│ │ ├── Cipher.md
│ │ ├── Encoding.md
│ │ ├── JWE.md
│ │ ├── JWEHeader.md
│ │ ├── JWS.md
│ │ ├── JWSHeader.md
│ │ ├── KeyRef.md
│ │ ├── Mac.md
│ │ ├── MessageDigest.md
│ │ ├── SecureRandom.md
│ │ ├── Signature.md
│ │ ├── WeakCipher.md
│ │ ├── WeakMac.md
│ │ ├── WeakMessageDigest.md
│ │ ├── WeakSignature.md
│ │ └── X509Certificate.md
│ ├── dw_customer
│ │ ├── AddressBook.md
│ │ ├── AgentUserMgr.md
│ │ ├── AgentUserStatusCodes.md
│ │ ├── AuthenticationStatus.md
│ │ ├── Credentials.md
│ │ ├── Customer.md
│ │ ├── CustomerActiveData.md
│ │ ├── CustomerAddress.md
│ │ ├── CustomerCDPData.md
│ │ ├── CustomerContextMgr.md
│ │ ├── CustomerGroup.md
│ │ ├── CustomerList.md
│ │ ├── CustomerMgr.md
│ │ ├── CustomerPasswordConstraints.md
│ │ ├── CustomerPaymentInstrument.md
│ │ ├── CustomerStatusCodes.md
│ │ ├── EncryptedObject.md
│ │ ├── ExternalProfile.md
│ │ ├── OrderHistory.md
│ │ ├── ProductList.md
│ │ ├── ProductListItem.md
│ │ ├── ProductListItemPurchase.md
│ │ ├── ProductListMgr.md
│ │ ├── ProductListRegistrant.md
│ │ ├── Profile.md
│ │ └── Wallet.md
│ ├── dw_extensions.applepay
│ │ ├── ApplePayHookResult.md
│ │ └── ApplePayHooks.md
│ ├── dw_extensions.facebook
│ │ ├── FacebookFeedHooks.md
│ │ └── FacebookProduct.md
│ ├── dw_extensions.paymentrequest
│ │ ├── PaymentRequestHookResult.md
│ │ └── PaymentRequestHooks.md
│ ├── dw_extensions.payments
│ │ ├── SalesforceBancontactPaymentDetails.md
│ │ ├── SalesforceCardPaymentDetails.md
│ │ ├── SalesforceEpsPaymentDetails.md
│ │ ├── SalesforceIdealPaymentDetails.md
│ │ ├── SalesforceKlarnaPaymentDetails.md
│ │ ├── SalesforcePaymentDetails.md
│ │ ├── SalesforcePaymentIntent.md
│ │ ├── SalesforcePaymentMethod.md
│ │ ├── SalesforcePaymentRequest.md
│ │ ├── SalesforcePaymentsHooks.md
│ │ ├── SalesforcePaymentsMgr.md
│ │ ├── SalesforcePaymentsSiteConfiguration.md
│ │ ├── SalesforcePayPalOrder.md
│ │ ├── SalesforcePayPalOrderAddress.md
│ │ ├── SalesforcePayPalOrderPayer.md
│ │ ├── SalesforcePayPalPaymentDetails.md
│ │ ├── SalesforceSepaDebitPaymentDetails.md
│ │ └── SalesforceVenmoPaymentDetails.md
│ ├── dw_extensions.pinterest
│ │ ├── PinterestAvailability.md
│ │ ├── PinterestFeedHooks.md
│ │ ├── PinterestOrder.md
│ │ ├── PinterestOrderHooks.md
│ │ └── PinterestProduct.md
│ ├── dw_io
│ │ ├── CSVStreamReader.md
│ │ ├── CSVStreamWriter.md
│ │ ├── File.md
│ │ ├── FileReader.md
│ │ ├── FileWriter.md
│ │ ├── InputStream.md
│ │ ├── OutputStream.md
│ │ ├── PrintWriter.md
│ │ ├── RandomAccessFileReader.md
│ │ ├── Reader.md
│ │ ├── StringWriter.md
│ │ ├── Writer.md
│ │ ├── XMLIndentingStreamWriter.md
│ │ ├── XMLStreamConstants.md
│ │ ├── XMLStreamReader.md
│ │ └── XMLStreamWriter.md
│ ├── dw_job
│ │ ├── JobExecution.md
│ │ └── JobStepExecution.md
│ ├── dw_net
│ │ ├── FTPClient.md
│ │ ├── FTPFileInfo.md
│ │ ├── HTTPClient.md
│ │ ├── HTTPRequestPart.md
│ │ ├── Mail.md
│ │ ├── SFTPClient.md
│ │ ├── SFTPFileInfo.md
│ │ ├── WebDAVClient.md
│ │ └── WebDAVFileInfo.md
│ ├── dw_object
│ │ ├── ActiveData.md
│ │ ├── CustomAttributes.md
│ │ ├── CustomObject.md
│ │ ├── CustomObjectMgr.md
│ │ ├── Extensible.md
│ │ ├── ExtensibleObject.md
│ │ ├── Note.md
│ │ ├── ObjectAttributeDefinition.md
│ │ ├── ObjectAttributeGroup.md
│ │ ├── ObjectAttributeValueDefinition.md
│ │ ├── ObjectTypeDefinition.md
│ │ ├── PersistentObject.md
│ │ ├── SimpleExtensible.md
│ │ └── SystemObjectMgr.md
│ ├── dw_order
│ │ ├── AbstractItem.md
│ │ ├── AbstractItemCtnr.md
│ │ ├── Appeasement.md
│ │ ├── AppeasementItem.md
│ │ ├── Basket.md
│ │ ├── BasketMgr.md
│ │ ├── BonusDiscountLineItem.md
│ │ ├── CouponLineItem.md
│ │ ├── CreateAgentBasketLimitExceededException.md
│ │ ├── CreateBasketFromOrderException.md
│ │ ├── CreateCouponLineItemException.md
│ │ ├── CreateOrderException.md
│ │ ├── CreateTemporaryBasketLimitExceededException.md
│ │ ├── GiftCertificate.md
│ │ ├── GiftCertificateLineItem.md
│ │ ├── GiftCertificateMgr.md
│ │ ├── GiftCertificateStatusCodes.md
│ │ ├── Invoice.md
│ │ ├── InvoiceItem.md
│ │ ├── LineItem.md
│ │ ├── LineItemCtnr.md
│ │ ├── Order.md
│ │ ├── OrderAddress.md
│ │ ├── OrderItem.md
│ │ ├── OrderMgr.md
│ │ ├── OrderPaymentInstrument.md
│ │ ├── OrderProcessStatusCodes.md
│ │ ├── PaymentCard.md
│ │ ├── PaymentInstrument.md
│ │ ├── PaymentMethod.md
│ │ ├── PaymentMgr.md
│ │ ├── PaymentProcessor.md
│ │ ├── PaymentStatusCodes.md
│ │ ├── PaymentTransaction.md
│ │ ├── PriceAdjustment.md
│ │ ├── PriceAdjustmentLimitTypes.md
│ │ ├── ProductLineItem.md
│ │ ├── ProductShippingCost.md
│ │ ├── ProductShippingLineItem.md
│ │ ├── ProductShippingModel.md
│ │ ├── Return.md
│ │ ├── ReturnCase.md
│ │ ├── ReturnCaseItem.md
│ │ ├── ReturnItem.md
│ │ ├── Shipment.md
│ │ ├── ShipmentShippingCost.md
│ │ ├── ShipmentShippingModel.md
│ │ ├── ShippingLineItem.md
│ │ ├── ShippingLocation.md
│ │ ├── ShippingMethod.md
│ │ ├── ShippingMgr.md
│ │ ├── ShippingOrder.md
│ │ ├── ShippingOrderItem.md
│ │ ├── SumItem.md
│ │ ├── TaxGroup.md
│ │ ├── TaxItem.md
│ │ ├── TaxMgr.md
│ │ ├── TrackingInfo.md
│ │ └── TrackingRef.md
│ ├── dw_order.hooks
│ │ ├── CalculateHooks.md
│ │ ├── OrderHooks.md
│ │ ├── PaymentHooks.md
│ │ ├── ReturnHooks.md
│ │ └── ShippingOrderHooks.md
│ ├── dw_rpc
│ │ ├── SOAPUtil.md
│ │ ├── Stub.md
│ │ └── WebReference.md
│ ├── dw_suggest
│ │ ├── BrandSuggestions.md
│ │ ├── CategorySuggestions.md
│ │ ├── ContentSuggestions.md
│ │ ├── CustomSuggestions.md
│ │ ├── ProductSuggestions.md
│ │ ├── SearchPhraseSuggestions.md
│ │ ├── SuggestedCategory.md
│ │ ├── SuggestedContent.md
│ │ ├── SuggestedPhrase.md
│ │ ├── SuggestedProduct.md
│ │ ├── SuggestedTerm.md
│ │ ├── SuggestedTerms.md
│ │ ├── Suggestions.md
│ │ └── SuggestModel.md
│ ├── dw_svc
│ │ ├── FTPService.md
│ │ ├── FTPServiceDefinition.md
│ │ ├── HTTPFormService.md
│ │ ├── HTTPFormServiceDefinition.md
│ │ ├── HTTPService.md
│ │ ├── HTTPServiceDefinition.md
│ │ ├── LocalServiceRegistry.md
│ │ ├── Result.md
│ │ ├── Service.md
│ │ ├── ServiceCallback.md
│ │ ├── ServiceConfig.md
│ │ ├── ServiceCredential.md
│ │ ├── ServiceDefinition.md
│ │ ├── ServiceProfile.md
│ │ ├── ServiceRegistry.md
│ │ ├── SOAPService.md
│ │ └── SOAPServiceDefinition.md
│ ├── dw_system
│ │ ├── AgentUserStatusCodes.md
│ │ ├── Cache.md
│ │ ├── CacheMgr.md
│ │ ├── HookMgr.md
│ │ ├── InternalObject.md
│ │ ├── JobProcessMonitor.md
│ │ ├── Log.md
│ │ ├── Logger.md
│ │ ├── LogNDC.md
│ │ ├── OrganizationPreferences.md
│ │ ├── Pipeline.md
│ │ ├── PipelineDictionary.md
│ │ ├── RemoteInclude.md
│ │ ├── Request.md
│ │ ├── RequestHooks.md
│ │ ├── Response.md
│ │ ├── RESTErrorResponse.md
│ │ ├── RESTResponseMgr.md
│ │ ├── RESTSuccessResponse.md
│ │ ├── SearchStatus.md
│ │ ├── Session.md
│ │ ├── Site.md
│ │ ├── SitePreferences.md
│ │ ├── Status.md
│ │ ├── StatusItem.md
│ │ ├── System.md
│ │ └── Transaction.md
│ ├── dw_util
│ │ ├── ArrayList.md
│ │ ├── Assert.md
│ │ ├── BigInteger.md
│ │ ├── Bytes.md
│ │ ├── Calendar.md
│ │ ├── Collection.md
│ │ ├── Currency.md
│ │ ├── DateUtils.md
│ │ ├── Decimal.md
│ │ ├── FilteringCollection.md
│ │ ├── Geolocation.md
│ │ ├── HashMap.md
│ │ ├── HashSet.md
│ │ ├── Iterator.md
│ │ ├── LinkedHashMap.md
│ │ ├── LinkedHashSet.md
│ │ ├── List.md
│ │ ├── Locale.md
│ │ ├── Map.md
│ │ ├── MapEntry.md
│ │ ├── MappingKey.md
│ │ ├── MappingMgr.md
│ │ ├── PropertyComparator.md
│ │ ├── SecureEncoder.md
│ │ ├── SecureFilter.md
│ │ ├── SeekableIterator.md
│ │ ├── Set.md
│ │ ├── SortedMap.md
│ │ ├── SortedSet.md
│ │ ├── StringUtils.md
│ │ ├── Template.md
│ │ └── UUIDUtils.md
│ ├── dw_value
│ │ ├── EnumValue.md
│ │ ├── MimeEncodedText.md
│ │ ├── Money.md
│ │ └── Quantity.md
│ ├── dw_web
│ │ ├── ClickStream.md
│ │ ├── ClickStreamEntry.md
│ │ ├── Cookie.md
│ │ ├── Cookies.md
│ │ ├── CSRFProtection.md
│ │ ├── Form.md
│ │ ├── FormAction.md
│ │ ├── FormElement.md
│ │ ├── FormElementValidationResult.md
│ │ ├── FormField.md
│ │ ├── FormFieldOption.md
│ │ ├── FormFieldOptions.md
│ │ ├── FormGroup.md
│ │ ├── FormList.md
│ │ ├── FormListItem.md
│ │ ├── Forms.md
│ │ ├── HttpParameter.md
│ │ ├── HttpParameterMap.md
│ │ ├── LoopIterator.md
│ │ ├── PageMetaData.md
│ │ ├── PageMetaTag.md
│ │ ├── PagingModel.md
│ │ ├── Resource.md
│ │ ├── URL.md
│ │ ├── URLAction.md
│ │ ├── URLParameter.md
│ │ ├── URLRedirect.md
│ │ ├── URLRedirectMgr.md
│ │ └── URLUtils.md
│ ├── sfra
│ │ ├── account.md
│ │ ├── address.md
│ │ ├── billing.md
│ │ ├── cart.md
│ │ ├── categories.md
│ │ ├── content.md
│ │ ├── locale.md
│ │ ├── order.md
│ │ ├── payment.md
│ │ ├── price-default.md
│ │ ├── price-range.md
│ │ ├── price-tiered.md
│ │ ├── product-bundle.md
│ │ ├── product-full.md
│ │ ├── product-line-items.md
│ │ ├── product-search.md
│ │ ├── product-tile.md
│ │ ├── querystring.md
│ │ ├── render.md
│ │ ├── request.md
│ │ ├── response.md
│ │ ├── server.md
│ │ ├── shipping.md
│ │ ├── store.md
│ │ ├── stores.md
│ │ └── totals.md
│ └── TopLevel
│ ├── APIException.md
│ ├── arguments.md
│ ├── Array.md
│ ├── ArrayBuffer.md
│ ├── BigInt.md
│ ├── Boolean.md
│ ├── ConversionError.md
│ ├── DataView.md
│ ├── Date.md
│ ├── Error.md
│ ├── ES6Iterator.md
│ ├── EvalError.md
│ ├── Fault.md
│ ├── Float32Array.md
│ ├── Float64Array.md
│ ├── Function.md
│ ├── Generator.md
│ ├── global.md
│ ├── Int16Array.md
│ ├── Int32Array.md
│ ├── Int8Array.md
│ ├── InternalError.md
│ ├── IOError.md
│ ├── Iterable.md
│ ├── Iterator.md
│ ├── JSON.md
│ ├── Map.md
│ ├── Math.md
│ ├── Module.md
│ ├── Namespace.md
│ ├── Number.md
│ ├── Object.md
│ ├── QName.md
│ ├── RangeError.md
│ ├── ReferenceError.md
│ ├── RegExp.md
│ ├── Set.md
│ ├── StopIteration.md
│ ├── String.md
│ ├── Symbol.md
│ ├── SyntaxError.md
│ ├── SystemError.md
│ ├── TypeError.md
│ ├── Uint16Array.md
│ ├── Uint32Array.md
│ ├── Uint8Array.md
│ ├── Uint8ClampedArray.md
│ ├── URIError.md
│ ├── WeakMap.md
│ ├── WeakSet.md
│ ├── XML.md
│ ├── XMLList.md
│ └── XMLStreamError.md
├── docs-site
│ ├── .gitignore
│ ├── App.tsx
│ ├── components
│ │ ├── Badge.tsx
│ │ ├── BreadcrumbSchema.tsx
│ │ ├── CodeBlock.tsx
│ │ ├── Collapsible.tsx
│ │ ├── ConfigBuilder.tsx
│ │ ├── ConfigHero.tsx
│ │ ├── ConfigModeTabs.tsx
│ │ ├── icons.tsx
│ │ ├── Layout.tsx
│ │ ├── LightCodeContainer.tsx
│ │ ├── NewcomerCTA.tsx
│ │ ├── NextStepsStrip.tsx
│ │ ├── OnThisPage.tsx
│ │ ├── Search.tsx
│ │ ├── SEO.tsx
│ │ ├── Sidebar.tsx
│ │ ├── StructuredData.tsx
│ │ ├── ToolCard.tsx
│ │ ├── ToolFilters.tsx
│ │ ├── Typography.tsx
│ │ └── VersionBadge.tsx
│ ├── constants.tsx
│ ├── index.html
│ ├── main.tsx
│ ├── metadata.json
│ ├── package-lock.json
│ ├── package.json
│ ├── pages
│ │ ├── AIInterfacesPage.tsx
│ │ ├── ConfigurationPage.tsx
│ │ ├── DevelopmentPage.tsx
│ │ ├── ExamplesPage.tsx
│ │ ├── FeaturesPage.tsx
│ │ ├── HomePage.tsx
│ │ ├── SecurityPage.tsx
│ │ ├── ToolsPage.tsx
│ │ └── TroubleshootingPage.tsx
│ ├── postcss.config.js
│ ├── public
│ │ ├── .well-known
│ │ │ └── security.txt
│ │ ├── 404.html
│ │ ├── android-chrome-192x192.png
│ │ ├── android-chrome-512x512.png
│ │ ├── apple-touch-icon.png
│ │ ├── explain-product-pricing-methods-no-mcp.png
│ │ ├── explain-product-pricing-methods.png
│ │ ├── favicon-16x16.png
│ │ ├── favicon-32x32.png
│ │ ├── favicon.ico
│ │ ├── llms.txt
│ │ ├── robots.txt
│ │ ├── site.webmanifest
│ │ └── sitemap.xml
│ ├── README.md
│ ├── scripts
│ │ ├── generate-search-index.js
│ │ ├── generate-sitemap.js
│ │ └── search-dev.js
│ ├── src
│ │ └── styles
│ │ ├── input.css
│ │ └── prism-theme.css
│ ├── tailwind.config.js
│ ├── tsconfig.json
│ ├── types.ts
│ ├── utils
│ │ ├── search.ts
│ │ └── toolsData.ts
│ └── vite.config.ts
├── eslint.config.js
├── jest.config.js
├── LICENSE
├── package-lock.json
├── package.json
├── README.md
├── scripts
│ └── convert-docs.js
├── SECURITY.md
├── server.json
├── src
│ ├── clients
│ │ ├── base
│ │ │ ├── http-client.ts
│ │ │ ├── oauth-token.ts
│ │ │ └── ocapi-auth-client.ts
│ │ ├── best-practices-client.ts
│ │ ├── cartridge-generation-client.ts
│ │ ├── docs
│ │ │ ├── class-content-parser.ts
│ │ │ ├── class-name-resolver.ts
│ │ │ ├── documentation-scanner.ts
│ │ │ ├── index.ts
│ │ │ └── referenced-types-extractor.ts
│ │ ├── docs-client.ts
│ │ ├── log-client.ts
│ │ ├── logs
│ │ │ ├── index.ts
│ │ │ ├── log-analyzer.ts
│ │ │ ├── log-client.ts
│ │ │ ├── log-constants.ts
│ │ │ ├── log-file-discovery.ts
│ │ │ ├── log-file-reader.ts
│ │ │ ├── log-formatter.ts
│ │ │ ├── log-processor.ts
│ │ │ ├── log-types.ts
│ │ │ └── webdav-client-manager.ts
│ │ ├── ocapi
│ │ │ ├── code-versions-client.ts
│ │ │ ├── site-preferences-client.ts
│ │ │ └── system-objects-client.ts
│ │ ├── ocapi-client.ts
│ │ └── sfra-client.ts
│ ├── config
│ │ ├── configuration-factory.ts
│ │ └── dw-json-loader.ts
│ ├── core
│ │ ├── handlers
│ │ │ ├── abstract-log-tool-handler.ts
│ │ │ ├── base-handler.ts
│ │ │ ├── best-practices-handler.ts
│ │ │ ├── cartridge-handler.ts
│ │ │ ├── client-factory.ts
│ │ │ ├── code-version-handler.ts
│ │ │ ├── docs-handler.ts
│ │ │ ├── job-log-handler.ts
│ │ │ ├── job-log-tool-config.ts
│ │ │ ├── log-handler.ts
│ │ │ ├── log-tool-config.ts
│ │ │ ├── sfra-handler.ts
│ │ │ ├── system-object-handler.ts
│ │ │ └── validation-helpers.ts
│ │ ├── server.ts
│ │ └── tool-definitions.ts
│ ├── index.ts
│ ├── main.ts
│ ├── services
│ │ ├── file-system-service.ts
│ │ ├── index.ts
│ │ └── path-service.ts
│ ├── tool-configs
│ │ ├── best-practices-tool-config.ts
│ │ ├── cartridge-tool-config.ts
│ │ ├── code-version-tool-config.ts
│ │ ├── docs-tool-config.ts
│ │ ├── job-log-tool-config.ts
│ │ ├── log-tool-config.ts
│ │ ├── sfra-tool-config.ts
│ │ └── system-object-tool-config.ts
│ ├── types
│ │ └── types.ts
│ └── utils
│ ├── cache.ts
│ ├── job-log-tool-config.ts
│ ├── job-log-utils.ts
│ ├── log-cache.ts
│ ├── log-tool-config.ts
│ ├── log-tool-constants.ts
│ ├── log-tool-utils.ts
│ ├── logger.ts
│ ├── ocapi-url-builder.ts
│ ├── path-resolver.ts
│ ├── query-builder.ts
│ ├── utils.ts
│ └── validator.ts
├── tests
│ ├── __mocks__
│ │ ├── docs-client.ts
│ │ ├── src
│ │ │ └── clients
│ │ │ └── base
│ │ │ └── http-client.js
│ │ └── webdav.js
│ ├── base-handler.test.ts
│ ├── base-http-client.test.ts
│ ├── best-practices-handler.test.ts
│ ├── cache.test.ts
│ ├── cartridge-handler.test.ts
│ ├── class-content-parser.test.ts
│ ├── class-name-resolver.test.ts
│ ├── client-factory.test.ts
│ ├── code-version-handler.test.ts
│ ├── code-versions-client.test.ts
│ ├── config.test.ts
│ ├── configuration-factory.test.ts
│ ├── docs-handler.test.ts
│ ├── documentation-scanner.test.ts
│ ├── file-system-service.test.ts
│ ├── job-log-handler.test.ts
│ ├── job-log-utils.test.ts
│ ├── log-client.test.ts
│ ├── log-handler.test.ts
│ ├── log-processor.test.ts
│ ├── logger.test.ts
│ ├── mcp
│ │ ├── AGENTS.md
│ │ ├── node
│ │ │ ├── activate-code-version-advanced.full-mode.programmatic.test.js
│ │ │ ├── code-versions.full-mode.programmatic.test.js
│ │ │ ├── generate-cartridge-structure.docs-only.programmatic.test.js
│ │ │ ├── get-available-best-practice-guides.docs-only.programmatic.test.js
│ │ │ ├── get-available-sfra-documents.programmatic.test.js
│ │ │ ├── get-best-practice-guide.docs-only.programmatic.test.js
│ │ │ ├── get-hook-reference.docs-only.programmatic.test.js
│ │ │ ├── get-job-execution-summary.full-mode.programmatic.test.js
│ │ │ ├── get-job-log-entries.full-mode.programmatic.test.js
│ │ │ ├── get-latest-debug.full-mode.programmatic.test.js
│ │ │ ├── get-latest-error.full-mode.programmatic.test.js
│ │ │ ├── get-latest-info.full-mode.programmatic.test.js
│ │ │ ├── get-latest-job-log-files.full-mode.programmatic.test.js
│ │ │ ├── get-latest-warn.full-mode.programmatic.test.js
│ │ │ ├── get-log-file-contents.full-mode.programmatic.test.js
│ │ │ ├── get-sfcc-class-documentation.docs-only.programmatic.test.js
│ │ │ ├── get-sfcc-class-info.docs-only.programmatic.test.js
│ │ │ ├── get-sfra-categories.docs-only.programmatic.test.js
│ │ │ ├── get-sfra-document.programmatic.test.js
│ │ │ ├── get-sfra-documents-by-category.docs-only.programmatic.test.js
│ │ │ ├── get-system-object-definition.full-mode.programmatic.test.js
│ │ │ ├── get-system-object-definitions.docs-only.programmatic.test.js
│ │ │ ├── get-system-object-definitions.full-mode.programmatic.test.js
│ │ │ ├── list-log-files.full-mode.programmatic.test.js
│ │ │ ├── list-sfcc-classes.docs-only.programmatic.test.js
│ │ │ ├── search-best-practices.docs-only.programmatic.test.js
│ │ │ ├── search-custom-object-attribute-definitions.full-mode.programmatic.test.js
│ │ │ ├── search-job-logs-by-name.full-mode.programmatic.test.js
│ │ │ ├── search-job-logs.full-mode.programmatic.test.js
│ │ │ ├── search-logs.full-mode.programmatic.test.js
│ │ │ ├── search-sfcc-classes.docs-only.programmatic.test.js
│ │ │ ├── search-sfcc-methods.docs-only.programmatic.test.js
│ │ │ ├── search-sfra-documentation.docs-only.programmatic.test.js
│ │ │ ├── search-site-preferences.full-mode.programmatic.test.js
│ │ │ ├── search-system-object-attribute-definitions.full-mode.programmatic.test.js
│ │ │ ├── search-system-object-attribute-groups.full-mode.programmatic.test.js
│ │ │ ├── summarize-logs.full-mode.programmatic.test.js
│ │ │ ├── tools.docs-only.programmatic.test.js
│ │ │ └── tools.full-mode.programmatic.test.js
│ │ ├── README.md
│ │ ├── test-fixtures
│ │ │ └── dw.json
│ │ └── yaml
│ │ ├── activate-code-version.docs-only.test.mcp.yml
│ │ ├── activate-code-version.full-mode.test.mcp.yml
│ │ ├── get_latest_error.test.mcp.yml
│ │ ├── get-available-best-practice-guides.docs-only.test.mcp.yml
│ │ ├── get-available-best-practice-guides.full-mode.test.mcp.yml
│ │ ├── get-available-sfra-documents.docs-only.test.mcp.yml
│ │ ├── get-available-sfra-documents.full-mode.test.mcp.yml
│ │ ├── get-best-practice-guide.docs-only.test.mcp.yml
│ │ ├── get-best-practice-guide.full-mode.test.mcp.yml
│ │ ├── get-code-versions.docs-only.test.mcp.yml
│ │ ├── get-code-versions.full-mode.test.mcp.yml
│ │ ├── get-hook-reference.docs-only.test.mcp.yml
│ │ ├── get-hook-reference.full-mode.test.mcp.yml
│ │ ├── get-job-execution-summary.full-mode.test.mcp.yml
│ │ ├── get-job-log-entries.full-mode.test.mcp.yml
│ │ ├── get-latest-debug.full-mode.test.mcp.yml
│ │ ├── get-latest-error.full-mode.test.mcp.yml
│ │ ├── get-latest-info.full-mode.test.mcp.yml
│ │ ├── get-latest-job-log-files.full-mode.test.mcp.yml
│ │ ├── get-latest-warn.full-mode.test.mcp.yml
│ │ ├── get-log-file-contents.full-mode.test.mcp.yml
│ │ ├── get-sfcc-class-documentation.docs-only.test.mcp.yml
│ │ ├── get-sfcc-class-documentation.full-mode.test.mcp.yml
│ │ ├── get-sfcc-class-info.docs-only.test.mcp.yml
│ │ ├── get-sfcc-class-info.full-mode.test.mcp.yml
│ │ ├── get-sfra-categories.docs-only.test.mcp.yml
│ │ ├── get-sfra-categories.full-mode.test.mcp.yml
│ │ ├── get-sfra-document.docs-only.test.mcp.yml
│ │ ├── get-sfra-document.full-mode.test.mcp.yml
│ │ ├── get-sfra-documents-by-category.docs-only.test.mcp.yml
│ │ ├── get-sfra-documents-by-category.full-mode.test.mcp.yml
│ │ ├── get-system-object-definition.docs-only.test.mcp.yml
│ │ ├── get-system-object-definition.full-mode.test.mcp.yml
│ │ ├── get-system-object-definitions.docs-only.test.mcp.yml
│ │ ├── get-system-object-definitions.full-mode.test.mcp.yml
│ │ ├── list-log-files.full-mode.test.mcp.yml
│ │ ├── list-sfcc-classes.docs-only.test.mcp.yml
│ │ ├── list-sfcc-classes.full-mode.test.mcp.yml
│ │ ├── search-best-practices.docs-only.test.mcp.yml
│ │ ├── search-best-practices.full-mode.test.mcp.yml
│ │ ├── search-custom-object-attribute-definitions.docs-only.test.mcp.yml
│ │ ├── search-custom-object-attribute-definitions.test.mcp.yml
│ │ ├── search-job-logs-by-name.full-mode.test.mcp.yml
│ │ ├── search-job-logs.full-mode.test.mcp.yml
│ │ ├── search-logs.full-mode.test.mcp.yml
│ │ ├── search-sfcc-classes.docs-only.test.mcp.yml
│ │ ├── search-sfcc-classes.full-mode.test.mcp.yml
│ │ ├── search-sfcc-methods.docs-only.test.mcp.yml
│ │ ├── search-sfcc-methods.full-mode.test.mcp.yml
│ │ ├── search-sfra-documentation.docs-only.test.mcp.yml
│ │ ├── search-sfra-documentation.full-mode.test.mcp.yml
│ │ ├── search-site-preferences.docs-only.test.mcp.yml
│ │ ├── search-site-preferences.full-mode.test.mcp.yml
│ │ ├── search-system-object-attribute-definitions.docs-only.test.mcp.yml
│ │ ├── search-system-object-attribute-definitions.full-mode.test.mcp.yml
│ │ ├── search-system-object-attribute-groups.docs-only.test.mcp.yml
│ │ ├── search-system-object-attribute-groups.full-mode.test.mcp.yml
│ │ ├── summarize-logs.full-mode.test.mcp.yml
│ │ ├── tools.docs-only.test.mcp.yml
│ │ └── tools.full-mode.test.mcp.yml
│ ├── oauth-token.test.ts
│ ├── ocapi-auth-client.test.ts
│ ├── ocapi-client.test.ts
│ ├── path-service.test.ts
│ ├── query-builder.test.ts
│ ├── referenced-types-extractor.test.ts
│ ├── servers
│ │ ├── sfcc-mock-server
│ │ │ ├── mock-data
│ │ │ │ └── ocapi
│ │ │ │ ├── code-versions.json
│ │ │ │ ├── custom-object-attributes-customapi.json
│ │ │ │ ├── custom-object-attributes-globalsettings.json
│ │ │ │ ├── custom-object-attributes-versionhistory.json
│ │ │ │ ├── site-preferences-ccv.json
│ │ │ │ ├── site-preferences-fastforward.json
│ │ │ │ ├── site-preferences-sfra.json
│ │ │ │ ├── site-preferences-storefront.json
│ │ │ │ ├── site-preferences-system.json
│ │ │ │ ├── system-object-attribute-groups-campaign.json
│ │ │ │ ├── system-object-attribute-groups-category.json
│ │ │ │ ├── system-object-attribute-groups-order.json
│ │ │ │ ├── system-object-attribute-groups-product.json
│ │ │ │ ├── system-object-attribute-groups-sitepreferences.json
│ │ │ │ ├── system-object-attributes-customeraddress.json
│ │ │ │ ├── system-object-attributes-product-expanded.json
│ │ │ │ ├── system-object-attributes-product.json
│ │ │ │ ├── system-object-definition-category.json
│ │ │ │ ├── system-object-definition-customer.json
│ │ │ │ ├── system-object-definition-customeraddress.json
│ │ │ │ ├── system-object-definition-order.json
│ │ │ │ ├── system-object-definition-product.json
│ │ │ │ ├── system-object-definitions-old.json
│ │ │ │ └── system-object-definitions.json
│ │ │ ├── package-lock.json
│ │ │ ├── package.json
│ │ │ ├── README.md
│ │ │ ├── scripts
│ │ │ │ └── setup-logs.js
│ │ │ ├── server.js
│ │ │ └── src
│ │ │ ├── app.js
│ │ │ ├── config
│ │ │ │ └── server-config.js
│ │ │ ├── middleware
│ │ │ │ ├── auth.js
│ │ │ │ ├── cors.js
│ │ │ │ └── logging.js
│ │ │ ├── routes
│ │ │ │ ├── ocapi
│ │ │ │ │ ├── code-versions-handler.js
│ │ │ │ │ ├── oauth-handler.js
│ │ │ │ │ ├── ocapi-error-utils.js
│ │ │ │ │ ├── ocapi-utils.js
│ │ │ │ │ ├── site-preferences-handler.js
│ │ │ │ │ └── system-objects-handler.js
│ │ │ │ ├── ocapi.js
│ │ │ │ └── webdav.js
│ │ │ └── utils
│ │ │ ├── mock-data-loader.js
│ │ │ └── webdav-xml.js
│ │ └── sfcc-mock-server-manager.ts
│ ├── sfcc-mock-server.test.ts
│ ├── site-preferences-client.test.ts
│ ├── system-objects-client.test.ts
│ ├── utils.test.ts
│ ├── validation-helpers.test.ts
│ └── validator.test.ts
├── tsconfig.json
└── tsconfig.test.json
```
# Files
--------------------------------------------------------------------------------
/docs/dw_extensions.facebook/FacebookProduct.md:
--------------------------------------------------------------------------------
```markdown
1 | ## Package: dw.extensions.facebook
2 |
3 | # Class FacebookProduct
4 |
5 | ## Inheritance Hierarchy
6 |
7 | - Object
8 | - dw.extensions.facebook.FacebookProduct
9 |
10 | ## Description
11 |
12 | Represents a row in the Facebook catalog feed export.
13 |
14 | ## Constants
15 |
16 | ### AGE_GROUP_ADULT
17 |
18 | **Type:** String = "adult"
19 |
20 | Indicates that the product is for adults.
21 |
22 | ### AGE_GROUP_INFANT
23 |
24 | **Type:** String = "infant"
25 |
26 | Indicates that the product is for infant children.
27 |
28 | ### AGE_GROUP_KIDS
29 |
30 | **Type:** String = "kids"
31 |
32 | Indicates that the product is for children.
33 |
34 | ### AGE_GROUP_NEWBORN
35 |
36 | **Type:** String = "newborn"
37 |
38 | Indicates that the product is for newborn children.
39 |
40 | ### AGE_GROUP_TODDLER
41 |
42 | **Type:** String = "toddler"
43 |
44 | Indicates that the product is for toddler children.
45 |
46 | ### AVAILABILITY_AVAILABLE_FOR_ORDER
47 |
48 | **Type:** String = "available
49 |
50 | Indicates that the product can be ordered for later shipment.
51 |
52 | ### AVAILABILITY_IN_STOCK
53 |
54 | **Type:** String = "in
55 |
56 | Indicates that the product is available to ship immediately.
57 |
58 | ### AVAILABILITY_OUT_OF_STOCK
59 |
60 | **Type:** String = "out
61 |
62 | Indicates that the product is out of stock.
63 |
64 | ### AVAILABILITY_PREORDER
65 |
66 | **Type:** String = "preorder"
67 |
68 | Indicates that the product will be available in the future.
69 |
70 | ### CONDITION_NEW
71 |
72 | **Type:** String = "new"
73 |
74 | Indicates that the product is new.
75 |
76 | ### CONDITION_REFURBISHED
77 |
78 | **Type:** String = "refurbished"
79 |
80 | Indicates that the product is used but has been refurbished.
81 |
82 | ### CONDITION_USED
83 |
84 | **Type:** String = "used"
85 |
86 | Indicates that the product has been used.
87 |
88 | ### GENDER_FEMALE
89 |
90 | **Type:** String = "female"
91 |
92 | Indicates that the product is for females.
93 |
94 | ### GENDER_MALE
95 |
96 | **Type:** String = "male"
97 |
98 | Indicates that the product is for males.
99 |
100 | ### GENDER_UNISEX
101 |
102 | **Type:** String = "unisex"
103 |
104 | Indicates that the product is for both males and females.
105 |
106 | ### SHIPPING_SIZE_UNIT_CM
107 |
108 | **Type:** String = "cm"
109 |
110 | Indicates that the product is measured in centimeters.
111 |
112 | ### SHIPPING_SIZE_UNIT_FT
113 |
114 | **Type:** String = "ft"
115 |
116 | Indicates that the product is measured in feet.
117 |
118 | ### SHIPPING_SIZE_UNIT_IN
119 |
120 | **Type:** String = "in"
121 |
122 | Indicates that the product is measured in inches.
123 |
124 | ### SHIPPING_SIZE_UNIT_M
125 |
126 | **Type:** String = "m"
127 |
128 | Indicates that the product is measured in meters.
129 |
130 | ### SHIPPING_WEIGHT_UNIT_G
131 |
132 | **Type:** String = "g"
133 |
134 | Indicates that the product is weighed in grams.
135 |
136 | ### SHIPPING_WEIGHT_UNIT_KG
137 |
138 | **Type:** String = "kg"
139 |
140 | Indicates that the product is weighed in kilograms.
141 |
142 | ### SHIPPING_WEIGHT_UNIT_LB
143 |
144 | **Type:** String = "lb"
145 |
146 | Indicates that the product is weighed in pounds.
147 |
148 | ### SHIPPING_WEIGHT_UNIT_OZ
149 |
150 | **Type:** String = "oz"
151 |
152 | Indicates that the product is weighed in ounces.
153 |
154 | ## Properties
155 |
156 | ### ageGroup
157 |
158 | **Type:** String
159 |
160 | The age group for the Facebook product.
161 |
162 | ### availability
163 |
164 | **Type:** String
165 |
166 | The availability of the Facebook product.
167 |
168 | ### brand
169 |
170 | **Type:** String
171 |
172 | The Facebook brand of the product.
173 |
174 | ### color
175 |
176 | **Type:** String
177 |
178 | The Facebook color value label of the product.
179 |
180 | ### condition
181 |
182 | **Type:** String
183 |
184 | The condition of the Facebook product.
185 |
186 | ### customLabel0
187 |
188 | **Type:** String
189 |
190 | The Facebook custom label 0 value of the product.
191 |
192 | ### customLabel1
193 |
194 | **Type:** String
195 |
196 | The Facebook custom label 1 value of the product.
197 |
198 | ### customLabel2
199 |
200 | **Type:** String
201 |
202 | The Facebook custom label 2 value of the product.
203 |
204 | ### customLabel3
205 |
206 | **Type:** String
207 |
208 | The Facebook custom label 3 value of the product.
209 |
210 | ### customLabel4
211 |
212 | **Type:** String
213 |
214 | The Facebook custom label 4 value of the product.
215 |
216 | ### description
217 |
218 | **Type:** String
219 |
220 | The description of the Facebook product.
221 |
222 | ### expirationDate
223 |
224 | **Type:** Date
225 |
226 | The Facebook expiration date of the product. If the product is expired it will not be shown.
227 |
228 | ### gender
229 |
230 | **Type:** String
231 |
232 | The gender for the Facebook product.
233 |
234 | ### googleProductCategory
235 |
236 | **Type:** String
237 |
238 | The category of this product in the Google category taxonomy. If the value is longer than 250 characters
239 | it is truncated.
240 |
241 | ### gtin
242 |
243 | **Type:** String
244 |
245 | The Facebook GTIN of the product.
246 |
247 | ### ID
248 |
249 | **Type:** String (Read Only)
250 |
251 | The ID of the Facebook product. This is the same as the ID of the Demandware product.
252 |
253 | ### imageLinks
254 |
255 | **Type:** List
256 |
257 | A list containing the URLs of the images to show in Facebook for the product.
258 |
259 | ### itemGroupID
260 |
261 | **Type:** String
262 |
263 | The ID of the Facebook item group for the product, that is, its master product.
264 |
265 | ### link
266 |
267 | **Type:** URL
268 |
269 | The URL of the Demandware storefront link to the product.
270 |
271 | ### material
272 |
273 | **Type:** String
274 |
275 | The Facebook material value label of the product.
276 |
277 | ### mpn
278 |
279 | **Type:** String
280 |
281 | The Facebook MPN of the product.
282 |
283 | ### pattern
284 |
285 | **Type:** String
286 |
287 | The Facebook pattern value label of the product.
288 |
289 | ### price
290 |
291 | **Type:** Money
292 |
293 | The price to show in Facebook for the product.
294 |
295 | ### productType
296 |
297 | **Type:** String
298 |
299 | The Facebook product type. This is the retailer-defined category of the item.
300 |
301 | ### salePrice
302 |
303 | **Type:** Money
304 |
305 | The sale price to show in Facebook for the product.
306 |
307 | ### salePriceEffectiveDateEnd
308 |
309 | **Type:** Date
310 |
311 | The end date of the Facebook sale price of the product.
312 |
313 | ### salePriceEffectiveDateStart
314 |
315 | **Type:** Date
316 |
317 | The start date of the Facebook sale price of the product.
318 |
319 | ### shippingHeight
320 |
321 | **Type:** Number
322 |
323 | The shipping height of the product.
324 |
325 | ### shippingLength
326 |
327 | **Type:** Number
328 |
329 | The shipping length of the product.
330 |
331 | ### shippingSizeUnit
332 |
333 | **Type:** String
334 |
335 | The shipping size unit of the product.
336 |
337 | ### shippingWeight
338 |
339 | **Type:** Quantity
340 |
341 | The shipping weight for the product.
342 |
343 | ### shippingWidth
344 |
345 | **Type:** Number
346 |
347 | The shipping width of the product.
348 |
349 | ### size
350 |
351 | **Type:** String
352 |
353 | The Facebook size value label of the product.
354 |
355 | ### title
356 |
357 | **Type:** String
358 |
359 | The title of the Facebook product.
360 |
361 | ## Constructor Summary
362 |
363 | ## Method Summary
364 |
365 | ### getAgeGroup
366 |
367 | **Signature:** `getAgeGroup() : String`
368 |
369 | Returns the age group for the Facebook product.
370 |
371 | ### getAvailability
372 |
373 | **Signature:** `getAvailability() : String`
374 |
375 | Returns the availability of the Facebook product.
376 |
377 | ### getBrand
378 |
379 | **Signature:** `getBrand() : String`
380 |
381 | Returns the Facebook brand of the product.
382 |
383 | ### getColor
384 |
385 | **Signature:** `getColor() : String`
386 |
387 | Returns the Facebook color value label of the product.
388 |
389 | ### getCondition
390 |
391 | **Signature:** `getCondition() : String`
392 |
393 | Returns the condition of the Facebook product.
394 |
395 | ### getCustomLabel0
396 |
397 | **Signature:** `getCustomLabel0() : String`
398 |
399 | Returns the Facebook custom label 0 value of the product.
400 |
401 | ### getCustomLabel1
402 |
403 | **Signature:** `getCustomLabel1() : String`
404 |
405 | Returns the Facebook custom label 1 value of the product.
406 |
407 | ### getCustomLabel2
408 |
409 | **Signature:** `getCustomLabel2() : String`
410 |
411 | Returns the Facebook custom label 2 value of the product.
412 |
413 | ### getCustomLabel3
414 |
415 | **Signature:** `getCustomLabel3() : String`
416 |
417 | Returns the Facebook custom label 3 value of the product.
418 |
419 | ### getCustomLabel4
420 |
421 | **Signature:** `getCustomLabel4() : String`
422 |
423 | Returns the Facebook custom label 4 value of the product.
424 |
425 | ### getDescription
426 |
427 | **Signature:** `getDescription() : String`
428 |
429 | Returns the description of the Facebook product.
430 |
431 | ### getExpirationDate
432 |
433 | **Signature:** `getExpirationDate() : Date`
434 |
435 | Returns the Facebook expiration date of the product.
436 |
437 | ### getGender
438 |
439 | **Signature:** `getGender() : String`
440 |
441 | Returns the gender for the Facebook product.
442 |
443 | ### getGoogleProductCategory
444 |
445 | **Signature:** `getGoogleProductCategory() : String`
446 |
447 | Returns the category of this product in the Google category taxonomy.
448 |
449 | ### getGtin
450 |
451 | **Signature:** `getGtin() : String`
452 |
453 | Returns the Facebook GTIN of the product.
454 |
455 | ### getID
456 |
457 | **Signature:** `getID() : String`
458 |
459 | Returns the ID of the Facebook product.
460 |
461 | ### getImageLinks
462 |
463 | **Signature:** `getImageLinks() : List`
464 |
465 | Returns a list containing the URLs of the images to show in Facebook for the product.
466 |
467 | ### getItemGroupID
468 |
469 | **Signature:** `getItemGroupID() : String`
470 |
471 | Returns the ID of the Facebook item group for the product, that is, its master product.
472 |
473 | ### getLink
474 |
475 | **Signature:** `getLink() : URL`
476 |
477 | Returns the URL of the Demandware storefront link to the product.
478 |
479 | ### getMaterial
480 |
481 | **Signature:** `getMaterial() : String`
482 |
483 | Returns the Facebook material value label of the product.
484 |
485 | ### getMpn
486 |
487 | **Signature:** `getMpn() : String`
488 |
489 | Returns the Facebook MPN of the product.
490 |
491 | ### getPattern
492 |
493 | **Signature:** `getPattern() : String`
494 |
495 | Returns the Facebook pattern value label of the product.
496 |
497 | ### getPrice
498 |
499 | **Signature:** `getPrice() : Money`
500 |
501 | Returns the price to show in Facebook for the product.
502 |
503 | ### getProductType
504 |
505 | **Signature:** `getProductType() : String`
506 |
507 | Returns the Facebook product type.
508 |
509 | ### getSalePrice
510 |
511 | **Signature:** `getSalePrice() : Money`
512 |
513 | Returns the sale price to show in Facebook for the product.
514 |
515 | ### getSalePriceEffectiveDateEnd
516 |
517 | **Signature:** `getSalePriceEffectiveDateEnd() : Date`
518 |
519 | Returns the end date of the Facebook sale price of the product.
520 |
521 | ### getSalePriceEffectiveDateStart
522 |
523 | **Signature:** `getSalePriceEffectiveDateStart() : Date`
524 |
525 | Returns the start date of the Facebook sale price of the product.
526 |
527 | ### getShippingHeight
528 |
529 | **Signature:** `getShippingHeight() : Number`
530 |
531 | Returns the shipping height of the product.
532 |
533 | ### getShippingLength
534 |
535 | **Signature:** `getShippingLength() : Number`
536 |
537 | Returns the shipping length of the product.
538 |
539 | ### getShippingSizeUnit
540 |
541 | **Signature:** `getShippingSizeUnit() : String`
542 |
543 | Returns the shipping size unit of the product.
544 |
545 | ### getShippingWeight
546 |
547 | **Signature:** `getShippingWeight() : Quantity`
548 |
549 | Returns the shipping weight for the product.
550 |
551 | ### getShippingWidth
552 |
553 | **Signature:** `getShippingWidth() : Number`
554 |
555 | Returns the shipping width of the product.
556 |
557 | ### getSize
558 |
559 | **Signature:** `getSize() : String`
560 |
561 | Returns the Facebook size value label of the product.
562 |
563 | ### getTitle
564 |
565 | **Signature:** `getTitle() : String`
566 |
567 | Returns the title of the Facebook product.
568 |
569 | ### setAgeGroup
570 |
571 | **Signature:** `setAgeGroup(ageGroup : String) : void`
572 |
573 | Sets the age group for the Facebook product.
574 |
575 | ### setAvailability
576 |
577 | **Signature:** `setAvailability(availability : String) : void`
578 |
579 | Sets the availability of the Facebook product.
580 |
581 | ### setBrand
582 |
583 | **Signature:** `setBrand(brand : String) : void`
584 |
585 | Sets the Facebook brand of the product.
586 |
587 | ### setColor
588 |
589 | **Signature:** `setColor(color : String) : void`
590 |
591 | Sets the Facebook color value label of the product.
592 |
593 | ### setCondition
594 |
595 | **Signature:** `setCondition(condition : String) : void`
596 |
597 | Sets the condition of the Facebook product.
598 |
599 | ### setCustomLabel0
600 |
601 | **Signature:** `setCustomLabel0(customLabel0 : String) : void`
602 |
603 | Sets the Facebook custom label 0 value of the product.
604 |
605 | ### setCustomLabel1
606 |
607 | **Signature:** `setCustomLabel1(customLabel1 : String) : void`
608 |
609 | Sets the Facebook custom label 1 value of the product.
610 |
611 | ### setCustomLabel2
612 |
613 | **Signature:** `setCustomLabel2(customLabel2 : String) : void`
614 |
615 | Sets the Facebook custom label 2 value of the product.
616 |
617 | ### setCustomLabel3
618 |
619 | **Signature:** `setCustomLabel3(customLabel3 : String) : void`
620 |
621 | Sets the Facebook custom label 3 value of the product.
622 |
623 | ### setCustomLabel4
624 |
625 | **Signature:** `setCustomLabel4(customLabel4 : String) : void`
626 |
627 | Sets the Facebook custom label 4 value of the product.
628 |
629 | ### setDescription
630 |
631 | **Signature:** `setDescription(description : String) : void`
632 |
633 | Sets the description of the Facebook product.
634 |
635 | ### setExpirationDate
636 |
637 | **Signature:** `setExpirationDate(expirationDate : Date) : void`
638 |
639 | Sets the Facebook expiration date of the product.
640 |
641 | ### setGender
642 |
643 | **Signature:** `setGender(gender : String) : void`
644 |
645 | Sets the gender for the Facebook product.
646 |
647 | ### setGoogleProductCategory
648 |
649 | **Signature:** `setGoogleProductCategory(googleProductCategory : String) : void`
650 |
651 | Sets the category of this product in the Google category taxonomy.
652 |
653 | ### setGtin
654 |
655 | **Signature:** `setGtin(gtin : String) : void`
656 |
657 | Sets the Facebook GTIN of the product.
658 |
659 | ### setImageLinks
660 |
661 | **Signature:** `setImageLinks(imageLinks : List) : void`
662 |
663 | Sets the list of URLs of images to show in Facebook for the product.
664 |
665 | ### setItemGroupID
666 |
667 | **Signature:** `setItemGroupID(itemGroupID : String) : void`
668 |
669 | Sets the ID of the Facebook item group for the product, that is, its master product.
670 |
671 | ### setLink
672 |
673 | **Signature:** `setLink(link : URL) : void`
674 |
675 | Sets the URL of the Demandware storefront link to the product.
676 |
677 | ### setMaterial
678 |
679 | **Signature:** `setMaterial(material : String) : void`
680 |
681 | Sets the Facebook material value label of the product.
682 |
683 | ### setMpn
684 |
685 | **Signature:** `setMpn(mpn : String) : void`
686 |
687 | Sets the Facebook MPN of the product.
688 |
689 | ### setPattern
690 |
691 | **Signature:** `setPattern(pattern : String) : void`
692 |
693 | Sets the Facebook pattern value label of the product.
694 |
695 | ### setPrice
696 |
697 | **Signature:** `setPrice(price : Money) : void`
698 |
699 | Sets the price to show in Facebook for the product.
700 |
701 | ### setProductType
702 |
703 | **Signature:** `setProductType(productType : String) : void`
704 |
705 | Sets the Facebook product type.
706 |
707 | ### setSalePrice
708 |
709 | **Signature:** `setSalePrice(salePrice : Money) : void`
710 |
711 | Sets the sale price to show in Facebook for the product.
712 |
713 | ### setSalePriceEffectiveDateEnd
714 |
715 | **Signature:** `setSalePriceEffectiveDateEnd(salePriceEffectiveDateEnd : Date) : void`
716 |
717 | Sets the end date of the Facebook sale price of the product.
718 |
719 | ### setSalePriceEffectiveDateStart
720 |
721 | **Signature:** `setSalePriceEffectiveDateStart(salePriceEffectiveDateStart : Date) : void`
722 |
723 | Sets the start date of the Facebook sale price of the product.
724 |
725 | ### setShippingHeight
726 |
727 | **Signature:** `setShippingHeight(shippingHeight : Number) : void`
728 |
729 | Sets the shipping height of the product.
730 |
731 | ### setShippingLength
732 |
733 | **Signature:** `setShippingLength(shippingLength : Number) : void`
734 |
735 | Sets the shipping length of the product.
736 |
737 | ### setShippingSizeUnit
738 |
739 | **Signature:** `setShippingSizeUnit(shippingSizeUnit : String) : void`
740 |
741 | Sets the shipping size unit of the product.
742 |
743 | ### setShippingWeight
744 |
745 | **Signature:** `setShippingWeight(shippingWeight : Quantity) : void`
746 |
747 | Sets the shipping weight for the product.
748 |
749 | ### setShippingWidth
750 |
751 | **Signature:** `setShippingWidth(shippingWidth : Number) : void`
752 |
753 | Sets the shipping width of the product.
754 |
755 | ### setSize
756 |
757 | **Signature:** `setSize(size : String) : void`
758 |
759 | Sets the Facebook size value label of the product.
760 |
761 | ### setTitle
762 |
763 | **Signature:** `setTitle(title : String) : void`
764 |
765 | Sets the title of the Facebook product.
766 |
767 | ## Method Detail
768 |
769 | ## Method Details
770 |
771 | ### getAgeGroup
772 |
773 | **Signature:** `getAgeGroup() : String`
774 |
775 | **Description:** Returns the age group for the Facebook product.
776 |
777 | **Returns:**
778 |
779 | product age group
780 |
781 | ---
782 |
783 | ### getAvailability
784 |
785 | **Signature:** `getAvailability() : String`
786 |
787 | **Description:** Returns the availability of the Facebook product.
788 |
789 | **Returns:**
790 |
791 | product availability
792 |
793 | ---
794 |
795 | ### getBrand
796 |
797 | **Signature:** `getBrand() : String`
798 |
799 | **Description:** Returns the Facebook brand of the product.
800 |
801 | **Returns:**
802 |
803 | the brand
804 |
805 | ---
806 |
807 | ### getColor
808 |
809 | **Signature:** `getColor() : String`
810 |
811 | **Description:** Returns the Facebook color value label of the product.
812 |
813 | **Returns:**
814 |
815 | the color value label
816 |
817 | ---
818 |
819 | ### getCondition
820 |
821 | **Signature:** `getCondition() : String`
822 |
823 | **Description:** Returns the condition of the Facebook product.
824 |
825 | **Returns:**
826 |
827 | product condition
828 |
829 | ---
830 |
831 | ### getCustomLabel0
832 |
833 | **Signature:** `getCustomLabel0() : String`
834 |
835 | **Description:** Returns the Facebook custom label 0 value of the product.
836 |
837 | **Returns:**
838 |
839 | the custom label 0 value
840 |
841 | ---
842 |
843 | ### getCustomLabel1
844 |
845 | **Signature:** `getCustomLabel1() : String`
846 |
847 | **Description:** Returns the Facebook custom label 1 value of the product.
848 |
849 | **Returns:**
850 |
851 | the custom label 1 value
852 |
853 | ---
854 |
855 | ### getCustomLabel2
856 |
857 | **Signature:** `getCustomLabel2() : String`
858 |
859 | **Description:** Returns the Facebook custom label 2 value of the product.
860 |
861 | **Returns:**
862 |
863 | the custom label 2 value
864 |
865 | ---
866 |
867 | ### getCustomLabel3
868 |
869 | **Signature:** `getCustomLabel3() : String`
870 |
871 | **Description:** Returns the Facebook custom label 3 value of the product.
872 |
873 | **Returns:**
874 |
875 | the custom label 3 value
876 |
877 | ---
878 |
879 | ### getCustomLabel4
880 |
881 | **Signature:** `getCustomLabel4() : String`
882 |
883 | **Description:** Returns the Facebook custom label 4 value of the product.
884 |
885 | **Returns:**
886 |
887 | the custom label 4 value
888 |
889 | ---
890 |
891 | ### getDescription
892 |
893 | **Signature:** `getDescription() : String`
894 |
895 | **Description:** Returns the description of the Facebook product.
896 |
897 | **Returns:**
898 |
899 | product description
900 |
901 | ---
902 |
903 | ### getExpirationDate
904 |
905 | **Signature:** `getExpirationDate() : Date`
906 |
907 | **Description:** Returns the Facebook expiration date of the product. If the product is expired it will not be shown.
908 |
909 | **Returns:**
910 |
911 | the expiration date
912 |
913 | ---
914 |
915 | ### getGender
916 |
917 | **Signature:** `getGender() : String`
918 |
919 | **Description:** Returns the gender for the Facebook product.
920 |
921 | **Returns:**
922 |
923 | product gender
924 |
925 | ---
926 |
927 | ### getGoogleProductCategory
928 |
929 | **Signature:** `getGoogleProductCategory() : String`
930 |
931 | **Description:** Returns the category of this product in the Google category taxonomy. If the value is longer than 250 characters it is truncated.
932 |
933 | **Returns:**
934 |
935 | the category of this product in the Google category taxonomy
936 |
937 | ---
938 |
939 | ### getGtin
940 |
941 | **Signature:** `getGtin() : String`
942 |
943 | **Description:** Returns the Facebook GTIN of the product.
944 |
945 | **Returns:**
946 |
947 | the GTIN
948 |
949 | ---
950 |
951 | ### getID
952 |
953 | **Signature:** `getID() : String`
954 |
955 | **Description:** Returns the ID of the Facebook product. This is the same as the ID of the Demandware product.
956 |
957 | **Returns:**
958 |
959 | product ID
960 |
961 | ---
962 |
963 | ### getImageLinks
964 |
965 | **Signature:** `getImageLinks() : List`
966 |
967 | **Description:** Returns a list containing the URLs of the images to show in Facebook for the product.
968 |
969 | **Returns:**
970 |
971 | the URLs of the images
972 |
973 | ---
974 |
975 | ### getItemGroupID
976 |
977 | **Signature:** `getItemGroupID() : String`
978 |
979 | **Description:** Returns the ID of the Facebook item group for the product, that is, its master product.
980 |
981 | **Returns:**
982 |
983 | the ID of the Facebook item group
984 |
985 | ---
986 |
987 | ### getLink
988 |
989 | **Signature:** `getLink() : URL`
990 |
991 | **Description:** Returns the URL of the Demandware storefront link to the product.
992 |
993 | **Returns:**
994 |
995 | the URL of the storefront link
996 |
997 | ---
998 |
999 | ### getMaterial
1000 |
1001 | **Signature:** `getMaterial() : String`
1002 |
1003 | **Description:** Returns the Facebook material value label of the product.
1004 |
1005 | **Returns:**
1006 |
1007 | the material value label
1008 |
1009 | ---
1010 |
1011 | ### getMpn
1012 |
1013 | **Signature:** `getMpn() : String`
1014 |
1015 | **Description:** Returns the Facebook MPN of the product.
1016 |
1017 | **Returns:**
1018 |
1019 | the MPN
1020 |
1021 | ---
1022 |
1023 | ### getPattern
1024 |
1025 | **Signature:** `getPattern() : String`
1026 |
1027 | **Description:** Returns the Facebook pattern value label of the product.
1028 |
1029 | **Returns:**
1030 |
1031 | the pattern value label
1032 |
1033 | ---
1034 |
1035 | ### getPrice
1036 |
1037 | **Signature:** `getPrice() : Money`
1038 |
1039 | **Description:** Returns the price to show in Facebook for the product.
1040 |
1041 | **Returns:**
1042 |
1043 | the price to show in Facebook
1044 |
1045 | ---
1046 |
1047 | ### getProductType
1048 |
1049 | **Signature:** `getProductType() : String`
1050 |
1051 | **Description:** Returns the Facebook product type. This is the retailer-defined category of the item.
1052 |
1053 | **Returns:**
1054 |
1055 | the Facebook product type
1056 |
1057 | ---
1058 |
1059 | ### getSalePrice
1060 |
1061 | **Signature:** `getSalePrice() : Money`
1062 |
1063 | **Description:** Returns the sale price to show in Facebook for the product.
1064 |
1065 | **Returns:**
1066 |
1067 | the sale price to show in Facebook
1068 |
1069 | ---
1070 |
1071 | ### getSalePriceEffectiveDateEnd
1072 |
1073 | **Signature:** `getSalePriceEffectiveDateEnd() : Date`
1074 |
1075 | **Description:** Returns the end date of the Facebook sale price of the product.
1076 |
1077 | **Returns:**
1078 |
1079 | the end date of the Facebook sale price
1080 |
1081 | ---
1082 |
1083 | ### getSalePriceEffectiveDateStart
1084 |
1085 | **Signature:** `getSalePriceEffectiveDateStart() : Date`
1086 |
1087 | **Description:** Returns the start date of the Facebook sale price of the product.
1088 |
1089 | **Returns:**
1090 |
1091 | the start date of the Facebook sale price
1092 |
1093 | ---
1094 |
1095 | ### getShippingHeight
1096 |
1097 | **Signature:** `getShippingHeight() : Number`
1098 |
1099 | **Description:** Returns the shipping height of the product.
1100 |
1101 | **Returns:**
1102 |
1103 | the shipping height
1104 |
1105 | **See Also:**
1106 |
1107 | getShippingLength()
1108 | getShippingWidth()
1109 | getShippingSizeUnit()
1110 |
1111 | ---
1112 |
1113 | ### getShippingLength
1114 |
1115 | **Signature:** `getShippingLength() : Number`
1116 |
1117 | **Description:** Returns the shipping length of the product.
1118 |
1119 | **Returns:**
1120 |
1121 | the shipping length
1122 |
1123 | **See Also:**
1124 |
1125 | getShippingWidth()
1126 | getShippingHeight()
1127 | getShippingSizeUnit()
1128 |
1129 | ---
1130 |
1131 | ### getShippingSizeUnit
1132 |
1133 | **Signature:** `getShippingSizeUnit() : String`
1134 |
1135 | **Description:** Returns the shipping size unit of the product.
1136 |
1137 | **Returns:**
1138 |
1139 | the shipping size unit
1140 |
1141 | **See Also:**
1142 |
1143 | getShippingLength()
1144 | getShippingWidth()
1145 | getShippingHeight()
1146 |
1147 | ---
1148 |
1149 | ### getShippingWeight
1150 |
1151 | **Signature:** `getShippingWeight() : Quantity`
1152 |
1153 | **Description:** Returns the shipping weight for the product.
1154 |
1155 | **Returns:**
1156 |
1157 | the shipping weight
1158 |
1159 | ---
1160 |
1161 | ### getShippingWidth
1162 |
1163 | **Signature:** `getShippingWidth() : Number`
1164 |
1165 | **Description:** Returns the shipping width of the product.
1166 |
1167 | **Returns:**
1168 |
1169 | the shipping width
1170 |
1171 | **See Also:**
1172 |
1173 | getShippingLength()
1174 | getShippingHeight()
1175 | getShippingSizeUnit()
1176 |
1177 | ---
1178 |
1179 | ### getSize
1180 |
1181 | **Signature:** `getSize() : String`
1182 |
1183 | **Description:** Returns the Facebook size value label of the product.
1184 |
1185 | **Returns:**
1186 |
1187 | the size value label
1188 |
1189 | ---
1190 |
1191 | ### getTitle
1192 |
1193 | **Signature:** `getTitle() : String`
1194 |
1195 | **Description:** Returns the title of the Facebook product.
1196 |
1197 | **Returns:**
1198 |
1199 | product title
1200 |
1201 | ---
1202 |
1203 | ### setAgeGroup
1204 |
1205 | **Signature:** `setAgeGroup(ageGroup : String) : void`
1206 |
1207 | **Description:** Sets the age group for the Facebook product. Possible values are AGE_GROUP_ADULT, AGE_GROUP_INFANT, AGE_GROUP_KIDS, AGE_GROUP_NEWBORN, AGE_GROUP_TODDLER, or null.
1208 |
1209 | **Parameters:**
1210 |
1211 | - `ageGroup`: the ageGroup to set for this product
1212 |
1213 | ---
1214 |
1215 | ### setAvailability
1216 |
1217 | **Signature:** `setAvailability(availability : String) : void`
1218 |
1219 | **Description:** Sets the availability of the Facebook product. Possible values are AVAILABILITY_AVAILABLE_FOR_ORDER, AVAILABILITY_IN_STOCK, AVAILABILITY_OUT_OF_STOCK, or AVAILABILITY_PREORDER
1220 |
1221 | **Parameters:**
1222 |
1223 | - `availability`: the availability status to set for this product
1224 |
1225 | ---
1226 |
1227 | ### setBrand
1228 |
1229 | **Signature:** `setBrand(brand : String) : void`
1230 |
1231 | **Description:** Sets the Facebook brand of the product. If the value is longer than 70 characters it is truncated.
1232 |
1233 | **Parameters:**
1234 |
1235 | - `brand`: Facebook brand, up to 70 characters
1236 |
1237 | ---
1238 |
1239 | ### setColor
1240 |
1241 | **Signature:** `setColor(color : String) : void`
1242 |
1243 | **Description:** Sets the Facebook color value label of the product. If the value is longer than 100 characters it is truncated.
1244 |
1245 | **Parameters:**
1246 |
1247 | - `color`: Facebook color value label, up to 100 characters
1248 |
1249 | ---
1250 |
1251 | ### setCondition
1252 |
1253 | **Signature:** `setCondition(condition : String) : void`
1254 |
1255 | **Description:** Sets the condition of the Facebook product. Possible values are CONDITION_NEW, CONDITION_REFURBISHED, or CONDITION_USED.
1256 |
1257 | **Parameters:**
1258 |
1259 | - `condition`: the condition status to set for this product
1260 |
1261 | ---
1262 |
1263 | ### setCustomLabel0
1264 |
1265 | **Signature:** `setCustomLabel0(customLabel0 : String) : void`
1266 |
1267 | **Description:** Sets the Facebook custom label 0 value of the product.
1268 |
1269 | **Parameters:**
1270 |
1271 | - `customLabel0`: custom label 0 value
1272 |
1273 | ---
1274 |
1275 | ### setCustomLabel1
1276 |
1277 | **Signature:** `setCustomLabel1(customLabel1 : String) : void`
1278 |
1279 | **Description:** Sets the Facebook custom label 1 value of the product.
1280 |
1281 | **Parameters:**
1282 |
1283 | - `customLabel1`: custom label 1 value
1284 |
1285 | ---
1286 |
1287 | ### setCustomLabel2
1288 |
1289 | **Signature:** `setCustomLabel2(customLabel2 : String) : void`
1290 |
1291 | **Description:** Sets the Facebook custom label 2 value of the product.
1292 |
1293 | **Parameters:**
1294 |
1295 | - `customLabel2`: custom label 2 value
1296 |
1297 | ---
1298 |
1299 | ### setCustomLabel3
1300 |
1301 | **Signature:** `setCustomLabel3(customLabel3 : String) : void`
1302 |
1303 | **Description:** Sets the Facebook custom label 3 value of the product.
1304 |
1305 | **Parameters:**
1306 |
1307 | - `customLabel3`: custom label 3 value
1308 |
1309 | ---
1310 |
1311 | ### setCustomLabel4
1312 |
1313 | **Signature:** `setCustomLabel4(customLabel4 : String) : void`
1314 |
1315 | **Description:** Sets the Facebook custom label 4 value of the product.
1316 |
1317 | **Parameters:**
1318 |
1319 | - `customLabel4`: custom label 4 value
1320 |
1321 | ---
1322 |
1323 | ### setDescription
1324 |
1325 | **Signature:** `setDescription(description : String) : void`
1326 |
1327 | **Description:** Sets the description of the Facebook product. If the value is longer than 5000 characters it is truncated.
1328 |
1329 | **Parameters:**
1330 |
1331 | - `description`: product description, up to 5000 characters
1332 |
1333 | ---
1334 |
1335 | ### setExpirationDate
1336 |
1337 | **Signature:** `setExpirationDate(expirationDate : Date) : void`
1338 |
1339 | **Description:** Sets the Facebook expiration date of the product.
1340 |
1341 | **Parameters:**
1342 |
1343 | - `expirationDate`: Facebook expiration date
1344 |
1345 | ---
1346 |
1347 | ### setGender
1348 |
1349 | **Signature:** `setGender(gender : String) : void`
1350 |
1351 | **Description:** Sets the gender for the Facebook product. Possible values are GENDER_MALE, GENDER_FEMALE, GENDER_UNISEX, or null.
1352 |
1353 | **Parameters:**
1354 |
1355 | - `gender`: the gender to set for this product
1356 |
1357 | ---
1358 |
1359 | ### setGoogleProductCategory
1360 |
1361 | **Signature:** `setGoogleProductCategory(googleProductCategory : String) : void`
1362 |
1363 | **Description:** Sets the category of this product in the Google category taxonomy.
1364 |
1365 | **Parameters:**
1366 |
1367 | - `googleProductCategory`: Google product category
1368 |
1369 | ---
1370 |
1371 | ### setGtin
1372 |
1373 | **Signature:** `setGtin(gtin : String) : void`
1374 |
1375 | **Description:** Sets the Facebook GTIN of the product. If the value is longer than 70 characters it is truncated.
1376 |
1377 | **Parameters:**
1378 |
1379 | - `gtin`: Facebook GTIN, up to 70 characters
1380 |
1381 | ---
1382 |
1383 | ### setImageLinks
1384 |
1385 | **Signature:** `setImageLinks(imageLinks : List) : void`
1386 |
1387 | **Description:** Sets the list of URLs of images to show in Facebook for the product.
1388 |
1389 | **Parameters:**
1390 |
1391 | - `imageLinks`: links to the product images
1392 |
1393 | ---
1394 |
1395 | ### setItemGroupID
1396 |
1397 | **Signature:** `setItemGroupID(itemGroupID : String) : void`
1398 |
1399 | **Description:** Sets the ID of the Facebook item group for the product, that is, its master product.
1400 |
1401 | **Parameters:**
1402 |
1403 | - `itemGroupID`: ID of Facebook item group
1404 |
1405 | ---
1406 |
1407 | ### setLink
1408 |
1409 | **Signature:** `setLink(link : URL) : void`
1410 |
1411 | **Description:** Sets the URL of the Demandware storefront link to the product.
1412 |
1413 | **Parameters:**
1414 |
1415 | - `link`: Demandware storefront link to the product
1416 |
1417 | ---
1418 |
1419 | ### setMaterial
1420 |
1421 | **Signature:** `setMaterial(material : String) : void`
1422 |
1423 | **Description:** Sets the Facebook material value label of the product. If the value is longer than 200 characters it is truncated.
1424 |
1425 | **Parameters:**
1426 |
1427 | - `material`: Facebook material value label, up to 200 characters
1428 |
1429 | ---
1430 |
1431 | ### setMpn
1432 |
1433 | **Signature:** `setMpn(mpn : String) : void`
1434 |
1435 | **Description:** Sets the Facebook MPN of the product. If the value is longer than 70 characters it is truncated.
1436 |
1437 | **Parameters:**
1438 |
1439 | - `mpn`: Facebook MPN, up to 70 characters
1440 |
1441 | ---
1442 |
1443 | ### setPattern
1444 |
1445 | **Signature:** `setPattern(pattern : String) : void`
1446 |
1447 | **Description:** Sets the Facebook pattern value label of the product. If the value is longer than 100 characters it is truncated.
1448 |
1449 | **Parameters:**
1450 |
1451 | - `pattern`: Facebook pattern value label, up to 100 characters
1452 |
1453 | ---
1454 |
1455 | ### setPrice
1456 |
1457 | **Signature:** `setPrice(price : Money) : void`
1458 |
1459 | **Description:** Sets the price to show in Facebook for the product.
1460 |
1461 | **Parameters:**
1462 |
1463 | - `price`: Facebook price
1464 |
1465 | ---
1466 |
1467 | ### setProductType
1468 |
1469 | **Signature:** `setProductType(productType : String) : void`
1470 |
1471 | **Description:** Sets the Facebook product type. If the value is longer than 750 characters it is truncated.
1472 |
1473 | **Parameters:**
1474 |
1475 | - `productType`: Facebook product type, up to 750 characters
1476 |
1477 | ---
1478 |
1479 | ### setSalePrice
1480 |
1481 | **Signature:** `setSalePrice(salePrice : Money) : void`
1482 |
1483 | **Description:** Sets the sale price to show in Facebook for the product.
1484 |
1485 | **Parameters:**
1486 |
1487 | - `salePrice`: Facebook sale price
1488 |
1489 | ---
1490 |
1491 | ### setSalePriceEffectiveDateEnd
1492 |
1493 | **Signature:** `setSalePriceEffectiveDateEnd(salePriceEffectiveDateEnd : Date) : void`
1494 |
1495 | **Description:** Sets the end date of the Facebook sale price of the product.
1496 |
1497 | **Parameters:**
1498 |
1499 | - `salePriceEffectiveDateEnd`: end date of Facebook sale price
1500 |
1501 | ---
1502 |
1503 | ### setSalePriceEffectiveDateStart
1504 |
1505 | **Signature:** `setSalePriceEffectiveDateStart(salePriceEffectiveDateStart : Date) : void`
1506 |
1507 | **Description:** Sets the start date of the Facebook sale price of the product.
1508 |
1509 | **Parameters:**
1510 |
1511 | - `salePriceEffectiveDateStart`: start date of Facebook sale price
1512 |
1513 | ---
1514 |
1515 | ### setShippingHeight
1516 |
1517 | **Signature:** `setShippingHeight(shippingHeight : Number) : void`
1518 |
1519 | **Description:** Sets the shipping height of the product. If the value is negative it is truncated to 0.
1520 |
1521 | **Parameters:**
1522 |
1523 | - `shippingHeight`: shipping height, may not be negative
1524 |
1525 | **See Also:**
1526 |
1527 | setShippingLength(Number)
1528 | setShippingWidth(Number)
1529 | setShippingSizeUnit(String)
1530 |
1531 | ---
1532 |
1533 | ### setShippingLength
1534 |
1535 | **Signature:** `setShippingLength(shippingLength : Number) : void`
1536 |
1537 | **Description:** Sets the shipping length of the product. If the value is negative it is truncated to 0.
1538 |
1539 | **Parameters:**
1540 |
1541 | - `shippingLength`: shipping length, may not be negative
1542 |
1543 | **See Also:**
1544 |
1545 | setShippingWidth(Number)
1546 | setShippingHeight(Number)
1547 | setShippingSizeUnit(String)
1548 |
1549 | ---
1550 |
1551 | ### setShippingSizeUnit
1552 |
1553 | **Signature:** `setShippingSizeUnit(shippingSizeUnit : String) : void`
1554 |
1555 | **Description:** Sets the shipping size unit of the product.
1556 |
1557 | **Parameters:**
1558 |
1559 | - `shippingSizeUnit`: shipping size unit
1560 |
1561 | **See Also:**
1562 |
1563 | setShippingLength(Number)
1564 | setShippingWidth(Number)
1565 | setShippingHeight(Number)
1566 |
1567 | ---
1568 |
1569 | ### setShippingWeight
1570 |
1571 | **Signature:** `setShippingWeight(shippingWeight : Quantity) : void`
1572 |
1573 | **Description:** Sets the shipping weight for the product. Possible unit values are SHIPPING_WEIGHT_UNIT_LB, SHIPPING_WEIGHT_UNIT_OZ, SHIPPING_WEIGHT_UNIT_G, or SHIPPING_WEIGHT_UNIT_KG.
1574 |
1575 | **Parameters:**
1576 |
1577 | - `shippingWeight`: product shipping weight
1578 |
1579 | ---
1580 |
1581 | ### setShippingWidth
1582 |
1583 | **Signature:** `setShippingWidth(shippingWidth : Number) : void`
1584 |
1585 | **Description:** Sets the shipping width of the product. If the value is negative it is truncated to 0.
1586 |
1587 | **Parameters:**
1588 |
1589 | - `shippingWidth`: shipping width, may not be negative
1590 |
1591 | **See Also:**
1592 |
1593 | setShippingLength(Number)
1594 | setShippingHeight(Number)
1595 | setShippingSizeUnit(String)
1596 |
1597 | ---
1598 |
1599 | ### setSize
1600 |
1601 | **Signature:** `setSize(size : String) : void`
1602 |
1603 | **Description:** Sets the Facebook size value label of the product. If the value is longer than 100 characters it is truncated.
1604 |
1605 | **Parameters:**
1606 |
1607 | - `size`: Facebook size value label, up to 100 characters
1608 |
1609 | ---
1610 |
1611 | ### setTitle
1612 |
1613 | **Signature:** `setTitle(title : String) : void`
1614 |
1615 | **Description:** Sets the title of the Facebook product. If the value is longer than 100 characters it is truncated.
1616 |
1617 | **Parameters:**
1618 |
1619 | - `title`: product title, up to 100 characters
1620 |
1621 | ---
```
--------------------------------------------------------------------------------
/tests/mcp/node/activate-code-version-advanced.full-mode.programmatic.test.js:
--------------------------------------------------------------------------------
```javascript
1 | // ==================================================================================
2 | // SFCC MCP Server - activate_code_version Advanced Programmatic Tests (Full Mode)
3 | // Comprehensive testing for complex scenarios, workflows, and edge cases
4 | //
5 | // Test Coverage:
6 | // - Multi-step code version management workflows
7 | // - Error recovery and resilience testing
8 | // - Integration with get_code_versions tool
9 | // - Advanced parameter validation and edge cases
10 | // - State consistency and transaction-like behavior
11 | // - Performance characteristics under various loads
12 | // - Complex business logic validation
13 | //
14 | // Usage:
15 | // node --test tests/mcp/node/activate-code-version-advanced.full-mode.programmatic.test.js
16 | // npm run test:mcp:node
17 | // ==================================================================================
18 |
19 | import { test, describe, before, after, beforeEach } from 'node:test';
20 | import { strict as assert } from 'node:assert';
21 | import { connect } from 'mcp-aegis';
22 |
23 | describe('activate_code_version Advanced Programmatic Tests (Full Mode)', () => {
24 | let client;
25 |
26 | before(async () => {
27 | client = await connect('./aegis.config.with-dw.json');
28 | assert.ok(client.connected, 'Client should be connected to server');
29 | });
30 |
31 | after(async () => {
32 | if (client?.connected) {
33 | await client.disconnect();
34 | }
35 | });
36 |
37 | beforeEach(() => {
38 | // CRITICAL: Clear all buffers to prevent test interference
39 | client.clearAllBuffers();
40 | });
41 |
42 | // ==================================================================================
43 | // TOOL AVAILABILITY AND SCHEMA VALIDATION
44 | // ==================================================================================
45 | describe('Tool Availability and Schema Validation', () => {
46 | test('should have activate_code_version tool available in full mode', async () => {
47 | const tools = await client.listTools();
48 | const activateTool = tools.find(tool => tool.name === 'activate_code_version');
49 |
50 | assert.ok(activateTool, 'activate_code_version tool should be available');
51 | assert.equal(activateTool.name, 'activate_code_version');
52 | assert.ok(activateTool.description.includes('Activate a specific code version'));
53 |
54 | // Validate input schema
55 | assert.equal(activateTool.inputSchema.type, 'object');
56 | assert.ok(activateTool.inputSchema.properties.codeVersionId);
57 | assert.equal(activateTool.inputSchema.properties.codeVersionId.type, 'string');
58 | assert.ok(Array.isArray(activateTool.inputSchema.required));
59 | assert.ok(activateTool.inputSchema.required.includes('codeVersionId'));
60 | });
61 |
62 | test('should have companion get_code_versions tool for workflow integration', async () => {
63 | const tools = await client.listTools();
64 | const getCodeVersionsTool = tools.find(tool => tool.name === 'get_code_versions');
65 |
66 | assert.ok(getCodeVersionsTool, 'get_code_versions tool should be available for workflow integration');
67 | assert.equal(getCodeVersionsTool.inputSchema.type, 'object');
68 | });
69 | });
70 |
71 | // ==================================================================================
72 | // COMPREHENSIVE PARAMETER VALIDATION
73 | // ==================================================================================
74 | describe('Comprehensive Parameter Validation', () => {
75 | test('should validate codeVersionId parameter types and formats', async () => {
76 | // Test missing parameter
77 | const missingResult = await client.callTool('activate_code_version', {});
78 | assert.equal(missingResult.isError, true);
79 | assert.ok(missingResult.content[0].text.includes('codeVersionId must be a non-empty string'));
80 |
81 | // Test empty string
82 | const emptyResult = await client.callTool('activate_code_version', { codeVersionId: '' });
83 | assert.equal(emptyResult.isError, true);
84 | assert.ok(emptyResult.content[0].text.includes('codeVersionId must be a non-empty string'));
85 |
86 | // Test null value
87 | const nullResult = await client.callTool('activate_code_version', { codeVersionId: null });
88 | assert.equal(nullResult.isError, true);
89 | assert.ok(nullResult.content[0].text.includes('codeVersionId must be a non-empty string'));
90 |
91 | // Test undefined value
92 | const undefinedResult = await client.callTool('activate_code_version', { codeVersionId: undefined });
93 | assert.equal(undefinedResult.isError, true);
94 | assert.ok(undefinedResult.content[0].text.includes('codeVersionId must be a non-empty string'));
95 | });
96 |
97 | test('should handle various invalid codeVersionId formats gracefully', async () => {
98 | const invalidFormats = [
99 | 123, // number
100 | true, // boolean
101 | [], // array
102 | {}, // object
103 | ' ', // whitespace only
104 | '\n\t', // whitespace characters
105 | ];
106 |
107 | for (const invalidFormat of invalidFormats) {
108 | const result = await client.callTool('activate_code_version', { codeVersionId: invalidFormat });
109 | assert.equal(result.isError, true, `Should reject ${typeof invalidFormat}: ${JSON.stringify(invalidFormat)}`);
110 | assert.ok(result.content[0].text.includes('codeVersionId must be a non-empty string'));
111 | }
112 | });
113 |
114 | test('should handle edge case codeVersionId values', async () => {
115 | const edgeCases = [
116 | 'a'.repeat(1000), // Very long ID
117 | 'test-version-with-special-chars!@#$%^&*()', // Special characters
118 | 'version with spaces', // Spaces
119 | 'UPPERCASE-VERSION', // Case variations
120 | 'version_nonexistent_test', // Non-existent version
121 | 'version.with.dots', // Dots
122 | '123-numeric-start', // Starting with numbers
123 | 'unicode-测试-version', // Unicode characters
124 | ];
125 |
126 | for (const edgeCase of edgeCases) {
127 | const result = await client.callTool('activate_code_version', { codeVersionId: edgeCase });
128 | assert.equal(result.isError, true, `Should handle edge case: ${edgeCase}`);
129 |
130 | // Should get 404 or similar SFCC error, not parameter validation error
131 | assert.ok(
132 | result.content[0].text.includes('404') ||
133 | result.content[0].text.includes('not found') ||
134 | result.content[0].text.includes('InvalidParameterException'),
135 | `Should get SFCC API error for edge case: ${edgeCase}, got: ${result.content[0].text}`
136 | );
137 | }
138 | });
139 | });
140 |
141 | // ==================================================================================
142 | // SFCC API ERROR HANDLING AND RESPONSE PARSING
143 | // ==================================================================================
144 | describe('SFCC API Error Handling and Response Parsing', () => {
145 | test('should parse and format SFCC API errors correctly', async () => {
146 | const result = await client.callTool('activate_code_version', {
147 | codeVersionId: 'nonexistent-test-version-12345'
148 | });
149 |
150 | assert.equal(result.isError, true);
151 | assert.equal(result.content.length, 1);
152 | assert.equal(result.content[0].type, 'text');
153 |
154 | const errorText = result.content[0].text;
155 | assert.ok(errorText.startsWith('Error:'), 'Error should start with Error:');
156 |
157 | // Should contain SFCC fault information
158 | assert.ok(
159 | errorText.includes('404') ||
160 | errorText.includes('not found') ||
161 | errorText.includes('InvalidParameterException'),
162 | `Should contain SFCC fault info, got: ${errorText}`
163 | );
164 | });
165 |
166 | test('should handle different types of SFCC API errors consistently', async () => {
167 | const testVersions = [
168 | 'definitely-nonexistent-version',
169 | 'another-invalid-version-name',
170 | 'test-error-scenario-version'
171 | ];
172 |
173 | const errorResponses = [];
174 |
175 | for (const versionId of testVersions) {
176 | const result = await client.callTool('activate_code_version', { codeVersionId: versionId });
177 | assert.equal(result.isError, true);
178 | errorResponses.push(result.content[0].text);
179 | }
180 |
181 | // All errors should follow similar format
182 | errorResponses.forEach(errorText => {
183 | assert.ok(errorText.startsWith('Error:'), 'All errors should start with Error:');
184 | assert.ok(errorText.length > 20, 'Error messages should be reasonably detailed');
185 | });
186 | });
187 |
188 | test('should handle malformed SFCC API responses gracefully', async () => {
189 | // Test with version ID that might cause unusual API responses
190 | const result = await client.callTool('activate_code_version', {
191 | codeVersionId: 'test-malformed-response-handling'
192 | });
193 |
194 | assert.equal(result.isError, true);
195 | assert.ok(result.content, 'Should always return content array');
196 | assert.ok(result.content[0].text, 'Should always return text content');
197 | assert.equal(typeof result.content[0].text, 'string', 'Error text should be string');
198 | });
199 | });
200 |
201 | // ==================================================================================
202 | // INTEGRATION WITH GET_CODE_VERSIONS WORKFLOW
203 | // ==================================================================================
204 | describe('Integration with get_code_versions Workflow', () => {
205 | test('should integrate with get_code_versions for complete workflow', async () => {
206 | // Step 1: Get list of available code versions
207 | const versionsResult = await client.callTool('get_code_versions', {});
208 | assert.equal(versionsResult.isError, false, 'get_code_versions should succeed');
209 |
210 | // Parse the response to understand available versions
211 | const versionsText = versionsResult.content[0].text;
212 | assert.ok(versionsText.length > 0, 'Should return version information');
213 |
214 | // Step 2: Try to activate a clearly non-existent version
215 | const activateResult = await client.callTool('activate_code_version', {
216 | codeVersionId: 'workflow-test-nonexistent-version'
217 | });
218 | assert.equal(activateResult.isError, true, 'Should fail for non-existent version');
219 |
220 | // Step 3: Verify error handling doesn't affect subsequent get_code_versions calls
221 | const versionsResult2 = await client.callTool('get_code_versions', {});
222 | assert.equal(versionsResult2.isError, false, 'get_code_versions should still work after failed activation');
223 | });
224 |
225 | test('should maintain consistent state across multiple tool calls', async () => {
226 | const operations = [
227 | { tool: 'get_code_versions', args: {} },
228 | { tool: 'activate_code_version', args: { codeVersionId: 'test-state-consistency-1' } },
229 | { tool: 'get_code_versions', args: {} },
230 | { tool: 'activate_code_version', args: { codeVersionId: 'test-state-consistency-2' } },
231 | { tool: 'get_code_versions', args: {} },
232 | ];
233 |
234 | const results = [];
235 |
236 | for (const operation of operations) {
237 | const result = await client.callTool(operation.tool, operation.args);
238 | results.push({ operation, result });
239 |
240 | // Each operation should return proper response structure
241 | assert.ok(result.content, `${operation.tool} should return content`);
242 | assert.ok(Array.isArray(result.content), `${operation.tool} content should be array`);
243 | assert.equal(typeof result.isError, 'boolean', `${operation.tool} should have isError boolean`);
244 | }
245 |
246 | // Verify get_code_versions calls succeeded while activate calls failed (expected for non-existent versions)
247 | const getVersionsResults = results.filter(r => r.operation.tool === 'get_code_versions');
248 | const activateResults = results.filter(r => r.operation.tool === 'activate_code_version');
249 |
250 | getVersionsResults.forEach((r, index) => {
251 | assert.equal(r.result.isError, false, `get_code_versions call ${index + 1} should succeed`);
252 | });
253 |
254 | activateResults.forEach((r, index) => {
255 | assert.equal(r.result.isError, true, `activate_code_version call ${index + 1} should fail for non-existent version`);
256 | });
257 | });
258 | });
259 |
260 | // ==================================================================================
261 | // ERROR RECOVERY AND RESILIENCE TESTING
262 | // ==================================================================================
263 | describe('Error Recovery and Resilience Testing', () => {
264 | test('should recover gracefully from various error scenarios', async () => {
265 | const errorScenarios = [
266 | { description: 'Empty codeVersionId', args: { codeVersionId: '' } },
267 | { description: 'Very long codeVersionId', args: { codeVersionId: 'x'.repeat(500) } },
268 | { description: 'Special characters', args: { codeVersionId: '!@#$%^&*()_+{}|:"<>?[]\\;\',./' } },
269 | { description: 'Unicode characters', args: { codeVersionId: '测试版本号码' } },
270 | { description: 'SQL injection attempt', args: { codeVersionId: "'; DROP TABLE versions; --" } },
271 | ];
272 |
273 | for (const scenario of errorScenarios) {
274 | const result = await client.callTool('activate_code_version', scenario.args);
275 |
276 | // Should handle all scenarios gracefully without throwing
277 | assert.equal(result.isError, true, `${scenario.description} should return error`);
278 | assert.ok(result.content, `${scenario.description} should return content`);
279 | assert.ok(result.content[0].text, `${scenario.description} should return error text`);
280 |
281 | // Verify server is still responsive after error
282 | const recoveryTest = await client.listTools();
283 | assert.ok(recoveryTest.length > 0, `Server should be responsive after ${scenario.description}`);
284 | }
285 | });
286 |
287 | test('should handle rapid sequential activation attempts', async () => {
288 | const rapidRequests = Array.from({ length: 10 }, (_, i) => ({
289 | codeVersionId: `rapid-test-version-${i}`
290 | }));
291 |
292 | const results = [];
293 |
294 | // Execute requests sequentially (MCP doesn't support concurrent requests)
295 | for (const request of rapidRequests) {
296 | const result = await client.callTool('activate_code_version', request);
297 | results.push(result);
298 | }
299 |
300 | // All requests should be handled properly
301 | results.forEach((result, index) => {
302 | assert.equal(result.isError, true, `Rapid request ${index} should fail for non-existent version`);
303 | assert.ok(result.content[0].text.length > 0, `Rapid request ${index} should have error message`);
304 | });
305 |
306 | // Server should still be responsive
307 | const finalTest = await client.listTools();
308 | assert.ok(finalTest.length > 0, 'Server should be responsive after rapid requests');
309 | });
310 |
311 | test('should maintain error isolation between requests', async () => {
312 | // Generate error
313 | const errorResult = await client.callTool('activate_code_version', { codeVersionId: '' });
314 | assert.equal(errorResult.isError, true);
315 |
316 | // Verify normal operation still works
317 | const normalResult = await client.callTool('get_code_versions', {});
318 | assert.equal(normalResult.isError, false, 'Normal operations should work after errors');
319 |
320 | // Generate different error
321 | const errorResult2 = await client.callTool('activate_code_version', { codeVersionId: 'another-error-test' });
322 | assert.equal(errorResult2.isError, true);
323 |
324 | // Verify isolation - errors should be different
325 | assert.notEqual(errorResult.content[0].text, errorResult2.content[0].text, 'Different errors should produce different messages');
326 | });
327 | });
328 |
329 | // ==================================================================================
330 | // RESPONSE FORMAT AND STRUCTURE VALIDATION
331 | // ==================================================================================
332 | describe('Response Format and Structure Validation', () => {
333 | test('should return consistent response structure across all scenarios', async () => {
334 | const testScenarios = [
335 | { name: 'missing parameter', args: {} },
336 | { name: 'empty parameter', args: { codeVersionId: '' } },
337 | { name: 'valid format nonexistent version', args: { codeVersionId: 'test-structure-validation' } },
338 | { name: 'special characters', args: { codeVersionId: 'test!@#$' } },
339 | ];
340 |
341 | for (const scenario of testScenarios) {
342 | const result = await client.callTool('activate_code_version', scenario.args);
343 |
344 | // Validate MCP response structure
345 | assert.ok('content' in result, `${scenario.name}: Should have content property`);
346 | assert.ok('isError' in result, `${scenario.name}: Should have isError property`);
347 | assert.ok(Array.isArray(result.content), `${scenario.name}: Content should be array`);
348 | assert.equal(typeof result.isError, 'boolean', `${scenario.name}: isError should be boolean`);
349 |
350 | // Validate content structure
351 | assert.equal(result.content.length, 1, `${scenario.name}: Should have exactly one content item`);
352 | assert.equal(result.content[0].type, 'text', `${scenario.name}: Content should be text type`);
353 | assert.ok(typeof result.content[0].text === 'string', `${scenario.name}: Text should be string`);
354 | assert.ok(result.content[0].text.length > 0, `${scenario.name}: Text should not be empty`);
355 |
356 | // All test scenarios should return errors for these test cases
357 | assert.equal(result.isError, true, `${scenario.name}: Should be error for test cases`);
358 | }
359 | });
360 |
361 | test('should format error messages consistently', async () => {
362 | const results = [];
363 |
364 | // Collect various error responses
365 | const errorCases = [
366 | 'format-test-version-1',
367 | 'format-test-version-2',
368 | 'format-test-version-3'
369 | ];
370 |
371 | for (const versionId of errorCases) {
372 | const result = await client.callTool('activate_code_version', { codeVersionId: versionId });
373 | results.push(result.content[0].text);
374 | }
375 |
376 | // All errors should start with "Error:"
377 | results.forEach((errorText, index) => {
378 | assert.ok(errorText.startsWith('Error:'), `Error ${index + 1} should start with 'Error:'`);
379 | assert.ok(errorText.length > 10, `Error ${index + 1} should be reasonably detailed`);
380 | });
381 | });
382 | });
383 |
384 | // ==================================================================================
385 | // BUSINESS LOGIC AND WORKFLOW VALIDATION
386 | // ==================================================================================
387 | describe('Business Logic and Workflow Validation', () => {
388 | test('should enforce code version management business rules', async () => {
389 | // Test that we get appropriate error for non-existent versions
390 | const result = await client.callTool('activate_code_version', {
391 | codeVersionId: 'business-logic-test-version'
392 | });
393 |
394 | assert.equal(result.isError, true);
395 |
396 | // Error should indicate version not found, not generic failure
397 | const errorText = result.content[0].text.toLowerCase();
398 | assert.ok(
399 | errorText.includes('not found') ||
400 | errorText.includes('404') ||
401 | errorText.includes('does not exist') ||
402 | errorText.includes('invalidparameterexception'),
403 | `Error should indicate version not found: ${result.content[0].text}`
404 | );
405 | });
406 |
407 | test('should validate code version activation preconditions', async () => {
408 | // According to tool description: "Only inactive code versions can be activated"
409 | // For non-existent versions, we should get appropriate error
410 |
411 | const result = await client.callTool('activate_code_version', {
412 | codeVersionId: 'precondition-test-version'
413 | });
414 |
415 | assert.equal(result.isError, true);
416 |
417 | // Should get proper SFCC API error about version not existing
418 | assert.ok(result.content[0].text.includes('Error:'));
419 | });
420 |
421 | test('should provide informative error messages for troubleshooting', async () => {
422 | const result = await client.callTool('activate_code_version', {
423 | codeVersionId: 'troubleshooting-test-version'
424 | });
425 |
426 | assert.equal(result.isError, true);
427 |
428 | const errorText = result.content[0].text;
429 |
430 | // Error should be helpful for developers
431 | assert.ok(errorText.length > 30, 'Error message should be detailed enough for troubleshooting');
432 | assert.ok(errorText.includes('Error:'), 'Should clearly indicate this is an error');
433 |
434 | // Should contain either version-specific info or general API error info
435 | assert.ok(
436 | errorText.includes('version') ||
437 | errorText.includes('404') ||
438 | errorText.includes('not found') ||
439 | errorText.includes('Request failed'),
440 | 'Should contain helpful error context'
441 | );
442 | });
443 | });
444 |
445 | // ==================================================================================
446 | // PERFORMANCE AND RELIABILITY CHARACTERISTICS
447 | // ==================================================================================
448 | describe('Performance and Reliability Characteristics', () => {
449 | test('should handle operations within reasonable time bounds', async () => {
450 | const startTime = Date.now();
451 |
452 | const result = await client.callTool('activate_code_version', {
453 | codeVersionId: 'performance-test-version'
454 | });
455 |
456 | const duration = Date.now() - startTime;
457 |
458 | // Should complete within reasonable time (lenient for CI environments)
459 | assert.ok(duration < 10000, `Operation should complete within 10 seconds, took ${duration}ms`);
460 |
461 | // Should still return proper response
462 | assert.ok(result.content, 'Should return response even under timing constraints');
463 | });
464 |
465 | test('should maintain consistent response times across multiple calls', async () => {
466 | const durations = [];
467 | const testCalls = 5;
468 |
469 | for (let i = 0; i < testCalls; i++) {
470 | const startTime = Date.now();
471 |
472 | await client.callTool('activate_code_version', {
473 | codeVersionId: `consistency-test-${i}`
474 | });
475 |
476 | durations.push(Date.now() - startTime);
477 | }
478 |
479 | // All calls should complete within reasonable bounds
480 | durations.forEach((duration, index) => {
481 | assert.ok(duration < 10000, `Call ${index + 1} should complete within 10 seconds, took ${duration}ms`);
482 | });
483 |
484 | // Calculate variance (should not be extreme)
485 | const maxVariation = Math.max(...durations) / Math.min(...durations);
486 |
487 | // Lenient variance check for CI environments
488 | assert.ok(maxVariation < 50, `Response time variation should be reasonable, got ${maxVariation}x variation`);
489 | });
490 |
491 | test('should handle stress scenarios gracefully', async () => {
492 | // Test with various payload sizes and complexity
493 | const stressTests = [
494 | { name: 'Long version ID', codeVersionId: 'stress-test-' + 'x'.repeat(200) },
495 | { name: 'Complex characters', codeVersionId: 'stress-测试-🔥-version-!@#$%^&*()' },
496 | { name: 'JSON-like string', codeVersionId: '{"version": "test", "data": [1,2,3]}' },
497 | { name: 'XML-like string', codeVersionId: '<version>test</version><data>stress</data>' },
498 | ];
499 |
500 | for (const stressTest of stressTests) {
501 | const result = await client.callTool('activate_code_version', {
502 | codeVersionId: stressTest.codeVersionId
503 | });
504 |
505 | // Should handle gracefully without crashing
506 | assert.ok(result.content, `${stressTest.name}: Should return content`);
507 | assert.equal(typeof result.isError, 'boolean', `${stressTest.name}: Should return boolean isError`);
508 |
509 | // Server should remain responsive
510 | const healthCheck = await client.listTools();
511 | assert.ok(healthCheck.length > 0, `${stressTest.name}: Server should remain responsive`);
512 | }
513 | });
514 | });
515 |
516 | // ==================================================================================
517 | // EDGE CASES AND BOUNDARY CONDITIONS
518 | // ==================================================================================
519 | describe('Edge Cases and Boundary Conditions', () => {
520 | test('should handle maximum length version IDs', async () => {
521 | // Test various length boundaries
522 | const lengthTests = [
523 | { length: 100, name: '100 characters' },
524 | { length: 255, name: '255 characters (common limit)' },
525 | { length: 500, name: '500 characters' },
526 | { length: 1000, name: '1000 characters' },
527 | ];
528 |
529 | for (const lengthTest of lengthTests) {
530 | const longVersionId = 'test-' + 'x'.repeat(lengthTest.length - 5);
531 |
532 | const result = await client.callTool('activate_code_version', {
533 | codeVersionId: longVersionId
534 | });
535 |
536 | // Should handle gracefully (expect error for non-existent version)
537 | assert.equal(result.isError, true, `${lengthTest.name}: Should handle long version ID`);
538 | assert.ok(result.content[0].text.length > 0, `${lengthTest.name}: Should return error message`);
539 | }
540 | });
541 |
542 | test('should handle unusual character encodings and formats', async () => {
543 | const encodingTests = [
544 | { name: 'Unicode characters', value: 'version-测试-版本-号码' },
545 | { name: 'Emoji characters', value: 'version-🚀-💻-🔥' },
546 | { name: 'Control characters', value: 'version\n\t\r\b\f' },
547 | { name: 'High unicode', value: 'version-𝕧𝕖𝕣𝕤𝕚𝕠𝕟' },
548 | { name: 'Mixed scripts', value: 'version-αβγ-أبج-中文-🌍' },
549 | ];
550 |
551 | for (const encodingTest of encodingTests) {
552 | const result = await client.callTool('activate_code_version', {
553 | codeVersionId: encodingTest.value
554 | });
555 |
556 | // Should handle without server errors
557 | assert.ok(result.content, `${encodingTest.name}: Should return content`);
558 | assert.equal(typeof result.isError, 'boolean', `${encodingTest.name}: Should return boolean isError`);
559 |
560 | // Check server responsiveness
561 | const healthCheck = await client.listTools();
562 | assert.ok(healthCheck.length > 0, `${encodingTest.name}: Server should remain responsive`);
563 | }
564 | });
565 |
566 | test('should validate parameter completeness and format', async () => {
567 | // Test various parameter scenarios
568 | const parameterTests = [
569 | { name: 'Extra parameters', args: { codeVersionId: 'test', extraParam: 'should-be-ignored' } },
570 | { name: 'Case variations', args: { CodeVersionId: 'test-case' } }, // Wrong case
571 | { name: 'Nested object', args: { codeVersionId: { nested: 'test' } } },
572 | { name: 'Array value', args: { codeVersionId: ['test', 'array'] } },
573 | ];
574 |
575 | for (const paramTest of parameterTests) {
576 | const result = await client.callTool('activate_code_version', paramTest.args);
577 |
578 | // Should handle parameter variations appropriately
579 | assert.ok(result.content, `${paramTest.name}: Should return content`);
580 | assert.equal(typeof result.isError, 'boolean', `${paramTest.name}: Should return boolean isError`);
581 |
582 | if (paramTest.name === 'Extra parameters') {
583 | // Extra parameters might be acceptable if codeVersionId is valid string
584 | // We expect error because version doesn't exist, not parameter error
585 | assert.ok(
586 | result.content[0].text.includes('404') ||
587 | result.content[0].text.includes('not found') ||
588 | result.content[0].text.includes('codeVersionId must be a non-empty string'),
589 | `${paramTest.name}: Should handle extra parameters gracefully`
590 | );
591 | } else {
592 | // Other cases should fail parameter validation
593 | assert.equal(result.isError, true, `${paramTest.name}: Should fail validation`);
594 | }
595 | }
596 | });
597 | });
598 |
599 | // ==================================================================================
600 | // MOCK VALIDATION AND TESTING ENVIRONMENT
601 | // ==================================================================================
602 | describe('Mock Validation and Testing Environment', () => {
603 | test('should validate we are testing against mock/sandbox environment', async () => {
604 | // Ensure we're not accidentally testing against production
605 | const result = await client.callTool('activate_code_version', {
606 | codeVersionId: 'PRODUCTION-SAFETY-CHECK-DO-NOT-ACTIVATE'
607 | });
608 |
609 | // Should fail (which is expected for non-existent version in sandbox)
610 | assert.equal(result.isError, true, 'Should fail for test version in sandbox environment');
611 |
612 | // Verify we get sandbox-appropriate error (not production access denied)
613 | const errorText = result.content[0].text.toLowerCase();
614 | assert.ok(
615 | errorText.includes('not found') ||
616 | errorText.includes('404') ||
617 | errorText.includes('invalidparameterexception'),
618 | `Should get sandbox error, not production access error: ${result.content[0].text}`
619 | );
620 | });
621 |
622 | test('should have consistent mock behavior across test runs', async () => {
623 | const testVersion = 'consistent-mock-test-version';
624 |
625 | // Call the same operation multiple times
626 | const results = [];
627 | for (let i = 0; i < 3; i++) {
628 | const result = await client.callTool('activate_code_version', {
629 | codeVersionId: testVersion
630 | });
631 | results.push(result);
632 | }
633 |
634 | // All results should be consistent
635 | results.forEach((result, index) => {
636 | assert.equal(result.isError, true, `Call ${index + 1}: Should consistently return error`);
637 | assert.ok(result.content[0].text.length > 0, `Call ${index + 1}: Should have error message`);
638 | });
639 |
640 | // Error messages should be similar (allowing for some variation in timing/IDs)
641 | const errorTexts = results.map(r => r.content[0].text);
642 |
643 | errorTexts.forEach((errorText, index) => {
644 | assert.ok(
645 | errorText.startsWith('Error:'),
646 | `Call ${index + 1}: Should have consistent error format`
647 | );
648 | });
649 | });
650 | });
651 | });
```
--------------------------------------------------------------------------------
/tests/mcp/yaml/search-sfcc-classes.full-mode.test.mcp.yml:
--------------------------------------------------------------------------------
```yaml
1 | # ==================================================================================
2 | # SFCC MCP Server - search_sfcc_classes Tool YAML Tests
3 | # Comprehensive testing for SFCC class search functionality
4 | # Tests both successful responses and error handling scenarios
5 | #
6 | # Quick Test Commands:
7 | # aegis "tests/mcp/yaml/search-sfcc-classes.full-mode.test.mcp.yml" --config "aegis.config.with-dw.json" --verbose
8 | # aegis "tests/mcp/yaml/search-sfcc-classes.full-mode.test.mcp.yml" --config "aegis.config.with-dw.json" --debug --timing
9 | # aegis query search_sfcc_classes '{"query": "catalog"}' --config "aegis.config.with-dw.json"
10 | # aegis query search_sfcc_classes '{"query": "product"}' --config "aegis.config.with-dw.json"
11 | # ==================================================================================
12 | description: "SFCC MCP Server search_sfcc_classes tool - comprehensive validation"
13 |
14 | # ==================================================================================
15 | # BASIC TOOL STRUCTURE VALIDATION
16 | # ==================================================================================
17 | tests:
18 | - it: "should list search_sfcc_classes tool in available tools"
19 | request:
20 | jsonrpc: "2.0"
21 | id: "tool-available"
22 | method: "tools/list"
23 | params: {}
24 | expect:
25 | response:
26 | jsonrpc: "2.0"
27 | id: "tool-available"
28 | result:
29 | match:extractField: "tools.*.name"
30 | value: "match:arrayContains:search_sfcc_classes"
31 | stderr: "toBeEmpty"
32 |
33 | - it: "should have search_sfcc_classes in tools list with proper structure"
34 | request:
35 | jsonrpc: "2.0"
36 | id: "tool-metadata"
37 | method: "tools/list"
38 | params: {}
39 | expect:
40 | response:
41 | jsonrpc: "2.0"
42 | id: "tool-metadata"
43 | result:
44 | tools: "match:arrayContains:name:search_sfcc_classes"
45 | stderr: "toBeEmpty"
46 |
47 | - it: "should have tool with meaningful description"
48 | request:
49 | jsonrpc: "2.0"
50 | id: "tool-description-quality"
51 | method: "tools/list"
52 | params: {}
53 | expect:
54 | response:
55 | jsonrpc: "2.0"
56 | id: "tool-description-quality"
57 | result:
58 | tools: "match:arrayContains:name:search_sfcc_classes"
59 | stderr: "toBeEmpty"
60 |
61 | - it: "should have proper inputSchema structure for search_sfcc_classes"
62 | request:
63 | jsonrpc: "2.0"
64 | id: "tool-schema-structure"
65 | method: "tools/list"
66 | params: {}
67 | expect:
68 | response:
69 | jsonrpc: "2.0"
70 | id: "tool-schema-structure"
71 | result:
72 | tools:
73 | match:arrayElements:
74 | match:partial:
75 | name: "match:type:string"
76 | inputSchema:
77 | type: "object"
78 | properties: "match:type:object"
79 |
80 | stderr: "toBeEmpty"
81 |
82 | # ==================================================================================
83 | # SUCCESSFUL EXECUTION TESTS - COMMON SEARCH TERMS
84 | # ==================================================================================
85 |
86 | - it: "should execute with catalog search term"
87 | request:
88 | jsonrpc: "2.0"
89 | id: "exec-catalog-search"
90 | method: "tools/call"
91 | params:
92 | name: "search_sfcc_classes"
93 | arguments:
94 | query: "catalog"
95 | expect:
96 | response:
97 | jsonrpc: "2.0"
98 | id: "exec-catalog-search"
99 | result:
100 | content:
101 | - type: "text"
102 | text: "match:contains:catalog"
103 | isError: false
104 | stderr: "toBeEmpty"
105 |
106 | - it: "should return JSON array structure for product search"
107 | request:
108 | jsonrpc: "2.0"
109 | id: "exec-product-json"
110 | method: "tools/call"
111 | params:
112 | name: "search_sfcc_classes"
113 | arguments:
114 | query: "product"
115 | expect:
116 | response:
117 | jsonrpc: "2.0"
118 | id: "exec-product-json"
119 | result:
120 | content:
121 | - type: "text"
122 | text: "match:regex:\\[[\\s\\S]*\\]" # Valid JSON array structure
123 | isError: false
124 | stderr: "toBeEmpty"
125 |
126 | - it: "should find customer-related classes"
127 | request:
128 | jsonrpc: "2.0"
129 | id: "exec-customer-search"
130 | method: "tools/call"
131 | params:
132 | name: "search_sfcc_classes"
133 | arguments:
134 | query: "customer"
135 | expect:
136 | response:
137 | jsonrpc: "2.0"
138 | id: "exec-customer-search"
139 | result:
140 | content:
141 | - type: "text"
142 | text: "match:contains:customer"
143 | isError: false
144 | stderr: "toBeEmpty"
145 |
146 | - it: "should find order-related classes"
147 | request:
148 | jsonrpc: "2.0"
149 | id: "exec-order-search"
150 | method: "tools/call"
151 | params:
152 | name: "search_sfcc_classes"
153 | arguments:
154 | query: "order"
155 | expect:
156 | response:
157 | jsonrpc: "2.0"
158 | id: "exec-order-search"
159 | result:
160 | content:
161 | - type: "text"
162 | text: "match:contains:order"
163 | isError: false
164 | stderr: "toBeEmpty"
165 |
166 | - it: "should find system-related classes"
167 | request:
168 | jsonrpc: "2.0"
169 | id: "exec-system-search"
170 | method: "tools/call"
171 | params:
172 | name: "search_sfcc_classes"
173 | arguments:
174 | query: "system"
175 | expect:
176 | response:
177 | jsonrpc: "2.0"
178 | id: "exec-system-search"
179 | result:
180 | content:
181 | - type: "text"
182 | text: "match:contains:system"
183 | isError: false
184 | stderr: "toBeEmpty"
185 |
186 | - it: "should find web-related classes"
187 | request:
188 | jsonrpc: "2.0"
189 | id: "exec-web-search"
190 | method: "tools/call"
191 | params:
192 | name: "search_sfcc_classes"
193 | arguments:
194 | query: "web"
195 | expect:
196 | response:
197 | jsonrpc: "2.0"
198 | id: "exec-web-search"
199 | result:
200 | content:
201 | - type: "text"
202 | text: "match:contains:web"
203 | isError: false
204 | stderr: "toBeEmpty"
205 |
206 | - it: "should find util-related classes"
207 | request:
208 | jsonrpc: "2.0"
209 | id: "exec-util-search"
210 | method: "tools/call"
211 | params:
212 | name: "search_sfcc_classes"
213 | arguments:
214 | query: "util"
215 | expect:
216 | response:
217 | jsonrpc: "2.0"
218 | id: "exec-util-search"
219 | result:
220 | content:
221 | - type: "text"
222 | text: "match:contains:util"
223 | isError: false
224 | stderr: "toBeEmpty"
225 |
226 | # ==================================================================================
227 | # SEARCH RESULT STRUCTURE VALIDATION
228 | # ==================================================================================
229 |
230 | - it: "should return JSON array in results"
231 | request:
232 | jsonrpc: "2.0"
233 | id: "validate-array-structure"
234 | method: "tools/call"
235 | params:
236 | name: "search_sfcc_classes"
237 | arguments:
238 | query: "catalog"
239 | expect:
240 | response:
241 | jsonrpc: "2.0"
242 | id: "validate-array-structure"
243 | result:
244 | content:
245 | - type: "text"
246 | text: "match:regex:\\[[\\s\\S]*\\]"
247 | isError: false
248 | stderr: "toBeEmpty"
249 |
250 | - it: "should return class names in array format"
251 | request:
252 | jsonrpc: "2.0"
253 | id: "validate-class-names"
254 | method: "tools/call"
255 | params:
256 | name: "search_sfcc_classes"
257 | arguments:
258 | query: "catalog"
259 | expect:
260 | response:
261 | jsonrpc: "2.0"
262 | id: "validate-class-names"
263 | result:
264 | content:
265 | - type: "text"
266 | text: "match:contains:dw.catalog.Product"
267 | isError: false
268 | stderr: "toBeEmpty"
269 |
270 | - it: "should include multiple matching classes"
271 | request:
272 | jsonrpc: "2.0"
273 | id: "validate-multiple-classes"
274 | method: "tools/call"
275 | params:
276 | name: "search_sfcc_classes"
277 | arguments:
278 | query: "catalog"
279 | expect:
280 | response:
281 | jsonrpc: "2.0"
282 | id: "validate-multiple-classes"
283 | result:
284 | content:
285 | - type: "text"
286 | text: "match:contains:dw.catalog.Catalog"
287 | isError: false
288 | stderr: "toBeEmpty"
289 |
290 | - it: "should format class names with quotes"
291 | request:
292 | jsonrpc: "2.0"
293 | id: "validate-quoted-names"
294 | method: "tools/call"
295 | params:
296 | name: "search_sfcc_classes"
297 | arguments:
298 | query: "product"
299 | expect:
300 | response:
301 | jsonrpc: "2.0"
302 | id: "validate-quoted-names"
303 | result:
304 | content:
305 | - type: "text"
306 | text: "match:regex:\"dw\\.catalog\\.Product\""
307 | isError: false
308 | stderr: "toBeEmpty"
309 |
310 | # ==================================================================================
311 | # CASE SENSITIVITY AND SEARCH VARIATIONS
312 | # ==================================================================================
313 |
314 | - it: "should handle uppercase search terms"
315 | request:
316 | jsonrpc: "2.0"
317 | id: "search-uppercase"
318 | method: "tools/call"
319 | params:
320 | name: "search_sfcc_classes"
321 | arguments:
322 | query: "CATALOG"
323 | expect:
324 | response:
325 | jsonrpc: "2.0"
326 | id: "search-uppercase"
327 | result:
328 | content:
329 | - type: "text"
330 | text: "match:regex:\\[[\\s\\S]*\\]"
331 | isError: false
332 | stderr: "toBeEmpty"
333 |
334 | - it: "should handle mixed case search terms"
335 | request:
336 | jsonrpc: "2.0"
337 | id: "search-mixedcase"
338 | method: "tools/call"
339 | params:
340 | name: "search_sfcc_classes"
341 | arguments:
342 | query: "Product"
343 | expect:
344 | response:
345 | jsonrpc: "2.0"
346 | id: "search-mixedcase"
347 | result:
348 | content:
349 | - type: "text"
350 | text: "match:regex:\\[[\\s\\S]*\\]"
351 | isError: false
352 | stderr: "toBeEmpty"
353 |
354 | - it: "should handle partial class names"
355 | request:
356 | jsonrpc: "2.0"
357 | id: "search-partial"
358 | method: "tools/call"
359 | params:
360 | name: "search_sfcc_classes"
361 | arguments:
362 | query: "cat" # Should find catalog classes
363 | expect:
364 | response:
365 | jsonrpc: "2.0"
366 | id: "search-partial"
367 | result:
368 | content:
369 | - type: "text"
370 | text: "match:regex:\\[[\\s\\S]*\\]"
371 | isError: false
372 | stderr: "toBeEmpty"
373 |
374 | - it: "should handle single character searches"
375 | request:
376 | jsonrpc: "2.0"
377 | id: "search-single-char"
378 | method: "tools/call"
379 | params:
380 | name: "search_sfcc_classes"
381 | arguments:
382 | query: "c"
383 | expect:
384 | response:
385 | jsonrpc: "2.0"
386 | id: "search-single-char"
387 | result:
388 | content:
389 | - type: "text"
390 | text: "match:regex:\\[[\\s\\S]*\\]"
391 | isError: false
392 | stderr: "toBeEmpty"
393 |
394 | # ==================================================================================
395 | # SPECIFIC SFCC DOMAIN SEARCHES
396 | # ==================================================================================
397 |
398 | - it: "should find dw.catalog namespace classes"
399 | request:
400 | jsonrpc: "2.0"
401 | id: "domain-catalog"
402 | method: "tools/call"
403 | params:
404 | name: "search_sfcc_classes"
405 | arguments:
406 | query: "catalog"
407 | expect:
408 | response:
409 | jsonrpc: "2.0"
410 | id: "domain-catalog"
411 | result:
412 | content:
413 | - type: "text"
414 | text: "match:contains:dw.catalog"
415 | isError: false
416 | stderr: "toBeEmpty"
417 |
418 | - it: "should find dw.customer namespace classes"
419 | request:
420 | jsonrpc: "2.0"
421 | id: "domain-customer"
422 | method: "tools/call"
423 | params:
424 | name: "search_sfcc_classes"
425 | arguments:
426 | query: "customer"
427 | expect:
428 | response:
429 | jsonrpc: "2.0"
430 | id: "domain-customer"
431 | result:
432 | content:
433 | - type: "text"
434 | text: "match:contains:dw.customer"
435 | isError: false
436 | stderr: "toBeEmpty"
437 |
438 | - it: "should find dw.order namespace classes"
439 | request:
440 | jsonrpc: "2.0"
441 | id: "domain-order"
442 | method: "tools/call"
443 | params:
444 | name: "search_sfcc_classes"
445 | arguments:
446 | query: "order"
447 | expect:
448 | response:
449 | jsonrpc: "2.0"
450 | id: "domain-order"
451 | result:
452 | content:
453 | - type: "text"
454 | text: "match:contains:dw.order"
455 | isError: false
456 | stderr: "toBeEmpty"
457 |
458 | - it: "should find dw.system namespace classes"
459 | request:
460 | jsonrpc: "2.0"
461 | id: "domain-system"
462 | method: "tools/call"
463 | params:
464 | name: "search_sfcc_classes"
465 | arguments:
466 | query: "system"
467 | expect:
468 | response:
469 | jsonrpc: "2.0"
470 | id: "domain-system"
471 | result:
472 | content:
473 | - type: "text"
474 | text: "match:contains:dw.system"
475 | isError: false
476 | stderr: "toBeEmpty"
477 |
478 | - it: "should find dw.web namespace classes"
479 | request:
480 | jsonrpc: "2.0"
481 | id: "domain-web"
482 | method: "tools/call"
483 | params:
484 | name: "search_sfcc_classes"
485 | arguments:
486 | query: "web"
487 | expect:
488 | response:
489 | jsonrpc: "2.0"
490 | id: "domain-web"
491 | result:
492 | content:
493 | - type: "text"
494 | text: "match:contains:dw.web"
495 | isError: false
496 | stderr: "toBeEmpty"
497 |
498 | - it: "should find dw.util namespace classes"
499 | request:
500 | jsonrpc: "2.0"
501 | id: "domain-util"
502 | method: "tools/call"
503 | params:
504 | name: "search_sfcc_classes"
505 | arguments:
506 | query: "util"
507 | expect:
508 | response:
509 | jsonrpc: "2.0"
510 | id: "domain-util"
511 | result:
512 | content:
513 | - type: "text"
514 | text: "match:contains:dw.util"
515 | isError: false
516 | stderr: "toBeEmpty"
517 |
518 | # ==================================================================================
519 | # FUNCTIONAL SEARCH TESTS
520 | # ==================================================================================
521 |
522 | - it: "should find inventory-related classes"
523 | request:
524 | jsonrpc: "2.0"
525 | id: "func-inventory"
526 | method: "tools/call"
527 | params:
528 | name: "search_sfcc_classes"
529 | arguments:
530 | query: "inventory"
531 | expect:
532 | response:
533 | jsonrpc: "2.0"
534 | id: "func-inventory"
535 | result:
536 | content:
537 | - type: "text"
538 | text: "match:contains:ProductInventoryList"
539 | isError: false
540 | stderr: "toBeEmpty"
541 |
542 | - it: "should find price-related classes"
543 | request:
544 | jsonrpc: "2.0"
545 | id: "func-price"
546 | method: "tools/call"
547 | params:
548 | name: "search_sfcc_classes"
549 | arguments:
550 | query: "price"
551 | expect:
552 | response:
553 | jsonrpc: "2.0"
554 | id: "func-price"
555 | result:
556 | content:
557 | - type: "text"
558 | text: "match:contains:PriceBook"
559 | isError: false
560 | stderr: "toBeEmpty"
561 |
562 | - it: "should find basket-related classes"
563 | request:
564 | jsonrpc: "2.0"
565 | id: "func-basket"
566 | method: "tools/call"
567 | params:
568 | name: "search_sfcc_classes"
569 | arguments:
570 | query: "basket"
571 | expect:
572 | response:
573 | jsonrpc: "2.0"
574 | id: "func-basket"
575 | result:
576 | content:
577 | - type: "text"
578 | text: "match:contains:Basket"
579 | isError: false
580 | stderr: "toBeEmpty"
581 |
582 | - it: "should find payment-related classes"
583 | request:
584 | jsonrpc: "2.0"
585 | id: "func-payment"
586 | method: "tools/call"
587 | params:
588 | name: "search_sfcc_classes"
589 | arguments:
590 | query: "payment"
591 | expect:
592 | response:
593 | jsonrpc: "2.0"
594 | id: "func-payment"
595 | result:
596 | content:
597 | - type: "text"
598 | text: "match:contains:Payment"
599 | isError: false
600 | stderr: "toBeEmpty"
601 |
602 | - it: "should find shipping-related classes"
603 | request:
604 | jsonrpc: "2.0"
605 | id: "func-shipping"
606 | method: "tools/call"
607 | params:
608 | name: "search_sfcc_classes"
609 | arguments:
610 | query: "shipping"
611 | expect:
612 | response:
613 | jsonrpc: "2.0"
614 | id: "func-shipping"
615 | result:
616 | content:
617 | - type: "text"
618 | text: "match:contains:Shipping"
619 | isError: false
620 | stderr: "toBeEmpty"
621 |
622 | # ==================================================================================
623 | # ERROR HANDLING TESTS
624 | # ==================================================================================
625 |
626 | - it: "should handle empty query gracefully"
627 | request:
628 | jsonrpc: "2.0"
629 | id: "error-empty-query"
630 | method: "tools/call"
631 | params:
632 | name: "search_sfcc_classes"
633 | arguments:
634 | query: ""
635 | expect:
636 | response:
637 | jsonrpc: "2.0"
638 | id: "error-empty-query"
639 | result:
640 | content:
641 | - type: "text"
642 | text: "match:contains:Error"
643 | isError: true
644 | stderr: "toBeEmpty"
645 |
646 | - it: "should handle missing query parameter"
647 | request:
648 | jsonrpc: "2.0"
649 | id: "error-missing-query"
650 | method: "tools/call"
651 | params:
652 | name: "search_sfcc_classes"
653 | arguments: {}
654 | expect:
655 | response:
656 | jsonrpc: "2.0"
657 | id: "error-missing-query"
658 | result:
659 | content:
660 | - type: "text"
661 | text: "match:contains:query"
662 | isError: true
663 | stderr: "toBeEmpty"
664 |
665 | - it: "should handle non-existent terms gracefully"
666 | request:
667 | jsonrpc: "2.0"
668 | id: "search-nonexistent"
669 | method: "tools/call"
670 | params:
671 | name: "search_sfcc_classes"
672 | arguments:
673 | query: "zzznothingfound"
674 | expect:
675 | response:
676 | jsonrpc: "2.0"
677 | id: "search-nonexistent"
678 | result:
679 | content:
680 | - type: "text"
681 | text: "match:regex:^\\[\\s*\\]$"
682 | isError: false
683 | stderr: "toBeEmpty"
684 |
685 | - it: "should handle special characters in query"
686 | request:
687 | jsonrpc: "2.0"
688 | id: "search-special-chars"
689 | method: "tools/call"
690 | params:
691 | name: "search_sfcc_classes"
692 | arguments:
693 | query: "!@#$%"
694 | expect:
695 | response:
696 | jsonrpc: "2.0"
697 | id: "search-special-chars"
698 | result:
699 | content:
700 | - type: "text"
701 | text: "match:regex:\\[[\\s\\S]*\\]"
702 | isError: false
703 | stderr: "toBeEmpty"
704 |
705 | - it: "should handle very long query strings"
706 | request:
707 | jsonrpc: "2.0"
708 | id: "search-long-query"
709 | method: "tools/call"
710 | params:
711 | name: "search_sfcc_classes"
712 | arguments:
713 | query: "verylongquerystringthatdoesnotmatchanythingbutshouldbetreatedgracefully"
714 | expect:
715 | response:
716 | jsonrpc: "2.0"
717 | id: "search-long-query"
718 | result:
719 | content:
720 | - type: "text"
721 | text: "match:regex:^\\[\\s*\\]$"
722 | isError: false
723 | stderr: "toBeEmpty"
724 |
725 | # ==================================================================================
726 | # RESPONSE FORMAT VALIDATION
727 | # ==================================================================================
728 |
729 | - it: "should return consistent MCP content structure"
730 | request:
731 | jsonrpc: "2.0"
732 | id: "format-content-structure"
733 | method: "tools/call"
734 | params:
735 | name: "search_sfcc_classes"
736 | arguments:
737 | query: "catalog"
738 | expect:
739 | response:
740 | jsonrpc: "2.0"
741 | id: "format-content-structure"
742 | result:
743 | content:
744 | match:arrayElements:
745 | match:partial:
746 | type: "text"
747 | text: "match:type:string"
748 | isError: false
749 | stderr: "toBeEmpty"
750 |
751 | - it: "should return single content item for successful calls"
752 | request:
753 | jsonrpc: "2.0"
754 | id: "format-single-content"
755 | method: "tools/call"
756 | params:
757 | name: "search_sfcc_classes"
758 | arguments:
759 | query: "product"
760 | expect:
761 | response:
762 | jsonrpc: "2.0"
763 | id: "format-single-content"
764 | result:
765 | content: "match:arrayLength:1"
766 | isError: false
767 | stderr: "toBeEmpty"
768 |
769 | - it: "should not set isError flag for successful responses"
770 | request:
771 | jsonrpc: "2.0"
772 | id: "format-no-error-flag"
773 | method: "tools/call"
774 | params:
775 | name: "search_sfcc_classes"
776 | arguments:
777 | query: "customer"
778 | expect:
779 | response:
780 | jsonrpc: "2.0"
781 | id: "format-no-error-flag"
782 | result:
783 | content: "match:type:array"
784 | isError: false
785 | stderr: "toBeEmpty"
786 |
787 | # ==================================================================================
788 | # EDGE CASES AND SEARCH BEHAVIOR
789 | # ==================================================================================
790 |
791 | - it: "should handle numeric query terms"
792 | request:
793 | jsonrpc: "2.0"
794 | id: "edge-numeric-query"
795 | method: "tools/call"
796 | params:
797 | name: "search_sfcc_classes"
798 | arguments:
799 | query: "123"
800 | expect:
801 | response:
802 | jsonrpc: "2.0"
803 | id: "edge-numeric-query"
804 | result:
805 | content:
806 | - type: "text"
807 | text: "match:regex:\\[[\\s\\S]*\\]"
808 | isError: false
809 | stderr: "toBeEmpty"
810 |
811 | - it: "should handle whitespace in query"
812 | request:
813 | jsonrpc: "2.0"
814 | id: "edge-whitespace"
815 | method: "tools/call"
816 | params:
817 | name: "search_sfcc_classes"
818 | arguments:
819 | query: " catalog "
820 | expect:
821 | response:
822 | jsonrpc: "2.0"
823 | id: "edge-whitespace"
824 | result:
825 | content:
826 | - type: "text"
827 | text: "match:regex:\\[[\\s\\S]*\\]"
828 | isError: false
829 | stderr: "toBeEmpty"
830 |
831 | - it: "should handle common abbreviations"
832 | request:
833 | jsonrpc: "2.0"
834 | id: "edge-abbreviations"
835 | method: "tools/call"
836 | params:
837 | name: "search_sfcc_classes"
838 | arguments:
839 | query: "mgr" # Should find manager classes
840 | expect:
841 | response:
842 | jsonrpc: "2.0"
843 | id: "edge-abbreviations"
844 | result:
845 | content:
846 | - type: "text"
847 | text: "match:regex:\\[[\\s\\S]*\\]"
848 | isError: false
849 | stderr: "toBeEmpty"
850 |
851 | - it: "should handle dots in search terms"
852 | request:
853 | jsonrpc: "2.0"
854 | id: "edge-dots"
855 | method: "tools/call"
856 | params:
857 | name: "search_sfcc_classes"
858 | arguments:
859 | query: "dw.catalog"
860 | expect:
861 | response:
862 | jsonrpc: "2.0"
863 | id: "edge-dots"
864 | result:
865 | content:
866 | - type: "text"
867 | text: "match:regex:\\[[\\s\\S]*\\]"
868 | isError: false
869 | stderr: "toBeEmpty"
870 |
871 | # ==================================================================================
872 | # PERFORMANCE AND CONSISTENCY VALIDATION
873 | # ==================================================================================
874 |
875 | - it: "should respond consistently for repeated searches"
876 | request:
877 | jsonrpc: "2.0"
878 | id: "perf-consistent-1"
879 | method: "tools/call"
880 | params:
881 | name: "search_sfcc_classes"
882 | arguments:
883 | query: "catalog"
884 | expect:
885 | response:
886 | jsonrpc: "2.0"
887 | id: "perf-consistent-1"
888 | result:
889 | content:
890 | - type: "text"
891 | text: "match:regex:\\[[\\s\\S]*\\]"
892 | isError: false
893 | stderr: "toBeEmpty"
894 |
895 | - it: "should respond consistently for repeated searches (second time)"
896 | request:
897 | jsonrpc: "2.0"
898 | id: "perf-consistent-2"
899 | method: "tools/call"
900 | params:
901 | name: "search_sfcc_classes"
902 | arguments:
903 | query: "catalog"
904 | expect:
905 | response:
906 | jsonrpc: "2.0"
907 | id: "perf-consistent-2"
908 | result:
909 | content:
910 | - type: "text"
911 | text: "match:regex:\\[[\\s\\S]*\\]"
912 | isError: false
913 | stderr: "toBeEmpty"
914 |
915 | # ==================================================================================
916 | # PERFORMANCE TIMING TESTS
917 | # ==================================================================================
918 |
919 | - it: "should return search results within acceptable time"
920 | request:
921 | jsonrpc: "2.0"
922 | id: "perf-basic-timing"
923 | method: "tools/call"
924 | params:
925 | name: "search_sfcc_classes"
926 | arguments:
927 | query: "catalog"
928 | expect:
929 | response:
930 | jsonrpc: "2.0"
931 | id: "perf-basic-timing"
932 | result:
933 | content:
934 | - type: "text"
935 | text: "match:regex:\\[[\\s\\S]*\\]"
936 | isError: false
937 | performance:
938 | maxResponseTime: "200ms" # Search should be fast
939 | stderr: "toBeEmpty"
940 |
941 | - it: "should handle complex searches efficiently"
942 | request:
943 | jsonrpc: "2.0"
944 | id: "perf-complex-search"
945 | method: "tools/call"
946 | params:
947 | name: "search_sfcc_classes"
948 | arguments:
949 | query: "product"
950 | expect:
951 | response:
952 | jsonrpc: "2.0"
953 | id: "perf-complex-search"
954 | result:
955 | content:
956 | - type: "text"
957 | text: "match:regex:\\[[\\s\\S]*\\]"
958 | isError: false
959 | performance:
960 | maxResponseTime: "100ms" # Even complex searches should be under 100ms
961 | stderr: "toBeEmpty"
962 |
963 | - it: "should handle partial searches quickly"
964 | request:
965 | jsonrpc: "2.0"
966 | id: "perf-partial-search"
967 | method: "tools/call"
968 | params:
969 | name: "search_sfcc_classes"
970 | arguments:
971 | query: "cat"
972 | expect:
973 | response:
974 | jsonrpc: "2.0"
975 | id: "perf-partial-search"
976 | result:
977 | content:
978 | - type: "text"
979 | text: "match:regex:\\[[\\s\\S]*\\]"
980 | isError: false
981 | performance:
982 | maxResponseTime: "100ms" # Partial searches should be fast
983 | stderr: "toBeEmpty"
984 |
985 | - it: "should handle no-result searches efficiently"
986 | request:
987 | jsonrpc: "2.0"
988 | id: "perf-no-results"
989 | method: "tools/call"
990 | params:
991 | name: "search_sfcc_classes"
992 | arguments:
993 | query: "zzznothingfound"
994 | expect:
995 | response:
996 | jsonrpc: "2.0"
997 | id: "perf-no-results"
998 | result:
999 | content:
1000 | - type: "text"
1001 | text: "match:regex:^\\[\\s*\\]$"
1002 | isError: false
1003 | performance:
1004 | maxResponseTime: "150ms" # No results should be very fast
1005 | stderr: "toBeEmpty"
1006 |
1007 | - it: "should handle error cases quickly"
1008 | request:
1009 | jsonrpc: "2.0"
1010 | id: "perf-error-timing"
1011 | method: "tools/call"
1012 | params:
1013 | name: "search_sfcc_classes"
1014 | arguments:
1015 | query: ""
1016 | expect:
1017 | response:
1018 | jsonrpc: "2.0"
1019 | id: "perf-error-timing"
1020 | result:
1021 | content:
1022 | - type: "text"
1023 | text: "match:contains:Error"
1024 | isError: true
1025 | performance:
1026 | maxResponseTime: "150ms" # Error handling should be very fast
1027 | stderr: "toBeEmpty"
1028 |
1029 | - it: "should handle cached results quickly"
1030 | request:
1031 | jsonrpc: "2.0"
1032 | id: "perf-cached-search"
1033 | method: "tools/call"
1034 | params:
1035 | name: "search_sfcc_classes"
1036 | arguments:
1037 | query: "catalog" # Same as first test - should be cached
1038 | expect:
1039 | response:
1040 | jsonrpc: "2.0"
1041 | id: "perf-cached-search"
1042 | result:
1043 | content:
1044 | - type: "text"
1045 | text: "match:regex:\\[[\\s\\S]*\\]"
1046 | isError: false
1047 | performance:
1048 | maxResponseTime: "150ms" # Cached responses should be extremely fast
1049 | stderr: "toBeEmpty"
1050 |
1051 | - it: "should handle single character searches within timeout"
1052 | request:
1053 | jsonrpc: "2.0"
1054 | id: "perf-single-char-timing"
1055 | method: "tools/call"
1056 | params:
1057 | name: "search_sfcc_classes"
1058 | arguments:
1059 | query: "c"
1060 | expect:
1061 | response:
1062 | jsonrpc: "2.0"
1063 | id: "perf-single-char-timing"
1064 | result:
1065 | content:
1066 | - type: "text"
1067 | text: "match:regex:\\[[\\s\\S]*\\]"
1068 | isError: false
1069 | performance:
1070 | maxResponseTime: "100ms" # Single char searches might return many results
1071 | stderr: "toBeEmpty"
1072 |
1073 | - it: "should handle long queries efficiently"
1074 | request:
1075 | jsonrpc: "2.0"
1076 | id: "perf-long-query-timing"
1077 | method: "tools/call"
1078 | params:
1079 | name: "search_sfcc_classes"
1080 | arguments:
1081 | query: "verylongquerystringthatdoesnotmatchanythingbutshouldbetreatedgracefully"
1082 | expect:
1083 | response:
1084 | jsonrpc: "2.0"
1085 | id: "perf-long-query-timing"
1086 | result:
1087 | content:
1088 | - type: "text"
1089 | text: "match:regex:^\\[\\s*\\]$"
1090 | isError: false
1091 | performance:
1092 | maxResponseTime: "150ms" # Long queries with no results should be fast
1093 | stderr: "toBeEmpty"
1094 |
1095 | # ==================================================================================
1096 | # SEARCH QUALITY AND RELEVANCE TESTS
1097 | # ==================================================================================
1098 |
1099 | - it: "should prioritize exact matches for common terms"
1100 | request:
1101 | jsonrpc: "2.0"
1102 | id: "quality-exact-match"
1103 | method: "tools/call"
1104 | params:
1105 | name: "search_sfcc_classes"
1106 | arguments:
1107 | query: "Product"
1108 | expect:
1109 | response:
1110 | jsonrpc: "2.0"
1111 | id: "quality-exact-match"
1112 | result:
1113 | content:
1114 | - type: "text"
1115 | text: "match:contains:dw.catalog.Product"
1116 | isError: false
1117 | stderr: "toBeEmpty"
1118 |
1119 | - it: "should find classes by functionality"
1120 | request:
1121 | jsonrpc: "2.0"
1122 | id: "quality-functionality"
1123 | method: "tools/call"
1124 | params:
1125 | name: "search_sfcc_classes"
1126 | arguments:
1127 | query: "inventory"
1128 | expect:
1129 | response:
1130 | jsonrpc: "2.0"
1131 | id: "quality-functionality"
1132 | result:
1133 | content:
1134 | - type: "text"
1135 | text: "match:contains:ProductInventoryList"
1136 | isError: false
1137 | stderr: "toBeEmpty"
1138 |
1139 | - it: "should include relevant namespace classes"
1140 | request:
1141 | jsonrpc: "2.0"
1142 | id: "quality-namespace"
1143 | method: "tools/call"
1144 | params:
1145 | name: "search_sfcc_classes"
1146 | arguments:
1147 | query: "system"
1148 | expect:
1149 | response:
1150 | jsonrpc: "2.0"
1151 | id: "quality-namespace"
1152 | result:
1153 | content:
1154 | - type: "text"
1155 | text: "match:regex:dw\\.system\\."
1156 | isError: false
1157 | stderr: "toBeEmpty"
1158 |
```