@salesforce/afv-skills 1.8.0 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/skills/activating-datacloud/CREDITS.md +5 -0
- package/skills/activating-datacloud/README.md +39 -0
- package/skills/activating-datacloud/SKILL.md +118 -0
- package/skills/analyzing-omnistudio-dependencies/CREDITS.md +5 -0
- package/skills/analyzing-omnistudio-dependencies/SKILL.md +477 -0
- package/skills/analyzing-omnistudio-dependencies/references/dependency-patterns.md +508 -0
- package/skills/analyzing-omnistudio-dependencies/references/namespace-guide.md +300 -0
- package/skills/building-omnistudio-callable-apex/CREDITS.md +9 -0
- package/skills/building-omnistudio-callable-apex/README.md +80 -0
- package/skills/building-omnistudio-callable-apex/SKILL.md +276 -0
- package/skills/building-omnistudio-callable-apex/assets/pattern_callable_openinterface.cls +40 -0
- package/skills/building-omnistudio-callable-apex/assets/pattern_callable_vanilla.cls +32 -0
- package/skills/building-omnistudio-callable-apex/assets/pattern_migration.cls +54 -0
- package/skills/building-omnistudio-callable-apex/assets/pattern_openinterface.cls +45 -0
- package/skills/building-omnistudio-callable-apex/assets/pattern_test_class.cls +65 -0
- package/skills/building-omnistudio-callable-apex/examples/Test_QuoteByProductCallable/IndustriesCallableException.cls +7 -0
- package/skills/building-omnistudio-callable-apex/examples/Test_QuoteByProductCallable/Industries_QuoteByProductCallable.cls +115 -0
- package/skills/building-omnistudio-callable-apex/examples/Test_QuoteByProductCallable/Industries_QuoteByProductCallableTest.cls +189 -0
- package/skills/building-omnistudio-callable-apex/examples/Test_QuoteByProductCallable/TRANSCRIPT.md +115 -0
- package/skills/building-omnistudio-callable-apex/examples/Test_VlocityOpenInterface2Conversion/IndustriesCallableException.cls +7 -0
- package/skills/building-omnistudio-callable-apex/examples/Test_VlocityOpenInterface2Conversion/MyCustomCallable.cls +74 -0
- package/skills/building-omnistudio-callable-apex/examples/Test_VlocityOpenInterface2Conversion/MyCustomCallableTest.cls +146 -0
- package/skills/building-omnistudio-callable-apex/examples/Test_VlocityOpenInterface2Conversion/MyCustomRemoteClass.cls +16 -0
- package/skills/building-omnistudio-callable-apex/examples/Test_VlocityOpenInterface2Conversion/TRANSCRIPT.md +120 -0
- package/skills/building-omnistudio-callable-apex/examples/Test_VlocityOpenInterfaceConversion/IndustriesCallableException.cls +7 -0
- package/skills/building-omnistudio-callable-apex/examples/Test_VlocityOpenInterfaceConversion/MyCustomCallable.cls +73 -0
- package/skills/building-omnistudio-callable-apex/examples/Test_VlocityOpenInterfaceConversion/MyCustomCallableTest.cls +128 -0
- package/skills/building-omnistudio-callable-apex/examples/Test_VlocityOpenInterfaceConversion/MyCustomVlocityOpenInterface2.cls +23 -0
- package/skills/building-omnistudio-callable-apex/examples/Test_VlocityOpenInterfaceConversion/TRANSCRIPT.md +75 -0
- package/skills/building-omnistudio-datamapper/CREDITS.md +5 -0
- package/skills/building-omnistudio-datamapper/SKILL.md +270 -0
- package/skills/building-omnistudio-datamapper/assets/completion-summary-template.md +28 -0
- package/skills/building-omnistudio-datamapper/assets/omni-data-transform-extract.json +6 -0
- package/skills/building-omnistudio-datamapper/assets/omni-data-transform-item.json +12 -0
- package/skills/building-omnistudio-datamapper/assets/omni-data-transform-load.json +6 -0
- package/skills/building-omnistudio-datamapper/assets/omni-data-transform-transform.json +6 -0
- package/skills/building-omnistudio-datamapper/references/best-practices.md +277 -0
- package/skills/building-omnistudio-datamapper/references/naming-conventions.md +145 -0
- package/skills/building-omnistudio-flexcard/CREDITS.md +5 -0
- package/skills/building-omnistudio-flexcard/SKILL.md +325 -0
- package/skills/building-omnistudio-flexcard/assets/omni-ui-card.json +10 -0
- package/skills/building-omnistudio-flexcard/references/best-practices.md +291 -0
- package/skills/building-omnistudio-flexcard/references/data-binding-guide.md +311 -0
- package/skills/building-omnistudio-flexcard/references/scoring-rubric.md +66 -0
- package/skills/building-omnistudio-flexcard/scripts/flexcard-commands.sh +24 -0
- package/skills/building-omnistudio-integration-procedure/CREDITS.md +5 -0
- package/skills/building-omnistudio-integration-procedure/SKILL.md +275 -0
- package/skills/building-omnistudio-integration-procedure/assets/omni-process-element-dr-extract.json +10 -0
- package/skills/building-omnistudio-integration-procedure/assets/omni-process-element-set-values.json +10 -0
- package/skills/building-omnistudio-integration-procedure/assets/omni-process-ip.json +12 -0
- package/skills/building-omnistudio-integration-procedure/assets/scoring-report-format.txt +14 -0
- package/skills/building-omnistudio-integration-procedure/references/best-practices.md +388 -0
- package/skills/building-omnistudio-integration-procedure/references/element-types.md +588 -0
- package/skills/building-omnistudio-integration-procedure/scripts/cli-commands.sh +18 -0
- package/skills/building-omnistudio-omniscript/CREDITS.md +5 -0
- package/skills/building-omnistudio-omniscript/SKILL.md +367 -0
- package/skills/building-omnistudio-omniscript/assets/omni-process-element-step.json +10 -0
- package/skills/building-omnistudio-omniscript/assets/omni-process-element-text-block.json +11 -0
- package/skills/building-omnistudio-omniscript/assets/omni-process-omniscript.json +12 -0
- package/skills/building-omnistudio-omniscript/references/best-practices.md +480 -0
- package/skills/building-omnistudio-omniscript/references/element-types.md +1172 -0
- package/skills/building-omnistudio-omniscript/scripts/check-duplicate-omniscript.sh +13 -0
- package/skills/building-omnistudio-omniscript/scripts/cli-reference.sh +21 -0
- package/skills/building-omnistudio-omniscript/scripts/deploy-omniscript.sh +29 -0
- package/skills/building-sf-integrations/CREDITS.md +5 -0
- package/skills/building-sf-integrations/README.md +95 -0
- package/skills/building-sf-integrations/SKILL.md +192 -0
- package/skills/building-sf-integrations/assets/callouts/callout-retry-handler.cls +167 -0
- package/skills/building-sf-integrations/assets/callouts/http-response-handler.cls +257 -0
- package/skills/building-sf-integrations/assets/callouts/rest-queueable-callout.cls +262 -0
- package/skills/building-sf-integrations/assets/callouts/rest-sync-callout.cls +211 -0
- package/skills/building-sf-integrations/assets/cdc/cdc-handler.cls +246 -0
- package/skills/building-sf-integrations/assets/cdc/cdc-subscriber-trigger.trigger +139 -0
- package/skills/building-sf-integrations/assets/endpoint-security/example.cspTrustedSite-meta.xml +58 -0
- package/skills/building-sf-integrations/assets/endpoint-security/example.remoteSite-meta.xml +39 -0
- package/skills/building-sf-integrations/assets/external-credentials/jwt-external-credential.externalCredential-meta.xml +90 -0
- package/skills/building-sf-integrations/assets/external-credentials/oauth-external-credential.externalCredential-meta.xml +87 -0
- package/skills/building-sf-integrations/assets/external-services/external-service-operations.md +221 -0
- package/skills/building-sf-integrations/assets/external-services/openapi-registration.externalServiceRegistration-meta.xml +193 -0
- package/skills/building-sf-integrations/assets/named-credentials/certificate-auth.namedCredential-meta.xml +62 -0
- package/skills/building-sf-integrations/assets/named-credentials/custom-auth.namedCredential-meta.xml +71 -0
- package/skills/building-sf-integrations/assets/named-credentials/oauth-client-credentials.namedCredential-meta.xml +51 -0
- package/skills/building-sf-integrations/assets/named-credentials/oauth-jwt-bearer.namedCredential-meta.xml +67 -0
- package/skills/building-sf-integrations/assets/platform-events/event-publisher.cls +191 -0
- package/skills/building-sf-integrations/assets/platform-events/event-subscriber-action.cls +295 -0
- package/skills/building-sf-integrations/assets/platform-events/event-subscriber-trigger.trigger +108 -0
- package/skills/building-sf-integrations/assets/platform-events/platform-event-definition.object-meta.xml +124 -0
- package/skills/building-sf-integrations/assets/soap/soap-callout-service.cls +186 -0
- package/skills/building-sf-integrations/assets/soap/wsdl2apex-guide.md +213 -0
- package/skills/building-sf-integrations/hooks/scripts/suggest_credential_setup.py +271 -0
- package/skills/building-sf-integrations/hooks/scripts/validate_integration.py +363 -0
- package/skills/building-sf-integrations/references/callout-patterns.md +719 -0
- package/skills/building-sf-integrations/references/cdc-guide.md +288 -0
- package/skills/building-sf-integrations/references/cli-reference.md +94 -0
- package/skills/building-sf-integrations/references/event-driven-architecture-guide.md +266 -0
- package/skills/building-sf-integrations/references/event-patterns.md +838 -0
- package/skills/building-sf-integrations/references/external-services-guide.md +303 -0
- package/skills/building-sf-integrations/references/messaging-api-v2.md +609 -0
- package/skills/building-sf-integrations/references/named-credentials-automation.md +201 -0
- package/skills/building-sf-integrations/references/named-credentials-guide.md +173 -0
- package/skills/building-sf-integrations/references/platform-events-guide.md +288 -0
- package/skills/building-sf-integrations/references/rest-callout-patterns.md +288 -0
- package/skills/building-sf-integrations/references/scoring-rubric.md +59 -0
- package/skills/building-sf-integrations/references/security-best-practices.md +248 -0
- package/skills/building-sf-integrations/scripts/README.md +100 -0
- package/skills/building-sf-integrations/scripts/configure-named-credential.sh +236 -0
- package/skills/building-sf-integrations/scripts/set-api-credential.sh +146 -0
- package/skills/building-sf-integrations/scripts/templates/setup-credentials-with-csp.sh +158 -0
- package/skills/configuring-connected-apps/CREDITS.md +3 -0
- package/skills/configuring-connected-apps/README.md +99 -0
- package/skills/configuring-connected-apps/SKILL.md +224 -0
- package/skills/configuring-connected-apps/assets/connected-app-basic.xml +29 -0
- package/skills/configuring-connected-apps/assets/connected-app-canvas.xml +62 -0
- package/skills/configuring-connected-apps/assets/connected-app-jwt.xml +49 -0
- package/skills/configuring-connected-apps/assets/connected-app-oauth.xml +65 -0
- package/skills/configuring-connected-apps/assets/eca-global-oauth.xml +36 -0
- package/skills/configuring-connected-apps/assets/eca-oauth-settings.xml +36 -0
- package/skills/configuring-connected-apps/assets/eca-policies.xml +36 -0
- package/skills/configuring-connected-apps/assets/external-client-app.xml +35 -0
- package/skills/configuring-connected-apps/references/example-usage.md +256 -0
- package/skills/configuring-connected-apps/references/migration-guide.md +328 -0
- package/skills/configuring-connected-apps/references/oauth-flows-reference.md +660 -0
- package/skills/configuring-connected-apps/references/security-checklist.md +209 -0
- package/skills/configuring-connected-apps/references/testing-validation-guide.md +275 -0
- package/skills/connecting-datacloud/CREDITS.md +5 -0
- package/skills/connecting-datacloud/README.md +59 -0
- package/skills/connecting-datacloud/SKILL.md +155 -0
- package/skills/connecting-datacloud/examples/connections/heroku-postgres.json +15 -0
- package/skills/connecting-datacloud/examples/connections/ingest-api-connection.json +5 -0
- package/skills/connecting-datacloud/examples/connections/ingest-api-schema.json +31 -0
- package/skills/connecting-datacloud/examples/connections/redshift.json +16 -0
- package/skills/connecting-datacloud/examples/connections/sharepoint-unstructured.json +20 -0
- package/skills/connecting-datacloud/examples/connections/snowflake-connection.json +42 -0
- package/skills/debugging-apex-logs/CREDITS.md +22 -0
- package/skills/debugging-apex-logs/README.md +74 -0
- package/skills/debugging-apex-logs/SKILL.md +172 -0
- package/skills/debugging-apex-logs/assets/benchmarking-template.cls +327 -0
- package/skills/debugging-apex-logs/assets/cpu-heap-optimization.cls +307 -0
- package/skills/debugging-apex-logs/assets/dml-in-loop-fix.cls +219 -0
- package/skills/debugging-apex-logs/assets/null-pointer-fix.cls +252 -0
- package/skills/debugging-apex-logs/assets/soql-in-loop-fix.cls +157 -0
- package/skills/debugging-apex-logs/references/analysis-playbook.md +53 -0
- package/skills/debugging-apex-logs/references/benchmarking-guide.md +287 -0
- package/skills/debugging-apex-logs/references/cli-commands.md +368 -0
- package/skills/debugging-apex-logs/references/common-issues.md +68 -0
- package/skills/debugging-apex-logs/references/debug-log-reference.md +328 -0
- package/skills/debugging-apex-logs/references/log-analysis-tools.md +248 -0
- package/skills/debugging-apex-logs/references/scoring-rubric.md +21 -0
- package/skills/deploying-metadata/CREDITS.md +25 -0
- package/skills/deploying-metadata/README.md +104 -0
- package/skills/deploying-metadata/SKILL.md +214 -0
- package/skills/deploying-metadata/assets/destructiveChanges.xml +143 -0
- package/skills/deploying-metadata/assets/package.xml +121 -0
- package/skills/deploying-metadata/references/agent-deployment-guide.md +628 -0
- package/skills/deploying-metadata/references/deploy.sh +73 -0
- package/skills/deploying-metadata/references/deployment-report-template.md +89 -0
- package/skills/deploying-metadata/references/deployment-workflows.md +395 -0
- package/skills/deploying-metadata/references/orchestration.md +183 -0
- package/skills/deploying-metadata/references/trigger-deployment-safety.md +376 -0
- package/skills/deploying-omnistudio-datapacks/CREDITS.md +5 -0
- package/skills/deploying-omnistudio-datapacks/README.md +88 -0
- package/skills/deploying-omnistudio-datapacks/SKILL.md +174 -0
- package/skills/deploying-omnistudio-datapacks/examples/business-internet-plus-bundle/TRANSCRIPT.md +124 -0
- package/skills/deploying-omnistudio-datapacks/examples/business-internet-plus-bundle/deploy-business-internet-plus-bundle.yaml +11 -0
- package/skills/deploying-omnistudio-datapacks/examples/business-internet-plus-bundle-deploy/TRANSCRIPT.md +142 -0
- package/skills/deploying-omnistudio-datapacks/examples/business-internet-plus-bundle-deploy/deploy-business-internet-plus-bundle.yaml +10 -0
- package/skills/deploying-omnistudio-datapacks/references/job-file-template.md +42 -0
- package/skills/deploying-omnistudio-datapacks/references/troubleshooting-matrix.md +24 -0
- package/skills/developing-agentforce/assets/metadata/http-callout-flow.flow-meta.xml +1 -1
- package/skills/developing-agentforce/references/actions-reference.md +8 -8
- package/skills/fetching-salesforce-docs/README.md +66 -0
- package/skills/fetching-salesforce-docs/SKILL.md +209 -0
- package/skills/fetching-salesforce-docs/requirements.txt +2 -0
- package/skills/fetching-salesforce-docs/scripts/extract_help_salesforce.py +497 -0
- package/skills/fetching-salesforce-docs/scripts/extract_salesforce_doc.py +357 -0
- package/skills/fetching-salesforce-docs/scripts/runtime_bootstrap.py +58 -0
- package/skills/generating-apex/CREDITS.md +1 -26
- package/skills/generating-apex-test/CREDITS.md +2 -27
- package/skills/generating-lwc-components/CREDITS.md +5 -0
- package/skills/generating-lwc-components/README.md +126 -0
- package/skills/generating-lwc-components/SKILL.md +191 -0
- package/skills/generating-lwc-components/assets/apex-controller/LwcController.cls +327 -0
- package/skills/generating-lwc-components/assets/basic-component/basicComponent.css +72 -0
- package/skills/generating-lwc-components/assets/basic-component/basicComponent.html +111 -0
- package/skills/generating-lwc-components/assets/basic-component/basicComponent.js +163 -0
- package/skills/generating-lwc-components/assets/basic-component/basicComponent.js-meta.xml +137 -0
- package/skills/generating-lwc-components/assets/datatable-component/datatableComponent.html +111 -0
- package/skills/generating-lwc-components/assets/datatable-component/datatableComponent.js +367 -0
- package/skills/generating-lwc-components/assets/flow-screen-component/flowScreenComponent.css +63 -0
- package/skills/generating-lwc-components/assets/flow-screen-component/flowScreenComponent.html +154 -0
- package/skills/generating-lwc-components/assets/flow-screen-component/flowScreenComponent.js +348 -0
- package/skills/generating-lwc-components/assets/flow-screen-component/flowScreenComponent.js-meta.xml +87 -0
- package/skills/generating-lwc-components/assets/form-component/formComponent.html +165 -0
- package/skills/generating-lwc-components/assets/form-component/formComponent.js +275 -0
- package/skills/generating-lwc-components/assets/graphql-component/graphqlComponent.html +100 -0
- package/skills/generating-lwc-components/assets/graphql-component/graphqlComponent.js +336 -0
- package/skills/generating-lwc-components/assets/jest-test/componentName.test.js.example +371 -0
- package/skills/generating-lwc-components/assets/message-channel/RecordSelected.messageChannel-meta.xml +71 -0
- package/skills/generating-lwc-components/assets/message-channel/lmsPublisher.js +103 -0
- package/skills/generating-lwc-components/assets/message-channel/lmsSubscriber.js +181 -0
- package/skills/generating-lwc-components/assets/modal-component/modalComponent.html +85 -0
- package/skills/generating-lwc-components/assets/modal-component/modalComponent.js +199 -0
- package/skills/generating-lwc-components/assets/record-picker/recordPicker.html +55 -0
- package/skills/generating-lwc-components/assets/record-picker/recordPicker.js +199 -0
- package/skills/generating-lwc-components/assets/state-store/store.js +282 -0
- package/skills/generating-lwc-components/assets/typescript-component/typescriptComponent.css +65 -0
- package/skills/generating-lwc-components/assets/typescript-component/typescriptComponent.html +95 -0
- package/skills/generating-lwc-components/assets/typescript-component/typescriptComponent.js-meta.xml +75 -0
- package/skills/generating-lwc-components/assets/typescript-component/typescriptComponent.test.ts.example +301 -0
- package/skills/generating-lwc-components/assets/typescript-component/typescriptComponent.ts +295 -0
- package/skills/generating-lwc-components/assets/workspace-api/workspaceComponent.html +71 -0
- package/skills/generating-lwc-components/assets/workspace-api/workspaceComponent.js +316 -0
- package/skills/generating-lwc-components/hooks/scripts/lwc-lsp-validate.py +295 -0
- package/skills/generating-lwc-components/hooks/scripts/post-tool-validate.py +347 -0
- package/skills/generating-lwc-components/hooks/scripts/slds_data/deprecated_patterns.json +74 -0
- package/skills/generating-lwc-components/hooks/scripts/slds_data/styling_hooks.json +111 -0
- package/skills/generating-lwc-components/hooks/scripts/slds_data/valid_slds_classes.json +127 -0
- package/skills/generating-lwc-components/hooks/scripts/slds_linter_wrapper.py +294 -0
- package/skills/generating-lwc-components/hooks/scripts/slds_rules/__init__.py +22 -0
- package/skills/generating-lwc-components/hooks/scripts/template_validator.py +332 -0
- package/skills/generating-lwc-components/hooks/scripts/validate_slds.py +595 -0
- package/skills/generating-lwc-components/references/accessibility-guide.md +843 -0
- package/skills/generating-lwc-components/references/advanced-features.md +108 -0
- package/skills/generating-lwc-components/references/async-notification-patterns.md +661 -0
- package/skills/generating-lwc-components/references/cli-commands.md +545 -0
- package/skills/generating-lwc-components/references/component-patterns.md +1476 -0
- package/skills/generating-lwc-components/references/flow-integration-guide.md +675 -0
- package/skills/generating-lwc-components/references/jest-testing.md +1011 -0
- package/skills/generating-lwc-components/references/lms-guide.md +860 -0
- package/skills/generating-lwc-components/references/lwc-best-practices.md +1310 -0
- package/skills/generating-lwc-components/references/performance-guide.md +861 -0
- package/skills/generating-lwc-components/references/scoring-and-testing.md +116 -0
- package/skills/generating-lwc-components/references/slds-blueprints.json +14389 -0
- package/skills/generating-lwc-components/references/slds-design-guide.md +166 -0
- package/skills/generating-lwc-components/references/state-management.md +642 -0
- package/skills/generating-lwc-components/references/template-anti-patterns.md +948 -0
- package/skills/generating-lwc-components/references/triangle-pattern.md +365 -0
- package/skills/generating-lwc-components/scripts/local-dev-preview.sh +34 -0
- package/skills/generating-mermaid-diagrams/CREDITS.md +46 -0
- package/skills/generating-mermaid-diagrams/README.md +114 -0
- package/skills/generating-mermaid-diagrams/SKILL.md +218 -0
- package/skills/generating-mermaid-diagrams/assets/agentforce/agent-flow.md +313 -0
- package/skills/generating-mermaid-diagrams/assets/architecture/system-landscape.md +351 -0
- package/skills/generating-mermaid-diagrams/assets/datamodel/b2b-commerce-erd.md +317 -0
- package/skills/generating-mermaid-diagrams/assets/datamodel/campaigns-erd.md +195 -0
- package/skills/generating-mermaid-diagrams/assets/datamodel/consent-erd.md +262 -0
- package/skills/generating-mermaid-diagrams/assets/datamodel/files-erd.md +266 -0
- package/skills/generating-mermaid-diagrams/assets/datamodel/forecasting-erd.md +261 -0
- package/skills/generating-mermaid-diagrams/assets/datamodel/fsl-erd.md +332 -0
- package/skills/generating-mermaid-diagrams/assets/datamodel/party-model-erd.md +237 -0
- package/skills/generating-mermaid-diagrams/assets/datamodel/quote-order-erd.md +277 -0
- package/skills/generating-mermaid-diagrams/assets/datamodel/revenue-cloud-erd.md +343 -0
- package/skills/generating-mermaid-diagrams/assets/datamodel/sales-cloud-erd.md +192 -0
- package/skills/generating-mermaid-diagrams/assets/datamodel/salesforce-erd.md +209 -0
- package/skills/generating-mermaid-diagrams/assets/datamodel/scheduler-erd.md +276 -0
- package/skills/generating-mermaid-diagrams/assets/datamodel/service-cloud-erd.md +217 -0
- package/skills/generating-mermaid-diagrams/assets/datamodel/territory-management-erd.md +241 -0
- package/skills/generating-mermaid-diagrams/assets/integration/api-sequence.md +387 -0
- package/skills/generating-mermaid-diagrams/assets/oauth/authorization-code-pkce.md +197 -0
- package/skills/generating-mermaid-diagrams/assets/oauth/authorization-code.md +152 -0
- package/skills/generating-mermaid-diagrams/assets/oauth/client-credentials.md +233 -0
- package/skills/generating-mermaid-diagrams/assets/oauth/device-authorization.md +295 -0
- package/skills/generating-mermaid-diagrams/assets/oauth/jwt-bearer.md +256 -0
- package/skills/generating-mermaid-diagrams/assets/oauth/refresh-token.md +281 -0
- package/skills/generating-mermaid-diagrams/assets/oauth/user-agent-social-sign-on.md +281 -0
- package/skills/generating-mermaid-diagrams/assets/role-hierarchy/user-hierarchy.md +322 -0
- package/skills/generating-mermaid-diagrams/references/color-palette.md +464 -0
- package/skills/generating-mermaid-diagrams/references/diagram-conventions.md +313 -0
- package/skills/generating-mermaid-diagrams/references/erd-conventions.md +320 -0
- package/skills/generating-mermaid-diagrams/references/mermaid-reference.md +434 -0
- package/skills/generating-mermaid-diagrams/references/mermaid-styling.md +81 -0
- package/skills/generating-mermaid-diagrams/references/preview-guide.md +49 -0
- package/skills/generating-mermaid-diagrams/references/usage-examples.md +340 -0
- package/skills/generating-mermaid-diagrams/scripts/README.md +160 -0
- package/skills/generating-mermaid-diagrams/scripts/mermaid_preview.py +654 -0
- package/skills/generating-mermaid-diagrams/scripts/query-org-metadata.py +293 -0
- package/skills/generating-visual-diagrams/CREDITS.md +80 -0
- package/skills/generating-visual-diagrams/README.md +83 -0
- package/skills/generating-visual-diagrams/SKILL.md +208 -0
- package/skills/generating-visual-diagrams/assets/architecture/integration-flow.md +55 -0
- package/skills/generating-visual-diagrams/assets/erd/core-objects.md +131 -0
- package/skills/generating-visual-diagrams/assets/erd/custom-objects.md +60 -0
- package/skills/generating-visual-diagrams/assets/lwc/dashboard-card.md +45 -0
- package/skills/generating-visual-diagrams/assets/lwc/data-table.md +57 -0
- package/skills/generating-visual-diagrams/assets/lwc/record-form.md +60 -0
- package/skills/generating-visual-diagrams/assets/review/apex-review.md +57 -0
- package/skills/generating-visual-diagrams/assets/review/lwc-review.md +48 -0
- package/skills/generating-visual-diagrams/references/architect-aesthetic-guide.md +257 -0
- package/skills/generating-visual-diagrams/references/examples-index.md +35 -0
- package/skills/generating-visual-diagrams/references/gemini-cli-setup.md +65 -0
- package/skills/generating-visual-diagrams/references/interview-questions.md +529 -0
- package/skills/generating-visual-diagrams/references/iteration-workflow.md +173 -0
- package/skills/generating-visual-diagrams/scripts/check-prerequisites.sh +101 -0
- package/skills/generating-visual-diagrams/scripts/generate_image.py +243 -0
- package/skills/handling-sf-data/CREDITS.md +5 -0
- package/skills/handling-sf-data/README.md +112 -0
- package/skills/handling-sf-data/SKILL.md +235 -0
- package/skills/handling-sf-data/assets/bulk/bulk-insert-10000.apex +293 -0
- package/skills/handling-sf-data/assets/bulk/bulk-insert-200.apex +208 -0
- package/skills/handling-sf-data/assets/bulk/bulk-insert-500.apex +219 -0
- package/skills/handling-sf-data/assets/bulk/bulk-upsert-external-id.apex +324 -0
- package/skills/handling-sf-data/assets/cleanup/delete-by-created-date.apex +319 -0
- package/skills/handling-sf-data/assets/cleanup/delete-by-name.apex +240 -0
- package/skills/handling-sf-data/assets/cleanup/delete-test-data.apex +311 -0
- package/skills/handling-sf-data/assets/cleanup/rollback-transaction.apex +266 -0
- package/skills/handling-sf-data/assets/csv/account-import.csv +11 -0
- package/skills/handling-sf-data/assets/csv/contact-import.csv +11 -0
- package/skills/handling-sf-data/assets/csv/custom-object-import.csv +11 -0
- package/skills/handling-sf-data/assets/csv/opportunity-import.csv +11 -0
- package/skills/handling-sf-data/assets/factories/account-factory.apex +165 -0
- package/skills/handling-sf-data/assets/factories/case-factory.apex +237 -0
- package/skills/handling-sf-data/assets/factories/contact-factory.apex +168 -0
- package/skills/handling-sf-data/assets/factories/custom-object-factory.apex +260 -0
- package/skills/handling-sf-data/assets/factories/event-factory.apex +275 -0
- package/skills/handling-sf-data/assets/factories/hierarchy-factory.apex +372 -0
- package/skills/handling-sf-data/assets/factories/lead-factory.apex +190 -0
- package/skills/handling-sf-data/assets/factories/opportunity-factory.apex +206 -0
- package/skills/handling-sf-data/assets/factories/task-factory.apex +246 -0
- package/skills/handling-sf-data/assets/factories/user-factory.apex +278 -0
- package/skills/handling-sf-data/assets/json/account-contact-tree.json +130 -0
- package/skills/handling-sf-data/assets/json/account-opportunity-tree.json +110 -0
- package/skills/handling-sf-data/assets/json/full-hierarchy-tree.json +188 -0
- package/skills/handling-sf-data/assets/soql/aggregate.soql +226 -0
- package/skills/handling-sf-data/assets/soql/child-to-parent.soql +162 -0
- package/skills/handling-sf-data/assets/soql/parent-to-child.soql +153 -0
- package/skills/handling-sf-data/assets/soql/polymorphic.soql +198 -0
- package/skills/handling-sf-data/assets/soql/subquery.soql +287 -0
- package/skills/handling-sf-data/references/anonymous-apex-guide.md +98 -0
- package/skills/handling-sf-data/references/bulk-operations-guide.md +94 -0
- package/skills/handling-sf-data/references/bulk-testing-example.md +194 -0
- package/skills/handling-sf-data/references/cleanup-rollback-example.md +322 -0
- package/skills/handling-sf-data/references/cleanup-rollback-guide.md +84 -0
- package/skills/handling-sf-data/references/crud-workflow-example.md +183 -0
- package/skills/handling-sf-data/references/governor-limits-reference.md +74 -0
- package/skills/handling-sf-data/references/orchestration.md +174 -0
- package/skills/handling-sf-data/references/relationship-query-examples.md +249 -0
- package/skills/handling-sf-data/references/sf-cli-data-commands.md +158 -0
- package/skills/handling-sf-data/references/soql-relationship-guide.md +84 -0
- package/skills/handling-sf-data/references/test-data-best-practices.md +104 -0
- package/skills/handling-sf-data/references/test-data-factory-usage.md +290 -0
- package/skills/handling-sf-data/references/test-data-patterns.md +98 -0
- package/skills/handling-sf-data/scripts/soql_validator.py +292 -0
- package/skills/handling-sf-data/scripts/validate_data_operation.py +379 -0
- package/skills/harmonizing-datacloud/CREDITS.md +3 -0
- package/skills/harmonizing-datacloud/README.md +31 -0
- package/skills/harmonizing-datacloud/SKILL.md +117 -0
- package/skills/modeling-omnistudio-epc-catalog/CREDITS.md +14 -0
- package/skills/modeling-omnistudio-epc-catalog/README.md +89 -0
- package/skills/modeling-omnistudio-epc-catalog/SKILL.md +395 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/attribute-assignment-template.json +402 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/compiled-attribute-overrides-template.json +43 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/completion-block-template.txt +8 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/decomposition-relationships-template.json +233 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-premium-fttc-simple-offer/Business-Internet-Premium-FTTC_AttributeAssignments.json +514 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-premium-fttc-simple-offer/Business-Internet-Premium-FTTC_CompiledAttributeOverrides.json +21 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-premium-fttc-simple-offer/Business-Internet-Premium-FTTC_DataPack.json +649 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-premium-fttc-simple-offer/Business-Internet-Premium-FTTC_DecompositionRelationships.json +200 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-premium-fttc-simple-offer/Business-Internet-Premium-FTTC_ObjectFieldAttributes.json +138 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-premium-fttc-simple-offer/Business-Internet-Premium-FTTC_OrchestrationScenarios.json +54 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-premium-fttc-simple-offer/Business-Internet-Premium-FTTC_OverrideDefinitions.json +266 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-premium-fttc-simple-offer/Business-Internet-Premium-FTTC_ParentKeys.json +23 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-premium-fttc-simple-offer/Business-Internet-Premium-FTTC_PriceListEntries.json +54 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-premium-fttc-simple-offer/Business-Internet-Premium-FTTC_PricebookEntries.json +35 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-premium-fttc-simple-offer/Business-Internet-Premium-FTTC_ProductChildItems.json +34 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-premium-fttc-simple-offer/Business-Internet-Premium-FTTC_RuleAssignments.json +21 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-pro-vpl-simple-offer/Business-Internet-Pro-VPL_AttributeAssignments.json +410 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-pro-vpl-simple-offer/Business-Internet-Pro-VPL_DataPack.json +535 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-pro-vpl-simple-offer/Business-Internet-Pro-VPL_DecompositionRelationships.json +35 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-pro-vpl-simple-offer/Business-Internet-Pro-VPL_ObjectFieldAttributes.json +138 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-pro-vpl-simple-offer/Business-Internet-Pro-VPL_OrchestrationScenarios.json +28 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-pro-vpl-simple-offer/Business-Internet-Pro-VPL_ParentKeys.json +23 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-pro-vpl-simple-offer/Business-Internet-Pro-VPL_PriceListEntries.json +220 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-pro-vpl-simple-offer/Business-Internet-Pro-VPL_PricebookEntries.json +35 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-pro-vpl-simple-offer/Business-Internet-Pro-VPL_ProductChildItems.json +414 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/samsung-galaxy-s22-bundle/Samsung-Galaxy-S22-Bundle_AttributeAssignments.json +382 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/samsung-galaxy-s22-bundle/Samsung-Galaxy-S22-Bundle_DataPack.json +565 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/samsung-galaxy-s22-bundle/Samsung-Galaxy-S22-Bundle_DecompositionRelationships.json +35 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/samsung-galaxy-s22-bundle/Samsung-Galaxy-S22-Bundle_ObjectFieldAttributes.json +104 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/samsung-galaxy-s22-bundle/Samsung-Galaxy-S22-Bundle_OrchestrationScenarios.json +28 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/samsung-galaxy-s22-bundle/Samsung-Galaxy-S22-Bundle_ParentKeys.json +13 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/samsung-galaxy-s22-bundle/Samsung-Galaxy-S22-Bundle_PriceListEntries.json +106 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/samsung-galaxy-s22-bundle/Samsung-Galaxy-S22-Bundle_PricebookEntries.json +35 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/samsung-galaxy-s22-bundle/Samsung-Galaxy-S22-Bundle_ProductChildItems.json +72 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/static-ip-simple-offer/Static-IP_AttributeAssignments.json +142 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/static-ip-simple-offer/Static-IP_DataPack.json +377 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/static-ip-simple-offer/Static-IP_DecompositionRelationships.json +35 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/static-ip-simple-offer/Static-IP_ObjectFieldAttributes.json +36 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/static-ip-simple-offer/Static-IP_ParentKeys.json +8 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/static-ip-simple-offer/Static-IP_PriceListEntries.json +54 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/static-ip-simple-offer/Static-IP_PricebookEntries.json +35 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/static-ip-simple-offer/Static-IP_ProductChildItems.json +34 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/object-field-attributes-template.json +138 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/orchestration-scenarios-template.json +54 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/override-definitions-template.json +134 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/parent-keys-template.json +29 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/price-list-entries-template.json +158 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/pricebook-entries-template.json +35 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/product-child-item-template.json +338 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/product2-offer-template.json +527 -0
- package/skills/modeling-omnistudio-epc-catalog/examples/.gitkeep +1 -0
- package/skills/modeling-omnistudio-epc-catalog/examples/business-internet-plus-bundle/Business-Internet-Plus_AttributeAssignments.json +95 -0
- package/skills/modeling-omnistudio-epc-catalog/examples/business-internet-plus-bundle/Business-Internet-Plus_CompiledAttributeOverrides.json +1 -0
- package/skills/modeling-omnistudio-epc-catalog/examples/business-internet-plus-bundle/Business-Internet-Plus_DataPack.json +214 -0
- package/skills/modeling-omnistudio-epc-catalog/examples/business-internet-plus-bundle/Business-Internet-Plus_DecompositionRelationships.json +28 -0
- package/skills/modeling-omnistudio-epc-catalog/examples/business-internet-plus-bundle/Business-Internet-Plus_ObjectFieldAttributes.json +98 -0
- package/skills/modeling-omnistudio-epc-catalog/examples/business-internet-plus-bundle/Business-Internet-Plus_OrchestrationScenarios.json +22 -0
- package/skills/modeling-omnistudio-epc-catalog/examples/business-internet-plus-bundle/Business-Internet-Plus_OverrideDefinitions.json +1 -0
- package/skills/modeling-omnistudio-epc-catalog/examples/business-internet-plus-bundle/Business-Internet-Plus_ParentKeys.json +13 -0
- package/skills/modeling-omnistudio-epc-catalog/examples/business-internet-plus-bundle/Business-Internet-Plus_PriceListEntries.json +35 -0
- package/skills/modeling-omnistudio-epc-catalog/examples/business-internet-plus-bundle/Business-Internet-Plus_PricebookEntries.json +28 -0
- package/skills/modeling-omnistudio-epc-catalog/examples/business-internet-plus-bundle/Business-Internet-Plus_ProductChildItems.json +110 -0
- package/skills/modeling-omnistudio-epc-catalog/examples/business-internet-plus-bundle/TRANSCRIPT.md +58 -0
- package/skills/modeling-omnistudio-epc-catalog/references/epc-field-guide.md +90 -0
- package/skills/modeling-omnistudio-epc-catalog/references/naming-conventions.md +80 -0
- package/skills/modeling-omnistudio-epc-catalog/references/scoring-model.md +57 -0
- package/skills/modeling-omnistudio-epc-catalog/scripts/cli-validation-commands.sh +19 -0
- package/skills/modeling-omnistudio-epc-catalog/scripts/sample-invocations.sh +18 -0
- package/skills/orchestrating-datacloud/CREDITS.md +15 -0
- package/skills/orchestrating-datacloud/README.md +129 -0
- package/skills/orchestrating-datacloud/SKILL.md +236 -0
- package/skills/orchestrating-datacloud/UPSTREAM.md +45 -0
- package/skills/orchestrating-datacloud/assets/definitions/activation-target.template.json +5 -0
- package/skills/orchestrating-datacloud/assets/definitions/activation.template.json +7 -0
- package/skills/orchestrating-datacloud/assets/definitions/calculated-insight.template.json +7 -0
- package/skills/orchestrating-datacloud/assets/definitions/data-action-target.template.json +5 -0
- package/skills/orchestrating-datacloud/assets/definitions/data-action.template.json +5 -0
- package/skills/orchestrating-datacloud/assets/definitions/data-graph.template.json +21 -0
- package/skills/orchestrating-datacloud/assets/definitions/data-stream.template.json +55 -0
- package/skills/orchestrating-datacloud/assets/definitions/dmo.template.json +17 -0
- package/skills/orchestrating-datacloud/assets/definitions/identity-resolution.template.json +30 -0
- package/skills/orchestrating-datacloud/assets/definitions/mapping.template.json +14 -0
- package/skills/orchestrating-datacloud/assets/definitions/relationship.template.json +12 -0
- package/skills/orchestrating-datacloud/assets/definitions/search-index.template.json +9 -0
- package/skills/orchestrating-datacloud/assets/definitions/segment.template.json +16 -0
- package/skills/orchestrating-datacloud/references/feature-readiness.md +157 -0
- package/skills/orchestrating-datacloud/references/plugin-setup.md +140 -0
- package/skills/orchestrating-datacloud/scripts/bootstrap-plugin.sh +53 -0
- package/skills/orchestrating-datacloud/scripts/diagnose-org.mjs +511 -0
- package/skills/orchestrating-datacloud/scripts/generate-manifest.mjs +68 -0
- package/skills/orchestrating-datacloud/scripts/verify-plugin.sh +58 -0
- package/skills/preparing-datacloud/CREDITS.md +7 -0
- package/skills/preparing-datacloud/README.md +51 -0
- package/skills/preparing-datacloud/SKILL.md +191 -0
- package/skills/preparing-datacloud/examples/ingestion-api/.env.example +8 -0
- package/skills/preparing-datacloud/examples/ingestion-api/README.md +48 -0
- package/skills/preparing-datacloud/examples/ingestion-api/send-data.py +144 -0
- package/skills/querying-soql/CREDITS.md +21 -0
- package/skills/querying-soql/README.md +41 -0
- package/skills/querying-soql/SKILL.md +143 -0
- package/skills/querying-soql/assets/aggregate-queries.soql +242 -0
- package/skills/querying-soql/assets/basic-queries.soql +188 -0
- package/skills/querying-soql/assets/bulkified-query-pattern.cls +280 -0
- package/skills/querying-soql/assets/optimization-patterns.soql +259 -0
- package/skills/querying-soql/assets/relationship-queries.soql +203 -0
- package/skills/querying-soql/assets/selector-class.cls +219 -0
- package/skills/querying-soql/references/anti-patterns.md +348 -0
- package/skills/querying-soql/references/cli-commands.md +358 -0
- package/skills/querying-soql/references/field-coverage-rules.md +514 -0
- package/skills/querying-soql/references/query-optimization.md +142 -0
- package/skills/querying-soql/references/selector-patterns.md +479 -0
- package/skills/querying-soql/references/soql-reference.md +227 -0
- package/skills/querying-soql/references/soql-syntax-reference.md +208 -0
- package/skills/querying-soql/scripts/post-tool-validate.py +322 -0
- package/skills/retrieving-datacloud/CREDITS.md +7 -0
- package/skills/retrieving-datacloud/README.md +44 -0
- package/skills/retrieving-datacloud/SKILL.md +120 -0
- package/skills/retrieving-datacloud/examples/search-indexes/hybrid-structured.json +44 -0
- package/skills/retrieving-datacloud/examples/search-indexes/vector-knowledge.json +43 -0
- package/skills/running-apex-tests/CREDITS.md +22 -0
- package/skills/running-apex-tests/README.md +94 -0
- package/skills/running-apex-tests/SKILL.md +158 -0
- package/skills/running-apex-tests/assets/basic-test.cls +169 -0
- package/skills/running-apex-tests/assets/bulk-test.cls +255 -0
- package/skills/running-apex-tests/assets/dml-mock.cls +339 -0
- package/skills/running-apex-tests/assets/mock-callout-test.cls +353 -0
- package/skills/running-apex-tests/assets/stub-provider-example.cls +364 -0
- package/skills/running-apex-tests/assets/test-data-factory.cls +328 -0
- package/skills/running-apex-tests/hooks/scripts/parse-test-results.py +364 -0
- package/skills/running-apex-tests/references/cli-commands.md +289 -0
- package/skills/running-apex-tests/references/mocking-patterns.md +500 -0
- package/skills/running-apex-tests/references/performance-optimization.md +283 -0
- package/skills/running-apex-tests/references/test-fix-loop.md +49 -0
- package/skills/running-apex-tests/references/test-patterns.md +154 -0
- package/skills/running-apex-tests/references/testing-best-practices.md +509 -0
- package/skills/segmenting-datacloud/CREDITS.md +3 -0
- package/skills/segmenting-datacloud/README.md +36 -0
- package/skills/segmenting-datacloud/SKILL.md +115 -0
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @description Bulk testing template for trigger and service validation
|
|
3
|
+
* Tests with 251+ records to ensure bulkification compliance.
|
|
4
|
+
* 251 records crosses the 200-record trigger batch boundary.
|
|
5
|
+
* @created {{Date}}
|
|
6
|
+
*/
|
|
7
|
+
@IsTest
|
|
8
|
+
private class {{ClassName}}BulkTest {
|
|
9
|
+
|
|
10
|
+
// Record counts for different test scenarios
|
|
11
|
+
private static final Integer BULK_SIZE = 251; // Crosses 200-batch boundary
|
|
12
|
+
private static final Integer LARGE_BULK_SIZE = 501; // Multiple batch boundaries
|
|
13
|
+
private static final Integer SINGLE_BATCH = 200; // Single batch (edge case)
|
|
14
|
+
|
|
15
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
16
|
+
// BULK INSERT TESTS
|
|
17
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @description Tests bulk insert with 251 records
|
|
21
|
+
* Verifies trigger handles multiple batch chunks correctly
|
|
22
|
+
*/
|
|
23
|
+
@IsTest
|
|
24
|
+
static void testBulkInsert_251Records_AllProcessed() {
|
|
25
|
+
// GIVEN
|
|
26
|
+
List<{{ObjectName}}> records = TestDataFactory.create{{ObjectName}}s(BULK_SIZE);
|
|
27
|
+
|
|
28
|
+
// WHEN
|
|
29
|
+
Test.startTest();
|
|
30
|
+
Database.SaveResult[] results = Database.insert(records, false);
|
|
31
|
+
Test.stopTest();
|
|
32
|
+
|
|
33
|
+
// THEN - All records should be successfully inserted
|
|
34
|
+
Integer successCount = 0;
|
|
35
|
+
Integer failCount = 0;
|
|
36
|
+
for (Database.SaveResult sr : results) {
|
|
37
|
+
if (sr.isSuccess()) {
|
|
38
|
+
successCount++;
|
|
39
|
+
} else {
|
|
40
|
+
failCount++;
|
|
41
|
+
System.debug('Insert failed: ' + sr.getErrors()[0].getMessage());
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
Assert.areEqual(BULK_SIZE, successCount,
|
|
46
|
+
'All ' + BULK_SIZE + ' records should insert successfully');
|
|
47
|
+
Assert.areEqual(0, failCount, 'No records should fail');
|
|
48
|
+
|
|
49
|
+
// Verify governor limits
|
|
50
|
+
assertGovernorLimitsNotExceeded();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* @description Tests bulk insert at exact batch boundary (200 records)
|
|
55
|
+
*/
|
|
56
|
+
@IsTest
|
|
57
|
+
static void testBulkInsert_ExactBatchSize_AllProcessed() {
|
|
58
|
+
// GIVEN
|
|
59
|
+
List<{{ObjectName}}> records = TestDataFactory.create{{ObjectName}}s(SINGLE_BATCH);
|
|
60
|
+
|
|
61
|
+
// WHEN
|
|
62
|
+
Test.startTest();
|
|
63
|
+
insert records;
|
|
64
|
+
Test.stopTest();
|
|
65
|
+
|
|
66
|
+
// THEN
|
|
67
|
+
Integer count = [SELECT COUNT() FROM {{ObjectName}}];
|
|
68
|
+
Assert.areEqual(SINGLE_BATCH, count,
|
|
69
|
+
'All ' + SINGLE_BATCH + ' records should be inserted');
|
|
70
|
+
assertGovernorLimitsNotExceeded();
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
74
|
+
// BULK UPDATE TESTS
|
|
75
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* @description Tests bulk update with 251 records
|
|
79
|
+
* Verifies update triggers handle multiple batches
|
|
80
|
+
*/
|
|
81
|
+
@IsTest
|
|
82
|
+
static void testBulkUpdate_251Records_AllUpdated() {
|
|
83
|
+
// GIVEN - Insert records first
|
|
84
|
+
List<{{ObjectName}}> records = TestDataFactory.create{{ObjectName}}s(BULK_SIZE);
|
|
85
|
+
insert records;
|
|
86
|
+
|
|
87
|
+
// Modify all records
|
|
88
|
+
for ({{ObjectName}} rec : records) {
|
|
89
|
+
// TODO: Update fields that trigger logic
|
|
90
|
+
// rec.SomeField__c = 'Updated Value';
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// WHEN
|
|
94
|
+
Test.startTest();
|
|
95
|
+
Database.SaveResult[] results = Database.update(records, false);
|
|
96
|
+
Test.stopTest();
|
|
97
|
+
|
|
98
|
+
// THEN
|
|
99
|
+
Integer successCount = 0;
|
|
100
|
+
for (Database.SaveResult sr : results) {
|
|
101
|
+
if (sr.isSuccess()) {
|
|
102
|
+
successCount++;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
Assert.areEqual(BULK_SIZE, successCount,
|
|
107
|
+
'All ' + BULK_SIZE + ' records should update successfully');
|
|
108
|
+
assertGovernorLimitsNotExceeded();
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
112
|
+
// BULK DELETE TESTS
|
|
113
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* @description Tests bulk delete with 251 records
|
|
117
|
+
* Verifies delete triggers handle cleanup correctly
|
|
118
|
+
*/
|
|
119
|
+
@IsTest
|
|
120
|
+
static void testBulkDelete_251Records_AllDeleted() {
|
|
121
|
+
// GIVEN
|
|
122
|
+
List<{{ObjectName}}> records = TestDataFactory.create{{ObjectName}}s(BULK_SIZE);
|
|
123
|
+
insert records;
|
|
124
|
+
|
|
125
|
+
// WHEN
|
|
126
|
+
Test.startTest();
|
|
127
|
+
Database.DeleteResult[] results = Database.delete(records, false);
|
|
128
|
+
Test.stopTest();
|
|
129
|
+
|
|
130
|
+
// THEN
|
|
131
|
+
Integer successCount = 0;
|
|
132
|
+
for (Database.DeleteResult dr : results) {
|
|
133
|
+
if (dr.isSuccess()) {
|
|
134
|
+
successCount++;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
Assert.areEqual(BULK_SIZE, successCount,
|
|
139
|
+
'All ' + BULK_SIZE + ' records should delete successfully');
|
|
140
|
+
|
|
141
|
+
Integer remainingCount = [SELECT COUNT() FROM {{ObjectName}}];
|
|
142
|
+
Assert.areEqual(0, remainingCount, 'No records should remain');
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
146
|
+
// MIXED DML BULK TESTS
|
|
147
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* @description Tests mixed operations in bulk
|
|
151
|
+
* Verifies partial success scenarios are handled
|
|
152
|
+
*/
|
|
153
|
+
@IsTest
|
|
154
|
+
static void testBulkMixedOperations_PartialSuccess() {
|
|
155
|
+
// GIVEN - Some valid, some invalid records
|
|
156
|
+
List<{{ObjectName}}> validRecords = TestDataFactory.create{{ObjectName}}s(200);
|
|
157
|
+
List<{{ObjectName}}> invalidRecords = new List<{{ObjectName}}>();
|
|
158
|
+
|
|
159
|
+
// Create invalid records (missing required fields or validation failures)
|
|
160
|
+
for (Integer i = 0; i < 51; i++) {
|
|
161
|
+
invalidRecords.add(new {{ObjectName}}(
|
|
162
|
+
// TODO: Set up record that will fail validation
|
|
163
|
+
));
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
List<{{ObjectName}}> allRecords = new List<{{ObjectName}}>();
|
|
167
|
+
allRecords.addAll(validRecords);
|
|
168
|
+
allRecords.addAll(invalidRecords);
|
|
169
|
+
|
|
170
|
+
// WHEN - Insert with allOrNone = false
|
|
171
|
+
Test.startTest();
|
|
172
|
+
Database.SaveResult[] results = Database.insert(allRecords, false);
|
|
173
|
+
Test.stopTest();
|
|
174
|
+
|
|
175
|
+
// THEN - Count successes and failures
|
|
176
|
+
Integer successCount = 0;
|
|
177
|
+
Integer failCount = 0;
|
|
178
|
+
for (Database.SaveResult sr : results) {
|
|
179
|
+
if (sr.isSuccess()) {
|
|
180
|
+
successCount++;
|
|
181
|
+
} else {
|
|
182
|
+
failCount++;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// Verify partial success handled correctly
|
|
187
|
+
Assert.isTrue(successCount > 0, 'Some records should succeed');
|
|
188
|
+
// Note: Uncomment if you expect failures
|
|
189
|
+
// Assert.isTrue(failCount > 0, 'Some records should fail validation');
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
193
|
+
// GOVERNOR LIMIT VERIFICATION
|
|
194
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* @description Helper method to verify governor limits not exceeded
|
|
198
|
+
* Call after Test.stopTest() to check limit usage
|
|
199
|
+
*/
|
|
200
|
+
private static void assertGovernorLimitsNotExceeded() {
|
|
201
|
+
// SOQL Queries (limit: 100)
|
|
202
|
+
Assert.isTrue(Limits.getQueries() < 90,
|
|
203
|
+
'SOQL queries approaching limit: ' + Limits.getQueries() + '/100');
|
|
204
|
+
|
|
205
|
+
// DML Statements (limit: 150)
|
|
206
|
+
Assert.isTrue(Limits.getDmlStatements() < 140,
|
|
207
|
+
'DML statements approaching limit: ' + Limits.getDmlStatements() + '/150');
|
|
208
|
+
|
|
209
|
+
// DML Rows (limit: 10,000)
|
|
210
|
+
Assert.isTrue(Limits.getDmlRows() < 9500,
|
|
211
|
+
'DML rows approaching limit: ' + Limits.getDmlRows() + '/10000');
|
|
212
|
+
|
|
213
|
+
// Heap Size (limit: 6MB sync, 12MB async)
|
|
214
|
+
Assert.isTrue(Limits.getHeapSize() < 5000000,
|
|
215
|
+
'Heap size approaching limit: ' + Limits.getHeapSize() + '/6000000');
|
|
216
|
+
|
|
217
|
+
// CPU Time (limit: 10,000ms sync, 60,000ms async)
|
|
218
|
+
Assert.isTrue(Limits.getCpuTime() < 9000,
|
|
219
|
+
'CPU time approaching limit: ' + Limits.getCpuTime() + '/10000');
|
|
220
|
+
|
|
221
|
+
System.debug('═══════════════════════════════════════════════════════');
|
|
222
|
+
System.debug('GOVERNOR LIMIT USAGE:');
|
|
223
|
+
System.debug(' SOQL Queries: ' + Limits.getQueries() + '/100');
|
|
224
|
+
System.debug(' DML Statements: ' + Limits.getDmlStatements() + '/150');
|
|
225
|
+
System.debug(' DML Rows: ' + Limits.getDmlRows() + '/10000');
|
|
226
|
+
System.debug(' Heap Size: ' + Limits.getHeapSize() + '/6000000');
|
|
227
|
+
System.debug(' CPU Time: ' + Limits.getCpuTime() + 'ms /10000ms');
|
|
228
|
+
System.debug('═══════════════════════════════════════════════════════');
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
232
|
+
// STRESS TESTS (Optional - Run sparingly)
|
|
233
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* @description Stress test with 501 records (multiple batch boundaries)
|
|
237
|
+
* Use sparingly - consumes significant test execution time
|
|
238
|
+
*/
|
|
239
|
+
@IsTest
|
|
240
|
+
static void testStressTest_501Records_AllProcessed() {
|
|
241
|
+
// GIVEN
|
|
242
|
+
List<{{ObjectName}}> records = TestDataFactory.create{{ObjectName}}s(LARGE_BULK_SIZE);
|
|
243
|
+
|
|
244
|
+
// WHEN
|
|
245
|
+
Test.startTest();
|
|
246
|
+
insert records;
|
|
247
|
+
Test.stopTest();
|
|
248
|
+
|
|
249
|
+
// THEN
|
|
250
|
+
Integer count = [SELECT COUNT() FROM {{ObjectName}}];
|
|
251
|
+
Assert.areEqual(LARGE_BULK_SIZE, count,
|
|
252
|
+
'All ' + LARGE_BULK_SIZE + ' records should be processed');
|
|
253
|
+
assertGovernorLimitsNotExceeded();
|
|
254
|
+
}
|
|
255
|
+
}
|
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DML Mocking Framework
|
|
3
|
+
*
|
|
4
|
+
* Enables true unit testing by replacing database operations with in-memory tracking.
|
|
5
|
+
* Tests using this pattern run ~35x faster than tests with actual DML.
|
|
6
|
+
*
|
|
7
|
+
* See: references/mocking-patterns.md for usage guidance
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
11
|
+
// INTERFACE: IDML
|
|
12
|
+
// Define the contract for DML operations
|
|
13
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Interface for DML operations - enables dependency injection
|
|
17
|
+
*/
|
|
18
|
+
public interface IDML {
|
|
19
|
+
void doInsert(SObject record);
|
|
20
|
+
void doInsert(List<SObject> records);
|
|
21
|
+
void doUpdate(SObject record);
|
|
22
|
+
void doUpdate(List<SObject> records);
|
|
23
|
+
void doUpsert(SObject record);
|
|
24
|
+
void doUpsert(List<SObject> records);
|
|
25
|
+
void doDelete(SObject record);
|
|
26
|
+
void doDelete(List<SObject> records);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
30
|
+
// PRODUCTION: DML
|
|
31
|
+
// Performs actual database operations
|
|
32
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Production implementation performing real database operations
|
|
36
|
+
*/
|
|
37
|
+
public class DML implements IDML {
|
|
38
|
+
|
|
39
|
+
public void doInsert(SObject record) {
|
|
40
|
+
insert record;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
public void doInsert(List<SObject> records) {
|
|
44
|
+
if (records != null && !records.isEmpty()) {
|
|
45
|
+
insert records;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
public void doUpdate(SObject record) {
|
|
50
|
+
update record;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
public void doUpdate(List<SObject> records) {
|
|
54
|
+
if (records != null && !records.isEmpty()) {
|
|
55
|
+
update records;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
public void doUpsert(SObject record) {
|
|
60
|
+
upsert record;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
public void doUpsert(List<SObject> records) {
|
|
64
|
+
if (records != null && !records.isEmpty()) {
|
|
65
|
+
upsert records;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
public void doDelete(SObject record) {
|
|
70
|
+
delete record;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
public void doDelete(List<SObject> records) {
|
|
74
|
+
if (records != null && !records.isEmpty()) {
|
|
75
|
+
delete records;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
81
|
+
// TEST MOCK: DMLMock
|
|
82
|
+
// Tracks operations without hitting the database
|
|
83
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Mock DML implementation for fast unit tests
|
|
87
|
+
*
|
|
88
|
+
* Usage:
|
|
89
|
+
* DMLMock.reset();
|
|
90
|
+
* MyService service = new MyService(new DMLMock());
|
|
91
|
+
* service.doSomething();
|
|
92
|
+
* Assert.areEqual(1, DMLMock.InsertedRecords.size());
|
|
93
|
+
*/
|
|
94
|
+
@IsTest
|
|
95
|
+
public class DMLMock implements IDML {
|
|
96
|
+
|
|
97
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
98
|
+
// TRACKED OPERATIONS
|
|
99
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
100
|
+
|
|
101
|
+
public static List<SObject> InsertedRecords = new List<SObject>();
|
|
102
|
+
public static List<SObject> UpdatedRecords = new List<SObject>();
|
|
103
|
+
public static List<SObject> UpsertedRecords = new List<SObject>();
|
|
104
|
+
public static List<SObject> DeletedRecords = new List<SObject>();
|
|
105
|
+
|
|
106
|
+
// Counter for generating unique fake IDs
|
|
107
|
+
private static Integer idCounter = 1;
|
|
108
|
+
|
|
109
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
110
|
+
// DML OPERATIONS
|
|
111
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
112
|
+
|
|
113
|
+
public void doInsert(SObject record) {
|
|
114
|
+
doInsert(new List<SObject>{ record });
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
public void doInsert(List<SObject> records) {
|
|
118
|
+
if (records == null || records.isEmpty()) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
for (SObject record : records) {
|
|
122
|
+
// Generate fake ID to simulate database insert
|
|
123
|
+
if (record.Id == null) {
|
|
124
|
+
record.Id = generateFakeId(record.getSObjectType());
|
|
125
|
+
}
|
|
126
|
+
InsertedRecords.add(record);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
public void doUpdate(SObject record) {
|
|
131
|
+
doUpdate(new List<SObject>{ record });
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
public void doUpdate(List<SObject> records) {
|
|
135
|
+
if (records != null && !records.isEmpty()) {
|
|
136
|
+
UpdatedRecords.addAll(records);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
public void doUpsert(SObject record) {
|
|
141
|
+
doUpsert(new List<SObject>{ record });
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
public void doUpsert(List<SObject> records) {
|
|
145
|
+
if (records != null && !records.isEmpty()) {
|
|
146
|
+
for (SObject record : records) {
|
|
147
|
+
if (record.Id == null) {
|
|
148
|
+
record.Id = generateFakeId(record.getSObjectType());
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
UpsertedRecords.addAll(records);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
public void doDelete(SObject record) {
|
|
156
|
+
doDelete(new List<SObject>{ record });
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
public void doDelete(List<SObject> records) {
|
|
160
|
+
if (records != null && !records.isEmpty()) {
|
|
161
|
+
DeletedRecords.addAll(records);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
166
|
+
// UTILITY METHODS
|
|
167
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Reset all tracked operations - call at start of each test
|
|
171
|
+
*/
|
|
172
|
+
public static void reset() {
|
|
173
|
+
InsertedRecords.clear();
|
|
174
|
+
UpdatedRecords.clear();
|
|
175
|
+
UpsertedRecords.clear();
|
|
176
|
+
DeletedRecords.clear();
|
|
177
|
+
idCounter = 1;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Generate a valid Salesforce ID for testing
|
|
182
|
+
* Uses the object's key prefix for realistic IDs
|
|
183
|
+
*/
|
|
184
|
+
private static Id generateFakeId(Schema.SObjectType sObjectType) {
|
|
185
|
+
String keyPrefix = sObjectType.getDescribe().getKeyPrefix();
|
|
186
|
+
if (keyPrefix == null) {
|
|
187
|
+
keyPrefix = '000'; // Fallback for objects without prefix
|
|
188
|
+
}
|
|
189
|
+
String idBody = String.valueOf(idCounter++).leftPad(12, '0');
|
|
190
|
+
return Id.valueOf(keyPrefix + idBody);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
194
|
+
// HELPER METHODS FOR ASSERTIONS
|
|
195
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Get inserted records of a specific SObject type
|
|
199
|
+
*/
|
|
200
|
+
public static List<SObject> getInsertedOfType(Schema.SObjectType sObjectType) {
|
|
201
|
+
List<SObject> result = new List<SObject>();
|
|
202
|
+
for (SObject record : InsertedRecords) {
|
|
203
|
+
if (record.getSObjectType() == sObjectType) {
|
|
204
|
+
result.add(record);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
return result;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Get updated records of a specific SObject type
|
|
212
|
+
*/
|
|
213
|
+
public static List<SObject> getUpdatedOfType(Schema.SObjectType sObjectType) {
|
|
214
|
+
List<SObject> result = new List<SObject>();
|
|
215
|
+
for (SObject record : UpdatedRecords) {
|
|
216
|
+
if (record.getSObjectType() == sObjectType) {
|
|
217
|
+
result.add(record);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
return result;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Get deleted records of a specific SObject type
|
|
225
|
+
*/
|
|
226
|
+
public static List<SObject> getDeletedOfType(Schema.SObjectType sObjectType) {
|
|
227
|
+
List<SObject> result = new List<SObject>();
|
|
228
|
+
for (SObject record : DeletedRecords) {
|
|
229
|
+
if (record.getSObjectType() == sObjectType) {
|
|
230
|
+
result.add(record);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
return result;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Check if any records of a specific type were inserted
|
|
238
|
+
*/
|
|
239
|
+
public static Boolean wasInserted(Schema.SObjectType sObjectType) {
|
|
240
|
+
return !getInsertedOfType(sObjectType).isEmpty();
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Check if any records of a specific type were updated
|
|
245
|
+
*/
|
|
246
|
+
public static Boolean wasUpdated(Schema.SObjectType sObjectType) {
|
|
247
|
+
return !getUpdatedOfType(sObjectType).isEmpty();
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Check if any records of a specific type were deleted
|
|
252
|
+
*/
|
|
253
|
+
public static Boolean wasDeleted(Schema.SObjectType sObjectType) {
|
|
254
|
+
return !getDeletedOfType(sObjectType).isEmpty();
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
259
|
+
// EXAMPLE: Service Using Injected DML
|
|
260
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Example service class demonstrating DML injection
|
|
264
|
+
*/
|
|
265
|
+
public class AccountService {
|
|
266
|
+
|
|
267
|
+
private IDML dml;
|
|
268
|
+
|
|
269
|
+
// Production constructor - uses real DML
|
|
270
|
+
public AccountService() {
|
|
271
|
+
this(new DML());
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// Test constructor - accepts mock DML
|
|
275
|
+
@TestVisible
|
|
276
|
+
private AccountService(IDML dml) {
|
|
277
|
+
this.dml = dml;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
public Id createAccount(Account acc) {
|
|
281
|
+
if (acc == null) {
|
|
282
|
+
throw new IllegalArgumentException('Account cannot be null');
|
|
283
|
+
}
|
|
284
|
+
dml.doInsert(acc);
|
|
285
|
+
return acc.Id;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
public void updateAccounts(List<Account> accounts) {
|
|
289
|
+
dml.doUpdate(accounts);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
294
|
+
// EXAMPLE: Test Class Using DML Mock
|
|
295
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
296
|
+
|
|
297
|
+
@IsTest
|
|
298
|
+
private class AccountServiceTest {
|
|
299
|
+
|
|
300
|
+
@IsTest
|
|
301
|
+
static void testCreateAccount_Success() {
|
|
302
|
+
// Arrange
|
|
303
|
+
DMLMock.reset();
|
|
304
|
+
AccountService service = new AccountService(new DMLMock());
|
|
305
|
+
Account testAcc = new Account(Name = 'Test Corp', Industry = 'Technology');
|
|
306
|
+
|
|
307
|
+
// Act
|
|
308
|
+
Test.startTest();
|
|
309
|
+
Id accountId = service.createAccount(testAcc);
|
|
310
|
+
Test.stopTest();
|
|
311
|
+
|
|
312
|
+
// Assert
|
|
313
|
+
Assert.isNotNull(accountId, 'Should have generated ID');
|
|
314
|
+
Assert.areEqual(1, DMLMock.InsertedRecords.size(), 'Should have 1 insert');
|
|
315
|
+
Assert.isTrue(DMLMock.wasInserted(Account.SObjectType), 'Account was inserted');
|
|
316
|
+
|
|
317
|
+
Account inserted = (Account) DMLMock.InsertedRecords[0];
|
|
318
|
+
Assert.areEqual('Test Corp', inserted.Name, 'Name should match');
|
|
319
|
+
Assert.areEqual('Technology', inserted.Industry, 'Industry should match');
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
@IsTest
|
|
323
|
+
static void testCreateAccount_NullInput_ThrowsException() {
|
|
324
|
+
// Arrange
|
|
325
|
+
DMLMock.reset();
|
|
326
|
+
AccountService service = new AccountService(new DMLMock());
|
|
327
|
+
|
|
328
|
+
// Act/Assert
|
|
329
|
+
try {
|
|
330
|
+
service.createAccount(null);
|
|
331
|
+
Assert.fail('Expected IllegalArgumentException');
|
|
332
|
+
} catch (IllegalArgumentException e) {
|
|
333
|
+
Assert.isTrue(e.getMessage().contains('null'), 'Error should mention null');
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
// Verify no DML occurred
|
|
337
|
+
Assert.areEqual(0, DMLMock.InsertedRecords.size(), 'No records should be inserted');
|
|
338
|
+
}
|
|
339
|
+
}
|