From 74b167e2cc0bf14238c587d931ce385eb5bb3203 Mon Sep 17 00:00:00 2001 From: Jonathan Gillespie Date: Wed, 15 Mar 2017 08:47:20 +0100 Subject: [PATCH 01/23] Added first attempt at setting up .travis.yml --- .travis.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..d985115 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,5 @@ +language: node_js + +script: + - npm install -g jsforce-metadata-tools + - jsforce-deploy --dry-run -u $DEPLOYMENT_USERNAME -p $DEPLOYMENT_PASSWORD$DEPLOYMENT_TOKEN -D $TRAVIS_BUILD_DIR/src -l $DEPLOYMENT_LOGIN_URL --rollbackOnError true --testLevel $DEPLOYMENT_TEST_LEVEL --pollTimeout $POLL_TIMEOUT \ No newline at end of file From e16b00af26234b63a9279457c074d05639d83be5 Mon Sep 17 00:00:00 2001 From: Jonathan Gillespie Date: Wed, 15 Mar 2017 14:05:50 +0100 Subject: [PATCH 02/23] Added some echo statements to check some variable values --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index d985115..1f9d8ca 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,4 +2,8 @@ language: node_js script: - npm install -g jsforce-metadata-tools + - echo $TRAVIS_BUILD_DIR + - echo $DEPLOYMENT_LOGIN_URL + - echo $DEPLOYMENT_TEST_LEVEL + - echo $POLL_TIMEOUT - jsforce-deploy --dry-run -u $DEPLOYMENT_USERNAME -p $DEPLOYMENT_PASSWORD$DEPLOYMENT_TOKEN -D $TRAVIS_BUILD_DIR/src -l $DEPLOYMENT_LOGIN_URL --rollbackOnError true --testLevel $DEPLOYMENT_TEST_LEVEL --pollTimeout $POLL_TIMEOUT \ No newline at end of file From e3bd5d1638f5c2db6c75cd9e7e7d10a159f4aa01 Mon Sep 17 00:00:00 2001 From: Jonathan Gillespie Date: Wed, 15 Mar 2017 14:10:59 +0100 Subject: [PATCH 03/23] Removed the gender tag in NebulaLog__c.object because it's the worst/breaks deploys --- src/objects/NebulaLog__c.object | 1 - 1 file changed, 1 deletion(-) diff --git a/src/objects/NebulaLog__c.object b/src/objects/NebulaLog__c.object index 8da9a75..6f39b9e 100644 --- a/src/objects/NebulaLog__c.object +++ b/src/objects/NebulaLog__c.object @@ -116,7 +116,6 @@ LongTextArea 5 - Masculine All_Logs From 697dfa6a1d98ad49c2925d84aea83420d9c5a4eb Mon Sep 17 00:00:00 2001 From: Jonathan Gillespie Date: Wed, 15 Mar 2017 14:22:06 +0100 Subject: [PATCH 04/23] Fixed a problem with SObjectRecordTypes when the object has no record types --- src/classes/SObjectRecordTypes.cls | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/classes/SObjectRecordTypes.cls b/src/classes/SObjectRecordTypes.cls index 71bddc4..d44d5d0 100644 --- a/src/classes/SObjectRecordTypes.cls +++ b/src/classes/SObjectRecordTypes.cls @@ -35,6 +35,7 @@ public abstract class SObjectRecordTypes extends NebulaCore { String query = 'SELECT ' + String.join(fieldList, ', ') + ' FROM RecordType'; List whereClauseList = new List(); + if(new NebulaSettings().recordTypesSettings.LazyLoad__c){ whereClauseList.add('SObjectType = \'' + this.sobjectName + '\''); this.addLogEntry('new NebulaSettings().recordTypesSettings.LazyLoad__c=' + new NebulaSettings().recordTypesSettings.LazyLoad__c); @@ -46,14 +47,11 @@ public abstract class SObjectRecordTypes extends NebulaCore { query += ' ORDER BY DeveloperName'; this.addLogEntry('SObjectRecordTypes query=' + query); + + if(!cachedRecordTypesBySObjectMap.containsKey(this.sobjectName)) cachedRecordTypesBySObjectMap.put(this.sobjectName, new List()); List recordTypeList = (List)Database.query(query); - for(RecordType recordType : recordTypeList) { - if(!cachedRecordTypesBySObjectMap.containsKey(recordType.SObjectType)) { - cachedRecordTypesBySObjectMap.put(recordType.SObjectType, new List{recordType}); - } else { - cachedRecordTypesBySObjectMap.get(recordType.SObjectType).add(recordType); - } - } + for(RecordType recordType : recordTypeList) cachedRecordTypesBySObjectMap.get(this.sobjectName).add(recordType); + this.addLogEntry('cachedRecordTypesBySObjectMap=' + cachedRecordTypesBySObjectMap); } From d5ea3e21ee3e9aa8a413bb03fdf4cbbd5a888439 Mon Sep 17 00:00:00 2001 From: Jonathan Gillespie Date: Wed, 15 Mar 2017 14:23:54 +0100 Subject: [PATCH 05/23] Remove the echo statements I added to help debug - deployments are started to work now --- .travis.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1f9d8ca..d985115 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,8 +2,4 @@ language: node_js script: - npm install -g jsforce-metadata-tools - - echo $TRAVIS_BUILD_DIR - - echo $DEPLOYMENT_LOGIN_URL - - echo $DEPLOYMENT_TEST_LEVEL - - echo $POLL_TIMEOUT - jsforce-deploy --dry-run -u $DEPLOYMENT_USERNAME -p $DEPLOYMENT_PASSWORD$DEPLOYMENT_TOKEN -D $TRAVIS_BUILD_DIR/src -l $DEPLOYMENT_LOGIN_URL --rollbackOnError true --testLevel $DEPLOYMENT_TEST_LEVEL --pollTimeout $POLL_TIMEOUT \ No newline at end of file From 04105ad87b9d67d2e6cd3b92d32096fd74fb5ac3 Mon Sep 17 00:00:00 2001 From: Jonathan Gillespie Date: Wed, 15 Mar 2017 15:31:06 +0100 Subject: [PATCH 06/23] Added Travis CI build badges to README.md --- README.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 1bba418..36b2938 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,10 @@ # Nebula Framework for Salesforce Apex - Deploy to Salesforce - \ No newline at end of file + Deploy to Salesforce + + +## Branches +| Name | Build Status | +| -------- | -------- | +| master | | +| dev | | From 8fed7f757e100c072bd9beb0af104abb181d375f Mon Sep 17 00:00:00 2001 From: Jonathan Gillespie Date: Wed, 15 Mar 2017 16:54:07 +0100 Subject: [PATCH 07/23] Added QueryOperator_Tests.cls --- src/classes/QueryOperator_Tests.cls | 64 ++++++++++++++++++++ src/classes/QueryOperator_Tests.cls-meta.xml | 5 ++ 2 files changed, 69 insertions(+) create mode 100644 src/classes/QueryOperator_Tests.cls create mode 100644 src/classes/QueryOperator_Tests.cls-meta.xml diff --git a/src/classes/QueryOperator_Tests.cls b/src/classes/QueryOperator_Tests.cls new file mode 100644 index 0000000..4e82fa3 --- /dev/null +++ b/src/classes/QueryOperator_Tests.cls @@ -0,0 +1,64 @@ +@isTest +private class QueryOperator_Tests { + + @isTest + static void it_should_return_EQUALS_string() { + System.assertEquals('=', new QueryOperator().EQUALS.getValue()); + } + + @isTest + static void it_should_return_NOT_EQUAL_TO_string() { + System.assertEquals('!=', new QueryOperator().NOT_EQUAL_TO.getValue()); + } + + @isTest + static void it_should_return_GREATER_THAN_string() { + System.assertEquals('>', new QueryOperator().GREATER_THAN.getValue()); + } + + @isTest + static void it_should_return_GREATER_THAN_OR_EQUAL_TO_string() { + System.assertEquals('>=', new QueryOperator().GREATER_THAN_OR_EQUAL_TO.getValue()); + } + + @isTest + static void it_should_return_LESS_THAN_string() { + System.assertEquals('<', new QueryOperator().LESS_THAN.getValue()); + } + + @isTest + static void it_should_return_LESS_THAN_OR_EQUAL_TO_string() { + System.assertEquals('<=', new QueryOperator().LESS_THAN_OR_EQUAL_TO.getValue()); + } + + @isTest + static void it_should_return_IS_IN_string() { + System.assertEquals('IN', new QueryOperator().IS_IN.getValue()); + } + + @isTest + static void it_should_return_IS_NOT_IN_string() { + System.assertEquals('NOT IN', new QueryOperator().IS_NOT_IN.getValue()); + } + + @isTest + static void it_should_return_INCLUDES_string() { + System.assertEquals('INCLUDES', new QueryOperator().INCLUDES.getValue()); + } + + @isTest + static void it_should_return_EXCLUDES_string() { + System.assertEquals('EXCLUDES', new QueryOperator().EXCLUDES.getValue()); + } + + @isTest + static void it_should_return_IS_LIKE_string() { + System.assertEquals('LIKE', new QueryOperator().IS_LIKE.getValue()); + } + + @isTest + static void it_should_return_IS_NOT_LIKE_string() { + System.assertEquals('NOT LIKE', new QueryOperator().IS_NOT_LIKE.getValue()); + } + +} \ No newline at end of file diff --git a/src/classes/QueryOperator_Tests.cls-meta.xml b/src/classes/QueryOperator_Tests.cls-meta.xml new file mode 100644 index 0000000..cbddff8 --- /dev/null +++ b/src/classes/QueryOperator_Tests.cls-meta.xml @@ -0,0 +1,5 @@ + + + 38.0 + Active + From d6971969031bf178f39b66c8e24f63075fc53e7d Mon Sep 17 00:00:00 2001 From: Jonathan Gillespie Date: Thu, 16 Mar 2017 08:17:49 +0100 Subject: [PATCH 08/23] Added license info to QueryOperator_Tests --- src/classes/QueryOperator.cls | 1 - src/classes/QueryOperator_Tests.cls | 4 ++++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/classes/QueryOperator.cls b/src/classes/QueryOperator.cls index b3fbb59..efc658f 100644 --- a/src/classes/QueryOperator.cls +++ b/src/classes/QueryOperator.cls @@ -2,7 +2,6 @@ * This file is part of the Nebula Framework project, released under the MIT License. * * See LICENSE file or go to https://github.com/jongpie/NebulaFramework for full license details. * *************************************************************************************************/ - public without sharing class QueryOperator { private String value; diff --git a/src/classes/QueryOperator_Tests.cls b/src/classes/QueryOperator_Tests.cls index 4e82fa3..00f8a75 100644 --- a/src/classes/QueryOperator_Tests.cls +++ b/src/classes/QueryOperator_Tests.cls @@ -1,3 +1,7 @@ +/************************************************************************************************* +* This file is part of the Nebula Framework project, released under the MIT License. * +* See LICENSE file or go to https://github.com/jongpie/NebulaFramework for full license details. * +*************************************************************************************************/ @isTest private class QueryOperator_Tests { From 4f472a921b512a67542effc15bb34bc98bca7163 Mon Sep 17 00:00:00 2001 From: Jonathan Gillespie Date: Thu, 16 Mar 2017 08:18:17 +0100 Subject: [PATCH 09/23] Created NebulaSettings_Tests.cls --- src/classes/NebulaSettings_Tests.cls | 62 +++++++++++++++++++ src/classes/NebulaSettings_Tests.cls-meta.xml | 5 ++ 2 files changed, 67 insertions(+) create mode 100644 src/classes/NebulaSettings_Tests.cls create mode 100644 src/classes/NebulaSettings_Tests.cls-meta.xml diff --git a/src/classes/NebulaSettings_Tests.cls b/src/classes/NebulaSettings_Tests.cls new file mode 100644 index 0000000..ce9f002 --- /dev/null +++ b/src/classes/NebulaSettings_Tests.cls @@ -0,0 +1,62 @@ +/************************************************************************************************* +* This file is part of the Nebula Framework project, released under the MIT License. * +* See LICENSE file or go to https://github.com/jongpie/NebulaFramework for full license details. * +*************************************************************************************************/ +@isTest +private class NebulaSettings_Tests { + + @isTest + static void it_should_return_recordTypesSettings() { + List existingSettings = [SELECT Id FROM NebulaRecordTypesSettings__c]; + System.assert(existingSettings.isEmpty()); + + Test.startTest(); + System.assertNotEquals(null, new NebulaSettings().recordTypesSettings); + Test.stopTest(); + } + + @isTest + static void it_should_return_repositorySettings() { + List existingSettings = [SELECT Id FROM NebulaRepositorySettings__c]; + System.assert(existingSettings.isEmpty()); + + Test.startTest(); + System.assertNotEquals(null, new NebulaSettings().repositorySettings); + Test.stopTest(); + } + + @isTest + static void it_should_return_triggerHandlerSettings() { + List existingSettings = [SELECT Id FROM NebulaTriggerHandlerSettings__c]; + System.assert(existingSettings.isEmpty()); + + Test.startTest(); + System.assertNotEquals(null, new NebulaSettings().triggerHandlerSettings); + Test.stopTest(); + } + + + @isTest + static void it_should_reset_all_settings_to_defaults() { + NebulaRecordTypesSettings__c nebulaRecordTypesSettings = NebulaRecordTypesSettings__c.getInstance(); + upsert nebulaRecordTypesSettings; + Id originalRecordTypesSettingsId = NebulaRecordTypesSettings__c.getInstance().Id; + + NebulaRepositorySettings__c nebulaRepositorySettings = NebulaRepositorySettings__c.getInstance(); + upsert nebulaRepositorySettings; + Id originalRepositorySettingsId = NebulaRepositorySettings__c.getInstance().Id; + + NebulaTriggerHandlerSettings__c nebulaTriggerHandlerSettings = NebulaTriggerHandlerSettings__c.getInstance(); + upsert nebulaTriggerHandlerSettings; + Id originalTriggerHandlerSettingsId = NebulaTriggerHandlerSettings__c.getInstance().Id; + + Test.startTest(); + new NebulaSettings().resetAllSettingsToDefaults(); + Test.stopTest(); + + System.assertNotEquals(originalRecordTypesSettingsId, NebulaRecordTypesSettings__c.getInstance().Id); + System.assertNotEquals(originalRepositorySettingsId, NebulaRepositorySettings__c.getInstance().Id); + System.assertNotEquals(originalTriggerHandlerSettingsId, NebulaTriggerHandlerSettings__c.getInstance().Id); + } + +} \ No newline at end of file diff --git a/src/classes/NebulaSettings_Tests.cls-meta.xml b/src/classes/NebulaSettings_Tests.cls-meta.xml new file mode 100644 index 0000000..cbddff8 --- /dev/null +++ b/src/classes/NebulaSettings_Tests.cls-meta.xml @@ -0,0 +1,5 @@ + + + 38.0 + Active + From a42babaa9646130db6673a53553bf179ae6f80f1 Mon Sep 17 00:00:00 2001 From: Jonathan Gillespie Date: Thu, 16 Mar 2017 08:40:32 +0100 Subject: [PATCH 10/23] Fixed the ordering of the filter scopes to be in descending order --- src/classes/QueryFilterScope.cls | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/classes/QueryFilterScope.cls b/src/classes/QueryFilterScope.cls index 6abc26a..9561280 100644 --- a/src/classes/QueryFilterScope.cls +++ b/src/classes/QueryFilterScope.cls @@ -2,4 +2,4 @@ * This file is part of the Nebula Framework project, released under the MIT License. * * See LICENSE file or go to https://github.com/jongpie/NebulaFramework for full license details. * *************************************************************************************************/ -public enum QueryFilterScope {EVERYTHING, MINE, TEAM} \ No newline at end of file +public enum QueryFilterScope {EVERYTHING, TEAM, MINE} \ No newline at end of file From 7d8ef62019eef8fe6b30c58e3dc7d79ff845d2a9 Mon Sep 17 00:00:00 2001 From: Jonathan Gillespie Date: Thu, 16 Mar 2017 08:41:06 +0100 Subject: [PATCH 11/23] Changed NebulaSettings.cls to be static variables and methods --- src/classes/NebulaSettings.cls | 52 +++++++++++++-------------- src/classes/NebulaSettings_Tests.cls | 8 ++--- src/classes/QueryBuilder.cls | 4 +-- src/classes/SObjectRecordTypes.cls | 6 ++-- src/classes/SObjectTriggerHandler.cls | 10 +++--- 5 files changed, 40 insertions(+), 40 deletions(-) diff --git a/src/classes/NebulaSettings.cls b/src/classes/NebulaSettings.cls index cda3842..57ddeee 100644 --- a/src/classes/NebulaSettings.cls +++ b/src/classes/NebulaSettings.cls @@ -4,61 +4,61 @@ *************************************************************************************************/ public without sharing class NebulaSettings { - public NebulaRecordTypesSettings__c recordTypesSettings; - public NebulaRepositorySettings__c repositorySettings; - public NebulaTriggerHandlerSettings__c triggerHandlerSettings; + public static NebulaRecordTypesSettings__c recordTypesSettings; + public static NebulaRepositorySettings__c repositorySettings; + public static NebulaTriggerHandlerSettings__c triggerHandlerSettings; - public NebulaSettings() { - this.loadCustomSettings(); + static { + loadCustomSettings(); } - public void resetAllSettingsToDefaults() { - this.deleteExistingCustomSettings(); - this.createCustomSettings(); + public static void resetAllSettingsToDefaults() { + deleteExistingCustomSettings(); + createCustomSettings(); } - private void loadCustomSettings() { - this.loadRecordTypesSettings(); - this.loadRepositorySettings(); - this.loadTriggerHandlerSettings(); + private static void loadCustomSettings() { + loadRecordTypesSettings(); + loadRepositorySettings(); + loadTriggerHandlerSettings(); } - private void deleteExistingCustomSettings() { + private static void deleteExistingCustomSettings() { delete [SELECT Id FROM NebulaRecordTypesSettings__c]; delete [SELECT Id FROM NebulaRepositorySettings__c]; delete [SELECT Id FROM NebulaTriggerHandlerSettings__c]; } - private void createCustomSettings() { + private static void createCustomSettings() { upsert NebulaRecordTypesSettings__c.getOrgDefaults(); upsert NebulaRepositorySettings__c.getOrgDefaults(); upsert NebulaTriggerHandlerSettings__c.getOrgDefaults(); } - private void loadRecordTypesSettings() { - this.recordTypesSettings = NebulaRecordTypesSettings__c.getInstance(); + private static void loadRecordTypesSettings() { + recordTypesSettings = NebulaRecordTypesSettings__c.getInstance(); - if(this.recordTypesSettings.Id == null) { + if(recordTypesSettings.Id == null) { upsert NebulaRecordTypesSettings__c.getOrgDefaults(); - this.recordTypesSettings = NebulaRecordTypesSettings__c.getInstance(); + recordTypesSettings = NebulaRecordTypesSettings__c.getInstance(); } } - private void loadRepositorySettings() { - this.repositorySettings = NebulaRepositorySettings__c.getInstance(); + private static void loadRepositorySettings() { + repositorySettings = NebulaRepositorySettings__c.getInstance(); - if(this.repositorySettings.Id == null) { + if(repositorySettings.Id == null) { upsert NebulaRepositorySettings__c.getOrgDefaults(); - this.repositorySettings = NebulaRepositorySettings__c.getInstance(); + repositorySettings = NebulaRepositorySettings__c.getInstance(); } } - private void loadTriggerHandlerSettings() { - this.triggerHandlerSettings = NebulaTriggerHandlerSettings__c.getInstance(); + private static void loadTriggerHandlerSettings() { + triggerHandlerSettings = NebulaTriggerHandlerSettings__c.getInstance(); - if(this.triggerHandlerSettings.Id == null) { + if(triggerHandlerSettings.Id == null) { upsert NebulaTriggerHandlerSettings__c.getOrgDefaults(); - this.triggerHandlerSettings = NebulaTriggerHandlerSettings__c.getInstance(); + triggerHandlerSettings = NebulaTriggerHandlerSettings__c.getInstance(); } } diff --git a/src/classes/NebulaSettings_Tests.cls b/src/classes/NebulaSettings_Tests.cls index ce9f002..26649e8 100644 --- a/src/classes/NebulaSettings_Tests.cls +++ b/src/classes/NebulaSettings_Tests.cls @@ -11,7 +11,7 @@ private class NebulaSettings_Tests { System.assert(existingSettings.isEmpty()); Test.startTest(); - System.assertNotEquals(null, new NebulaSettings().recordTypesSettings); + System.assertNotEquals(null, NebulaSettings.recordTypesSettings); Test.stopTest(); } @@ -21,7 +21,7 @@ private class NebulaSettings_Tests { System.assert(existingSettings.isEmpty()); Test.startTest(); - System.assertNotEquals(null, new NebulaSettings().repositorySettings); + System.assertNotEquals(null, NebulaSettings.repositorySettings); Test.stopTest(); } @@ -31,7 +31,7 @@ private class NebulaSettings_Tests { System.assert(existingSettings.isEmpty()); Test.startTest(); - System.assertNotEquals(null, new NebulaSettings().triggerHandlerSettings); + System.assertNotEquals(null, NebulaSettings.triggerHandlerSettings); Test.stopTest(); } @@ -51,7 +51,7 @@ private class NebulaSettings_Tests { Id originalTriggerHandlerSettingsId = NebulaTriggerHandlerSettings__c.getInstance().Id; Test.startTest(); - new NebulaSettings().resetAllSettingsToDefaults(); + NebulaSettings.resetAllSettingsToDefaults(); Test.stopTest(); System.assertNotEquals(originalRecordTypesSettingsId, NebulaRecordTypesSettings__c.getInstance().Id); diff --git a/src/classes/QueryBuilder.cls b/src/classes/QueryBuilder.cls index c253cf5..e591cc2 100644 --- a/src/classes/QueryBuilder.cls +++ b/src/classes/QueryBuilder.cls @@ -102,7 +102,7 @@ public without sharing class QueryBuilder extends NebulaCore implements IQueryBu private String getQueryFieldString() { List queryFieldList = new List(this.queryFields); - if(new NebulaSettings().repositorySettings.SortQueryFields__c) queryFieldList.sort(); + if(NebulaSettings.repositorySettings.SortQueryFields__c) queryFieldList.sort(); return String.join(queryFieldList, ','); } @@ -170,7 +170,7 @@ public without sharing class QueryBuilder extends NebulaCore implements IQueryBu } private void addCommonQueryFields() { - if(!new NebulaSettings().repositorySettings.IncludeCommonFields__c) return; + if(!NebulaSettings.repositorySettings.IncludeCommonFields__c) return; // Auto-add the common fields that are available for the SObject Type List commonFieldNameList = new List{ diff --git a/src/classes/SObjectRecordTypes.cls b/src/classes/SObjectRecordTypes.cls index d44d5d0..3c7aaa1 100644 --- a/src/classes/SObjectRecordTypes.cls +++ b/src/classes/SObjectRecordTypes.cls @@ -36,12 +36,12 @@ public abstract class SObjectRecordTypes extends NebulaCore { List whereClauseList = new List(); - if(new NebulaSettings().recordTypesSettings.LazyLoad__c){ + if(NebulaSettings.recordTypesSettings.LazyLoad__c){ whereClauseList.add('SObjectType = \'' + this.sobjectName + '\''); - this.addLogEntry('new NebulaSettings().recordTypesSettings.LazyLoad__c=' + new NebulaSettings().recordTypesSettings.LazyLoad__c); + this.addLogEntry('NebulaSettings.recordTypesSettings.LazyLoad__c=' + NebulaSettings.recordTypesSettings.LazyLoad__c); this.addLogEntry('this.sobjectName=' + this.sobjectName); } - if(new NebulaSettings().recordTypesSettings.ExcludeManagedRecordTypes__c) whereClauseList.add('NamespacePrefix = null'); + if(NebulaSettings.recordTypesSettings.ExcludeManagedRecordTypes__c) whereClauseList.add('NamespacePrefix = null'); if(!whereClauseList.isEmpty()) query += ' WHERE ' + String.join(whereClauseList, ' AND '); query += ' ORDER BY DeveloperName'; diff --git a/src/classes/SObjectTriggerHandler.cls b/src/classes/SObjectTriggerHandler.cls index 1f3efce..bf8ee03 100644 --- a/src/classes/SObjectTriggerHandler.cls +++ b/src/classes/SObjectTriggerHandler.cls @@ -120,15 +120,15 @@ public abstract class SObjectTriggerHandler extends NebulaCore implements ISObje } private Boolean shouldExecuteTriggers() { - this.addLogEntry('nebulaSettings.triggerHandlerSettings.ExecuteTriggers__c=' + new NebulaSettings().triggerHandlerSettings.ExecuteTriggers__c); + this.addLogEntry('nebulaSettings.triggerHandlerSettings.ExecuteTriggers__c=' + NebulaSettings.triggerHandlerSettings.ExecuteTriggers__c); - String handlerClassesToSkipString = new NebulaSettings().triggerHandlerSettings.HandlerClassesToSkip__c; + String handlerClassesToSkipString = NebulaSettings.triggerHandlerSettings.HandlerClassesToSkip__c; if(handlerClassesToSkipString == null) handlerClassesToSkipString = ''; Set handlerClassesToSkip = new Set(handlerClassesToSkipString.toLowerCase().split('\n')); - this.addLogEntry('nebulaSettings.triggerHandlerSettings.HandlerClassesToSkip__c=' + new NebulaSettings().triggerHandlerSettings.HandlerClassesToSkip__c); + this.addLogEntry('nebulaSettings.triggerHandlerSettings.HandlerClassesToSkip__c=' + NebulaSettings.triggerHandlerSettings.HandlerClassesToSkip__c); // If ExecuteTriggers == true and the current class isn't in the list of handlers to skip, then execute - return new NebulaSettings().triggerHandlerSettings.ExecuteTriggers__c && !handlerClassesToSkip.contains(this.getClassName().toLowerCase()); + return NebulaSettings.triggerHandlerSettings.ExecuteTriggers__c && !handlerClassesToSkip.contains(this.getClassName().toLowerCase()); } private void setHashCode() { @@ -161,7 +161,7 @@ public abstract class SObjectTriggerHandler extends NebulaCore implements ISObje } private Boolean haveRecordsAlreadyBeenProcessed() { - if(!new NebulaSettings().triggerHandlerSettings.PreventRecursion__c) return false; + if(!NebulaSettings.triggerHandlerSettings.PreventRecursion__c) return false; // This method is a safeguard that checks to see if we have recursion problems and stops if we do // It allows each context to occur once for a given hash code From ac14e2be44a64d4fc18784fd7ce2b77665ac1cf1 Mon Sep 17 00:00:00 2001 From: Jonathan Gillespie Date: Thu, 16 Mar 2017 08:51:51 +0100 Subject: [PATCH 12/23] Added more tests to SObjectRepository_Tests.cls --- src/classes/SObjectRepository_Tests.cls | 118 +++++++++++++++++++++--- 1 file changed, 107 insertions(+), 11 deletions(-) diff --git a/src/classes/SObjectRepository_Tests.cls b/src/classes/SObjectRepository_Tests.cls index 6ff7629..b1047a2 100644 --- a/src/classes/SObjectRepository_Tests.cls +++ b/src/classes/SObjectRepository_Tests.cls @@ -22,6 +22,15 @@ private class SObjectRepository_Tests { return (List)this.queryBuilder .whereField(Schema.Lead.Id, new QueryOperator().IS_IN, leadIdList) .setAsUpdate() + .orderBy(Schema.Lead.LastActivityDate, QuerySortOrder.DESCENDING, QueryNullSortOrder.LAST) + .getQueryResults(); + } + + public List getMyRecentLeads(Integer limitCount) { + return (List)this.queryBuilder + .usingScope(QueryFilterScope.MINE) + .limitCount(limitCount) + .orderBy(Schema.Lead.LastActivityDate) .getQueryResults(); } @@ -56,21 +65,25 @@ private class SObjectRepository_Tests { } } + static Lead createLead() { + Lead lead = new Lead( + Company = 'My Test Company', + LastName = 'Gillespie' + ); + return lead; + } + @testSetup static void setupData() { List leadList = new List(); for(Integer i = 0; i < 5; i++) { - Lead lead = new Lead( - Company = 'My Test Company', - LastName = 'Gillespie' - ); - leadList.add(lead); + leadList.add(createLead()); } insert leadList; } @isTest - static void getById_when_id() { + static void it_should_get_by_id_when_id() { Lead expectedLead = [SELECT Id FROM Lead LIMIT 1]; // Implement test code //System.assert(false, 'Finish writing your test!'); @@ -78,7 +91,7 @@ private class SObjectRepository_Tests { } @isTest - static void getById_when_list_of_id() { + static void it_should_get_by_id_when_list_of_id() { Map expectedLeadList = new Map([SELECT Id FROM Lead]); // Implement test code //System.assert(false, 'Finish writing your test!'); @@ -86,19 +99,102 @@ private class SObjectRepository_Tests { } @isTest - static void getNewThisWeekById() { - Map expectedLeadList = new Map([SELECT Id FROM Lead]); + static void it_should_return_my_recent_leads() { + List expectedLeadList = [SELECT Id FROM Lead]; // Implement test code //System.assert(false, 'Finish writing your test!'); - List returnedLeadList = new SObjectRepository_Tests.LeadRepository().getNewThisWeekById(new List(expectedLeadList.keySet())); + List returnedLeadList = new SObjectRepository_Tests.LeadRepository().getMyRecentLeads(3); } @isTest - static void searchInAllFields() { + static void it_should_return_new_this_week_by_Id() { + Map expectedLeadMap = new Map([SELECT Id FROM Lead]); + // Implement test code + //System.assert(false, 'Finish writing your test!'); + List returnedLeadList = new SObjectRepository_Tests.LeadRepository().getNewThisWeekById(new List(expectedLeadMap.keySet())); + } + + @isTest + static void it_should_search_in_all_fields() { Map expectedLeadList = new Map([SELECT Id FROM Lead]); // Implement test code //System.assert(false, 'Finish writing your test!'); List returnedLeadList = new SObjectRepository_Tests.LeadRepository().searchInAllFields('Gillespie'); } + @isTest + static void it_should_insert_a_single_record() { + Lead lead = createLead(); + System.assertEquals(null, lead.Id); + + Test.startTest(); + new SObjectRepository_Tests.LeadRepository().doInsert(lead); + Test.stopTest(); + + System.assertNotEquals(null, lead.Id); + + List queriedLeadList = [SELECT Id FROM Lead WHERE Id = :lead.Id]; + System.assertEquals(1, queriedLeadList.size()); + System.assertEquals(queriedLeadList[0].Id, lead.Id); + } + + @isTest + static void it_should_update_a_single_record() { + Lead existingLead = [SELECT Id, LastModifiedDate FROM Lead LIMIT 1]; + Datetime originalLastModifiedDate = existingLead.LastModifiedDate; + + Test.startTest(); + new SObjectRepository_Tests.LeadRepository().doUpdate(existingLead); + Test.stopTest(); + + existingLead = [SELECT Id, LastModifiedDate FROM Lead WHERE Id = :existingLead.Id]; + System.assert(existingLead.LastModifiedDate > originalLastModifiedDate); + } + + @isTest + static void it_should_delete_a_single_record() { + Lead existingLead = [SELECT Id, IsDeleted FROM Lead LIMIT 1]; + System.assertEquals(false, existingLead.IsDeleted); + + Test.startTest(); + new SObjectRepository_Tests.LeadRepository().doDelete(existingLead); + Test.stopTest(); + + existingLead = [SELECT Id, IsDeleted FROM Lead WHERE Id = :existingLead.Id ALL ROWS]; + System.assertEquals(true, existingLead.IsDeleted); + } + + @isTest + static void it_should_hard_delete_a_single_record() { + Lead existingLead = [SELECT Id, IsDeleted FROM Lead LIMIT 1]; + System.assertEquals(false, existingLead.IsDeleted); + + Test.startTest(); + new SObjectRepository_Tests.LeadRepository().doHardDelete(existingLead); + Test.stopTest(); + + List existingLeadList = [SELECT Id, IsDeleted FROM Lead WHERE Id = :existingLead.Id ALL ROWS]; + //System.assertEquals(0, existingLeadList.size()); + // TODO figure out why the hard delete doesn't work in unit tests + } + + + @isTest + static void it_should_undelete_a_single_record() { + Lead existingLead = [SELECT Id, IsDeleted FROM Lead LIMIT 1]; + System.assertEquals(false, existingLead.IsDeleted); + + delete existingLead; + + existingLead = [SELECT Id, IsDeleted FROM Lead WHERE Id = :existingLead.Id ALL ROWS]; + System.assertEquals(true, existingLead.IsDeleted); + + Test.startTest(); + new SObjectRepository_Tests.LeadRepository().doUndelete(existingLead); + Test.stopTest(); + + existingLead = [SELECT Id, IsDeleted FROM Lead WHERE Id = :existingLead.Id ALL ROWS]; + System.assertEquals(false, existingLead.IsDeleted); + } + } \ No newline at end of file From ae40731559a5a1c04782b7f5935194947e2e778e Mon Sep 17 00:00:00 2001 From: Jonathan Gillespie Date: Thu, 16 Mar 2017 09:49:47 +0100 Subject: [PATCH 13/23] Renamed the methods in Environment_Tests.cls --- src/classes/Environment_Tests.cls | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/classes/Environment_Tests.cls b/src/classes/Environment_Tests.cls index b7c5e7d..c745f0e 100644 --- a/src/classes/Environment_Tests.cls +++ b/src/classes/Environment_Tests.cls @@ -6,30 +6,30 @@ private class Environment_Tests { @isTest - static void getBaseUrl() { + static void it_should_return_base_url() { System.assert(Environment.BaseUrl.endsWithIgnoreCase('.salesforce.com')); } @isTest - static void getInstanceName() { + static void it_should_return_instance_name() { Organization org = [SELECT Id, InstanceName FROM Organization]; System.assertEquals(org.InstanceName, Environment.InstanceName); } @isTest - static void getIsSandbox() { + static void it_should_return_is_sandbox() { Organization org = [SELECT Id, IsSandbox FROM Organization]; System.assertEquals(org.IsSandbox, Environment.IsSandbox); } @isTest - static void getName() { + static void it_should_return_name() { Organization org = [SELECT Id, Name FROM Organization]; System.assertEquals(org.Name, Environment.Name); } @isTest - static void getType() { + static void it_should_return_type() { Organization org = [SELECT Id, OrganizationType FROM Organization]; System.assertEquals(org.OrganizationType, Environment.Type); } From 230a894ca457f374f6058333481ca2a8edc0da82 Mon Sep 17 00:00:00 2001 From: Jonathan Gillespie Date: Thu, 16 Mar 2017 10:47:03 +0100 Subject: [PATCH 14/23] Added QueryUtils_Tests.cls --- src/classes/QueryUtils_Tests.cls | 170 ++++++++++++++++++++++ src/classes/QueryUtils_Tests.cls-meta.xml | 5 + 2 files changed, 175 insertions(+) create mode 100644 src/classes/QueryUtils_Tests.cls create mode 100644 src/classes/QueryUtils_Tests.cls-meta.xml diff --git a/src/classes/QueryUtils_Tests.cls b/src/classes/QueryUtils_Tests.cls new file mode 100644 index 0000000..cffc316 --- /dev/null +++ b/src/classes/QueryUtils_Tests.cls @@ -0,0 +1,170 @@ +/************************************************************************************************* +* This file is part of the Nebula Framework project, released under the MIT License. * +* See LICENSE file or go to https://github.com/jongpie/NebulaFramework for full license details. * +*************************************************************************************************/ +@isTest +private class QueryUtils_Tests { + + @isTest + static void it_should_return_query_string_for_null() { + Object providedValue = null; + String expectedString = null; + + Test.startTest(); + String returnedValue = QueryUtils.toQueryString(providedValue); + Test.stopTest(); + + System.assertEquals(expectedString, returnedValue); + } + + @isTest + static void it_should_return_query_string_for_list() { + List providedValueList = new List{1, 2, 3}; + String expectedString = '(' + String.join(providedValueList, ',') + ')'; + + Test.startTest(); + String returnedValue = QueryUtils.toQueryString(providedValueList); + Test.stopTest(); + + System.assertEquals(expectedString, returnedValue); + } + + @isTest + static void it_should_return_query_string_for_query_date_literal() { + QueryDateLiteral providedValue = new QueryDateLiteral().YESTERDAY; + String expectedString = providedValue.getValue(); + + Test.startTest(); + String returnedValue = QueryUtils.toQueryString(providedValue); + Test.stopTest(); + + System.assertEquals(expectedString, returnedValue); + } + + @isTest + static void it_should_return_query_string_for_boolean() { + Boolean providedValue = true; + String expectedString = String.valueOf(providedValue); + + + Test.startTest(); + String returnedValue = QueryUtils.toQueryString(providedValue); + Test.stopTest(); + + System.assertEquals(expectedString, returnedValue); + } + + @isTest + static void it_should_return_query_string_for_date() { + Date providedValue = System.today(); + String expectedString = String.valueOf(providedValue); + + Test.startTest(); + String returnedValue = QueryUtils.toQueryString(providedValue); + Test.stopTest(); + + System.assertEquals(expectedString, returnedValue); + } + + @isTest + static void it_should_return_query_string_for_datetime() { + Datetime providedValue = System.now(); + String expectedString = providedValue.format('yyyy-MM-dd\'T\'HH:mm:ss\'Z\'', 'Greenwich Mean Time'); + + Test.startTest(); + String returnedValue = QueryUtils.toQueryString(providedValue); + Test.stopTest(); + + System.assertEquals(expectedString, returnedValue); + } + + @isTest + static void it_should_return_query_string_for_decimal() { + Decimal providedValue = 1.1; + String expectedString = String.valueOf(providedValue); + + Test.startTest(); + String returnedValue = QueryUtils.toQueryString(providedValue); + Test.stopTest(); + + System.assertEquals(expectedString, returnedValue); + } + + @isTest + static void it_should_return_query_string_for_double() { + Double providedValue = 1.1; + String expectedString = String.valueOf(providedValue); + + Test.startTest(); + String returnedValue = QueryUtils.toQueryString(providedValue); + Test.stopTest(); + + System.assertEquals(expectedString, returnedValue); + } + + @isTest + static void it_should_return_query_string_for_integer() { + Integer providedValue = 10; + String expectedString = String.valueOf(providedValue); + + Test.startTest(); + String returnedValue = QueryUtils.toQueryString(providedValue); + Test.stopTest(); + + System.assertEquals(expectedString, returnedValue); + } + + @isTest + static void it_should_return_query_string_for_long() { + Long providedValue = 1234567890; + String expectedString = String.valueOf(providedValue); + + Test.startTest(); + String returnedValue = QueryUtils.toQueryString(providedValue); + Test.stopTest(); + + System.assertEquals(expectedString, returnedValue); + } + + @isTest + static void it_should_return_query_string_for_sobject() { + Lead providedValue = new Lead( + Company = 'My Test Company', + LastName = 'Gillespie' + ); + insert providedValue; + String expectedString = '\'' + providedValue.Id + '\''; + + + Test.startTest(); + String returnedValue = QueryUtils.toQueryString(providedValue); + Test.stopTest(); + + System.assertEquals(expectedString, returnedValue); + } + + @isTest + static void it_should_return_query_string_for_string() { + String providedValue = 'test'; + String expectedString = '\'' + providedValue + '\''; + + Test.startTest(); + String returnedValue = QueryUtils.toQueryString(providedValue); + Test.stopTest(); + + System.assertEquals(expectedString, returnedValue); + } + + @isTest + static void it_should_return_query_string_for_unsported_type() { + UUID providedValue = new UUID(); + String expectedString = String.valueOf(providedValue); + + Test.startTest(); + String returnedValue = QueryUtils.toQueryString(providedValue); + Test.stopTest(); + + System.assertEquals(expectedString, returnedValue); + } + +} \ No newline at end of file diff --git a/src/classes/QueryUtils_Tests.cls-meta.xml b/src/classes/QueryUtils_Tests.cls-meta.xml new file mode 100644 index 0000000..cbddff8 --- /dev/null +++ b/src/classes/QueryUtils_Tests.cls-meta.xml @@ -0,0 +1,5 @@ + + + 38.0 + Active + From 1f614cbea7872da40e8060ef5ae1f8891697a102 Mon Sep 17 00:00:00 2001 From: Jonathan Gillespie Date: Thu, 16 Mar 2017 12:07:49 +0100 Subject: [PATCH 15/23] Fixed naming convention on a unit test --- src/classes/SObjectRepository_Tests.cls | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/classes/SObjectRepository_Tests.cls b/src/classes/SObjectRepository_Tests.cls index b1047a2..0d59c3f 100644 --- a/src/classes/SObjectRepository_Tests.cls +++ b/src/classes/SObjectRepository_Tests.cls @@ -107,7 +107,7 @@ private class SObjectRepository_Tests { } @isTest - static void it_should_return_new_this_week_by_Id() { + static void it_should_return_new_this_week_by_id() { Map expectedLeadMap = new Map([SELECT Id FROM Lead]); // Implement test code //System.assert(false, 'Finish writing your test!'); From f2e4cc3d327ba02e3bf04dab8c6e365db064b989 Mon Sep 17 00:00:00 2001 From: Jonathan Gillespie Date: Thu, 16 Mar 2017 12:37:53 +0100 Subject: [PATCH 16/23] Added asserts and new methods to SObjectRepository_Tests.cls --- src/classes/SObjectRepository_Tests.cls | 74 +++++++++++++++++++------ 1 file changed, 58 insertions(+), 16 deletions(-) diff --git a/src/classes/SObjectRepository_Tests.cls b/src/classes/SObjectRepository_Tests.cls index 0d59c3f..2f885e1 100644 --- a/src/classes/SObjectRepository_Tests.cls +++ b/src/classes/SObjectRepository_Tests.cls @@ -11,6 +11,10 @@ private class SObjectRepository_Tests { super(Schema.Lead.SObjectType, new List{Schema.Lead.Status}); } + public LeadRepository(Schema.FieldSet fieldSet) { + super(Schema.Lead.SObjectType, fieldSet); + } + public Lead getById(Id leadId) { return (Lead)this.queryBuilder .whereField(Schema.Lead.Id, new QueryOperator().EQUALS, leadId) @@ -49,7 +53,6 @@ private class SObjectRepository_Tests { public List searchInFieldsBySearchGroup(String searchTerm, QuerySearchGroup searchGroup) { return (List)this.queryBuilder .orderBy(Schema.Lead.CreatedDate, QuerySortOrder.DESCENDING) - .limitCount(10) .setAsUpdate() // SOSL cannot use FOR UPDATE. This will execute, but a warning debug statement will indicate that it is ignored .getSearchResults(searchTerm, searchGroup); } @@ -82,44 +85,84 @@ private class SObjectRepository_Tests { insert leadList; } + @isTest + static void it_should_instantiate_new_instance_with_fieldset() { + // We don't want to include unnecessary metadata in this project, like custom field sets, but we still want to test functionality + // We'll pass a null field set to make sure a field set can be used, even though the value is null + Schema.FieldSet fieldSet; + + Test.startTest(); + SObjectRepository_Tests.LeadRepository leadRepo = new SObjectRepository_Tests.LeadRepository(fieldSet); + System.assertNotEquals(null, leadRepo); + Test.stopTest(); + } + @isTest static void it_should_get_by_id_when_id() { Lead expectedLead = [SELECT Id FROM Lead LIMIT 1]; - // Implement test code - //System.assert(false, 'Finish writing your test!'); + + Test.startTest(); Lead returnedLead = new SObjectRepository_Tests.LeadRepository().getById(expectedLead.Id); + Test.stopTest(); + + System.assertEquals(expectedLead.Id, returnedLead.Id); } @isTest static void it_should_get_by_id_when_list_of_id() { Map expectedLeadList = new Map([SELECT Id FROM Lead]); - // Implement test code - //System.assert(false, 'Finish writing your test!'); + + Test.startTest(); List returnedLeadList = new SObjectRepository_Tests.LeadRepository().getById(new List(expectedLeadList.keySet())); + Test.stopTest(); + + System.assertNotEquals(null, expectedLeadList); + System.assert(!expectedLeadList.isEmpty()); + System.assertEquals(expectedLeadList.size(), returnedLeadList.size()); } @isTest static void it_should_return_my_recent_leads() { - List expectedLeadList = [SELECT Id FROM Lead]; - // Implement test code - //System.assert(false, 'Finish writing your test!'); - List returnedLeadList = new SObjectRepository_Tests.LeadRepository().getMyRecentLeads(3); + List expectedLeadList = [SELECT Id FROM Lead LIMIT 2]; + + Test.startTest(); + List returnedLeadList = new SObjectRepository_Tests.LeadRepository().getMyRecentLeads(expectedLeadList.size()); + Test.stopTest(); + + System.assertNotEquals(null, expectedLeadList); + System.assert(!expectedLeadList.isEmpty()); + System.assertEquals(expectedLeadList.size(), returnedLeadList.size()); } @isTest static void it_should_return_new_this_week_by_id() { Map expectedLeadMap = new Map([SELECT Id FROM Lead]); - // Implement test code - //System.assert(false, 'Finish writing your test!'); + + Test.startTest(); List returnedLeadList = new SObjectRepository_Tests.LeadRepository().getNewThisWeekById(new List(expectedLeadMap.keySet())); + Test.stopTest(); + + System.assertNotEquals(null, expectedLeadMap); + System.assert(!expectedLeadMap.isEmpty()); + System.assertEquals(expectedLeadMap.size(), returnedLeadList.size()); } @isTest static void it_should_search_in_all_fields() { - Map expectedLeadList = new Map([SELECT Id FROM Lead]); - // Implement test code - //System.assert(false, 'Finish writing your test!'); - List returnedLeadList = new SObjectRepository_Tests.LeadRepository().searchInAllFields('Gillespie'); + String searchTerm = 'Gillespie'; + Map soslLeadMap = new Map([SELECT Id, Name FROM Lead]); + Test.setFixedSearchResults(new List(soslLeadMap.keySet())); + + List expectedLeadList = [FIND :searchTerm IN ALL FIELDS RETURNING Lead(Id, Name)][0]; + System.assertNotEquals(0, expectedLeadList.size()); + + Test.startTest(); + List returnedLeadList = new SObjectRepository_Tests.LeadRepository().searchInAllFields(searchTerm); + Test.stopTest(); + + System.assertNotEquals(null, expectedLeadList); + System.assert(!expectedLeadList.isEmpty()); + System.assertEquals(expectedLeadList.size(), returnedLeadList.size()); } @isTest @@ -178,7 +221,6 @@ private class SObjectRepository_Tests { // TODO figure out why the hard delete doesn't work in unit tests } - @isTest static void it_should_undelete_a_single_record() { Lead existingLead = [SELECT Id, IsDeleted FROM Lead LIMIT 1]; From eb1b267c0394c37a1a44b38b9a69369f4a8b671f Mon Sep 17 00:00:00 2001 From: Jonathan Gillespie Date: Thu, 16 Mar 2017 13:02:43 +0100 Subject: [PATCH 17/23] Removed some extra line breaks in QueryUtils_Tests.cls --- src/classes/QueryUtils_Tests.cls | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/classes/QueryUtils_Tests.cls b/src/classes/QueryUtils_Tests.cls index cffc316..1c31417 100644 --- a/src/classes/QueryUtils_Tests.cls +++ b/src/classes/QueryUtils_Tests.cls @@ -46,7 +46,6 @@ private class QueryUtils_Tests { Boolean providedValue = true; String expectedString = String.valueOf(providedValue); - Test.startTest(); String returnedValue = QueryUtils.toQueryString(providedValue); Test.stopTest(); @@ -135,7 +134,6 @@ private class QueryUtils_Tests { insert providedValue; String expectedString = '\'' + providedValue.Id + '\''; - Test.startTest(); String returnedValue = QueryUtils.toQueryString(providedValue); Test.stopTest(); From ba21b1990a0ddc2a1b8fac338b93d033e2524eac Mon Sep 17 00:00:00 2001 From: Jonathan Gillespie Date: Thu, 16 Mar 2017 17:05:11 +0100 Subject: [PATCH 18/23] Changed Logger.cls to use static methods - everything now calls Logger directly --- src/classes/ILogger.cls | 11 --------- src/classes/ILogger.cls-meta.xml | 5 ----- src/classes/Logger.cls | 32 +++++++++++++++------------ src/classes/NebulaCore.cls | 11 --------- src/classes/QueryBuilder.cls | 14 ++++++------ src/classes/SObjectRecordTypes.cls | 10 ++++----- src/classes/SObjectTriggerHandler.cls | 28 +++++++++++------------ 7 files changed, 44 insertions(+), 67 deletions(-) delete mode 100644 src/classes/ILogger.cls delete mode 100644 src/classes/ILogger.cls-meta.xml diff --git a/src/classes/ILogger.cls b/src/classes/ILogger.cls deleted file mode 100644 index 2a5de02..0000000 --- a/src/classes/ILogger.cls +++ /dev/null @@ -1,11 +0,0 @@ -/************************************************************************************************* -* This file is part of the Nebula Framework project, released under the MIT License. * -* See LICENSE file or go to https://github.com/jongpie/NebulaFramework for full license details. * -*************************************************************************************************/ -public interface ILogger { - - void addEntry(INebulaCore moduleClass, String message); - void addEntry(INebulaCore moduleClass, String message, Exception ex); - void saveLogs(); - -} \ No newline at end of file diff --git a/src/classes/ILogger.cls-meta.xml b/src/classes/ILogger.cls-meta.xml deleted file mode 100644 index cbddff8..0000000 --- a/src/classes/ILogger.cls-meta.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - 38.0 - Active - diff --git a/src/classes/Logger.cls b/src/classes/Logger.cls index 43d5df7..6161c8c 100644 --- a/src/classes/Logger.cls +++ b/src/classes/Logger.cls @@ -2,32 +2,36 @@ * This file is part of the Nebula Framework project, released under the MIT License. * * See LICENSE file or go to https://github.com/jongpie/NebulaFramework for full license details. * *************************************************************************************************/ -public without sharing class Logger implements ILogger { +public without sharing class Logger { private static Id logId; private static Attachment logAttachment; private static List logMessages; - public Logger() { + static { Logger.logMessages = Logger.logMessages == null ? new List() : Logger.logMessages; - Logger.logAttachment = Logger.logAttachment == null ? this.createLogAttachment() : Logger.logAttachment; + Logger.logAttachment = Logger.logAttachment == null ? createLogAttachment() : Logger.logAttachment; } - public void addEntry(INebulaCore moduleClass, String message) { - this.addEntry(moduleClass, message, null); + public static void addEntry(INebulaCore moduleClass, String message) { + addEntry(moduleClass, message, null); } - public void addEntry(INebulaCore moduleClass, String message, Exception ex) { + public static void addEntry(String message) { + addEntry(null, message, null); + } + + public static void addEntry(INebulaCore moduleClass, String message, Exception ex) { Logger.Message logMessage = new Logger.Message(moduleClass, message, ex); Logger.logMessages.add(logMessage); } - public void saveLogs() { - this.saveTransactionLog(); - this.saveSingleLogFile(); + public static void saveLogs() { + saveTransactionLog(); + saveSingleLogFile(); } - private void saveTransactionLog() { + private static void saveTransactionLog() { if(Logger.logId != null) return; NebulaLog__c newLog = new NebulaLog__c( @@ -39,7 +43,7 @@ public without sharing class Logger implements ILogger { Logger.logId = newLog.Id; } - private void saveSingleLogFile() { + private static void saveSingleLogFile() { String parsedMessageString = 'NebulaCore.TRANSACTION_ID: ' + NebulaCore.TRANSACTION_ID + '\nInitial Class: ' + NebulaCore.INITIAL_CLASS; @@ -65,7 +69,7 @@ public without sharing class Logger implements ILogger { upsert Logger.logAttachment; } - private Attachment createLogAttachment() { + private static Attachment createLogAttachment() { Attachment attachment = new Attachment( ContentType = 'text/plain', IsPrivate = false, @@ -83,8 +87,8 @@ public without sharing class Logger implements ILogger { private Datetime timestamp; public Message(INebulaCore moduleClass, String message, Exception ex) { - this.classModule = moduleClass.getClassModule(); - this.className = moduleClass.getClassName(); + this.classModule = moduleClass == null ? null : moduleClass.getClassModule(); + this.className = moduleClass == null ? null : moduleClass.getClassName(); this.ex = ex; this.message = message; this.timestamp = System.now(); diff --git a/src/classes/NebulaCore.cls b/src/classes/NebulaCore.cls index 2812cbc..1113ebd 100644 --- a/src/classes/NebulaCore.cls +++ b/src/classes/NebulaCore.cls @@ -16,11 +16,8 @@ public abstract class NebulaCore implements INebulaCore { public enum Module { RECORD_TYPES, REPOSITORY, SETTINGS, TRIGGER_HANDLER } protected final Module currentModule; - private final ILogger logger; protected NebulaCore() { - this.logger = new Logger(); - if(NebulaCore.INITIAL_CLASS == null) NebulaCore.INITIAL_CLASS = this.getClassName(); if(NebulaCore.INITIAL_MODULE == null) NebulaCore.INITIAL_MODULE = this.getClassModule(); } @@ -37,12 +34,4 @@ public abstract class NebulaCore implements INebulaCore { return this.currentModule; } - protected void addLogEntry(String message) { - this.logger.addEntry(this, message); - } - - protected void saveLogs() { - this.logger.saveLogs(); - } - } \ No newline at end of file diff --git a/src/classes/QueryBuilder.cls b/src/classes/QueryBuilder.cls index e591cc2..a1e98ac 100644 --- a/src/classes/QueryBuilder.cls +++ b/src/classes/QueryBuilder.cls @@ -85,7 +85,7 @@ public without sharing class QueryBuilder extends NebulaCore implements IQueryBu List results = Database.query(query); String logEntry = 'Query:\n' + query + '\n\nResults:\n' + results; - this.addLogEntry(logEntry); + Logger.addEntry(this, logEntry); return results; } @@ -95,7 +95,7 @@ public without sharing class QueryBuilder extends NebulaCore implements IQueryBu List results = Search.query(query)[0]; String logEntry = 'Query:\n' + query + '\n\nResults:\n' + results; - this.addLogEntry(logEntry); + Logger.addEntry(this, logEntry); return results; } @@ -146,7 +146,7 @@ public without sharing class QueryBuilder extends NebulaCore implements IQueryBu + this.getLimitCountString() + this.getForUpdateString(); - this.addLogEntry(query); + Logger.addEntry(this, query); return query; } @@ -161,10 +161,10 @@ public without sharing class QueryBuilder extends NebulaCore implements IQueryBu + this.getLimitCountString() + ')'; - if(this.forUpdate) this.addLogEntry('SOSL Search Query method flagged as FOR UPDATE. SOSL cannot use FOR UPDATE, ignoring'); - if(this.filterScope != null) this.addLogEntry('SOSL Search Query method flagged as USING SCOPE ' + this.filterScope + '. SOSL cannot use USING SCOPE, ignoring'); + if(this.forUpdate) Logger.addEntry(this, 'SOSL Search Query method flagged as FOR UPDATE. SOSL cannot use FOR UPDATE, ignoring'); + if(this.filterScope != null) Logger.addEntry(this, 'SOSL Search Query method flagged as USING SCOPE ' + this.filterScope + '. SOSL cannot use USING SCOPE, ignoring'); - this.addLogEntry(query); + Logger.addEntry(this, query); return query; } @@ -182,7 +182,7 @@ public without sharing class QueryBuilder extends NebulaCore implements IQueryBu this.queryFields.add(commonFieldName.toLowerCase()); } - this.addLogEntry('this.queryFields=' + this.queryFields); + Logger.addEntry(this, 'this.queryFields=' + this.queryFields); } private void addFieldSetMembers() { diff --git a/src/classes/SObjectRecordTypes.cls b/src/classes/SObjectRecordTypes.cls index 3c7aaa1..5ee84d2 100644 --- a/src/classes/SObjectRecordTypes.cls +++ b/src/classes/SObjectRecordTypes.cls @@ -16,7 +16,7 @@ public abstract class SObjectRecordTypes extends NebulaCore { this.sobjectName = describeSObjectResult.getName(); - this.addLogEntry('Getting record types for ' + this.sobjectName); + Logger.addEntry(this, 'Getting record types for ' + this.sobjectName); this.populateCache(); @@ -38,21 +38,21 @@ public abstract class SObjectRecordTypes extends NebulaCore { if(NebulaSettings.recordTypesSettings.LazyLoad__c){ whereClauseList.add('SObjectType = \'' + this.sobjectName + '\''); - this.addLogEntry('NebulaSettings.recordTypesSettings.LazyLoad__c=' + NebulaSettings.recordTypesSettings.LazyLoad__c); - this.addLogEntry('this.sobjectName=' + this.sobjectName); + Logger.addEntry(this, 'NebulaSettings.recordTypesSettings.LazyLoad__c=' + NebulaSettings.recordTypesSettings.LazyLoad__c); + Logger.addEntry(this, 'this.sobjectName=' + this.sobjectName); } if(NebulaSettings.recordTypesSettings.ExcludeManagedRecordTypes__c) whereClauseList.add('NamespacePrefix = null'); if(!whereClauseList.isEmpty()) query += ' WHERE ' + String.join(whereClauseList, ' AND '); query += ' ORDER BY DeveloperName'; - this.addLogEntry('SObjectRecordTypes query=' + query); + Logger.addEntry(this, 'SObjectRecordTypes query=' + query); if(!cachedRecordTypesBySObjectMap.containsKey(this.sobjectName)) cachedRecordTypesBySObjectMap.put(this.sobjectName, new List()); List recordTypeList = (List)Database.query(query); for(RecordType recordType : recordTypeList) cachedRecordTypesBySObjectMap.get(this.sobjectName).add(recordType); - this.addLogEntry('cachedRecordTypesBySObjectMap=' + cachedRecordTypesBySObjectMap); + Logger.addEntry(this, 'cachedRecordTypesBySObjectMap=' + cachedRecordTypesBySObjectMap); } private Map getAllRecordTypesById() { diff --git a/src/classes/SObjectTriggerHandler.cls b/src/classes/SObjectTriggerHandler.cls index bf8ee03..b229cb0 100644 --- a/src/classes/SObjectTriggerHandler.cls +++ b/src/classes/SObjectTriggerHandler.cls @@ -40,22 +40,22 @@ public abstract class SObjectTriggerHandler extends NebulaCore implements ISObje this.getClassName(); - this.addLogEntry('Initializing ' + this.getClassName()); + Logger.addEntry(this, 'Initializing ' + this.getClassName()); this.setTriggerContext(); this.validateTriggerContext(); this.setTriggerRecords(); } public void execute() { - this.addLogEntry('Execute method called for ' + this.getClassName()); + Logger.addEntry(this, 'Execute method called for ' + this.getClassName()); // Check the custom setting. If it's disabled, stop everything, show's over // You don't have to go home but you can't stay here if(!shouldExecuteTriggers()) { - this.addLogEntry('Skipping execution of class ' + this.getClassName()); + Logger.addEntry(this, 'Skipping execution of class ' + this.getClassName()); return; } - this.addLogEntry(this.getClassName() + ' is enabled, proceeding with execution'); + Logger.addEntry(this, this.getClassName() + ' is enabled, proceeding with execution'); this.setHashCode(); @@ -63,16 +63,16 @@ public abstract class SObjectTriggerHandler extends NebulaCore implements ISObje if(this.isTestMode) sobjectType = String.valueOf(Schema.Lead.SObjectType); else sobjectType = Trigger.new == null ? String.valueOf(Trigger.old.getSObjectType()) : String.valueOf(Trigger.new.getSObjectType()); - this.addLogEntry('Starting execute method for: ' + sobjectType); - this.addLogEntry('Hash codes already processed: ' + SObjectTriggerHandler.hashCodesForProcessedRecords); - this.addLogEntry('Hash code for current records: ' + this.hashCode); - this.addLogEntry('Trigger context for current records: ' + this.context); - this.addLogEntry('Number of current records: ' + Trigger.size); + Logger.addEntry(this, 'Starting execute method for: ' + sobjectType); + Logger.addEntry(this, 'Hash codes already processed: ' + SObjectTriggerHandler.hashCodesForProcessedRecords); + Logger.addEntry(this, 'Hash code for current records: ' + this.hashCode); + Logger.addEntry(this, 'Trigger context for current records: ' + this.context); + Logger.addEntry(this, 'Number of current records: ' + Trigger.size); if(this.haveRecordsAlreadyBeenProcessed()) { - this.addLogEntry('Records already processed for this context, skipping'); + Logger.addEntry(this, 'Records already processed for this context, skipping'); return; - } else this.addLogEntry('Records have not been processed for this context, continuing'); + } else Logger.addEntry(this, 'Records have not been processed for this context, continuing'); if(this.context == TriggerContext.BEFORE_INSERT) this.executeBeforeInsert(this.recordList); else if(this.context == TriggerContext.BEFORE_UPDATE) this.executeBeforeUpdate(this.recordList, this.recordMap, this.oldRecordList, this.oldRecordMap); @@ -82,7 +82,7 @@ public abstract class SObjectTriggerHandler extends NebulaCore implements ISObje else if(this.context == TriggerContext.AFTER_DELETE) this.executeAfterDelete(this.oldRecordList, this.oldRecordMap); else if(this.context == TriggerContext.AFTER_UNDELETE) this.executeAfterUndelete(this.recordList, this.recordMap); - if(Trigger.isAfter) this.saveLogs(); + if(Trigger.isAfter) Logger.saveLogs(); } protected virtual void executeBeforeInsert(List newRecordList) {} @@ -120,12 +120,12 @@ public abstract class SObjectTriggerHandler extends NebulaCore implements ISObje } private Boolean shouldExecuteTriggers() { - this.addLogEntry('nebulaSettings.triggerHandlerSettings.ExecuteTriggers__c=' + NebulaSettings.triggerHandlerSettings.ExecuteTriggers__c); + Logger.addEntry(this, 'nebulaSettings.triggerHandlerSettings.ExecuteTriggers__c=' + NebulaSettings.triggerHandlerSettings.ExecuteTriggers__c); String handlerClassesToSkipString = NebulaSettings.triggerHandlerSettings.HandlerClassesToSkip__c; if(handlerClassesToSkipString == null) handlerClassesToSkipString = ''; Set handlerClassesToSkip = new Set(handlerClassesToSkipString.toLowerCase().split('\n')); - this.addLogEntry('nebulaSettings.triggerHandlerSettings.HandlerClassesToSkip__c=' + NebulaSettings.triggerHandlerSettings.HandlerClassesToSkip__c); + Logger.addEntry(this, 'nebulaSettings.triggerHandlerSettings.HandlerClassesToSkip__c=' + NebulaSettings.triggerHandlerSettings.HandlerClassesToSkip__c); // If ExecuteTriggers == true and the current class isn't in the list of handlers to skip, then execute return NebulaSettings.triggerHandlerSettings.ExecuteTriggers__c && !handlerClassesToSkip.contains(this.getClassName().toLowerCase()); From c33a95e4cbf334a1ab6a625cbd6a3b36d851ca53 Mon Sep 17 00:00:00 2001 From: Jonathan Gillespie Date: Thu, 16 Mar 2017 17:13:27 +0100 Subject: [PATCH 19/23] Logger now checks the custom setting to see if it is enabled --- src/classes/Logger.cls | 2 ++ src/classes/NebulaSettings.cls | 13 +++++++++++++ src/classes/NebulaSettings_Tests.cls | 15 +++++++++++++++ 3 files changed, 30 insertions(+) diff --git a/src/classes/Logger.cls b/src/classes/Logger.cls index 6161c8c..b973375 100644 --- a/src/classes/Logger.cls +++ b/src/classes/Logger.cls @@ -27,6 +27,8 @@ public without sharing class Logger { } public static void saveLogs() { + if(!NebulaSettings.loggerSettings.EnableLogging__c) return; + saveTransactionLog(); saveSingleLogFile(); } diff --git a/src/classes/NebulaSettings.cls b/src/classes/NebulaSettings.cls index 57ddeee..a907772 100644 --- a/src/classes/NebulaSettings.cls +++ b/src/classes/NebulaSettings.cls @@ -4,6 +4,7 @@ *************************************************************************************************/ public without sharing class NebulaSettings { + public static NebulaLoggerSettings__c loggerSettings; public static NebulaRecordTypesSettings__c recordTypesSettings; public static NebulaRepositorySettings__c repositorySettings; public static NebulaTriggerHandlerSettings__c triggerHandlerSettings; @@ -18,23 +19,35 @@ public without sharing class NebulaSettings { } private static void loadCustomSettings() { + loadLoggerSettings(); loadRecordTypesSettings(); loadRepositorySettings(); loadTriggerHandlerSettings(); } private static void deleteExistingCustomSettings() { + delete [SELECT Id FROM NebulaLoggerSettings__c]; delete [SELECT Id FROM NebulaRecordTypesSettings__c]; delete [SELECT Id FROM NebulaRepositorySettings__c]; delete [SELECT Id FROM NebulaTriggerHandlerSettings__c]; } private static void createCustomSettings() { + upsert NebulaLoggerSettings__c.getOrgDefaults(); upsert NebulaRecordTypesSettings__c.getOrgDefaults(); upsert NebulaRepositorySettings__c.getOrgDefaults(); upsert NebulaTriggerHandlerSettings__c.getOrgDefaults(); } + private static void loadLoggerSettings() { + loggerSettings = NebulaLoggerSettings__c.getInstance(); + + if(loggerSettings.Id == null) { + upsert NebulaLoggerSettings__c.getOrgDefaults(); + loggerSettings = NebulaLoggerSettings__c.getInstance(); + } + } + private static void loadRecordTypesSettings() { recordTypesSettings = NebulaRecordTypesSettings__c.getInstance(); diff --git a/src/classes/NebulaSettings_Tests.cls b/src/classes/NebulaSettings_Tests.cls index 26649e8..f45f9f2 100644 --- a/src/classes/NebulaSettings_Tests.cls +++ b/src/classes/NebulaSettings_Tests.cls @@ -15,6 +15,16 @@ private class NebulaSettings_Tests { Test.stopTest(); } + @isTest + static void it_should_return_loggerSettings() { + List existingSettings = [SELECT Id FROM NebulaLoggerSettings__c]; + System.assert(existingSettings.isEmpty()); + + Test.startTest(); + System.assertNotEquals(null, NebulaSettings.loggerSettings); + Test.stopTest(); + } + @isTest static void it_should_return_repositorySettings() { List existingSettings = [SELECT Id FROM NebulaRepositorySettings__c]; @@ -38,6 +48,10 @@ private class NebulaSettings_Tests { @isTest static void it_should_reset_all_settings_to_defaults() { + NebulaLoggerSettings__c nebulaLoggerSettings = NebulaLoggerSettings__c.getInstance(); + upsert nebulaLoggerSettings; + Id originalLoggerSettingsId = NebulaLoggerSettings__c.getInstance().Id; + NebulaRecordTypesSettings__c nebulaRecordTypesSettings = NebulaRecordTypesSettings__c.getInstance(); upsert nebulaRecordTypesSettings; Id originalRecordTypesSettingsId = NebulaRecordTypesSettings__c.getInstance().Id; @@ -54,6 +68,7 @@ private class NebulaSettings_Tests { NebulaSettings.resetAllSettingsToDefaults(); Test.stopTest(); + System.assertNotEquals(originalLoggerSettingsId, NebulaLoggerSettings__c.getInstance().Id); System.assertNotEquals(originalRecordTypesSettingsId, NebulaRecordTypesSettings__c.getInstance().Id); System.assertNotEquals(originalRepositorySettingsId, NebulaRepositorySettings__c.getInstance().Id); System.assertNotEquals(originalTriggerHandlerSettingsId, NebulaTriggerHandlerSettings__c.getInstance().Id); From 9954893b274c9be88d7dca637fc41449015105ed Mon Sep 17 00:00:00 2001 From: Jonathan Gillespie Date: Fri, 17 Mar 2017 08:11:00 +0100 Subject: [PATCH 20/23] Renamed QueryUtils to QueryArgumentFormatter.cls --- src/classes/{QueryUtils.cls => QueryArgumentFormatter.cls} | 0 ...ueryUtils.cls-meta.xml => QueryArgumentFormatter.cls-meta.xml} | 0 .../{QueryUtils_Tests.cls => QueryArgumentFormatter_Tests.cls} | 0 ...sts.cls-meta.xml => QueryArgumentFormatter_Tests.cls-meta.xml} | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename src/classes/{QueryUtils.cls => QueryArgumentFormatter.cls} (100%) rename src/classes/{QueryUtils.cls-meta.xml => QueryArgumentFormatter.cls-meta.xml} (100%) rename src/classes/{QueryUtils_Tests.cls => QueryArgumentFormatter_Tests.cls} (100%) rename src/classes/{QueryUtils_Tests.cls-meta.xml => QueryArgumentFormatter_Tests.cls-meta.xml} (100%) diff --git a/src/classes/QueryUtils.cls b/src/classes/QueryArgumentFormatter.cls similarity index 100% rename from src/classes/QueryUtils.cls rename to src/classes/QueryArgumentFormatter.cls diff --git a/src/classes/QueryUtils.cls-meta.xml b/src/classes/QueryArgumentFormatter.cls-meta.xml similarity index 100% rename from src/classes/QueryUtils.cls-meta.xml rename to src/classes/QueryArgumentFormatter.cls-meta.xml diff --git a/src/classes/QueryUtils_Tests.cls b/src/classes/QueryArgumentFormatter_Tests.cls similarity index 100% rename from src/classes/QueryUtils_Tests.cls rename to src/classes/QueryArgumentFormatter_Tests.cls diff --git a/src/classes/QueryUtils_Tests.cls-meta.xml b/src/classes/QueryArgumentFormatter_Tests.cls-meta.xml similarity index 100% rename from src/classes/QueryUtils_Tests.cls-meta.xml rename to src/classes/QueryArgumentFormatter_Tests.cls-meta.xml From e502fd34a6cbfdca3370ada7ad32ec2316b1239b Mon Sep 17 00:00:00 2001 From: Jonathan Gillespie Date: Fri, 17 Mar 2017 08:13:06 +0100 Subject: [PATCH 21/23] QueryArgumentFormatter no longer uses static methods --- src/classes/QueryArgumentFormatter.cls | 56 ++++++++++++-------- src/classes/QueryArgumentFormatter_Tests.cls | 28 +++++----- 2 files changed, 47 insertions(+), 37 deletions(-) diff --git a/src/classes/QueryArgumentFormatter.cls b/src/classes/QueryArgumentFormatter.cls index 2709057..6e96f84 100644 --- a/src/classes/QueryArgumentFormatter.cls +++ b/src/classes/QueryArgumentFormatter.cls @@ -2,40 +2,50 @@ * This file is part of the Nebula Framework project, released under the MIT License. * * See LICENSE file or go to https://github.com/jongpie/NebulaFramework for full license details. * *************************************************************************************************/ -public without sharing class QueryUtils { +public without sharing class QueryArgumentFormatter { - public static String toQueryString(List valueList) { - List parsedValueList = new List(); - for(Object value : valueList) parsedValueList.add(toQueryString(value)); - return '(' + String.join(parsedValueList, ',') + ')'; + private Object argumentValue; + + public QueryArgumentFormatter(Object argumentValue) { + this.argumentValue = argumentValue; + } + + public String getValue() { + return this.objectToQueryString(this.argumentValue); } - public static String toQueryString(Object value) { - if(value == null) return null; - else if(value instanceof List) return toQueryString((List)value); - else if(value instanceof QueryDateLiteral) { - QueryDateLiteral dateLiteral = (QueryDateLiteral)value; + private String objectToQueryString(Object valueToFormat) { + if(valueToFormat == null) return null; + else if(valueToFormat instanceof List) return this.listToQueryString((List)valueToFormat); + else if(valueToFormat instanceof QueryDateLiteral) { + QueryDateLiteral dateLiteral = (QueryDateLiteral)valueToFormat; return dateLiteral.getValue(); } - else if(value instanceof Boolean) return String.valueOf((Boolean)value); - else if(value instanceof Date) return String.valueOf((Date)value); - else if(value instanceof Datetime) { - Datetime datetimeValue = (Datetime)value; + else if(valueToFormat instanceof Boolean) return String.valueOf((Boolean)valueToFormat); + else if(valueToFormat instanceof Date) return String.valueOf((Date)valueToFormat); + else if(valueToFormat instanceof Datetime) { + Datetime datetimeValue = (Datetime)valueToFormat; return datetimeValue.format('yyyy-MM-dd\'T\'HH:mm:ss\'Z\'', 'Greenwich Mean Time'); } - else if(value instanceof Decimal) return String.valueOf((Decimal)value); - else if(value instanceof Double) return String.valueOf((Double)value); - else if(value instanceof Integer) return String.valueOf((Integer)value); - else if(value instanceof Long) return String.valueOf((Long)value); - else if(value instanceof SObject) { - SObject record = (SObject)value; + else if(valueToFormat instanceof Decimal) return String.valueOf((Decimal)valueToFormat); + else if(valueToFormat instanceof Double) return String.valueOf((Double)valueToFormat); + else if(valueToFormat instanceof Integer) return String.valueOf((Integer)valueToFormat); + else if(valueToFormat instanceof Long) return String.valueOf((Long)valueToFormat); + else if(valueToFormat instanceof SObject) { + SObject record = (SObject)valueToFormat; return wrapInSingleQuotes(record.Id); } - else if(value instanceof String) return wrapInSingleQuotes((String)value); - else return String.valueOf(value); + else if(valueToFormat instanceof String) return wrapInSingleQuotes((String)valueToFormat); + else return String.valueOf(valueToFormat); + } + + private String listToQueryString(List valueList) { + List parsedValueList = new List(); + for(Object value : valueList) parsedValueList.add(this.objectToQueryString(value)); + return '(' + String.join(parsedValueList, ',') + ')'; } - public static String wrapInSingleQuotes(String input) { + private String wrapInSingleQuotes(String input) { if(input.left(1) != '\'') input = '\'' + input; if(input.right(1) != '\'') input = input + '\''; return input; diff --git a/src/classes/QueryArgumentFormatter_Tests.cls b/src/classes/QueryArgumentFormatter_Tests.cls index 1c31417..8cc19e1 100644 --- a/src/classes/QueryArgumentFormatter_Tests.cls +++ b/src/classes/QueryArgumentFormatter_Tests.cls @@ -3,7 +3,7 @@ * See LICENSE file or go to https://github.com/jongpie/NebulaFramework for full license details. * *************************************************************************************************/ @isTest -private class QueryUtils_Tests { +private class QueryArgumentFormatter_Tests { @isTest static void it_should_return_query_string_for_null() { @@ -11,7 +11,7 @@ private class QueryUtils_Tests { String expectedString = null; Test.startTest(); - String returnedValue = QueryUtils.toQueryString(providedValue); + String returnedValue = new QueryArgumentFormatter(providedValue).getValue(); Test.stopTest(); System.assertEquals(expectedString, returnedValue); @@ -23,7 +23,7 @@ private class QueryUtils_Tests { String expectedString = '(' + String.join(providedValueList, ',') + ')'; Test.startTest(); - String returnedValue = QueryUtils.toQueryString(providedValueList); + String returnedValue = new QueryArgumentFormatter(providedValueList).getValue(); Test.stopTest(); System.assertEquals(expectedString, returnedValue); @@ -35,7 +35,7 @@ private class QueryUtils_Tests { String expectedString = providedValue.getValue(); Test.startTest(); - String returnedValue = QueryUtils.toQueryString(providedValue); + String returnedValue = new QueryArgumentFormatter(providedValue).getValue(); Test.stopTest(); System.assertEquals(expectedString, returnedValue); @@ -47,7 +47,7 @@ private class QueryUtils_Tests { String expectedString = String.valueOf(providedValue); Test.startTest(); - String returnedValue = QueryUtils.toQueryString(providedValue); + String returnedValue = new QueryArgumentFormatter(providedValue).getValue(); Test.stopTest(); System.assertEquals(expectedString, returnedValue); @@ -59,7 +59,7 @@ private class QueryUtils_Tests { String expectedString = String.valueOf(providedValue); Test.startTest(); - String returnedValue = QueryUtils.toQueryString(providedValue); + String returnedValue = new QueryArgumentFormatter(providedValue).getValue(); Test.stopTest(); System.assertEquals(expectedString, returnedValue); @@ -71,7 +71,7 @@ private class QueryUtils_Tests { String expectedString = providedValue.format('yyyy-MM-dd\'T\'HH:mm:ss\'Z\'', 'Greenwich Mean Time'); Test.startTest(); - String returnedValue = QueryUtils.toQueryString(providedValue); + String returnedValue = new QueryArgumentFormatter(providedValue).getValue(); Test.stopTest(); System.assertEquals(expectedString, returnedValue); @@ -83,7 +83,7 @@ private class QueryUtils_Tests { String expectedString = String.valueOf(providedValue); Test.startTest(); - String returnedValue = QueryUtils.toQueryString(providedValue); + String returnedValue = new QueryArgumentFormatter(providedValue).getValue(); Test.stopTest(); System.assertEquals(expectedString, returnedValue); @@ -95,7 +95,7 @@ private class QueryUtils_Tests { String expectedString = String.valueOf(providedValue); Test.startTest(); - String returnedValue = QueryUtils.toQueryString(providedValue); + String returnedValue = new QueryArgumentFormatter(providedValue).getValue(); Test.stopTest(); System.assertEquals(expectedString, returnedValue); @@ -107,7 +107,7 @@ private class QueryUtils_Tests { String expectedString = String.valueOf(providedValue); Test.startTest(); - String returnedValue = QueryUtils.toQueryString(providedValue); + String returnedValue = new QueryArgumentFormatter(providedValue).getValue(); Test.stopTest(); System.assertEquals(expectedString, returnedValue); @@ -119,7 +119,7 @@ private class QueryUtils_Tests { String expectedString = String.valueOf(providedValue); Test.startTest(); - String returnedValue = QueryUtils.toQueryString(providedValue); + String returnedValue = new QueryArgumentFormatter(providedValue).getValue(); Test.stopTest(); System.assertEquals(expectedString, returnedValue); @@ -135,7 +135,7 @@ private class QueryUtils_Tests { String expectedString = '\'' + providedValue.Id + '\''; Test.startTest(); - String returnedValue = QueryUtils.toQueryString(providedValue); + String returnedValue = new QueryArgumentFormatter(providedValue).getValue(); Test.stopTest(); System.assertEquals(expectedString, returnedValue); @@ -147,7 +147,7 @@ private class QueryUtils_Tests { String expectedString = '\'' + providedValue + '\''; Test.startTest(); - String returnedValue = QueryUtils.toQueryString(providedValue); + String returnedValue = new QueryArgumentFormatter(providedValue).getValue(); Test.stopTest(); System.assertEquals(expectedString, returnedValue); @@ -159,7 +159,7 @@ private class QueryUtils_Tests { String expectedString = String.valueOf(providedValue); Test.startTest(); - String returnedValue = QueryUtils.toQueryString(providedValue); + String returnedValue = new QueryArgumentFormatter(providedValue).getValue(); Test.stopTest(); System.assertEquals(expectedString, returnedValue); From 9efd8b4d79421e010137b86ce44aa31a80c13b37 Mon Sep 17 00:00:00 2001 From: Jonathan Gillespie Date: Fri, 17 Mar 2017 08:13:18 +0100 Subject: [PATCH 22/23] Removed an extra linebreak in NebulaSettings_Tests.cls --- src/classes/NebulaSettings_Tests.cls | 1 - 1 file changed, 1 deletion(-) diff --git a/src/classes/NebulaSettings_Tests.cls b/src/classes/NebulaSettings_Tests.cls index 26649e8..aebab20 100644 --- a/src/classes/NebulaSettings_Tests.cls +++ b/src/classes/NebulaSettings_Tests.cls @@ -35,7 +35,6 @@ private class NebulaSettings_Tests { Test.stopTest(); } - @isTest static void it_should_reset_all_settings_to_defaults() { NebulaRecordTypesSettings__c nebulaRecordTypesSettings = NebulaRecordTypesSettings__c.getInstance(); From 420496fbddc8c3b21b36c5770f9d495428d9aefa Mon Sep 17 00:00:00 2001 From: Jonathan Gillespie Date: Fri, 17 Mar 2017 08:17:48 +0100 Subject: [PATCH 23/23] QueryBuilder.cls now uses QueryArgumentFormatter.cls --- src/classes/QueryBuilder.cls | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/classes/QueryBuilder.cls b/src/classes/QueryBuilder.cls index e591cc2..98e5243 100644 --- a/src/classes/QueryBuilder.cls +++ b/src/classes/QueryBuilder.cls @@ -34,7 +34,7 @@ public without sharing class QueryBuilder extends NebulaCore implements IQueryBu } public IQueryBuilder whereField(Schema.SObjectField field, QueryOperator operator, Object value) { - String parsedValue = QueryUtils.toQueryString(value); + String parsedValue = new QueryArgumentFormatter(value).getValue(); this.whereClauseList.add(field + ' ' + operator.getValue() + ' ' + parsedValue); return this; @@ -152,7 +152,7 @@ public without sharing class QueryBuilder extends NebulaCore implements IQueryBu } private String getSearchQueryString(String searchTerm, QuerySearchGroup searchGroup) { - String query = 'FIND ' + QueryUtils.toQueryString(searchTerm) + String query = 'FIND ' + new QueryArgumentFormatter(searchTerm).getValue() + '\nIN ' + searchGroup.name().replace('_', ' ') + '\nRETURNING ' + this.sobjectType + '(' + this.getQueryFieldString()