diff --git a/.gitignore b/.gitignore index 75a96fbfc..577fc12bb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ # Salesforce / SFDX / CCI .cci .sfdx +.sf /src.orig /src diff --git a/README.md b/README.md index 6b8f2de8d..69ba36bfb 100644 --- a/README.md +++ b/README.md @@ -27,4 +27,3 @@ PMM AND SFDO BASE ARE NON-SFDC APPLICATIONS OR THIRD-PARTY APPLICATIONS, AND NOT SFDC WILL NOT HAVE ANY LIABILITY ARISING OUT OF OR RELATED TO YOUR USE OF PMM OR SFDO BASE FOR ANY DIRECT DAMAGES OR FOR ANY LOST PROFITS, REVENUES, GOODWILL OR INDIRECT, SPECIAL, INCIDENTAL, CONSEQUENTIAL, EXEMPLARY, COVER, BUSINESS INTERRUPTION OR PUNITIVE DAMAGES, WHETHER AN ACTION IS IN CONTRACT OR TORT AND REGARDLESS OF THE THEORY OF LIABILITY, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES OR IF A REMEDY OTHERWISE FAILS OF ITS ESSENTIAL PURPOSE. THE FOREGOING DISCLAIMER WILL NOT APPLY TO THE EXTENT PROHIBITED BY LAW. SFDC DISCLAIMS ALL LIABILITY AND INDEMNIFICATION OBLIGATIONS FOR ANY HARM OR DAMAGES CAUSED BY ANY THIRD-PARTY HOSTING PROVIDERS. THIS AGREEMENT SHALL BE GOVERNED EXCLUSIVELY BY, AND CONSTRUED EXCLUSIVELY IN ACCORDANCE WITH, THE LAWS OF THE UNITED STATES AND THE STATE OF CALIFORNIA, WITHOUT REGARD TO ITS CONFLICT OF LAWS PROVISIONS. THE STATE AND FEDERAL COURTS LOCATED IN SAN FRANCISCO, CALIFORNIA SHALL HAVE EXCLUSIVE JURISDICTION TO ADJUDICATE ANY DISPUTE ARISING OUT OF OR RELATING TO THIS AGREEMENT. EACH PARTY HEREBY CONSENTS TO THE JURISDICTION OF SUCH COURTS AND WAIVES ANY RIGHT IT MAY OTHERWISE HAVE TO CHALLENGE THE APPROPRIATENESS OF SUCH FORUMS. - diff --git a/force-app/main/default/classes/ProgramEngagementSelector.cls b/force-app/main/default/classes/ProgramEngagementSelector.cls index 2e5894d7f..5ac052935 100755 --- a/force-app/main/default/classes/ProgramEngagementSelector.cls +++ b/force-app/main/default/classes/ProgramEngagementSelector.cls @@ -22,11 +22,11 @@ public with sharing class ProgramEngagementSelector { } List queriedEngagements = [ - SELECT Id, Name, Program__c, Program__r.Name + SELECT Id, Name, Program__c, Program__r.Name, Stage__c FROM ProgramEngagement__c WHERE Contact__c = :contactId ]; - + queriedEngagements.sort(); return Security.stripInaccessible(AccessType.READABLE, queriedEngagements) .getRecords(); } diff --git a/force-app/main/default/classes/ProgramSelector.cls b/force-app/main/default/classes/ProgramSelector.cls index d9391c411..b0e48e172 100644 --- a/force-app/main/default/classes/ProgramSelector.cls +++ b/force-app/main/default/classes/ProgramSelector.cls @@ -41,9 +41,8 @@ public with sharing class ProgramSelector { ' IN :allowedProgramCohortStatuses' ); } - programCohorts = Database.query(queryBuilder.buildSoqlQuery()); - + programCohorts.sort(); return Security.stripInaccessible(AccessType.READABLE, programCohorts) .getRecords(); } diff --git a/force-app/main/default/classes/ServiceSelector.cls b/force-app/main/default/classes/ServiceSelector.cls index 09e15c255..b1fa15381 100755 --- a/force-app/main/default/classes/ServiceSelector.cls +++ b/force-app/main/default/classes/ServiceSelector.cls @@ -16,11 +16,11 @@ public with sharing class ServiceSelector { return new List(); } List queriedServices = [ - SELECT Id, Name, Program__c + SELECT Id, Name, Program__c, Status__c FROM Service__c WHERE Program__c IN :programIds ]; - + queriedServices.sort(); return Security.stripInaccessible(AccessType.READABLE, queriedServices) .getRecords(); } @@ -40,7 +40,7 @@ public with sharing class ServiceSelector { WHERE Id = :programEngagementId ) ]; - + services.sort(); return Security.stripInaccessible(AccessType.READABLE, services).getRecords(); } diff --git a/force-app/main/default/classes/ServiceService.cls b/force-app/main/default/classes/ServiceService.cls index 0f6d4c778..2baf2ea1c 100644 --- a/force-app/main/default/classes/ServiceService.cls +++ b/force-app/main/default/classes/ServiceService.cls @@ -11,36 +11,118 @@ public with sharing class ServiceService { public ServiceService() { } + private static final String SERVICE_STATUS_ACTIVE = 'ServiceStatusActive'; + private static final String ENGAGEMENTS = 'engagements'; + private static final String SERVICES = 'services'; + private static final String LABEL = 'label'; + private static final String VALUE = 'value'; + private static final String NAME = 'Name'; + private static final String Id = 'Id'; + private static final String PROGRAM = 'program'; + private static final String BSDT_ACTIVE_FILTER = 'BSDTActiveFilter'; + + @TestVisible + private FieldBucketSelector bucketSelector = new FieldBucketSelector(); + @TestVisible private FieldSetService fieldSetService = new FieldSetService(); @TestVisible private ServiceSelector serviceSelector = new ServiceSelector(); + @TestVisible + private ProgramEngagementService engagementService = new ProgramEngagementService(); + @TestVisible private ProgramEngagementSelector engagementSelector = new ProgramEngagementSelector(); + @TestVisible + private Set activeStatuses { + get { + if (activeStatuses == null) { + activeStatuses = getActiveStatuses(); + } + return activeStatuses; + } + set; + } + + private Set getActiveStatuses() { + List bucketNames = new List{ SERVICE_STATUS_ACTIVE }; + Set activeStatuses = new Set(); + + Schema.SObjectType serviceSObjType = Service__c.SObjectType; + Schema.SObjectField statusField = Service__c.Status__c; + + for ( + Bucket__mdt bucket : bucketSelector.getBuckets( + bucketNames, + serviceSObjType, + statusField + ) + ) { + for (BucketedValue__mdt value : bucket.BucketedValues__r) { + activeStatuses.add(value.Value__c); + } + } + + return activeStatuses; + } + + private Boolean isBsdtActiveFilterActive() { + List features = CustomMetadataSelector.getInstance() + .getAllFeatureGates(); + + for (FeatureGate__mdt feature : features) { + if ( + feature.IsActive__c && BSDT_ACTIVE_FILTER.contains(feature.DeveloperName) + ) { + return feature.IsActive__c; + } + } + + return false; + } + public Map> getServicesEngagementsByContactId(Id contactId) { Set programIds = new Set(); String serviceProgram = Schema.SObjectType.Service__c.Fields.Program__c.getName(); String engageProgram = Schema.SObjectType.ProgramEngagement__c.Fields.Program__c.getName(); + Set activeServiceStatuses = new Set(); + Set activeProgramEngagementStages = new Set(); + Boolean bsdtFilterIsActive = isBsdtActiveFilterActive(); + + if (bsdtFilterIsActive) { + activeServiceStatuses = activeStatuses; + activeProgramEngagementStages = engagementService.getActiveStages(); + } Map> result = new Map>(); - result.put('engagements', new List()); - result.put('services', new List()); + result.put(ENGAGEMENTS, new List()); + result.put(SERVICES, new List()); for ( ProgramEngagement__c engagement : engagementSelector.getProgramEngagementsByContactId( contactId ) ) { - programIds.add(engagement.Program__c); - result.get('engagements') - .add(convertObjectToOption(engagement, engageProgram)); + if ( + activeProgramEngagementStages.isEmpty() || + activeProgramEngagementStages.contains(engagement.Stage__c) + ) { + programIds.add(engagement.Program__c); + result.get(ENGAGEMENTS) + .add(convertObjectToOption(engagement, engageProgram)); + } } for (Service__c service : serviceSelector.getServicesByProgramIds(programIds)) { - result.get('services').add(convertObjectToOption(service, serviceProgram)); + if ( + activeServiceStatuses.isEmpty() || + activeServiceStatuses.contains(service.Status__c) + ) { + result.get(SERVICES).add(convertObjectToOption(service, serviceProgram)); + } } return result; @@ -48,9 +130,9 @@ public with sharing class ServiceService { private Map convertObjectToOption(sObject obj, String programField) { Map result = new Map(); - result.put('label', (String) obj.get('Name')); - result.put('value', (String) obj.get('Id')); - result.put('program', (String) obj.get(programField)); + result.put(LABEL, (String) obj.get(NAME)); + result.put(VALUE, (String) obj.get(ID)); + result.put(PROGRAM, (String) obj.get(programField)); return result; } diff --git a/force-app/main/default/classes/ServiceService_TEST.cls b/force-app/main/default/classes/ServiceService_TEST.cls index 51aad9973..05ceb8e23 100644 --- a/force-app/main/default/classes/ServiceService_TEST.cls +++ b/force-app/main/default/classes/ServiceService_TEST.cls @@ -10,7 +10,7 @@ @isTest public with sharing class ServiceService_TEST { @IsTest - private static void testGetServicesEngagementsByContactId() { + private static void testGetServicesEngagementsByContactIdFeatureOn() { Id contactId = TestUtil.mockId(Contact.SObjectType); Program__c program1 = new Program__c( @@ -23,6 +23,14 @@ public with sharing class ServiceService_TEST { ProgramEngagement__c engagement1 = new ProgramEngagement__c( Name = 'Engagement 1', + Stage__c = 'Active', + Contact__c = contactId, + Program__c = program1.Id, + Role__c = 'Client' + ); + + ProgramEngagement__c engagement2 = new ProgramEngagement__c( + Name = 'Engagement 2', Stage__c = 'Enrolled', Contact__c = contactId, Program__c = program1.Id, @@ -37,10 +45,155 @@ public with sharing class ServiceService_TEST { UnitOfMeasurement__c = 'Hours' ); + Service__c service2 = new Service__c( + Id = TestUtil.mockId(Service__c.SObjectType), + Name = 'Service 2', + Program__c = program1.Id, + Status__c = 'Planned', + UnitOfMeasurement__c = 'Hours' + ); + List engagements = new List{ - engagement1 + engagement1, + engagement2 }; - List services = new List{ service1 }; + List services = new List{ service1, service2 }; + List bucketNames = new List{ 'ServiceStatusActive' }; + Schema.SObjectType serviceSObjType = Service__c.SObjectType; + Schema.SObjectField statusField = Service__c.Status__c; + List statusBuckets = createBuckets(); + Set activeStages = new Set{ 'Active' }; + + TestStub engagementServiceStub = new StubBuilder(ProgramEngagementService.class) + .when('getActiveStages') + .called() + .thenReturn(activeStages) + .build(); + TestStub engagementSelectorStub = new StubBuilder(ProgramEngagementSelector.class) + .when('getProgramEngagementsByContactId', Id.class) + .calledWith(contactId) + .thenReturn(engagements) + .build(); + TestStub serviceSelectorStub = new StubBuilder(ServiceSelector.class) + .when('getServicesByProgramIds', Set.class) + .calledWith(new Set{ program1.Id }) + .thenReturn(services) + .build(); + TestStub bucketSelectorStub = new StubBuilder(FieldBucketSelector.class) + .when( + 'getBuckets', + List.class, + Schema.SObjectType.class, + Schema.SObjectField.class + ) + .calledWith(bucketNames, serviceSObjType, statusField) + .thenReturn(statusBuckets) + .build(); + + ServiceService service = new ServiceService(); + service.serviceSelector = (ServiceSelector) serviceSelectorStub.create(); + service.engagementSelector = (ProgramEngagementSelector) engagementSelectorStub.create(); + service.bucketSelector = (FieldBucketSelector) bucketSelectorStub.create(); + service.engagementService = (ProgramEngagementService) engagementServiceStub.create(); + + // By turning off none, we turn on all + TestUtil.turnOffFeatureGates(new Set{}); + + Test.startTest(); + Map> actual = service.getServicesEngagementsByContactId( + contactId + ); + Test.stopTest(); + + Set expectedKeySet = new Set{ 'engagements', 'services' }; + System.assertEquals( + expectedKeySet, + actual.keySet(), + 'Expected both keys to be returned.' + ); + + for (List objList : actual.values()) { + System.assert(!objList.isEmpty()); + } + + System.assertEquals( + 1, + actual.get('engagements').size(), + 'Only active Program Engagements should be returned' + ); + + System.assertEquals( + 1, + actual.get('services').size(), + 'Only active Services should be returned' + ); + + engagementSelectorStub.assertCalledAsExpected(); + serviceSelectorStub.assertCalledAsExpected(); + bucketSelectorStub.assertCalledAsExpected(); + } + + @IsTest + private static void testGetServicesEngagementsByContactIdFeatureOff() { + final String BSDT_ACTIVE_FILTER = 'BSDTActiveFilter'; + Id contactId = TestUtil.mockId(Contact.SObjectType); + + Program__c program1 = new Program__c( + Id = TestUtil.mockId(Program__c.SObjectType), + Name = 'Program 1', + Status__c = 'Active', + StartDate__c = Date.today(), + EndDate__c = Date.today().addDays(30) + ); + + ProgramEngagement__c engagement1 = new ProgramEngagement__c( + Name = 'Engagement 1', + Stage__c = 'Active', + Contact__c = contactId, + Program__c = program1.Id, + Role__c = 'Client' + ); + + ProgramEngagement__c engagement2 = new ProgramEngagement__c( + Name = 'Engagement 2', + Stage__c = 'Enrolled', + Contact__c = contactId, + Program__c = program1.Id, + Role__c = 'Client' + ); + + Service__c service1 = new Service__c( + Id = TestUtil.mockId(Service__c.SObjectType), + Name = 'Service 1', + Program__c = program1.Id, + Status__c = 'Active', + UnitOfMeasurement__c = 'Hours' + ); + + Service__c service2 = new Service__c( + Id = TestUtil.mockId(Service__c.SObjectType), + Name = 'Service 2', + Program__c = program1.Id, + Status__c = 'Planned', + UnitOfMeasurement__c = 'Hours' + ); + + List engagements = new List{ + engagement1, + engagement2 + }; + List services = new List{ service1, service2 }; + List bucketNames = new List{ 'ServiceStatusActive' }; + Schema.SObjectType serviceSObjType = Service__c.SObjectType; + Schema.SObjectField statusField = Service__c.Status__c; + List statusBuckets = createBuckets(); + Set activeStages = new Set{ 'Active' }; + + TestStub engagementServiceStub = new StubBuilder(ProgramEngagementService.class) + .when('getActiveStages') + .called() + .thenReturn(activeStages) + .build(); TestStub engagementSelectorStub = new StubBuilder(ProgramEngagementSelector.class) .when('getProgramEngagementsByContactId', Id.class) .calledWith(contactId) @@ -51,10 +204,24 @@ public with sharing class ServiceService_TEST { .calledWith(new Set{ program1.Id }) .thenReturn(services) .build(); + TestStub bucketSelectorStub = new StubBuilder(FieldBucketSelector.class) + .when( + 'getBuckets', + List.class, + Schema.SObjectType.class, + Schema.SObjectField.class + ) + .calledWith(bucketNames, serviceSObjType, statusField) + .thenReturn(statusBuckets) + .build(); ServiceService service = new ServiceService(); service.serviceSelector = (ServiceSelector) serviceSelectorStub.create(); service.engagementSelector = (ProgramEngagementSelector) engagementSelectorStub.create(); + service.bucketSelector = (FieldBucketSelector) bucketSelectorStub.create(); + service.engagementService = (ProgramEngagementService) engagementServiceStub.create(); + + TestUtil.turnOffFeatureGates(new Set{ BSDT_ACTIVE_FILTER }); Test.startTest(); Map> actual = service.getServicesEngagementsByContactId( @@ -73,6 +240,18 @@ public with sharing class ServiceService_TEST { System.assert(!objList.isEmpty()); } + System.assertEquals( + 2, + actual.get('engagements').size(), + 'All Program Engagements should be returned' + ); + + System.assertEquals( + 2, + actual.get('services').size(), + 'All Services should be returned' + ); + engagementSelectorStub.assertCalledAsExpected(); serviceSelectorStub.assertCalledAsExpected(); } @@ -701,4 +880,35 @@ public with sharing class ServiceService_TEST { fieldSetServiceStub.assertCalledAsExpected(); } + + private static List createBuckets() { + BucketedField__mdt bucketedField = (BucketedField__mdt) new TestUtil.BucketedFieldBuilder() + .withDeveloperName('ServiceStatuses') + .withQualifiedApiName(Util.prefixNamespace('ServiceStatuses')) + .withField('Status__c') + .withObject('Service__c') + .withMockId() + .build(); + + List activeValues = new List(); + activeValues.add( + (BucketedValue__mdt) new TestUtil.BucketedValueBuilder() + .withDeveloperName('ServiceStatusActive') + .withQualifiedApiName(Util.prefixNamespace('ServiceStatusActive')) + .withBucket('ServiceStatusActive') + .withValue('Active') + .withMockId() + .build() + ); + + Bucket__mdt activeBucket = (Bucket__mdt) new TestUtil.BucketBuilder() + .withBucketedField(bucketedField) + .withBucketedValues(activeValues) + .withDeveloperName('ServiceStatusActive') + .withQualifiedApiName(Util.prefixNamespace('ServiceStatusActive')) + .withMockId() + .build(); + + return new List{ activeBucket }; + } } diff --git a/force-app/main/default/classes/TestUtil.cls b/force-app/main/default/classes/TestUtil.cls index ad1ab1073..aff65f9aa 100755 --- a/force-app/main/default/classes/TestUtil.cls +++ b/force-app/main/default/classes/TestUtil.cls @@ -13,6 +13,7 @@ */ public with sharing class TestUtil { private static final Set featureGateNames = new Set{ + 'BSDTActiveFilter', 'ServiceDeliveriesToContact', 'ServiceDeliveriesToService', 'ServiceDeliveriesToServiceSession', diff --git a/force-app/main/default/customMetadata/Bucket.ServiceStatusActive.md-meta.xml b/force-app/main/default/customMetadata/Bucket.ServiceStatusActive.md-meta.xml new file mode 100644 index 000000000..361af2506 --- /dev/null +++ b/force-app/main/default/customMetadata/Bucket.ServiceStatusActive.md-meta.xml @@ -0,0 +1,9 @@ + + + + false + + BucketedField__c + ServiceStatuses + + diff --git a/force-app/main/default/customMetadata/BucketedField.ServiceStatuses.md-meta.xml b/force-app/main/default/customMetadata/BucketedField.ServiceStatuses.md-meta.xml new file mode 100644 index 000000000..030117da0 --- /dev/null +++ b/force-app/main/default/customMetadata/BucketedField.ServiceStatuses.md-meta.xml @@ -0,0 +1,13 @@ + + + + false + + Field__c + Status__c + + + Object__c + Service__c + + diff --git a/force-app/main/default/customMetadata/BucketedValue.ServiceStatusActive.md-meta.xml b/force-app/main/default/customMetadata/BucketedValue.ServiceStatusActive.md-meta.xml new file mode 100644 index 000000000..9b409ac87 --- /dev/null +++ b/force-app/main/default/customMetadata/BucketedValue.ServiceStatusActive.md-meta.xml @@ -0,0 +1,13 @@ + + + + false + + Bucket__c + ServiceStatusActive + + + Value__c + Active + + diff --git a/force-app/main/default/customMetadata/FeatureGate.BSDTActiveFilter.md-meta.xml b/force-app/main/default/customMetadata/FeatureGate.BSDTActiveFilter.md-meta.xml new file mode 100644 index 000000000..79917bd92 --- /dev/null +++ b/force-app/main/default/customMetadata/FeatureGate.BSDTActiveFilter.md-meta.xml @@ -0,0 +1,9 @@ + + + + false + + IsActive__c + false + + diff --git a/force-app/main/default/lwc/bulkServiceDeliveryUI/bulkServiceDeliveryUI.js b/force-app/main/default/lwc/bulkServiceDeliveryUI/bulkServiceDeliveryUI.js index c77cd8be4..191efe86a 100644 --- a/force-app/main/default/lwc/bulkServiceDeliveryUI/bulkServiceDeliveryUI.js +++ b/force-app/main/default/lwc/bulkServiceDeliveryUI/bulkServiceDeliveryUI.js @@ -180,6 +180,10 @@ export default class BulkServiceDeliveryUI extends NavigationMixin(LightningElem return "error"; } + get isSaveDisabled() { + return this.isSaving; + } + addDelivery() { let serviceDelivery = { index: this._nextIndex, @@ -221,9 +225,9 @@ export default class BulkServiceDeliveryUI extends NavigationMixin(LightningElem // eslint-disable-next-line no-unused-vars handleRowError(event) { this.errorCount++; - if (this.savingComplete()) { this.showSaveSummaryToast(); + this.isSaving = false; } } @@ -241,6 +245,7 @@ export default class BulkServiceDeliveryUI extends NavigationMixin(LightningElem } if (row.isDirty) { this.currentSaveCount++; + this.isSaving = true; } row.saveRow(); }); @@ -256,6 +261,7 @@ export default class BulkServiceDeliveryUI extends NavigationMixin(LightningElem if (this.savingComplete()) { this.showSaveSummaryToast(); + this.isSaving = false; } if (this.savedCount === this.targetSaveCount) { diff --git a/force-app/main/default/lwc/serviceScheduleCreator/serviceScheduleCreator.js b/force-app/main/default/lwc/serviceScheduleCreator/serviceScheduleCreator.js index dd7eba3ac..7297d8a68 100644 --- a/force-app/main/default/lwc/serviceScheduleCreator/serviceScheduleCreator.js +++ b/force-app/main/default/lwc/serviceScheduleCreator/serviceScheduleCreator.js @@ -354,8 +354,8 @@ export default class ServiceScheduleCreator extends NavigationMixin(LightningEle this.navigate(); } else { this.init(); + this.dispatchEvent(new CustomEvent("close", { bubbles: true })); } - this.dispatchEvent(new CustomEvent("close", { bubbles: true })); } reset() { diff --git a/robot/pmm/resources/pmm.py b/robot/pmm/resources/pmm.py index df26bcf53..b00f991a5 100644 --- a/robot/pmm/resources/pmm.py +++ b/robot/pmm/resources/pmm.py @@ -348,6 +348,7 @@ def click_dialog_button(self, label): self.selenium.wait_until_element_is_enabled( locator, error="Button is not enabled" ) + self.scroll_element_into_view(locator) self.selenium.set_focus_to_element(locator) element = self.selenium.driver.find_element_by_xpath(locator) self.selenium.driver.execute_script("arguments[0].click()", element) @@ -527,6 +528,7 @@ def manage_records_bucketed_value(self): def click_custom_metadata_button(self, button): """Clicks on a button within the custom metadata iFrame""" + time.sleep(3) if button == "New": locator = pmm_lex_locators["custom_metadata_button"].format(button) self.select_frame_with_value( diff --git a/robot/pmm/tests/browser/Attendance/update_attendance.robot b/robot/pmm/tests/browser/Attendance/update_attendance.robot index 75fe0a6ce..626798cd7 100644 --- a/robot/pmm/tests/browser/Attendance/update_attendance.robot +++ b/robot/pmm/tests/browser/Attendance/update_attendance.robot @@ -48,7 +48,7 @@ Setup Test Data UA1: Update attendance when service session status is Pending [Documentation] This test updates attendance for a service session record with Pending Status [tags] W-8607484 perm:admin perm:manage feature:Attendance - Go To Page Details ServiceSession__c object_id=${service_session1}[Id] + Go To Page Details ServiceSession__c quadrant:Q2 object_id=${service_session1}[Id] Populate Attendance Field ${contact1}[Name] Hours 10 Populate Attendance Dropdown ${contact1}[Name] Attendance Status Present Populate Attendance Field ${contact2}[Name] Hours 10 @@ -66,7 +66,7 @@ UA1: Update attendance when service session status is Pending UA2: Update attendance when service session status is Complete [Documentation] This test updates attendance for a service session record with Complete Status - [tags] W-8611541 perm:admin perm:manage feature:Attendance + [tags] W-8611541 perm:admin perm:manage quadrant:Q2 feature:Attendance Go To Page Details ServiceSession__c object_id=${service_session2}[Id] Click Dialog Button Update Page Should Contain Track Attendance @@ -84,7 +84,7 @@ UA2: Update attendance when service session status is Complete UA3: Validate fields added to AttendanceServiceDeliveries Fieldset [Documentation] This test updates attendance for a service session record with Complete Status - [tags] W-9505038 quadrant:Q2 perm:admin feature:Attendance + [tags] W-9505038 quadrant:Q2 perm:admin quadrant:Q3 feature:Attendance Run task add_fields_to_field_set ... field_set=${ns}ServiceDelivery__c.${ns}Attendance_Service_Deliveries ... fields=${{ ["${ns}Service_Provider__c"] }} diff --git a/robot/pmm/tests/browser/Bulk_Service_Delivery/group_service_delivery.robot b/robot/pmm/tests/browser/Bulk_Service_Delivery/group_service_delivery.robot index 2a01f7283..8fa618554 100644 --- a/robot/pmm/tests/browser/Bulk_Service_Delivery/group_service_delivery.robot +++ b/robot/pmm/tests/browser/Bulk_Service_Delivery/group_service_delivery.robot @@ -70,6 +70,33 @@ Setup Test Data API Update Records ${ns}ProgramEngagement__c ${program_engagement4}[Id] ${ns}Stage__c=Applied *** Test Cases *** +Setup custom bucketed values and validate on participant selector component + [Documentation] Create custom bucketed values for Program Cohort Status and Program Engagement Stages and + ... validate the same on the participant selector component on BSDT + [tags] quadrant:Q3 perm:admin + Setup Custom Metadata Bucketed Value Completed Completed ProgramCohortStatusActive Completed + Setup Custom Metadata Bucketed Value Applied Applied Active Applied + Go To Page Custom Bulk_Service_Deliveries + Click Dialog Button Create by Group + Page Should Contain Text Default Service Delivery Values + Populate Lookup Field Service ${service1}[Name] + Page Should Contain ${service1}[${ns}UnitOfMeasurement__c] + Populate Field Quantity ${quantity} + Click Dialog Button Next + Page Should Contain Text Contact Selection + Load Page Object New ServiceSchedule__c + Page Should Contain Applied + Verify dropdown Options Filter by: Program Cohort contains ${program_cohort1}[Name] + sleep 3s + Verify dropdown Options Filter by: Program Cohort does not contain ${program_cohort2}[Name] + sleep 3s + Verify dropdown Options Filter by: Program Cohort does not contain ${program_cohort3}[Name] + sleep 3s + Select Service Participant ${contact1}[Name] + Validate Participant Is Added ${contact1}[Name] + Click Dialog Button Next + Page Should Contain Delivery Date + GSD1: Create service delivery using BSDT Wizard [Documentation] Clicks on Create by Group on BSDT, selects default service delivery values, adds contact ... and creates service delivery using wizard @@ -97,13 +124,11 @@ GSD1: Create service delivery using BSDT Wizard Verify Details Service Delivery Name contains ${contact1}[FirstName] ${contact1}[LastName] ${today}: ${service}[Name] Verify Details Quantity contains ${quantity}.00 Verify Details Unit of Measurement contains ${service}[${ns}UnitOfMeasurement__c] - Save Current Record ID For Deletion ${ns}ServiceDelivery__c Go To Page Listing ${ns}ServiceDelivery__c Click Listview Link ${contact2}[FirstName] ${contact2}[LastName] ${today}: ${service}[Name] Verify Details Service Delivery Name contains ${contact2}[FirstName] ${contact2}[LastName] ${today}: ${service}[Name] Verify Details Quantity contains ${quantity}.00 Verify Details Unit of Measurement contains ${service}[${ns}UnitOfMeasurement__c] - Save Current Record ID For Deletion ${ns}ServiceDelivery__c GSD2: Filter on bsdt wizard based on Program Cohort [Documentation] On BSDT wizard contact selection screen,filter based on program cohort and @@ -119,7 +144,7 @@ GSD2: Filter on bsdt wizard based on Program Cohort Page Should Contain Text Contact Selection Load Page Object New ServiceSchedule__c Page Should Contain No records selected - Select Value From Dropdown Filter by Program Cohort ${program_cohort2}[Name] + Select Value From Dropdown Filter by: Program Cohort ${program_cohort2}[Name] Page Should Not Contain ${contact1}[Name] Page Should Not Contain ${contact2}[Name] Page Should Contain Text ${contact3}[Name] @@ -159,31 +184,3 @@ GSD4: Filter on bsdt wizard based on Stage Page Should Contain No records selected Filter Participants Applied Page Should Contain No records found. - -Setup custom bucketed values and validate on participant selector component - [Documentation] Create custom bucketed values for Program Cohort Status and Program Engagement Stages and - ... validate the same on the participant selector component on BSDT - [tags] quadrant:Q3 perm:admin - Setup Custom Metadata Bucketed Value Completed Completed ProgramCohortStatusActive Completed - Setup Custom Metadata Bucketed Value Applied Applied Active Applied - Go To Page Custom Bulk_Service_Deliveries - Click Dialog Button Create by Group - Page Should Contain Text Default Service Delivery Values - Populate Lookup Field Service ${service1}[Name] - Page Should Contain ${service1}[${ns}UnitOfMeasurement__c] - Populate Field Quantity ${quantity} - Click Dialog Button Next - Page Should Contain Text Contact Selection - Load Page Object New ServiceSchedule__c - Page Should Contain Applied - Verify dropdown Options Filter by Program Cohort contains ${program_cohort1}[Name] - sleep 3s - Verify dropdown Options Filter by Program Cohort does not contain ${program_cohort2}[Name] - sleep 3s - Verify dropdown Options Filter by Program Cohort does not contain ${program_cohort3}[Name] - sleep 3s - Select Service Participant ${contact1}[Name] - Validate Participant Is Added ${contact1}[Name] - Click Dialog Button Next - Page Should Contain Delivery Date - diff --git a/robot/pmm/tests/browser/Bulk_Service_Delivery/individual_service_delivery.robot b/robot/pmm/tests/browser/Bulk_Service_Delivery/individual_service_delivery.robot index 8190550d4..be5898e55 100644 --- a/robot/pmm/tests/browser/Bulk_Service_Delivery/individual_service_delivery.robot +++ b/robot/pmm/tests/browser/Bulk_Service_Delivery/individual_service_delivery.robot @@ -35,6 +35,17 @@ Setup Test Data ${service1} = API Create Service ${Program1}[Id] Set suite variable ${service1} + ${contact4} = API Create Contact + Set suite variable ${contact4} + ${program4} = API Create Program + Set suite variable ${program4} + ${service4} = API Create Service ${Program4}[Id] + Set suite variable ${service4} + API Update Records ${ns}Service__c ${service4}[Id] ${ns}Status__c=Canceled + ${program_engagement4} = API Create Program Engagement ${Program4}[Id] ${contact4}[Id] + Set suite variable ${program_engagement4} + API Update Records ${ns}ProgramEngagement__c ${program_engagement4}[Id] ${ns}Stage__c=Withdrawn + ${contact2} = API Create Contact Set suite variable ${contact2} ${program2} = API Create Program @@ -57,7 +68,9 @@ ISD1: Add service delivery on bulk service delivery [Documentation] This test adds two service deliveries on bulk service delivery and ... navigates to service delivery listview and verifies that the service delivery ... records are displayed - [tags] W-040316 quadrant:Q2 perm:admin perm:manage perm:deliver feature:Service Delivery + [tags] W-040316 quadrant:Q3 perm:admin perm:manage perm:deliver feature:Service Delivery + Setup Custom Metadata Bucketed Value Canceled Service Canceled_Service ServiceStatusActive Canceled + Setup Custom Metadata Bucketed Value PE:Withdrawn PE_Withrawn Active Withdrawn Go To Page Custom Bulk_Service_Deliveries Click Dialog Button Create by Individual Populate Bsdt Lookup 1 Client ${contact1}[FirstName] ${contact1}[LastName] @@ -69,15 +82,20 @@ ISD1: Add service delivery on bulk service delivery Populate Bsdt Dropdown 2 Program Engagement ${program_engagement2}[Name] Populate Bsdt Dropdown 2 Service ${service2}[Name] Populate Bsdt Field 2 Quantity ${quantity2} + Click Bsdt Button Add Entry + Populate Bsdt Lookup 3 Client ${contact4}[FirstName] ${contact4}[LastName] + Populate Bsdt Dropdown 3 Program Engagement ${program_engagement4}[Name] + Populate Bsdt Dropdown 3 Service ${service4}[Name] + Populate Bsdt Field 3 Quantity ${quantity2} Click Bsdt Button Save Verify Persist Save Icon 1 Saved Verify Persist Save Icon 2 Saved + Verify Persist Save Icon 3 Saved Go To Page Listing ${ns}ServiceDelivery__c Page Should Contain ${contact1}[FirstName] ${contact1}[LastName] ${today}: ${service1}[Name] Page Should Contain ${contact2}[FirstName] ${contact2}[LastName] ${today}: ${service2}[Name] Click Listview Link ${contact1}[FirstName] ${contact1}[LastName] ${today}: ${service1}[Name] Verify Details Service Delivery Name contains ${contact1}[FirstName] ${contact1}[LastName] ${today}: ${service1}[Name] - Save Current Record ID For Deletion ${ns}ServiceDelivery__c ISD2: Verify error message when there are no services associated with the program [Documentation] This test verifies that an error message is displayed when there are no diff --git a/robot/pmm/tests/browser/ServiceSchedule/service_schedule_filter.robot b/robot/pmm/tests/browser/ServiceSchedule/service_schedule_filter.robot index 77bace0d0..3382c7605 100644 --- a/robot/pmm/tests/browser/ServiceSchedule/service_schedule_filter.robot +++ b/robot/pmm/tests/browser/ServiceSchedule/service_schedule_filter.robot @@ -59,7 +59,7 @@ SSF1: Filter based on Program Cohort Verify Wizard Screen Title Add Service Participants Page Should Contain ${service_schedule_name} Page Should Contain No records selected - Select Value From Dropdown Filter by Program Cohort ${program_cohort2}[Name] + Select Value From Dropdown Filter by: Program Cohort ${program_cohort2}[Name] Page Should Not Contain ${contact1}[Name] Page Should Not Contain ${contact2}[Name] Page Should Contain Text ${contact3}[Name] diff --git a/robot/pmm/tests/browser/ServiceSchedule/service_schedule_screen3.robot b/robot/pmm/tests/browser/ServiceSchedule/service_schedule_screen3.robot index b8b9f01b9..60ec8a330 100644 --- a/robot/pmm/tests/browser/ServiceSchedule/service_schedule_screen3.robot +++ b/robot/pmm/tests/browser/ServiceSchedule/service_schedule_screen3.robot @@ -150,9 +150,9 @@ Setup custom bucketed values and validate on service schedule wizard Click Dialog Button Next Verify Wizard Screen Title Add Service Participants Page Should Contain Waitlisted - Verify dropdown Options Filter by Program Cohort contains ${program_cohort1}[Name] - Verify dropdown Options Filter by Program Cohort does not contain ${program_cohort2}[Name] - Verify dropdown Options Filter by Program Cohort does not contain ${program_cohort3}[Name] + Verify dropdown Options Filter by: Program Cohort contains ${program_cohort1}[Name] + Verify dropdown Options Filter by: Program Cohort does not contain ${program_cohort2}[Name] + Verify dropdown Options Filter by: Program Cohort does not contain ${program_cohort3}[Name] Select Service Participant ${contact1}[Name] Validate Participant Is Added ${contact1}[Name] Click Dialog Button Next