@IsTest private class AppraiserCasePayloadBuilderTest { @TestSetup static void setupTestData() { // Create test Appraiser Case Appraiser_Case__c testCase = new Appraiser_Case__c( Appraiser_Field_Review_Date__c = Date.newInstance(2026, 4, 2), Letter_Sent_Date__c = Date.newInstance(2026, 4, 9), FHA_Case_Number__c = '123-4567890', Appraiser_Name__c = 'Jamie Appraiser', Appraiser_Salutation__c = 'Ms.', Appraiser_Last_Name__c = 'Appraiser', Appraiser_Email__c = 'jamie.appraiser@example.com', Appraiser_Street__c = '245 Lexington Ave', Appraiser_City__c = 'New York', Appraiser_State_Province__c = 'NY', Appraiser_Postal_Code__c = '10016', Appraiser_Country__c = 'USA', Property_Street__c = '123 Main St', Property_City__c = 'Denver', Property_State_Province__c = 'CO', Property_Postal_Code__c = '80202', Property_Country__c = 'USA' ); insert testCase; // Create test deficiency records List testDefs = new List(); testDefs.add(new Appraiser_Case_Deficiency__c( Appraiser_Case__c = testCase.Id, Deficiency_Number__c = 1, Description__c = 'Missing comparable sale adjustment detail.', Resolution__c = 'Added adjustment rationale and supporting calculations.', Reference__c = 'VC-1' )); testDefs.add(new Appraiser_Case_Deficiency__c( Appraiser_Case__c = testCase.Id, Deficiency_Number__c = 2, Description__c = 'Neighborhood trend explanation insufficient.', Resolution__c = 'Expanded market trend narrative with MLS evidence.', Reference__c = 'MC-2' )); insert testDefs; } @IsTest static void testBuildPayload() { Appraiser_Case__c testCase = [SELECT Id FROM Appraiser_Case__c LIMIT 1]; Map payload = AppraiserCasePayloadBuilder.buildPayload(testCase.Id); Assert.isNotNull(payload, 'Payload should not be null'); Assert.isTrue(payload.containsKey('AppraiserCaseNumber'), 'Payload should contain AppraiserCaseNumber'); Assert.isTrue(payload.containsKey('AppraiserFieldReviewDate'), 'Payload should contain AppraiserFieldReviewDate'); Assert.isTrue(payload.containsKey('LetterSentDate'), 'Payload should contain LetterSentDate'); Assert.isTrue(payload.containsKey('FHACaseNumber'), 'Payload should contain FHACaseNumber'); Assert.isTrue(payload.containsKey('AppraiserName'), 'Payload should contain AppraiserName'); Assert.isTrue(payload.containsKey('AppraiserSalutation'), 'Payload should contain AppraiserSalutation'); Assert.isTrue(payload.containsKey('AppraiserLastName'), 'Payload should contain AppraiserLastName'); Assert.isTrue(payload.containsKey('AppraiserEmail'), 'Payload should contain AppraiserEmail'); Assert.isTrue(payload.containsKey('AppraiserAddress'), 'Payload should contain AppraiserAddress'); Assert.isTrue(payload.containsKey('PropertyAddress'), 'Payload should contain PropertyAddress'); Assert.isTrue(payload.containsKey('PropertyStreet'), 'Payload should contain PropertyStreet'); Assert.isTrue(payload.containsKey('PropertyCity'), 'Payload should contain PropertyCity'); Assert.isTrue(payload.containsKey('PropertyStateProvince'), 'Payload should contain PropertyStateProvince'); Assert.isTrue(payload.containsKey('PropertyPostalCode'), 'Payload should contain PropertyPostalCode'); Assert.isTrue(payload.containsKey('PropertyCountry'), 'Payload should contain PropertyCountry'); Assert.isTrue(payload.containsKey('DeficiencyList'), 'Payload should contain DeficiencyList'); Assert.areEqual('123 Main St', (String) payload.get('PropertyStreet')); Assert.areEqual('Denver', (String) payload.get('PropertyCity')); Assert.areEqual('CO', (String) payload.get('PropertyStateProvince')); Assert.areEqual('80202', (String) payload.get('PropertyPostalCode')); Assert.areEqual('USA', (String) payload.get('PropertyCountry')); Assert.areEqual('123-4567890', (String) payload.get('FHACaseNumber')); Assert.areEqual('Apr 02, 2026', (String) payload.get('AppraiserFieldReviewDate')); Assert.areEqual('Apr 09, 2026', (String) payload.get('LetterSentDate')); Assert.areEqual('Jamie Appraiser', (String) payload.get('AppraiserName')); Assert.areEqual('Ms.', (String) payload.get('AppraiserSalutation')); Assert.areEqual('Appraiser', (String) payload.get('AppraiserLastName')); Assert.areEqual('jamie.appraiser@example.com', (String) payload.get('AppraiserEmail')); Assert.areEqual('245 Lexington Ave, New York, NY 10016, USA', (String) payload.get('AppraiserAddress')); Assert.areEqual('123 Main St, Denver, CO 80202, USA', (String) payload.get('PropertyAddress')); List deficiencyList = (List) payload.get('DeficiencyList'); Assert.areEqual(2, deficiencyList.size(), 'DeficiencyList should contain 2 items'); Map firstDeficiency = (Map) deficiencyList[0]; Assert.areEqual('VC-1', (String) firstDeficiency.get('reference')); } @IsTest static void testBuildPayloadJson() { Appraiser_Case__c testCase = [SELECT Id FROM Appraiser_Case__c LIMIT 1]; String jsonPayload = AppraiserCasePayloadBuilder.buildPayloadJson(testCase.Id); Assert.isNotNull(jsonPayload, 'JSON payload should not be null'); Assert.isTrue(jsonPayload.contains('AppraiserCaseNumber'), 'JSON should contain AppraiserCaseNumber'); Assert.isTrue(jsonPayload.contains('DeficiencyList'), 'JSON should contain DeficiencyList'); } @IsTest static void testPayloadWithNullDate() { // Create case without review date Appraiser_Case__c testCase = new Appraiser_Case__c( Property_Street__c = '456 Oak Ave', Property_City__c = 'Boulder', Property_State_Province__c = 'CO', Property_Postal_Code__c = '80301' ); insert testCase; Map payload = AppraiserCasePayloadBuilder.buildPayload(testCase.Id); Assert.isNotNull(payload, 'Payload should not be null even with null date'); Assert.isNull(payload.get('AppraiserFieldReviewDate'), 'Null date should map to null in payload'); Assert.areEqual('456 Oak Ave, Boulder, CO 80301', (String) payload.get('PropertyAddress')); } @IsTest static void testInvalidCaseId() { try { AppraiserCasePayloadBuilder.buildPayload('a0wKW000000000000'); Assert.fail('Should have thrown exception for invalid case id'); } catch (IllegalArgumentException ex) { Assert.isTrue(ex.getMessage().contains('Appraiser Case not found')); } } }