diff --git a/.vscode/settings.json b/.vscode/settings.json index 52707b26..a12ade59 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -12,7 +12,6 @@ "editor.detectIndentation": false, "git.autofetch": true, "eslint.nodePath": "./node_modules", - "apexPMD.rulesets": ["ruleset.xml"], "editor.defaultFormatter": "esbenp.prettier-vscode", "[xml]": { "editor.defaultFormatter": "redhat.vscode-xml" diff --git a/config/project-scratch-def.json b/config/project-scratch-def.json index 4c14bae6..1ddd803b 100644 --- a/config/project-scratch-def.json +++ b/config/project-scratch-def.json @@ -22,7 +22,8 @@ "FieldService:5", "FieldServiceDispatcherUser:5", "FieldServiceMobileUser:5", - "FieldServiceSchedulingUser:5" + "FieldServiceSchedulingUser:5", + "LiveMessage" ], "country": "NO", "language": "en_US", @@ -62,6 +63,9 @@ "workOrderLineItemSearchFields": "Subject", "workOrderSearchFields": "Subject" }, + "liveMessageSettings": { + "enableLiveMessage": true + }, "liveAgentSettings": { "enableLiveAgent": true }, diff --git a/force-app/main/default/classes/STO_GroupMemberSkillService.cls b/force-app/main/default/classes/STO_GroupMemberSkillService.cls index 2dec7129..3d2aa5f6 100644 --- a/force-app/main/default/classes/STO_GroupMemberSkillService.cls +++ b/force-app/main/default/classes/STO_GroupMemberSkillService.cls @@ -1,81 +1,76 @@ -public with sharing class STO_GroupMemberSkillService { +/** + * @description This class is used to sync skills between groups and users + * !IMPORTANT! This class can be called using the Callable interface + * in other packaged wich are not dependent on crm-sto. (f.e. hot-servicetjenesten) + * @updated : 2025-02-07 + */ +public with sharing class STO_GroupMemberSkillService implements Callable { private LoggerUtility logger = new LoggerUtility('AD_SKILL_SYNC'); public static final String FORTOLIG_ADDRESSE_SKILL = 'Fortrolig_addresse'; public static final String SKJERMEDE_PERSONER_SKILL = 'Skjermede_personer'; public static final String FORTROLIG_GROUP_NAME = 'group_AD_Fortrolig_Adresse'; public static final String SKJERMEDE_GROUP_NAME = 'NKS_Skjermede_Personer_AD'; - private Set groupNamesToSync = new Set{ FORTROLIG_GROUP_NAME, SKJERMEDE_GROUP_NAME }; - - private final Map groupSkillMap = new Map{ - 'group_AD_Fortrolig_Adresse' => FORTOLIG_ADDRESSE_SKILL, - 'NKS_Skjermede_Personer_AD' => SKJERMEDE_PERSONER_SKILL - }; - - @testVisible - private static Map nksUserMap { - get { - if (nksUserMap == null) { - nksUserMap = new Map(); - for (User usr : [ - SELECT Id, Name - FROM User - WHERE - Id IN ( - SELECT AssigneeId - FROM PermissionSetAssignment - WHERE PermissionSetGroup.DeveloperName = 'Kontaktsenter' - ) - ]) { - nksUserMap.put(usr.Id, usr); - } - } - return nksUserMap; - } - private set { - } - } - - @testVisible - private Map skillIdMap { - get { - if (skillIdMap == null) { - skillIdMap = new Map(); - for (Skill skill : [ - SELECT Id, DeveloperName - FROM Skill - WHERE DeveloperName = :FORTOLIG_ADDRESSE_SKILL OR DeveloperName = :SKJERMEDE_PERSONER_SKILL - ]) { - skillIdMap.put(skill.DeveloperName, skill.Id); - } - } - return skillIdMap; - } - private set { - } - } - + public static final String PERMSET_GROUP_NAME = 'Kontaktsenter'; + public static final String SR_DOMAIN = 'NKS'; + private String fortroligGroupName = FORTROLIG_GROUP_NAME; + private String skjermedeGroupName = SKJERMEDE_GROUP_NAME; + private String permsetGroupName = PERMSET_GROUP_NAME; + private String srDomain = SR_DOMAIN; + private String srSubDomain; private Set fortroligMembers = new Set(); private Set skjermedeMembers = new Set(); private Set fortroligSkillUsers = new Set(); private Set skjermedeSkillUsers = new Set(); + @TestVisible + private Map userMap; + @TestVisible + private Map skillIdMap; - public STO_GroupMemberSkillService() { - getGroupMembers(); - initSkillUserSets(); + @TestVisible + private Map initUserMap() { + userMap = new Map( + [ + SELECT Id, Name + FROM User + WHERE + Id IN ( + SELECT AssigneeId + FROM PermissionSetAssignment + WHERE PermissionSetGroup.DeveloperName = :permsetGroupName + ) + ] + ); + return userMap; + } + @TestVisible + @SuppressWarnings('PMD.ApexCRUDViolation') + private Map initSkillIdMap() { + skillIdMap = new Map(); + for (Skill skill : [ + SELECT Id, DeveloperName + FROM Skill + WHERE DeveloperName = :FORTOLIG_ADDRESSE_SKILL OR DeveloperName = :SKJERMEDE_PERSONER_SKILL + ]) { + skillIdMap.put(skill.DeveloperName, skill.Id); + } + return skillIdMap; } /** - * @description: Initalizes the set og userIds who are member of the fortrolig and skjermet + * @description Initalizes the set og userIds who are member of the fortrolig and skjermet * @author Stian Ruud Schikora | 12-16-2021 **/ + @SuppressWarnings('PMD.ApexCRUDViolation') public void getGroupMembers() { for (GroupMember groupMember : [ SELECT UserOrGroupId, Group.DeveloperName FROM GroupMember - WHERE Group.DeveloperName IN :groupNamesToSync AND UserOrGroupId IN :nksUserMap.keySet() + WHERE + Group.DeveloperName IN (:fortroligGroupName, :skjermedeGroupName) + AND UserOrGroupId IN :userMap.keySet() ]) { String userOrGroupId = String.valueOf(GroupMember.UserOrGroupId); - if (groupMember.Group.DeveloperName == FORTROLIG_GROUP_NAME) { + if (groupMember.Group.DeveloperName == fortroligGroupName) { fortroligMembers.add(groupMember.UserOrGroupId); } else { skjermedeMembers.add(groupMember.UserOrGroupId); @@ -84,14 +79,18 @@ public with sharing class STO_GroupMemberSkillService { } /** - * @description: Initializes the set og userIds having the fortrolig and skjermet skill + * @description Initializes the set og userIds having the fortrolig and skjermet skill * @author Stian Ruud Schikora | 12-16-2021 **/ + @SuppressWarnings('PMD.ApexCRUDViolation') private void initSkillUserSets() { for (ServiceResourceSkill servSkill : [ SELECT Id, ServiceResourceId, Skill.DeveloperName FROM ServiceResourceSkill - WHERE Skill.DeveloperName = :FORTOLIG_ADDRESSE_SKILL OR Skill.DeveloperName = :SKJERMEDE_PERSONER_SKILL + WHERE + (Skill.DeveloperName = :FORTOLIG_ADDRESSE_SKILL + OR Skill.DeveloperName = :SKJERMEDE_PERSONER_SKILL) + AND ServiceResource.CRM_Domain__c = :srDomain ]) { if (servSkill.Skill.DeveloperName == FORTOLIG_ADDRESSE_SKILL) { fortroligSkillUsers.add(servSkill.ServiceResourceId); @@ -100,29 +99,34 @@ public with sharing class STO_GroupMemberSkillService { } } } - + /** + * @description Handles syncronization of users having a groupmember to the skills they have + */ public void handleGroupAndSkillSync() { + initUserMap(); + initSkillIdMap(); + getGroupMembers(); + initSkillUserSets(); //Ensures all NKS users have a related service resource created - Map userResourceMap = handleServiceResourceCreation(nksUserMap.keySet()); - handleSkillInsert(userResourceMap); + handleSkillInsert(); handleSkillDeletion(); } /** - * @description: Inserts new skills for group members who have not yet been assigned the skill. + * @description Inserts new skills for group members who have not yet been assigned the skill. * @author Stian Ruud Schikora | 12-16-2021 - * @param userResourceMap **/ - private void handleSkillInsert(Map userResourceMap) { + private void handleSkillInsert() { + Map userResourceMap = handleServiceResourceCreation(); List skillsToCreate = new List(); - for (Id memberId : this.fortroligMembers) { + for (Id memberId : fortroligMembers) { //If a userId in the fortrolig group is not contained in the fortroligSkillUser set, we need to ass the skill for that user if (!fortroligSkillUsers.contains(memberId)) { skillsToCreate.add(createSkill(skillIdMap.get(FORTOLIG_ADDRESSE_SKILL), userResourceMap.get(memberId))); } } - for (Id memberId : this.skjermedeMembers) { + for (Id memberId : skjermedeMembers) { //If a userId in the fortrolig group is not contained in the skjermedeSkillUsers set, we need to ass the skill for that user if (!skjermedeSkillUsers.contains(memberId)) { skillsToCreate.add( @@ -131,36 +135,38 @@ public with sharing class STO_GroupMemberSkillService { } } - if (!skillsToCreate.isEmpty() && !Test.isRunningTest()) { + if (!skillsToCreate.isEmpty()) { List saveResList = Database.insert(skillsToCreate, false); verifySkillinsert(saveResList); } } /** - * @description: Deletes the skill for all users who are no longer members og the synced groups + * @description Deletes the skill for all users who are no longer members og the synced groups * @author Stian Ruud Schikora | 12-16-2021 **/ + @SuppressWarnings('PMD.ApexCRUDViolation') private void handleSkillDeletion() { //Get list of skills to be deleted for users who are not longer members of the synced AD groups List skillsToDelete = [ SELECT Id, ServiceResourceId, Skill.DeveloperName FROM ServiceResourceSkill WHERE - (Skill.DeveloperName = :FORTOLIG_ADDRESSE_SKILL + ServiceResource.CRM_Domain__c = :srDomain + AND ((Skill.DeveloperName = :FORTOLIG_ADDRESSE_SKILL AND ServiceResource.RelatedRecordId NOT IN :fortroligMembers) OR (Skill.DeveloperName = :SKJERMEDE_PERSONER_SKILL - AND ServiceResource.RelatedRecordId NOT IN :skjermedeMembers) + AND ServiceResource.RelatedRecordId NOT IN :skjermedeMembers)) ]; - if (!skillsToDelete.isEmpty() && !Test.isRunningTest()) { + if (!skillsToDelete.isEmpty()) { List deleteResList = Database.delete(skillsToDelete, false); verifySkillRemoval(deleteResList); } } /** - * @description: Constructs a new ServiceResourceSkill record for the defined skill and service resource + * @description Constructs a new ServiceResourceSkill record for the defined skill and service resource * @author Stian Ruud Schikora | 12-16-2021 * @param skillId * @param servRes @@ -175,22 +181,19 @@ public with sharing class STO_GroupMemberSkillService { } /** - * @description: Asserts if there were any skill insert that failed and logs to application log + * @description Asserts if there were any skill insert that failed and logs to application log * If the service resource is assigned the skill already the insert will fail with the DUPLICATE_VALUE status code and thus not treated as an error * @author Stian Ruud Schikora | 12-15-2021 * @param saveResList **/ - @testVisible + @TestVisible private void verifySkillinsert(List saveResList) { for (Database.SaveResult saveRes : saveResList) { - if (saveRes.isSuccess()) { - //Successfully inserted skill for the resource - } else { + if (!saveRes.isSuccess()) { for (Database.Error err : saveRes.getErrors()) { - if (err.getStatusCode() == StatusCode.DUPLICATE_VALUE) { - //The resource is already assigned this skill - } else { - logger.error('Failed to create skill', null, CRM_ApplicationDomain.Domain.NKS); + //Skip already assigned skill + if (!(err.getStatusCode() == StatusCode.DUPLICATE_VALUE)) { + logger.error('Failed to create skill', null, CRM_ApplicationDomain.Domain.valueOf(srDomain)); } } } @@ -199,18 +202,20 @@ public with sharing class STO_GroupMemberSkillService { } /** - * @description: Asserts if there were any deletions that failed and logs to application log + * @description Asserts if there were any deletions that failed and logs to application log * @author Stian Ruud Schikora | 12-15-2021 * @param deleteResList **/ - @testVisible + @TestVisible private void verifySkillRemoval(List deleteResList) { for (Database.DeleteResult delRes : deleteResList) { - if (delRes.isSuccess()) { - //Successfully inserted skill for the resource - } else { + if (!delRes.isSuccess()) { for (Database.Error err : delRes.getErrors()) { - logger.error('Failed to create skill: ' + err.getMessage(), null, CRM_ApplicationDomain.Domain.NKS); + logger.error( + 'Failed to create skill: ' + err.getMessage(), + null, + CRM_ApplicationDomain.Domain.valueOf(srDomain) + ); } } } @@ -218,55 +223,106 @@ public with sharing class STO_GroupMemberSkillService { } /** - * @description: Creates service resources for users who do not already have a resource connected to their user + * @description Creates service resources for users who do not already have a resource connected to their user * Returns a map og userId -> ServiceResource * @author Stian Ruud Schikora | 12-15-2021 - * @param userIds * @return Map **/ - private Map handleServiceResourceCreation(Set userIds) { - Map userResourceMap = getServiceResources(userIds); + @SuppressWarnings('PMD.ApexCRUDViolation') + private Map handleServiceResourceCreation() { + Map userResourceMap = getServiceResources(); //If the resource map contains less keys than input userIds, we need to create serviceresources - if (userResourceMap.keySet().size() < userIds.size()) { - List resourcesToCreate = new List(); - for (User usr : [SELECT Id, Name FROM User WHERE Id IN :userIds]) { - if (!userResourceMap.containsKey(usr.Id)) { - resourcesToCreate.add( - new ServiceResource( - ResourceType = 'A', - RelatedRecordId = usr.Id, - Name = usr.Name, - IsActive = true - ) - ); - } - } - + Set usersWithoutSR = new Set(userMap.keySet()); + usersWithoutSR.removeAll(userResourceMap.keySet()); + List resourcesToCreate = new List(); + for (Id userId : usersWithoutSR) { + User usr = userMap.get(userId); + resourcesToCreate.add( + new ServiceResource( + ResourceType = 'A', + RelatedRecordId = usr.Id, + Name = usr.Name, + IsActive = true, + CRM_Domain__c = srDomain + ) + ); + } + if (resourcesToCreate.size() > 0) { insert resourcesToCreate; - //Adding the newly created resources to the return map - for (ServiceResource servRes : resourcesToCreate) { - userResourceMap.put(servRes.RelatedRecordId, servRes); - } + } + for (ServiceResource servRes : resourcesToCreate) { + userResourceMap.put(servRes.RelatedRecordId, servRes); } return userResourceMap; } /** - * @description: Returns a map of userIds to a ServiceResource record + * @description Returns a map of userIds to a ServiceResource record * @author Stian Ruud Schikora | 12-14-2021 * @return Map **/ - private Map getServiceResources(Set userIds) { + @SuppressWarnings('PMD.ApexCRUDViolation') + private Map getServiceResources() { Map userResourceMap = new Map(); for (ServiceResource servRes : [ - SELECT Id, RelatedRecordId + SELECT Id, RelatedRecordId, CRM_Domain__c FROM ServiceResource - WHERE RelatedRecordId IN :userIds AND ResourceType = 'A' + WHERE RelatedRecordId IN :userMap.keySet() AND CRM_Domain__c = :srDomain AND CRM_SubDomain__c = :srSubDomain ]) { userResourceMap.put(servRes.RelatedRecordId, servRes); } return userResourceMap; } + /** + * @description Executes handleGroupAndSkillSync from an external package(hot-servicetjenesten) + * @author Eugenijus Margalikas | 07.02.2025 + * @param action - `String` - Action to execute for now only `handleGroupAndSkillSync` + * @param args - `Map` where + * keys are domain,subdomain,permsetgroup,fortroliggroup,skjermedegroup + * @return Object + */ + public Object call(String action, Map args) { + switch on action.toLowerCase() { + when 'handlegroupandskillsync' { + setParams(args).handleGroupAndSkillSync(); + return 0; + } + when else { + throw new STO_SkillServiceMalformedCallException('Action: ' + action + ' is not implemented'); + } + } + } + @TestVisible + private STO_GroupMemberSkillService setParams(Map params) { + for (String key : params.keySet()) { + if (params.get(key) == null || !(params.get(key) instanceof String)) { + continue; + } + switch on key.toLowerCase() { + when 'domain' { + srDomain = (String) params.get(key); + } + when 'subdomain' { + srSubDomain = (String) params.get(key); + } + when 'permsetgroup' { + permsetGroupName = (String) params.get(key); + } + when 'fortroliggroup' { + fortroligGroupName = (String) params.get(key); + } + when 'skjermedegroup' { + skjermedeGroupName = (String) params.get(key); + } + } + } + return this; + } + /** + * @description Custom exception type for handling malformed calls. + */ + public class STO_SkillServiceMalformedCallException extends Exception { + } } diff --git a/force-app/main/default/classes/STO_GroupMemberSkillService_Test.cls b/force-app/main/default/classes/STO_GroupMemberSkillService_Test.cls index dc775d70..08d745c2 100644 --- a/force-app/main/default/classes/STO_GroupMemberSkillService_Test.cls +++ b/force-app/main/default/classes/STO_GroupMemberSkillService_Test.cls @@ -1,40 +1,277 @@ -@isTest +@IsTest public class STO_GroupMemberSkillService_Test { @TestSetup - static void makeData() { - Group fortroligGroup = TestDataFactory.getPublicGroup('group_AD_Fortrolig_Adresse', 'group_AD_Fortrolig_Adresse'); - Group skjermedeGroup = TestDataFactory.getPublicGroup('NKS_Skjermede_Personer_AD', 'NKS_Skjermede_Personer_AD'); + private static void makeData() { + myTriggers.disable(PersonAccessHandler.class); + myTriggers.disable(UserPermissionSetAssignmentHandler.class); + myTriggers.disable(UserDefaultValuesHandler.class); + myTriggers.disable(UserProfileHandler.class); + myTriggers.disable(UserGroupMemberHandler.class); + myTriggers.disable(UserRegionHandler.class); + myTriggers.disable(UserRoleAssignmentHandler.class); + Group fortroligGroup = TestDataFactory.getPublicGroup( + 'group_AD_Fortrolig_Adresse', + 'group_AD_Fortrolig_Adresse' + ); + Group nksSkjermedeGroup = TestDataFactory.getPublicGroup( + 'NKS_Skjermede_Personer_AD', + 'NKS_Skjermede_Personer_AD' + ); + Group skjermedeGroup = TestDataFactory.getPublicGroup('Skjermede_Personer_AD', 'Skjermede_Personer_AD'); //Adds the testuser as a member in both groups - User usr = (User) STO_TestDataFactory.createRecord(new User(FirstName = 'SUPER', LastName = 'SKILLED')); + User usr1 = (User) STO_TestDataFactory.createRecord(new User(FirstName = 'SUPER', LastName = 'SKILLED')); + User usr2 = (User) STO_TestDataFactory.createRecord(new User(FirstName = 'HOTST', LastName = 'HOTST')); List memberList = new List(); - memberList.add(new GroupMember(GroupId = fortroligGroup.Id, UserOrGroupId = usr.Id)); - memberList.add(new GroupMember(GroupId = skjermedeGroup.Id, UserOrGroupId = usr.Id)); + memberList.add(new GroupMember(GroupId = fortroligGroup.Id, UserOrGroupId = usr1.Id)); + memberList.add(new GroupMember(GroupId = nksSkjermedeGroup.Id, UserOrGroupId = usr1.Id)); + memberList.add(new GroupMember(GroupId = fortroligGroup.Id, UserOrGroupId = usr2.Id)); + memberList.add(new GroupMember(GroupId = skjermedeGroup.Id, UserOrGroupId = usr2.Id)); STO_TestDataFactory.createRecordList(memberList); + PermissionSetGroup kontaktsenterPSG; + PermissionSetGroup servicetjenestenPSG; + List psgs = [ + SELECT Id, DeveloperName + FROM PermissionSetGroup + WHERE DeveloperName IN ('Kontaktsenter', 'HOT_Servicetjenesten_Group') + ]; + for (PermissionSetGroup psg : psgs) { + if (psg.DeveloperName == 'Kontaktsenter') { + kontaktsenterPSG = psg; + } else if (psg.DeveloperName == 'HOT_Servicetjenesten_Group') { + servicetjenestenPSG = psg; + } + } + if (kontaktsenterPSG == null) { + kontaktsenterPSG = new PermissionSetGroup(MasterLabel = 'Kontaktsenter', DeveloperName = 'Kontaktsenter'); + insert kontaktsenterPSG; + } + if (servicetjenestenPSG == null) { + servicetjenestenPSG = new PermissionSetGroup( + MasterLabel = 'Servicetjenesten', + DeveloperName = 'HOT_Servicetjenesten_Group' + ); + insert servicetjenestenPSG; + } + PermissionSetAssignment psa1 = new PermissionSetAssignment( + AssigneeId = usr1.ID, + PermissionSetGroupId = kontaktsenterPSG.Id + ); + PermissionSetAssignment psa2 = new PermissionSetAssignment( + AssigneeId = usr2.ID, + PermissionSetGroupId = servicetjenestenPSG.Id + ); + insert new List{ psa1, psa2 }; + + if ( + [ + SELECT Id, DeveloperName + FROM Skill + WHERE DeveloperName = 'Fortrolig_addresse' + ] + .isEmpty() + ) { + Test.loadData(Skill.sObjectType, 'testFortroligSkill'); + } + if ( + [ + SELECT Id, DeveloperName + FROM Skill + WHERE DeveloperName = 'Skjermede_Personer' + ] + .isEmpty() + ) { + Test.loadData(Skill.sObjectType, 'testSkjermetSkill'); + } } - @isTest - static void testSkillCreate() { - User testUser = [SELECT Id, Name FROM User WHERE LastName = 'SKILLED']; - STO_GroupMemberSkillService.nksUserMap.clear(); - STO_GroupMemberSkillService.nksUserMap.put(testUser.Id, testUser); //Override the return of the map since the permission set group does not exist in this package + @IsTest + private static void nksServiceResourceWithSkillCreate() { STO_GroupMemberSkillService service = new STO_GroupMemberSkillService(); + System.assertEquals( + 2, + [ + SELECT COUNT() + FROM GroupMember + WHERE + UserOrGroupId IN (SELECT Id FROM User WHERE LastName = 'SKILLED') + AND Group.DeveloperName IN ( + 'group_AD_Fortrolig_Adresse', + 'NKS_Skjermede_Personer_AD', + 'Skjermede_Personer_AD' + ) + ], + 'Expected 2 groups for NKS user' + ); + Test.startTest(); + service.handleGroupAndSkillSync(); + Test.stopTest(); + System.assertEquals( + 1, + [SELECT COUNT() FROM ServiceResource WHERE RelatedRecord.LastName = 'SKILLED'], + 'Expected serviceresource for NKS user' + ); + System.assertEquals( + 0, + [SELECT COUNT() FROM ServiceResource WHERE RelatedRecord.LastName = 'HOTST'], + 'Expected no serviceresource for HOT user' + ); + + ServiceResource nksSR = [ + SELECT Id, RelatedRecordId, CRM_Domain__c + FROM ServiceResource + WHERE RelatedRecord.LastName = 'SKILLED' + LIMIT 1 + ]; + System.assertEquals( + 2, + [ + SELECT COUNT() + FROM ServiceResourceSkill + WHERE ServiceResourceId = :nksSR.Id + ], + 'Expected 2 skills for NKS user' + ); + } + @IsTest + private static void hotServiceResourceWithSkillCreate() { + STO_GroupMemberSkillService service = new STO_GroupMemberSkillService(); + service.setParams( + new Map{ + 'domain' => 'HOT', + 'subdomain' => 'Servicetjenesten', + 'permsetgroup' => 'HOT_Servicetjenesten_Group', + 'fortroliggroup' => 'group_AD_Fortrolig_Adresse', + 'skjermedegroup' => 'Skjermede_Personer_AD' + } + ); + System.assertEquals( + 2, + [ + SELECT COUNT() + FROM GroupMember + WHERE + UserOrGroupId IN (SELECT Id FROM User WHERE LastName = 'HOTST') + AND Group.DeveloperName IN ( + 'group_AD_Fortrolig_Adresse', + 'NKS_Skjermede_Personer_AD', + 'Skjermede_Personer_AD' + ) + ], + 'Expected 2 groups for HOT users' + ); Test.startTest(); service.handleGroupAndSkillSync(); Test.stopTest(); - System.assertEquals(1, [SELECT COUNT() FROM ServiceResource]); + System.assertEquals( + 1, + [SELECT COUNT() FROM ServiceResource WHERE RelatedRecord.LastName = 'HOTST'], + 'Expected serviceresource for HOT user' + ); + System.assertEquals( + 0, + [SELECT COUNT() FROM ServiceResource WHERE RelatedRecord.LastName = 'SKILLED'], + 'Expected no serviceresource for NKS user' + ); + + ServiceResource hotSR = [ + SELECT Id, RelatedRecordId, RelatedRecord.LastName, CRM_Domain__c + FROM ServiceResource + WHERE RelatedRecord.LastName = 'HOTST' + LIMIT 1 + ]; + System.assertEquals('HOT', hotSR.CRM_Domain__c, 'Expected HOT domain'); + System.assertEquals( + 2, + [ + SELECT COUNT() + FROM ServiceResourceSkill + WHERE ServiceResourceId = :hotSR.Id + ], + 'Expected 2 skills for HOT user' + ); } - @isTest - static void testSkillRemove() { + @IsTest + private static void callableSync() { + System.assertEquals( + 2, + [ + SELECT COUNT() + FROM GroupMember + WHERE + UserOrGroupId IN (SELECT Id FROM User WHERE LastName = 'HOTST') + AND Group.DeveloperName IN ( + 'group_AD_Fortrolig_Adresse', + 'NKS_Skjermede_Personer_AD', + 'Skjermede_Personer_AD' + ) + ], + 'Expected 2 groups for HOT users' + ); + Test.startTest(); + try { + Callable syncService = (Callable) Type.forName('STO_GroupMemberSkillService').newInstance(); + syncService.call( + 'handleGroupAndSkillSync', + new Map{ + 'domain' => 'HOT', + 'subdomain' => 'Servicetjenesten', + 'permsetgroup' => 'HOT_Servicetjenesten_Group', + 'fortroliggroup' => 'group_AD_Fortrolig_Adresse', + 'skjermedegroup' => 'Skjermede_Personer_AD' + } + ); + } catch (Exception e) { + System.Assert.isTrue(false, 'Could not call callable class' + e.getMessage()); + } + Test.stopTest(); + + System.assertEquals( + 1, + [SELECT COUNT() FROM ServiceResource WHERE RelatedRecord.LastName = 'HOTST'], + 'Expected serviceresource for HOT user' + ); + System.assertEquals( + 0, + [SELECT COUNT() FROM ServiceResource WHERE RelatedRecord.LastName = 'SKILLED'], + 'Expected no serviceresource for NKS user' + ); + + ServiceResource hotSR = [ + SELECT Id, RelatedRecordId, RelatedRecord.LastName, CRM_Domain__c + FROM ServiceResource + WHERE RelatedRecord.LastName = 'HOTST' + LIMIT 1 + ]; + System.assertEquals('HOT', hotSR.CRM_Domain__c, 'Expected HOT domain'); + System.assertEquals( + 2, + [ + SELECT COUNT() + FROM ServiceResourceSkill + WHERE ServiceResourceId = :hotSR.Id + ], + 'Expected 2 skills for HOT user' + ); + } + + @IsTest + private static void testSkillRemove() { User testUser = [SELECT Id, Name FROM User WHERE LastName = 'SKILLED']; - STO_GroupMemberSkillService.nksUserMap.clear(); - STO_GroupMemberSkillService.nksUserMap.put(testUser.Id, testUser); //Override the return of the map since the permission set group does not exist in this package STO_GroupMemberSkillService service = new STO_GroupMemberSkillService(); service.handleGroupAndSkillSync(); - + System.assertEquals( + 2, + [ + SELECT COUNT() + FROM ServiceResourceSkill + WHERE ServiceResource.RelatedRecordId = :testUser.Id + ], + 'Expected 2 skills for NKS user' + ); Test.startTest(); //Removing from the skjermede group removeFromGroup(testUser.Id, 'NKS_Skjermede_Personer_AD'); @@ -42,10 +279,19 @@ public class STO_GroupMemberSkillService_Test { //Create new service as the memberlist have changed STO_GroupMemberSkillService service2 = new STO_GroupMemberSkillService(); service2.handleGroupAndSkillSync(); + System.assertEquals( + 1, + [ + SELECT COUNT() + FROM ServiceResourceSkill + WHERE ServiceResource.RelatedRecordId = :testUser.Id + ], + 'Expected 1 skills for NKS user' + ); } - @isTest - static void testDmlVerification() { + @IsTest + private static void testDmlVerification() { Account testAcc = new Account(Name = 'Test Account'); User testUser = [SELECT Id, Name FROM User WHERE LastName = 'SKILLED']; List saveResList = Database.insert(new List{ testAcc, testUser }, false); @@ -60,10 +306,9 @@ public class STO_GroupMemberSkillService_Test { service.verifySkillRemoval(deleteResList); Test.stopTest(); - System.assertEquals(2, [SELECT COUNT() FROM Application_Log__c]); //Two errors should be logged + System.assertEquals(2, [SELECT COUNT() FROM Application_Log__c], 'Two errors should be logged'); } - - @future + @Future private static void removeFromGroup(Id userId, String groupDevName) { delete [SELECT Id FROM GroupMember WHERE UserOrGroupId = :userId AND Group.DeveloperName = :groupDevName]; } diff --git a/force-app/main/default/staticresources/testFortroligSkill.csv b/force-app/main/default/staticresources/testFortroligSkill.csv new file mode 100644 index 00000000..d13bf28e --- /dev/null +++ b/force-app/main/default/staticresources/testFortroligSkill.csv @@ -0,0 +1,2 @@ +DeveloperName,MasterLabel +Fortrolig_addresse,Fortrolig \ No newline at end of file diff --git a/force-app/main/default/staticresources/testFortroligSkill.resource-meta.xml b/force-app/main/default/staticresources/testFortroligSkill.resource-meta.xml new file mode 100644 index 00000000..14c796fa --- /dev/null +++ b/force-app/main/default/staticresources/testFortroligSkill.resource-meta.xml @@ -0,0 +1,4 @@ + + + text/csv + \ No newline at end of file diff --git a/force-app/main/default/staticresources/testSkjermetSkill.csv b/force-app/main/default/staticresources/testSkjermetSkill.csv new file mode 100644 index 00000000..c8839efe --- /dev/null +++ b/force-app/main/default/staticresources/testSkjermetSkill.csv @@ -0,0 +1,2 @@ +DeveloperName,MasterLabel +Skjermede_personer,Skjermet \ No newline at end of file diff --git a/force-app/main/default/staticresources/testSkjermetSkill.resource-meta.xml b/force-app/main/default/staticresources/testSkjermetSkill.resource-meta.xml new file mode 100644 index 00000000..14c796fa --- /dev/null +++ b/force-app/main/default/staticresources/testSkjermetSkill.resource-meta.xml @@ -0,0 +1,4 @@ + + + text/csv + \ No newline at end of file diff --git a/ruleset.xml b/ruleset.xml deleted file mode 100644 index 29d468a0..00000000 --- a/ruleset.xml +++ /dev/null @@ -1,292 +0,0 @@ - - - Default ruleset used by the Code Climate Engine for Salesforce.com Apex - .*/.sfdx/.* - - - 3 - - - - - - 3 - - - - - - - 3 - - - - - - 3 - - - - - - 3 - - - - - - 3 - - - - - - 3 - - - - - - 3 - - - - - - 3 - - - - - - 3 - - - - - - 3 - - - - 3 - - - - 3 - - - - 3 - - - - 3 - - - - 3 - - - - - - - 3 - - - - - - 3 - - - - 3 - - - - 3 - - - - 3 - - - - - - 4 - - - 4 - - - 3 - - - - 3 - - - - - - 3 - - - - 3 - - - - 3 - - - - 3 - - - - 3 - - - - 3 - - - - 3 - - - - 3 - - - - - 3 - - - - 3 - - - - - - 3 - - - - 3 - - - - 3 - - - - 3 - - - - - - 3 - - - - 3 - - - - 3 - - - - 3 - - - - 3 - - - - - - 3 - - - - - - 3 - - - - 3 - - diff --git a/sfdx-project.json b/sfdx-project.json index 60474308..d047c674 100644 --- a/sfdx-project.json +++ b/sfdx-project.json @@ -9,7 +9,7 @@ "dependencies": [ { "package": "crm-platform-base", - "versionNumber": "0.226.0.LATEST" + "versionNumber": "0.240.0.LATEST" }, { "package": "crm-platform-reporting", @@ -114,4 +114,4 @@ "crm-thread-view": "0Ho7U000000000zSAA", "crm-nks-integration": "0Ho2o000000fxX6CAI" } -} +} \ No newline at end of file