afv-library/skills/trigger-refactor-pipeline/assets/test_template.apex
Mohan Raj Rajamanickam 2320c50264
ci: publish skills as @salesforce/afv-skills npm package @W-21534193@ (#30)
* ci: update package details and add GitHub workflows for skills validation and release

* chore: update Node version, change license, and refactor skills validation script to TypeScript

* chore: remove unused deps

* fix: npm package

* fix: flatten skills to pass validation

* chore: add validation script to package.json and update GitHub workflow to use it

* chore: enhance skills validation and update workflows for npm publishing

* refactor: streamline skills validation process in workflow and script

* refactor: improve documentation and structure of skills validation script

* implement checks based on jeff's best practices doc

* chore: add pull request template for skill submissions

* chore: update pull request template with additional references and improve automated checks section

* chore: update pull request template to clarify naming convention with a warning for gerund form

* chore: update pull request template to reference skill authoring guide and enhance checklist structure

* chore: enhance GitHub workflows for skills validation and release process

* refactor: improve parsing logic for SKILL.md files and enhance error collection in validation

* chore: update validation checks to enforce character limits for skill names and descriptions

* fix: remove unnecessary whitespace in footer string in validate-skills.ts
2026-03-12 13:41:52 -07:00

322 lines
10 KiB
Plaintext

/**
* Test class template for trigger handlers
*
* INSTRUCTIONS:
* 1. Replace [ObjectName] with your SObject (e.g., Opportunity)
* 2. Replace [HandlerClass] with your handler class name
* 3. Implement the setupTestData() method with your test records
* 4. Add specific test methods for each handler method
* 5. Ensure 100% code coverage
*/
@IsTest
private class [ObjectName]TriggerHandlerTest {
/**
* Setup test data that all test methods can use
*/
@TestSetup
static void setupTestData() {
// TODO: Create test records here
// Example:
// List<Opportunity> testOpps = new List<Opportunity>();
// for (Integer i = 0; i < 10; i++) {
// testOpps.add(new Opportunity(
// Name = 'Test Opp ' + i,
// StageName = 'Prospecting',
// CloseDate = Date.today().addDays(30),
// Amount = 5000
// ));
// }
// insert testOpps;
}
/**
* Test beforeInsert handler - Positive case
*/
@IsTest
static void testBeforeInsert_Positive() {
Test.startTest();
// TODO: Create valid test records
// List<Opportunity> testRecords = new List<Opportunity>{
// new Opportunity(
// Name = 'Valid Opp',
// StageName = 'Prospecting',
// CloseDate = Date.today().addDays(30),
// Amount = 10000
// )
// };
// Insert should succeed
// insert testRecords;
Test.stopTest();
// TODO: Add assertions
// List<Opportunity> inserted = [SELECT Id, Name FROM Opportunity WHERE Name = 'Valid Opp'];
// System.Assert.areEqual(1, inserted.size(), 'Should insert 1 record');
}
/**
* Test beforeInsert handler - Negative case
*/
@IsTest
static void testBeforeInsert_Negative() {
Test.startTest();
Boolean exceptionThrown = false;
try {
// TODO: Create invalid test records that should fail validation
// List<Opportunity> testRecords = new List<Opportunity>{
// new Opportunity(
// Name = 'Invalid Opp',
// StageName = 'Closed Won',
// CloseDate = Date.today(),
// Amount = 500 // Below minimum
// )
// };
// insert testRecords;
} catch (DmlException e) {
exceptionThrown = true;
// TODO: Assert error message
// System.Assert.isTrue(e.getMessage().contains('must have Amount'),
// 'Should throw validation error');
}
Test.stopTest();
// System.Assert.isTrue(exceptionThrown, 'Should have thrown an exception');
}
/**
* Test beforeUpdate handler - Positive case
*/
@IsTest
static void testBeforeUpdate_Positive() {
// TODO: Query existing test data from @TestSetup
// List<Opportunity> testOpps = [SELECT Id, StageName, Description FROM Opportunity LIMIT 1];
Test.startTest();
// TODO: Update records to trigger handler logic
// testOpps[0].StageName = 'Qualification';
// update testOpps;
Test.stopTest();
// TODO: Add assertions
// Opportunity updated = [SELECT Description FROM Opportunity WHERE Id = :testOpps[0].Id];
// System.Assert.isTrue(updated.Description.contains('Stage changed'),
// 'Description should be updated');
}
/**
* Test beforeUpdate handler - Negative case
*/
@IsTest
static void testBeforeUpdate_Negative() {
// TODO: Implement negative test for beforeUpdate
Test.startTest();
// TODO: Attempt update that should fail
Test.stopTest();
// TODO: Assert failure occurred
}
/**
* Test afterInsert handler - Positive case
*/
@IsTest
static void testAfterInsert_Positive() {
Test.startTest();
// TODO: Create and insert records
Test.stopTest();
// TODO: Query for related records created by handler
// List<Task> createdTasks = [SELECT Id FROM Task];
// System.Assert.areEqual(1, createdTasks.size(), 'Should create 1 task');
}
/**
* Test afterUpdate handler - Positive case
*/
@IsTest
static void testAfterUpdate_Positive() {
// TODO: Query existing test data
// List<Opportunity> testOpps = [SELECT Id, StageName FROM Opportunity LIMIT 1];
Test.startTest();
// TODO: Update to trigger after-update logic
// testOpps[0].StageName = 'Closed Won';
// update testOpps;
Test.stopTest();
// TODO: Query for side effects (e.g., Tasks created)
// List<Task> tasks = [SELECT Id, Subject FROM Task WHERE WhatId = :testOpps[0].Id];
// System.Assert.areEqual(1, tasks.size(), 'Should create 1 task');
// System.Assert.areEqual('Send thank-you', tasks[0].Subject);
}
/**
* Test bulk operations - 200+ records
* Critical for validating bulkification
*/
@IsTest
static void testBulkInsert() {
Test.startTest();
// TODO: Create 200+ records
// List<Opportunity> bulkOpps = new List<Opportunity>();
// for (Integer i = 0; i < 200; i++) {
// bulkOpps.add(new Opportunity(
// Name = 'Bulk Opp ' + i,
// StageName = 'Prospecting',
// CloseDate = Date.today().addDays(30),
// Amount = 10000
// ));
// }
// insert bulkOpps;
Test.stopTest();
// TODO: Assert all records inserted successfully
// List<Opportunity> inserted = [SELECT Id FROM Opportunity WHERE Name LIKE 'Bulk Opp%'];
// System.Assert.areEqual(200, inserted.size(), 'Should insert all 200 records');
}
/**
* Test bulk update with mixed scenarios
* Some records qualify for logic, others don't
*/
@IsTest
static void testBulkUpdate_Mixed() {
// Create test data
List<Opportunity> testOpps = new List<Opportunity>();
for (Integer i = 0; i < 50; i++) {
testOpps.add(new Opportunity(
Name = 'Bulk Update Opp ' + i,
StageName = 'Prospecting',
CloseDate = Date.today().addDays(30),
Amount = 10000
));
}
insert testOpps;
Test.startTest();
// Update half to trigger logic, half to not trigger
for (Integer i = 0; i < testOpps.size(); i++) {
if (Math.mod(i, 2) == 0) {
// TODO: Set condition that triggers handler logic
// testOpps[i].StageName = 'Closed Won';
} else {
// TODO: Set condition that doesn't trigger handler logic
// testOpps[i].Amount = 15000;
}
}
// update testOpps;
Test.stopTest();
// TODO: Assert only qualifying records triggered side effects
// List<Task> tasks = [SELECT Id FROM Task WHERE WhatId IN :testOpps];
// System.Assert.areEqual(25, tasks.size(), 'Should create tasks for 25 qualifying records');
}
/**
* Test governor limits are not exceeded
*/
@IsTest
static void testGovernorLimits() {
Test.startTest();
// TODO: Create maximum allowed records
// List<Opportunity> maxOpps = new List<Opportunity>();
// for (Integer i = 0; i < 200; i++) {
// maxOpps.add(new Opportunity(
// Name = 'Limit Test ' + i,
// StageName = 'Closed Won',
// CloseDate = Date.today(),
// Amount = 10000
// ));
// }
// insert maxOpps;
Test.stopTest();
// Assert we're under governor limits
System.Assert.isTrue(Limits.getDmlStatements() < Limits.getLimitDmlStatements(),
'Should not exceed DML statement limit');
System.Assert.isTrue(Limits.getQueries() < Limits.getLimitQueries(),
'Should not exceed SOQL query limit');
}
/**
* Test with null or empty collections
* Ensures handler doesn't break with edge cases
*/
@IsTest
static void testWithEmptyCollection() {
Test.startTest();
// TODO: Call handler methods with empty lists
// OpportunityTriggerHandler handler = new OpportunityTriggerHandler();
// handler.beforeInsert(new List<Opportunity>());
Test.stopTest();
// If we get here without exception, test passes
System.Assert.isTrue(true, 'Handler should handle empty collections gracefully');
}
/**
* Helper method to create test data inline
* Use when @TestSetup is not sufficient
*/
private static List<Opportunity> createTestOpportunities(Integer count) {
List<Opportunity> testOpps = new List<Opportunity>();
for (Integer i = 0; i < count; i++) {
testOpps.add(new Opportunity(
Name = 'Test Opp ' + i,
StageName = 'Prospecting',
CloseDate = Date.today().addDays(30),
Amount = 10000
));
}
return testOpps;
}
/**
* Helper method to assert task creation
*/
private static void assertTasksCreated(List<Id> oppIds, Integer expectedCount, String subject) {
List<Task> tasks = [
SELECT Id, Subject, WhatId
FROM Task
WHERE WhatId IN :oppIds
];
System.Assert.areEqual(expectedCount, tasks.size(),
'Should create ' + expectedCount + ' task(s)');
if (expectedCount > 0) {
System.Assert.areEqual(subject, tasks[0].Subject,
'Task subject should match');
}
}
}