From 8a5dfdacd94cff179880547429bbd520c9e438fc Mon Sep 17 00:00:00 2001 From: Robert Baillie Date: Thu, 10 Mar 2022 14:23:16 +0000 Subject: [PATCH] Renamed the BulkObjectCache to the correct ObjectCache Removed the defunct SobjectCache Hid references to the partition specification Removed 'getKeys' as this should no longer be needed Removed 'clearAll' from SOQL cache, as this in an inappropriate level (it would clear all Org level cache) Ensure that all classes have inherited sharing --- .../caching/CachedSoqlExecutor.cls | 25 +- .../fflib-extension/caching/ICacheAdaptor.cls | 15 +- .../fflib-extension/caching/NullCache.cls | 71 +- .../{BulkObjectCache.cls => ObjectCache.cls} | 49 +- ....cls-meta.xml => ObjectCache.cls-meta.xml} | 0 .../fflib-extension/caching/OrgCache.cls | 40 +- .../fflib-extension/caching/SessionCache.cls | 22 +- .../fflib-extension/caching/SobjectCache.cls | 139 ---- .../caching/SobjectCache.cls-meta.xml | 5 - .../caching/tests/CachedSoqlExecutorTest.cls | 778 +++++++----------- .../classes/null-objects/NullAction.cls | 2 +- .../classes/null-objects/NullDomain.cls | 2 +- 12 files changed, 389 insertions(+), 759 deletions(-) rename framework/default/ortoo-core/default/classes/fflib-extension/caching/{BulkObjectCache.cls => ObjectCache.cls} (85%) rename framework/default/ortoo-core/default/classes/fflib-extension/caching/{BulkObjectCache.cls-meta.xml => ObjectCache.cls-meta.xml} (100%) delete mode 100644 framework/default/ortoo-core/default/classes/fflib-extension/caching/SobjectCache.cls delete mode 100644 framework/default/ortoo-core/default/classes/fflib-extension/caching/SobjectCache.cls-meta.xml diff --git a/framework/default/ortoo-core/default/classes/fflib-extension/caching/CachedSoqlExecutor.cls b/framework/default/ortoo-core/default/classes/fflib-extension/caching/CachedSoqlExecutor.cls index e6c64ae341a..1f68b28a99e 100644 --- a/framework/default/ortoo-core/default/classes/fflib-extension/caching/CachedSoqlExecutor.cls +++ b/framework/default/ortoo-core/default/classes/fflib-extension/caching/CachedSoqlExecutor.cls @@ -12,7 +12,6 @@ public inherited sharing class CachedSoqlExecutor //NOPMD: incorrect report of t ICacheAdaptor cacheWrapper = new OrgCache(); // by default, configure the cache to use the org version - private final static String PARTITION_NAME = 'core'; private final static Integer CACHE_LIFESPAN_SECONDS = 28800; // TODO: soft setting / option /** @@ -118,30 +117,8 @@ public inherited sharing class CachedSoqlExecutor //NOPMD: incorrect report of t cacheWrapper.remove( generateKey( soql ) ); } - /** - * Clears the cached results for all cached SOQL - */ - public void clearAllCache() - { - String fullSoqlPartitionName = cacheWrapper.createFullyQualifiedPartitionName( PARTITION_NAME ); - for ( String thisKey : cacheWrapper.getKeys() ) - { - String qualifiedKey = qualifiedKey( thisKey ); - if ( cacheWrapper.contains( qualifiedKey ) ) - { - cacheWrapper.remove( qualifiedKey ); - } - } - } - private String generateKey( String soql ) { - String subkey = EncodingUtil.convertToHex( Crypto.generateDigest( 'SHA1', Blob.valueOf( soql ) ) ); - return qualifiedKey( subkey ); - } - - private String qualifiedKey( String subkey ) - { - return cacheWrapper.createFullyQualifiedKey( PARTITION_NAME, subkey ); + return EncodingUtil.convertToHex( Crypto.generateDigest( 'SHA1', Blob.valueOf( soql ) ) ); } } \ No newline at end of file diff --git a/framework/default/ortoo-core/default/classes/fflib-extension/caching/ICacheAdaptor.cls b/framework/default/ortoo-core/default/classes/fflib-extension/caching/ICacheAdaptor.cls index 512d3f5d0bc..75d4a510d9b 100644 --- a/framework/default/ortoo-core/default/classes/fflib-extension/caching/ICacheAdaptor.cls +++ b/framework/default/ortoo-core/default/classes/fflib-extension/caching/ICacheAdaptor.cls @@ -9,13 +9,10 @@ */ public interface ICacheAdaptor { - Boolean hasAccessToCache(); - Boolean isACache(); - Object get( String key ); - void put( String key, Object value, Integer lifespan ); - Set getKeys(); - Boolean contains( String key ); - void remove( String key ); - String createFullyQualifiedPartitionName( String partitionName ); - String createFullyQualifiedKey( String partitionName, String key ); + Boolean hasAccessToCache(); + Boolean isACache(); + Object get( String key ); + void put( String key, Object value, Integer lifespan ); + Boolean contains( String key ); + void remove( String key ); } \ No newline at end of file diff --git a/framework/default/ortoo-core/default/classes/fflib-extension/caching/NullCache.cls b/framework/default/ortoo-core/default/classes/fflib-extension/caching/NullCache.cls index 0007e590817..db5db784508 100644 --- a/framework/default/ortoo-core/default/classes/fflib-extension/caching/NullCache.cls +++ b/framework/default/ortoo-core/default/classes/fflib-extension/caching/NullCache.cls @@ -5,48 +5,33 @@ * * All users are assumed to be allowed to use the cache, but it describes itself as 'not a cache' and effectively does nothing. */ -public class NullCache implements ICacheAdaptor +public inherited sharing class NullCache implements ICacheAdaptor { - public Boolean hasAccessToCache() - { - return true; - } - - public Boolean isACache() - { - return false; - } - - public Object get( String key ) - { - return null; - } - - public void put( String key, Object value, Integer lifespan ) // NOPMD: Intentionally left empty, as this should do nothing in a NullCache - { - } - - public Set getKeys() - { - return new Set(); - } - - public Boolean contains( String key ) - { - return false; - } - - public void remove( String key ) // NOPMD: Intentionally left empty, as this should do nothing in a NullCache - { - } - - public String createFullyQualifiedPartitionName( String partitionName ) - { - return partitionName; - } - - public String createFullyQualifiedKey( String partitionName, String subKey ) - { - return partitionName + '.' + subkey; - } + public Boolean hasAccessToCache() + { + return true; + } + + public Boolean isACache() + { + return false; + } + + public Object get( String key ) + { + return null; + } + + public void put( String key, Object value, Integer lifespan ) // NOPMD: Intentionally left empty, as this should do nothing in a NullCache + { + } + + public Boolean contains( String key ) + { + return false; + } + + public void remove( String key ) // NOPMD: Intentionally left empty, as this should do nothing in a NullCache + { + } } \ No newline at end of file diff --git a/framework/default/ortoo-core/default/classes/fflib-extension/caching/BulkObjectCache.cls b/framework/default/ortoo-core/default/classes/fflib-extension/caching/ObjectCache.cls similarity index 85% rename from framework/default/ortoo-core/default/classes/fflib-extension/caching/BulkObjectCache.cls rename to framework/default/ortoo-core/default/classes/fflib-extension/caching/ObjectCache.cls index 4133a2d33a9..c7c4e9dd83b 100644 --- a/framework/default/ortoo-core/default/classes/fflib-extension/caching/BulkObjectCache.cls +++ b/framework/default/ortoo-core/default/classes/fflib-extension/caching/ObjectCache.cls @@ -8,7 +8,7 @@ * Note: The lifespan of a given object is reset whenever any object in that object's list is written. * That is, either the whole of the list is aged out, or none of it is. */ -public with sharing class BulkObjectCache +public with sharing class ObjectCache { // TODO: do we need to protect against 100kb limit // TODO: could implement a longest time since accessed, first out @@ -16,8 +16,6 @@ public with sharing class BulkObjectCache // TODO: could just ignore and invalidate the cache - check with the rest of the seniors // TODO: Docs on keys - // TODO: hide createFullyQualifiedPartitionName and createFullyQualifiedKey - public class InvalidIdentifierException extends Exceptions.DeveloperException {} public enum CacheScope { ORG, SESSION } @@ -80,7 +78,6 @@ public with sharing class BulkObjectCache ICacheAdaptor cacheWrapper = new OrgCache(); // by default, configure the cache to use the org version - private final static String PARTITION_NAME = 'core'; private final static Integer CACHE_LIFESPAN_SECONDS = 28800; // TODO: soft setting / option /** @@ -89,7 +86,7 @@ public with sharing class BulkObjectCache * @param CacheScope The scope of this cache instance. * @return CachedSoqlExecutor Itself, allowing for a fluent interface */ - public BulkObjectCache setScope( CacheScope scope ) + public ObjectCache setScope( CacheScope scope ) { Contract.requires( scope != null, 'setScope called with a null scope' ); @@ -122,7 +119,7 @@ public with sharing class BulkObjectCache CacheRetrieval values = new CacheRetrieval(); - Map cachedObjects = (Map)cacheWrapper.get( createFullyQualifiedKey( key ) ); + Map cachedObjects = (Map)cacheWrapper.get( key ); if ( cachedObjects == null ) { @@ -194,9 +191,9 @@ public with sharing class BulkObjectCache * * @param String The base key to put the objects into * @param List The SObjects to store - * @return BulkObjectCache Itself, allowing for a fluent interface + * @return ObjectCache Itself, allowing for a fluent interface */ - public BulkObjectCache put( String key, List sobjects ) + public ObjectCache put( String key, List sobjects ) { return put( key, 'Id', sobjects ); } @@ -208,9 +205,9 @@ public with sharing class BulkObjectCache * @param String The base key to put the objects into * @param String The field to get the individual SObject identifiers from (field value must be a non-null String) * @param List The SObjects to store - * @return BulkObjectCache Itself, allowing for a fluent interface + * @return ObjectCache Itself, allowing for a fluent interface */ - public BulkObjectCache put( String key, String idField, List sobjects ) + public ObjectCache put( String key, String idField, List sobjects ) { Contract.requires( idField != null, 'put called with a null idField' ); return put( key, new SobjectIdGetter( idField ), sobjects ); @@ -223,16 +220,15 @@ public with sharing class BulkObjectCache * @param String The base key to put the objects into * @param IdGetter The mechanism for getting the Id from each of the given objects * @param List The Objects to store - * @return BulkObjectCache Itself, allowing for a fluent interface + * @return ObjectCache Itself, allowing for a fluent interface */ - public BulkObjectCache put( String key, IdGetter idGetter, List objects ) + public ObjectCache put( String key, IdGetter idGetter, List objects ) { Contract.requires( key != null, 'put called with a null key' ); Contract.requires( idGetter != null, 'put called with a null idGetter' ); Contract.requires( objects != null, 'put called with a null objects' ); - String fullyQualifiedKey = createFullyQualifiedKey( key ); - Map cachedObjects = (Map)cacheWrapper.get( fullyQualifiedKey ); + Map cachedObjects = (Map)cacheWrapper.get( key ); if ( cachedObjects == null ) { @@ -247,7 +243,7 @@ public with sharing class BulkObjectCache Contract.assert( thisId != null, 'put called with an object that has a null Id: ' + thisObject ); cachedObjects.put( thisId, thisObject ); } - cacheWrapper.put( fullyQualifiedKey, cachedObjects, CACHE_LIFESPAN_SECONDS ); + cacheWrapper.put( key, cachedObjects, CACHE_LIFESPAN_SECONDS ); return this; } @@ -256,12 +252,12 @@ public with sharing class BulkObjectCache * Remove all the cached objects from the given base key. * * @param String The base key to remove the objects from. - * @return BulkObjectCache Itself, allowing for a fluent interface + * @return ObjectCache Itself, allowing for a fluent interface */ - public BulkObjectCache remove( String key ) + public ObjectCache remove( String key ) { Contract.requires( key != null, 'remove called with a null key' ); - cacheWrapper.remove( createFullyQualifiedKey( key ) ); + cacheWrapper.remove( key ); return this; } @@ -270,9 +266,9 @@ public with sharing class BulkObjectCache * * @param String The base key to remove the SObjects from. * @param Set The cache identifiers of the SObjects to remove. - * @return BulkObjectCache Itself, allowing for a fluent interface + * @return ObjectCache Itself, allowing for a fluent interface */ - public BulkObjectCache remove( String key, Set ids ) + public ObjectCache remove( String key, Set ids ) { Contract.requires( ids != null, 'remove called with a null ids' ); return remove( key, SetUtils.convertToSetOfStrings( ids ) ); @@ -283,29 +279,24 @@ public with sharing class BulkObjectCache * * @param String The base key to remove the objects from. * @param Set The cache identifiers of the objects to remove. - * @return BulkObjectCache Itself, allowing for a fluent interface + * @return ObjectCache Itself, allowing for a fluent interface */ - public BulkObjectCache remove( String key, Set ids ) + public ObjectCache remove( String key, Set ids ) { Contract.requires( key != null, 'remove called with a null key' ); Contract.requires( ids != null, 'remove called with a null ids' ); - Map cachedObjects = (Map)cacheWrapper.get( createFullyQualifiedKey( key ) ); + Map cachedObjects = (Map)cacheWrapper.get( key ); for ( String thisId : ids ) { Contract.assert( thisId != null, 'remove called with a null entry in ids' ); cachedObjects.remove( thisId ); } - cacheWrapper.put( createFullyQualifiedKey( key ), cachedObjects, CACHE_LIFESPAN_SECONDS ); + cacheWrapper.put( key, cachedObjects, CACHE_LIFESPAN_SECONDS ); return this; } - private String createFullyQualifiedKey( String key ) - { - return cacheWrapper.createFullyQualifiedKey( PARTITION_NAME, key ); - } - private class SobjectIdGetter implements IdGetter { String idField; diff --git a/framework/default/ortoo-core/default/classes/fflib-extension/caching/BulkObjectCache.cls-meta.xml b/framework/default/ortoo-core/default/classes/fflib-extension/caching/ObjectCache.cls-meta.xml similarity index 100% rename from framework/default/ortoo-core/default/classes/fflib-extension/caching/BulkObjectCache.cls-meta.xml rename to framework/default/ortoo-core/default/classes/fflib-extension/caching/ObjectCache.cls-meta.xml diff --git a/framework/default/ortoo-core/default/classes/fflib-extension/caching/OrgCache.cls b/framework/default/ortoo-core/default/classes/fflib-extension/caching/OrgCache.cls index a4d17b4ba06..acb6eec3422 100644 --- a/framework/default/ortoo-core/default/classes/fflib-extension/caching/OrgCache.cls +++ b/framework/default/ortoo-core/default/classes/fflib-extension/caching/OrgCache.cls @@ -6,11 +6,14 @@ * * Attempting to access the cache without this permission will result in an OrgCache.AccessViolationException */ -public class OrgCache implements ICacheAdaptor +public inherited sharing class OrgCache implements ICacheAdaptor { + // TODO: clear all public class AccessViolationException extends Exceptions.DeveloperException {} // this looks like a config exception, but actually the system should be built // in such a way that it's never possible to get this exception + private final static String PARTITION_NAME = 'core'; + private Boolean hasAccessToCache { get @@ -65,7 +68,7 @@ public class OrgCache implements ICacheAdaptor .addContext( 'key', key ); } - return Cache.Org.get( key ); + return Cache.Org.get( createFullyQualifiedKey( key ) ); } /** @@ -93,26 +96,7 @@ public class OrgCache implements ICacheAdaptor .addContext( 'value', value ); } - Cache.Org.put( key, value, lifespan, Cache.Visibility.NAMESPACE, true ); // immutable outside of namespace - } - - /** - * Retrieve a set of the current keys of objects stored in this cache. - * - * If the user does not have access to the cache, will throw an AccessViolationException. - * - * @return Set The keys that currently exist in the cache - */ - public Set getKeys() - { - if ( ! hasAccessToCache ) - { - throw new AccessViolationException( Label.ortoo_core_org_cache_access_violation ) - .setErrorCode( FrameworkErrorCodes.CACHE_ACCESS_VIOLATION ) - .addContext( 'method', 'getKeys' ); - } - - return Cache.Org.getKeys(); + Cache.Org.put( createFullyQualifiedKey( key ), value, lifespan, Cache.Visibility.NAMESPACE, true ); // immutable outside of namespace } /** @@ -132,7 +116,7 @@ public class OrgCache implements ICacheAdaptor .addContext( 'method', 'contains' ) .addContext( 'key', key ); } - return Cache.Org.contains( key ); + return Cache.Org.contains( createFullyQualifiedKey( key ) ); } /** @@ -151,16 +135,16 @@ public class OrgCache implements ICacheAdaptor .addContext( 'method', 'remove' ) .addContext( 'key', key ); } - Cache.Org.remove( key ); + Cache.Org.remove( createFullyQualifiedKey( key ) ); } - public String createFullyQualifiedPartitionName( String partitionName ) + private String createFullyQualifiedPartitionName() { - return Cache.OrgPartition.createFullyQualifiedPartition( PackageUtils.NAMESPACE_PREFIX, partitionName ); + return Cache.OrgPartition.createFullyQualifiedPartition( PackageUtils.NAMESPACE_PREFIX, PARTITION_NAME ); } - public String createFullyQualifiedKey( String partitionName, String subKey ) + private String createFullyQualifiedKey( String key ) { - return Cache.OrgPartition.createFullyQualifiedKey( PackageUtils.NAMESPACE_PREFIX, partitionName, subkey ); + return Cache.OrgPartition.createFullyQualifiedKey( PackageUtils.NAMESPACE_PREFIX, PARTITION_NAME, key ); } } \ No newline at end of file diff --git a/framework/default/ortoo-core/default/classes/fflib-extension/caching/SessionCache.cls b/framework/default/ortoo-core/default/classes/fflib-extension/caching/SessionCache.cls index 4bfc5f4bfec..f65ceb5cd5c 100644 --- a/framework/default/ortoo-core/default/classes/fflib-extension/caching/SessionCache.cls +++ b/framework/default/ortoo-core/default/classes/fflib-extension/caching/SessionCache.cls @@ -3,8 +3,10 @@ * * All users are assumed to have access to the cache. */ -public class SessionCache implements ICacheAdaptor +public inherited sharing class SessionCache implements ICacheAdaptor { + private static final String PARTITION_NAME = 'core'; + /** * States if this user has access to the cache - which is always true * @@ -49,16 +51,6 @@ public class SessionCache implements ICacheAdaptor Cache.Session.put( key, value, lifespan, Cache.Visibility.NAMESPACE, true ); // immutable outside of namespace } - /** - * Retrieve a set of the current keys of objects stored in this cache. - * - * @return Set The keys that currently exist in the cache - */ - public Set getKeys() - { - return Cache.Session.getKeys(); - } - /** * States if the cache currently contains an object in the given key. * @@ -80,13 +72,13 @@ public class SessionCache implements ICacheAdaptor Cache.Session.remove( key ); } - public String createFullyQualifiedPartitionName( String partitionName ) + private String createFullyQualifiedPartitionName() { - return Cache.SessionPartition.createFullyQualifiedPartition( PackageUtils.NAMESPACE_PREFIX, partitionName ); + return Cache.SessionPartition.createFullyQualifiedPartition( PackageUtils.NAMESPACE_PREFIX, PARTITION_NAME ); } - public String createFullyQualifiedKey( String partitionName, String subKey ) + private String createFullyQualifiedKey( String key ) { - return Cache.SessionPartition.createFullyQualifiedKey( PackageUtils.NAMESPACE_PREFIX, partitionName, subkey ); + return Cache.SessionPartition.createFullyQualifiedKey( PackageUtils.NAMESPACE_PREFIX, PARTITION_NAME, key ); } } \ No newline at end of file diff --git a/framework/default/ortoo-core/default/classes/fflib-extension/caching/SobjectCache.cls b/framework/default/ortoo-core/default/classes/fflib-extension/caching/SobjectCache.cls deleted file mode 100644 index 5d2b88601e3..00000000000 --- a/framework/default/ortoo-core/default/classes/fflib-extension/caching/SobjectCache.cls +++ /dev/null @@ -1,139 +0,0 @@ -// TODO: defunt -public with sharing class SobjectCache -{ - public class CacheAccessViolationException extends Exceptions.DeveloperException {} // this looks like a config exception, but actually the system should be built - // in such a way that it's never possible to get this exception - public enum CacheScope { ORG, SESSION } - - ICacheAdaptor cacheWrapper = new OrgCache(); // by default, configure the cache to use the org version - - private final static String PARTITION_NAME = 'soql'; // TODO: same partition? - private final static Integer CACHE_LIFESPAN_SECONDS = 28800; // TODO: soft setting / option - - private Boolean hasAccessToCache - { - get - { - if ( hasAccessToCache == null ) - { - hasAccessToCache = PermissionsService.hasAccessToCorePlatformCache(); - } - return hasAccessToCache; - } - set; - } - - public SobjectCache setScope( CacheScope scope ) - { - Contract.requires( scope != null, 'setScope called with a null scope' ); - - switch on scope - { - when ORG - { - cacheWrapper = new OrgCache(); - } - when SESSION - { - cacheWrapper = new SessionCache(); - } - } - - return this; - } - - public CacheRetrieval get( String key, Set ids ) - { - CacheRetrieval values = new CacheRetrieval(); - for ( Id thisId : ids ) - { - SObject thisValue = (SObject)cacheWrapper.get( createFullyQualifiedKey( key, thisId ) ); - if ( thisValue != null ) - { - values.addCacheHit( thisId, thisValue ); - } - else - { - values.addCacheMiss( thisId ); - } - } - return values; - } - - public SobjectCache put( String key, List sobjects ) - { - return put( key, 'Id', sobjects ); - } - - public SobjectCache put( String key, String idField, List sobjects ) - { - for ( Sobject thisSobject : sobjects ) - { - final String thisKey = createFullyQualifiedKey( key, (Id)thisSobject.get( idField ) ); - cacheWrapper.put( thisKey, thisSobject, CACHE_LIFESPAN_SECONDS ); - } - return this; - } - - public SobjectCache remove( String subkeyToRemove ) - { - Set keys = cacheWrapper.getKeys(); - - for ( String thisKey : keys ) - { - if ( isAKeyFor( thisKey, subkeyToRemove ) ) - { - cacheWrapper.remove( thisKey ); - } - } - return this; - } - - public SobjectCache remove( String key, Set ids ) - { - for ( Id thisId : ids ) - { - cacheWrapper.remove( createFullyQualifiedKey( key, thisId ) ); - } - return this; - } - - private Boolean isAKeyFor( String keyToCheck, String keyToCheckAgainst ) - { - return keyToCheck.startsWith( createKeyPrefix( keyToCheckAgainst ) ); - } - - private String createFullyQualifiedKey( String subKey, String id ) - { - return createKeyPrefix( subKey ) + id; - } - - private String createKeyPrefix( String subKey ) - { - return cacheWrapper.createFullyQualifiedKey( PARTITION_NAME, subkey ) + 'x'; - } - - public class CacheRetrieval - { - public Map cacheHits { get; private set; } - public Set cacheMisses { get; private set; } - - private CacheRetrieval() - { - cacheHits = new Map(); - cacheMisses = new Set(); - } - - private CacheRetrieval addCacheMiss( Id id ) - { - cacheMisses.add( id ); - return this; - } - - private CacheRetrieval addCacheHit( Id id, Sobject value ) - { - cacheHits.put( id, value ); - return this; - } - } -} diff --git a/framework/default/ortoo-core/default/classes/fflib-extension/caching/SobjectCache.cls-meta.xml b/framework/default/ortoo-core/default/classes/fflib-extension/caching/SobjectCache.cls-meta.xml deleted file mode 100644 index dd61d1f917e..00000000000 --- a/framework/default/ortoo-core/default/classes/fflib-extension/caching/SobjectCache.cls-meta.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - 52.0 - Active - diff --git a/framework/default/ortoo-core/default/classes/fflib-extension/caching/tests/CachedSoqlExecutorTest.cls b/framework/default/ortoo-core/default/classes/fflib-extension/caching/tests/CachedSoqlExecutorTest.cls index 1ead66f5e98..f54244a8e4f 100644 --- a/framework/default/ortoo-core/default/classes/fflib-extension/caching/tests/CachedSoqlExecutorTest.cls +++ b/framework/default/ortoo-core/default/classes/fflib-extension/caching/tests/CachedSoqlExecutorTest.cls @@ -1,581 +1,429 @@ @isTest private without sharing class CachedSoqlExecutorTest { - @isTest - private static void query_whenCalledTwiceByAUserWithAccessToTheCache_onlyIssuesOneSoqlStatement() // NOPMD: Test method name format - { - String soqlStatement = 'SELECT Id FROM Account'; + @isTest + private static void query_whenCalledTwiceByAUserWithAccessToTheCache_onlyIssuesOneSoqlStatement() // NOPMD: Test method name format + { + String soqlStatement = 'SELECT Id FROM Account'; - setupAccessToSoqlCache( true ); + setupAccessToSoqlCache( true ); - CachedSoqlExecutor executor = new CachedSoqlExecutor(); + CachedSoqlExecutor executor = new CachedSoqlExecutor(); - Test.startTest(); - List originalResults = executor.query( soqlStatement ); - List secondResults = executor.query( soqlStatement ); - Integer soqlCalls = Limits.getQueries(); - Test.stopTest(); + Test.startTest(); + List originalResults = executor.query( soqlStatement ); + List secondResults = executor.query( soqlStatement ); + Integer soqlCalls = Limits.getQueries(); + Test.stopTest(); - System.assertEquals( 1, soqlCalls, 'query, when called twice by a user with access to the cache, will only issue one SOQL statement' ); - System.assertEquals( originalResults, secondResults, 'query, when called twice by a user with access to the cache, returns the same results in both calls' ); - } + System.assertEquals( 1, soqlCalls, 'query, when called twice by a user with access to the cache, will only issue one SOQL statement' ); + System.assertEquals( originalResults, secondResults, 'query, when called twice by a user with access to the cache, returns the same results in both calls' ); + } - @isTest - private static void query_org_whenCalledTwiceByAUserWithAccessToTheCache_onlyIssuesOneSoqlStatement() // NOPMD: Test method name format - { - String soqlStatement = 'SELECT Id FROM Account'; + @isTest + private static void query_org_whenCalledTwiceByAUserWithAccessToTheCache_onlyIssuesOneSoqlStatement() // NOPMD: Test method name format + { + String soqlStatement = 'SELECT Id FROM Account'; - setupAccessToSoqlCache( true ); + setupAccessToSoqlCache( true ); - CachedSoqlExecutor executor = new CachedSoqlExecutor().setScope( CachedSoqlExecutor.CacheScope.SESSION ); + CachedSoqlExecutor executor = new CachedSoqlExecutor().setScope( CachedSoqlExecutor.CacheScope.SESSION ); - Test.startTest(); - List originalResults = executor.query( soqlStatement ); - List secondResults = executor.query( soqlStatement ); - Integer soqlCalls = Limits.getQueries(); - Test.stopTest(); + Test.startTest(); + List originalResults = executor.query( soqlStatement ); + List secondResults = executor.query( soqlStatement ); + Integer soqlCalls = Limits.getQueries(); + Test.stopTest(); - System.assertEquals( 1, soqlCalls, 'query, when called twice by a user with access to the cache, will only issue one SOQL statement' ); - System.assertEquals( originalResults, secondResults, 'query, when called twice by a user with access to the cache, returns the same results in both calls' ); - } + System.assertEquals( 1, soqlCalls, 'query, when called twice by a user with access to the cache, will only issue one SOQL statement' ); + System.assertEquals( originalResults, secondResults, 'query, when called twice by a user with access to the cache, returns the same results in both calls' ); + } - @isTest - private static void query_whenCalledTwiceByAUserWithoutAccessToTheCache_issuesTwoSoqlStatements() // NOPMD: Test method name format - { - String soqlStatement = 'SELECT Id FROM Account'; + @isTest + private static void query_whenCalledTwiceByAUserWithoutAccessToTheCache_issuesTwoSoqlStatements() // NOPMD: Test method name format + { + String soqlStatement = 'SELECT Id FROM Account'; - setupAccessToSoqlCache( false ); + setupAccessToSoqlCache( false ); - CachedSoqlExecutor executor = new CachedSoqlExecutor(); + CachedSoqlExecutor executor = new CachedSoqlExecutor(); - Test.startTest(); - List originalResults = executor.query( soqlStatement ); - List secondResults = executor.query( soqlStatement ); - Integer soqlCalls = Limits.getQueries(); - Test.stopTest(); + Test.startTest(); + List originalResults = executor.query( soqlStatement ); + List secondResults = executor.query( soqlStatement ); + Integer soqlCalls = Limits.getQueries(); + Test.stopTest(); - System.assertEquals( 2, soqlCalls, 'query, when called twice by a user with no access to the cache, will issue two SOQL statements' ); - System.assertEquals( originalResults, secondResults, 'query, when called twice by a user with not access to the cache, returns the same results in both calls' ); - } + System.assertEquals( 2, soqlCalls, 'query, when called twice by a user with no access to the cache, will issue two SOQL statements' ); + System.assertEquals( originalResults, secondResults, 'query, when called twice by a user with not access to the cache, returns the same results in both calls' ); + } - @isTest - private static void clearAllCache_willClearAllStatementsAndResultsFromTheCache() // NOPMD: Test method name format - { - String soqlStatement = 'SELECT Id FROM Account'; + @isTest + private static void clearCacheFor_whenGivenASoqlStatementThatHasBeenExecuted_willClearTheCacheForThatStatement() // NOPMD: Test method name format + { + String soqlStatement = 'SELECT Id FROM Account'; - setupAccessToSoqlCache( true ); + setupAccessToSoqlCache( true ); - CachedSoqlExecutor executor = new CachedSoqlExecutor(); + CachedSoqlExecutor executor = new CachedSoqlExecutor(); - Test.startTest(); + executor.query( soqlStatement ); - executor.query( soqlStatement ); // executes SOQL - executor.clearAllCache(); + Test.startTest(); + executor.clearCacheFor( soqlStatement ); + executor.query( soqlStatement ); // should execute another soql + Integer soqlCalls = Limits.getQueries(); + Test.stopTest(); - executor.query( soqlStatement ); // executes another SOQL - executor.query( soqlStatement ); - executor.query( soqlStatement ); + System.assertEquals( 1, soqlCalls, 'clearCacheFor, when given a SOQL statement that is already in the cache, will clear that soql from the cache' ); + } + @isTest + private static void clearCacheFor_whenGivenASoqlStatementThatHasBeenExecuted_willNotClearTheCacheForOtherStatements() // NOPMD: Test method name format + { + String soqlStatement1 = 'SELECT Id FROM Account'; + String soqlStatement2 = 'SELECT Id FROM Account LIMIT 1'; - Integer soqlCalls = Limits.getQueries(); - Test.stopTest(); + setupAccessToSoqlCache( true ); - System.assertEquals( 2, soqlCalls, 'clearAllCache, when called, will clear statements and results from the cache meaning that SOQL executions will need to be repeated when query is called' ); - } + CachedSoqlExecutor executor = new CachedSoqlExecutor(); - @isTest - private static void clearAllCache_whenThereIsNothingInTheCache_willNotThrowAnException() // NOPMD: Test method name format - { - setupAccessToSoqlCache( true ); + executor.query( soqlStatement1 ); + executor.query( soqlStatement2 ); - CachedSoqlExecutor executor = new CachedSoqlExecutor(); + Test.startTest(); + executor.clearCacheFor( soqlStatement1 ); + executor.query( soqlStatement2 ); // should not execute another soql + Integer soqlCalls = Limits.getQueries(); + Test.stopTest(); - Test.startTest(); - executor.clearAllCache(); - Test.stopTest(); + System.assertEquals( 0, soqlCalls, 'clearCacheFor, when given a SOQL statement that is already in the cache, will not clear other soql from the cache' ); + } - System.assert( true, 'clearAllCache, when there is nothing in the cache, will not throw an exception' ); - } + @isTest + private static void clearCacheFor_whenGivenASoqlStatementThatHasNotBeenExecuted_willNotThrowAnException() // NOPMD: Test method name format + { + String soqlStatement = 'SELECT Id FROM Account'; - @isTest - private static void clearAllCache_whenTheUserDoesNotHaveAccessToTheCache_throwsAnException() // NOPMD: Test method name format - { - setupAccessToSoqlCache( false ); + setupAccessToSoqlCache( true ); - CachedSoqlExecutor executor = new CachedSoqlExecutor(); + CachedSoqlExecutor executor = new CachedSoqlExecutor(); - Test.startTest(); - Exception exceptionThrown; - try - { - executor.clearAllCache(); - } - catch ( OrgCache.AccessViolationException e ) - { - exceptionThrown = e; - } - Test.stopTest(); + Test.startTest(); + executor.clearCacheFor( soqlStatement ); + Test.stopTest(); - ortoo_Asserts.assertContains( Label.ortoo_core_org_cache_access_violation, exceptionThrown?.getMessage(), 'clearAllCache, when the user does not have access to the cache, will throw an exception' ); - } + System.assert( true, 'clearCacheFor, when given a SOQL statement that has not been executed, will not throw an exception' ); + } - @isTest - private static void clearCacheFor_whenGivenASoqlStatementThatHasBeenExecuted_willClearTheCacheForThatStatement() // NOPMD: Test method name format - { - String soqlStatement = 'SELECT Id FROM Account'; + @isTest + private static void clearCacheFor_whenTheUserDoesNotHaveAccessToTheCache_throwsAnException() // NOPMD: Test method name format + { + String soqlStatement = 'SELECT Id FROM Account'; - setupAccessToSoqlCache( true ); + setupAccessToSoqlCache( false ); - CachedSoqlExecutor executor = new CachedSoqlExecutor(); + CachedSoqlExecutor executor = new CachedSoqlExecutor(); - executor.query( soqlStatement ); + Test.startTest(); + Exception exceptionThrown; + try + { + executor.clearCacheFor( soqlStatement ); + } + catch ( OrgCache.AccessViolationException e ) + { + exceptionThrown = e; + } + Test.stopTest(); - Test.startTest(); - executor.clearCacheFor( soqlStatement ); - executor.query( soqlStatement ); // should execute another soql - Integer soqlCalls = Limits.getQueries(); - Test.stopTest(); + ortoo_Asserts.assertContains( Label.ortoo_core_org_cache_access_violation, exceptionThrown?.getMessage(), 'clearCacheFor, when the user does not have access to the cache, will throw an exception' ); + } - System.assertEquals( 1, soqlCalls, 'clearCacheFor, when given a SOQL statement that is already in the cache, will clear that soql from the cache' ); - } + @isTest + private static void query_whenRanFor100Queries_willNotThrowAnException() + { + List soqlStatements = new List(); + for ( Integer i=1; i<=100; i++ ) + { + soqlStatements.add( 'SELECT Id FROM Account LIMIT ' + i ); + } - @isTest - private static void clearCacheFor_whenGivenASoqlStatementThatHasBeenExecuted_willNotClearTheCacheForOtherStatements() // NOPMD: Test method name format - { - String soqlStatement1 = 'SELECT Id FROM Account'; - String soqlStatement2 = 'SELECT Id FROM Account LIMIT 1'; + setupAccessToSoqlCache( true ); - setupAccessToSoqlCache( true ); + CachedSoqlExecutor executor = new CachedSoqlExecutor(); - CachedSoqlExecutor executor = new CachedSoqlExecutor(); + Test.startTest(); - executor.query( soqlStatement1 ); - executor.query( soqlStatement2 ); + // Run each statement multiple times, one by one + for ( String thisSoqlStatement : soqlStatements ) + { + executor.query( thisSoqlStatement ); + executor.query( thisSoqlStatement ); + executor.query( thisSoqlStatement ); + executor.query( thisSoqlStatement ); + executor.query( thisSoqlStatement ); + } - Test.startTest(); - executor.clearCacheFor( soqlStatement1 ); - executor.query( soqlStatement2 ); // should not execute another soql - Integer soqlCalls = Limits.getQueries(); - Test.stopTest(); + // Then run each statement again + for ( String thisSoqlStatement : soqlStatements ) + { + executor.query( thisSoqlStatement ); + } - System.assertEquals( 0, soqlCalls, 'clearCacheFor, when given a SOQL statement that is already in the cache, will not clear other soql from the cache' ); - } + Test.stopTest(); - @isTest - private static void clearCacheFor_whenGivenASoqlStatementThatHasNotBeenExecuted_willNotThrowAnException() // NOPMD: Test method name format - { - String soqlStatement = 'SELECT Id FROM Account'; + System.assert( true, 'query, when run multiple times for 100 distinct queries, will not throw an exception' ); + } - setupAccessToSoqlCache( true ); + @isTest + private static void query_session_whenCalledTwiceByAUserWithAccessToTheCache_onlyIssuesOneSoqlStatement() // NOPMD: Test method name format + { + String soqlStatement = 'SELECT Id FROM Account'; - CachedSoqlExecutor executor = new CachedSoqlExecutor(); + setupAccessToSoqlCache( true ); - Test.startTest(); - executor.clearCacheFor( soqlStatement ); - Test.stopTest(); + CachedSoqlExecutor executor = new CachedSoqlExecutor().setScope( CachedSoqlExecutor.CacheScope.SESSION ); - System.assert( true, 'clearCacheFor, when given a SOQL statement that has not been executed, will not throw an exception' ); - } + Test.startTest(); + List originalResults = executor.query( soqlStatement ); + List secondResults = executor.query( soqlStatement ); + Integer soqlCalls = Limits.getQueries(); + Test.stopTest(); - @isTest - private static void clearCacheFor_whenTheUserDoesNotHaveAccessToTheCache_throwsAnException() // NOPMD: Test method name format - { - String soqlStatement = 'SELECT Id FROM Account'; + System.assertEquals( 1, soqlCalls, 'query, when called twice by a user with access to the cache, will only issue one SOQL statement' ); + System.assertEquals( originalResults, secondResults, 'query, when called twice by a user with access to the cache, returns the same results in both calls' ); + } - setupAccessToSoqlCache( false ); + @isTest + private static void query_session_whenCalledTwiceByAUserWithoutAccessToTheCache_issuesOneSoqlStatement() // NOPMD: Test method name format + { + String soqlStatement = 'SELECT Id FROM Account'; - CachedSoqlExecutor executor = new CachedSoqlExecutor(); + setupAccessToSoqlCache( false ); - Test.startTest(); - Exception exceptionThrown; - try - { - executor.clearCacheFor( soqlStatement ); - } - catch ( OrgCache.AccessViolationException e ) - { - exceptionThrown = e; - } - Test.stopTest(); + CachedSoqlExecutor executor = new CachedSoqlExecutor().setScope( CachedSoqlExecutor.CacheScope.SESSION ); - ortoo_Asserts.assertContains( Label.ortoo_core_org_cache_access_violation, exceptionThrown?.getMessage(), 'clearCacheFor, when the user does not have access to the cache, will throw an exception' ); - } + Test.startTest(); + List originalResults = executor.query( soqlStatement ); + List secondResults = executor.query( soqlStatement ); + Integer soqlCalls = Limits.getQueries(); + Test.stopTest(); - @isTest - private static void query_whenRanFor100Queries_willNotThrowAnException() - { - List soqlStatements = new List(); - for ( Integer i=1; i<=100; i++ ) - { - soqlStatements.add( 'SELECT Id FROM Account LIMIT ' + i ); - } + System.assertEquals( 1, soqlCalls, 'query, when called twice by a user with no access to the org cache, will issue one SOQL statement' ); + System.assertEquals( originalResults, secondResults, 'query, when called twice by a user with no access to the cache, returns the same results in both calls' ); + } - setupAccessToSoqlCache( true ); + @isTest + private static void clearCacheFor_session_whenGivenASoqlStatementThatHasBeenExecuted_willClearTheCacheForThatStatement() // NOPMD: Test method name format + { + String soqlStatement = 'SELECT Id FROM Account'; - CachedSoqlExecutor executor = new CachedSoqlExecutor(); + setupAccessToSoqlCache( true ); - Test.startTest(); + CachedSoqlExecutor executor = new CachedSoqlExecutor().setScope( CachedSoqlExecutor.CacheScope.SESSION ); - // Run each statement multiple times, one by one - for ( String thisSoqlStatement : soqlStatements ) - { - executor.query( thisSoqlStatement ); - executor.query( thisSoqlStatement ); - executor.query( thisSoqlStatement ); - executor.query( thisSoqlStatement ); - executor.query( thisSoqlStatement ); - } + executor.query( soqlStatement ); - // Then run each statement again - for ( String thisSoqlStatement : soqlStatements ) - { - executor.query( thisSoqlStatement ); - } + Test.startTest(); + executor.clearCacheFor( soqlStatement ); + executor.query( soqlStatement ); // should execute another soql + Integer soqlCalls = Limits.getQueries(); + Test.stopTest(); - Test.stopTest(); + System.assertEquals( 1, soqlCalls, 'clearCacheFor, when given a SOQL statement that is already in the cache, will clear that soql from the cache' ); + } - System.assert( true, 'query, when run multiple times for 100 distinct queries, will not throw an exception' ); - } + @isTest + private static void clearCacheFor_session_whenGivenASoqlStatementThatHasBeenExecuted_willNotClearTheCacheForOtherStatements() // NOPMD: Test method name format + { + String soqlStatement1 = 'SELECT Id FROM Account'; + String soqlStatement2 = 'SELECT Id FROM Account LIMIT 1'; - @isTest - private static void query_session_whenCalledTwiceByAUserWithAccessToTheCache_onlyIssuesOneSoqlStatement() // NOPMD: Test method name format - { - String soqlStatement = 'SELECT Id FROM Account'; + setupAccessToSoqlCache( true ); - setupAccessToSoqlCache( true ); + CachedSoqlExecutor executor = new CachedSoqlExecutor().setScope( CachedSoqlExecutor.CacheScope.SESSION ); - CachedSoqlExecutor executor = new CachedSoqlExecutor().setScope( CachedSoqlExecutor.CacheScope.SESSION ); + executor.query( soqlStatement1 ); + executor.query( soqlStatement2 ); - Test.startTest(); - List originalResults = executor.query( soqlStatement ); - List secondResults = executor.query( soqlStatement ); - Integer soqlCalls = Limits.getQueries(); - Test.stopTest(); + Test.startTest(); + executor.clearCacheFor( soqlStatement1 ); + executor.query( soqlStatement2 ); // should not execute another soql + Integer soqlCalls = Limits.getQueries(); + Test.stopTest(); - System.assertEquals( 1, soqlCalls, 'query, when called twice by a user with access to the cache, will only issue one SOQL statement' ); - System.assertEquals( originalResults, secondResults, 'query, when called twice by a user with access to the cache, returns the same results in both calls' ); - } + System.assertEquals( 0, soqlCalls, 'clearCacheFor, when given a SOQL statement that is already in the cache, will not clear other soql from the cache' ); + } - @isTest - private static void query_session_whenCalledTwiceByAUserWithoutAccessToTheCache_issuesOneSoqlStatement() // NOPMD: Test method name format - { - String soqlStatement = 'SELECT Id FROM Account'; + @isTest + private static void clearCacheFor_session_whenGivenASoqlStatementThatHasNotBeenExecuted_willNotThrowAnException() // NOPMD: Test method name format + { + String soqlStatement = 'SELECT Id FROM Account'; - setupAccessToSoqlCache( false ); + setupAccessToSoqlCache( true ); - CachedSoqlExecutor executor = new CachedSoqlExecutor().setScope( CachedSoqlExecutor.CacheScope.SESSION ); + CachedSoqlExecutor executor = new CachedSoqlExecutor().setScope( CachedSoqlExecutor.CacheScope.SESSION ); - Test.startTest(); - List originalResults = executor.query( soqlStatement ); - List secondResults = executor.query( soqlStatement ); - Integer soqlCalls = Limits.getQueries(); - Test.stopTest(); + Test.startTest(); + executor.clearCacheFor( soqlStatement ); + Test.stopTest(); - System.assertEquals( 1, soqlCalls, 'query, when called twice by a user with no access to the org cache, will issue one SOQL statement' ); - System.assertEquals( originalResults, secondResults, 'query, when called twice by a user with no access to the cache, returns the same results in both calls' ); - } + System.assert( true, 'clearCacheFor, when given a SOQL statement that has not been executed, will not throw an exception' ); + } - @isTest - private static void clearAllCache_session_willClearAllStatementsAndResultsFromTheCache() // NOPMD: Test method name format - { - String soqlStatement = 'SELECT Id FROM Account'; + @isTest + private static void clearCacheFor_session_whenTheUserDoesNotHaveAccessToTheOrgCache_willNotThrowAnException() // NOPMD: Test method name format + { + String soqlStatement = 'SELECT Id FROM Account'; - setupAccessToSoqlCache( true ); + setupAccessToSoqlCache( false ); - CachedSoqlExecutor executor = new CachedSoqlExecutor().setScope( CachedSoqlExecutor.CacheScope.SESSION ); + CachedSoqlExecutor executor = new CachedSoqlExecutor().setScope( CachedSoqlExecutor.CacheScope.SESSION ); - Test.startTest(); + Test.startTest(); + executor.clearCacheFor( soqlStatement ); + Test.stopTest(); - executor.query( soqlStatement ); // executes SOQL - executor.clearAllCache(); - - executor.query( soqlStatement ); // executes another SOQL - executor.query( soqlStatement ); - executor.query( soqlStatement ); - - Integer soqlCalls = Limits.getQueries(); - Test.stopTest(); - - System.assertEquals( 2, soqlCalls, 'clearAllCache, when called, will clear statements and results from the cache meaning that SOQL executions will need to be repeated when query is called' ); - } - - @isTest - private static void clearAllCache_session_whenThereIsNothingInTheCache_willNotThrowAnException() // NOPMD: Test method name format - { - setupAccessToSoqlCache( true ); - - CachedSoqlExecutor executor = new CachedSoqlExecutor().setScope( CachedSoqlExecutor.CacheScope.SESSION ); - - Test.startTest(); - executor.clearAllCache(); - Test.stopTest(); - - System.assert( true, 'clearAllCache, when there is nothing in the cache, will not throw an exception' ); - } - - @isTest - private static void clearAllCache_session_whenTheUserDoesNotHaveAccessToTheOrgCache_willNotThrowAnException() // NOPMD: Test method name format - { - setupAccessToSoqlCache( false ); - - CachedSoqlExecutor executor = new CachedSoqlExecutor().setScope( CachedSoqlExecutor.CacheScope.SESSION ); - - Test.startTest(); - executor.clearAllCache(); - Test.stopTest(); - - System.assert( true, 'clearAllCache, when the user does not have access to the org cache, will not throw an exception' ); - } - - @isTest - private static void clearCacheFor_session_whenGivenASoqlStatementThatHasBeenExecuted_willClearTheCacheForThatStatement() // NOPMD: Test method name format - { - String soqlStatement = 'SELECT Id FROM Account'; - - setupAccessToSoqlCache( true ); - - CachedSoqlExecutor executor = new CachedSoqlExecutor().setScope( CachedSoqlExecutor.CacheScope.SESSION ); - - executor.query( soqlStatement ); - - Test.startTest(); - executor.clearCacheFor( soqlStatement ); - executor.query( soqlStatement ); // should execute another soql - Integer soqlCalls = Limits.getQueries(); - Test.stopTest(); - - System.assertEquals( 1, soqlCalls, 'clearCacheFor, when given a SOQL statement that is already in the cache, will clear that soql from the cache' ); - } - - @isTest - private static void clearCacheFor_session_whenGivenASoqlStatementThatHasBeenExecuted_willNotClearTheCacheForOtherStatements() // NOPMD: Test method name format - { - String soqlStatement1 = 'SELECT Id FROM Account'; - String soqlStatement2 = 'SELECT Id FROM Account LIMIT 1'; - - setupAccessToSoqlCache( true ); - - CachedSoqlExecutor executor = new CachedSoqlExecutor().setScope( CachedSoqlExecutor.CacheScope.SESSION ); - - executor.query( soqlStatement1 ); - executor.query( soqlStatement2 ); - - Test.startTest(); - executor.clearCacheFor( soqlStatement1 ); - executor.query( soqlStatement2 ); // should not execute another soql - Integer soqlCalls = Limits.getQueries(); - Test.stopTest(); - - System.assertEquals( 0, soqlCalls, 'clearCacheFor, when given a SOQL statement that is already in the cache, will not clear other soql from the cache' ); - } - - @isTest - private static void clearCacheFor_session_whenGivenASoqlStatementThatHasNotBeenExecuted_willNotThrowAnException() // NOPMD: Test method name format - { - String soqlStatement = 'SELECT Id FROM Account'; - - setupAccessToSoqlCache( true ); - - CachedSoqlExecutor executor = new CachedSoqlExecutor().setScope( CachedSoqlExecutor.CacheScope.SESSION ); - - Test.startTest(); - executor.clearCacheFor( soqlStatement ); - Test.stopTest(); - - System.assert( true, 'clearCacheFor, when given a SOQL statement that has not been executed, will not throw an exception' ); - } - - @isTest - private static void clearCacheFor_session_whenTheUserDoesNotHaveAccessToTheOrgCache_willNotThrowAnException() // NOPMD: Test method name format - { - String soqlStatement = 'SELECT Id FROM Account'; - - setupAccessToSoqlCache( false ); - - CachedSoqlExecutor executor = new CachedSoqlExecutor().setScope( CachedSoqlExecutor.CacheScope.SESSION ); - - Test.startTest(); - executor.clearCacheFor( soqlStatement ); - Test.stopTest(); - - System.assert( true, 'clearCacheFor, when the user does not have access to the org cache, will not throw an exception' ); + System.assert( true, 'clearCacheFor, when the user does not have access to the org cache, will not throw an exception' ); } - @isTest - private static void query_session_whenRanFor100Queries_willNotThrowAnException() - { - List soqlStatements = new List(); - for ( Integer i=1; i<=100; i++ ) - { - soqlStatements.add( 'SELECT Id FROM Account LIMIT ' + i ); - } - - setupAccessToSoqlCache( true ); - - CachedSoqlExecutor executor = new CachedSoqlExecutor().setScope( CachedSoqlExecutor.CacheScope.SESSION ); - - Test.startTest(); - - // Run each statement multiple times, one by one - for ( String thisSoqlStatement : soqlStatements ) - { - executor.query( thisSoqlStatement ); - executor.query( thisSoqlStatement ); - executor.query( thisSoqlStatement ); - executor.query( thisSoqlStatement ); - executor.query( thisSoqlStatement ); - } - - // Then run each statement again - for ( String thisSoqlStatement : soqlStatements ) - { - executor.query( thisSoqlStatement ); - } - - Test.stopTest(); - - System.assert( true, 'query, when run multiple times for 100 distinct queries, will not throw an exception' ); - } - - @isTest - private static void query_none_whenCalledTwiceByAUserWithAccessToTheCache_issuesTwoSoqlStatements() // NOPMD: Test method name format - { - String soqlStatement = 'SELECT Id FROM Account'; - - setupAccessToSoqlCache( true ); - - CachedSoqlExecutor executor = new CachedSoqlExecutor().setScope( CachedSoqlExecutor.CacheScope.NONE ); - - Test.startTest(); - List originalResults = executor.query( soqlStatement ); - List secondResults = executor.query( soqlStatement ); - Integer soqlCalls = Limits.getQueries(); - Test.stopTest(); - - System.assertEquals( 2, soqlCalls, 'query against a NONE cache, when called twice by a user with access to the cache, will issue two SOQL statements' ); - } - - @isTest - private static void query_none_whenCalledTwiceByAUserWithoutAccessToTheCache_issuesTwoSoqlStatements() // NOPMD: Test method name format - { - String soqlStatement = 'SELECT Id FROM Account'; + @isTest + private static void query_session_whenRanFor100Queries_willNotThrowAnException() + { + List soqlStatements = new List(); + for ( Integer i=1; i<=100; i++ ) + { + soqlStatements.add( 'SELECT Id FROM Account LIMIT ' + i ); + } - setupAccessToSoqlCache( false ); + setupAccessToSoqlCache( true ); - CachedSoqlExecutor executor = new CachedSoqlExecutor().setScope( CachedSoqlExecutor.CacheScope.NONE ); + CachedSoqlExecutor executor = new CachedSoqlExecutor().setScope( CachedSoqlExecutor.CacheScope.SESSION ); - Test.startTest(); - List originalResults = executor.query( soqlStatement ); - List secondResults = executor.query( soqlStatement ); - Integer soqlCalls = Limits.getQueries(); - Test.stopTest(); + Test.startTest(); - System.assertEquals( 2, soqlCalls, 'query against a NONE cache, when called twice by a user with no access to the cache, will issue two SOQL statements' ); - } + // Run each statement multiple times, one by one + for ( String thisSoqlStatement : soqlStatements ) + { + executor.query( thisSoqlStatement ); + executor.query( thisSoqlStatement ); + executor.query( thisSoqlStatement ); + executor.query( thisSoqlStatement ); + executor.query( thisSoqlStatement ); + } - @isTest - private static void clearAllCache_none_willNotThrowAnException() // NOPMD: Test method name format - { - String soqlStatement = 'SELECT Id FROM Account'; + // Then run each statement again + for ( String thisSoqlStatement : soqlStatements ) + { + executor.query( thisSoqlStatement ); + } - setupAccessToSoqlCache( true ); + Test.stopTest(); - CachedSoqlExecutor executor = new CachedSoqlExecutor().setScope( CachedSoqlExecutor.CacheScope.NONE ); + System.assert( true, 'query, when run multiple times for 100 distinct queries, will not throw an exception' ); + } - Test.startTest(); + @isTest + private static void query_none_whenCalledTwiceByAUserWithAccessToTheCache_issuesTwoSoqlStatements() // NOPMD: Test method name format + { + String soqlStatement = 'SELECT Id FROM Account'; - executor.query( soqlStatement ); - executor.clearAllCache(); + setupAccessToSoqlCache( true ); - executor.query( soqlStatement ); - executor.query( soqlStatement ); - executor.query( soqlStatement ); + CachedSoqlExecutor executor = new CachedSoqlExecutor().setScope( CachedSoqlExecutor.CacheScope.NONE ); + Test.startTest(); + List originalResults = executor.query( soqlStatement ); + List secondResults = executor.query( soqlStatement ); + Integer soqlCalls = Limits.getQueries(); + Test.stopTest(); - Integer soqlCalls = Limits.getQueries(); - Test.stopTest(); + System.assertEquals( 2, soqlCalls, 'query against a NONE cache, when called twice by a user with access to the cache, will issue two SOQL statements' ); + } - System.assertEquals( 4, soqlCalls, 'clearAllCache against a none cache, when called, will not throw an exception and will not affect the number of SOQL statements issued' ); - } + @isTest + private static void query_none_whenCalledTwiceByAUserWithoutAccessToTheCache_issuesTwoSoqlStatements() // NOPMD: Test method name format + { + String soqlStatement = 'SELECT Id FROM Account'; - @isTest - private static void clearAllCache_none_whenTheUserDoesNotHaveAccessToTheOrgCache_willNotThrowAnException() // NOPMD: Test method name format - { - setupAccessToSoqlCache( false ); + setupAccessToSoqlCache( false ); - CachedSoqlExecutor executor = new CachedSoqlExecutor().setScope( CachedSoqlExecutor.CacheScope.NONE ); + CachedSoqlExecutor executor = new CachedSoqlExecutor().setScope( CachedSoqlExecutor.CacheScope.NONE ); - Test.startTest(); - executor.clearAllCache(); - Test.stopTest(); + Test.startTest(); + List originalResults = executor.query( soqlStatement ); + List secondResults = executor.query( soqlStatement ); + Integer soqlCalls = Limits.getQueries(); + Test.stopTest(); - System.assert( true, 'clearAllCache against a none cache, when called by a user that does not have access to the org cache, will not throw an exception' ); - } + System.assertEquals( 2, soqlCalls, 'query against a NONE cache, when called twice by a user with no access to the cache, will issue two SOQL statements' ); + } - @isTest - private static void clearCacheFor_none_doesNotAffectTheNumberOfSoqlStatementsIssued() // NOPMD: Test method name format - { - String soqlStatement = 'SELECT Id FROM Account'; + @isTest + private static void clearCacheFor_none_doesNotAffectTheNumberOfSoqlStatementsIssued() // NOPMD: Test method name format + { + String soqlStatement = 'SELECT Id FROM Account'; - setupAccessToSoqlCache( true ); + setupAccessToSoqlCache( true ); - CachedSoqlExecutor executor = new CachedSoqlExecutor().setScope( CachedSoqlExecutor.CacheScope.NONE ); + CachedSoqlExecutor executor = new CachedSoqlExecutor().setScope( CachedSoqlExecutor.CacheScope.NONE ); - executor.query( soqlStatement ); + executor.query( soqlStatement ); - Test.startTest(); - executor.clearCacheFor( soqlStatement ); - executor.query( soqlStatement ); - Integer soqlCalls = Limits.getQueries(); - Test.stopTest(); + Test.startTest(); + executor.clearCacheFor( soqlStatement ); + executor.query( soqlStatement ); + Integer soqlCalls = Limits.getQueries(); + Test.stopTest(); - System.assertEquals( 1, soqlCalls, 'clearCacheFor against a none cache, does not affect the number of SOQL statements issued' ); - } + System.assertEquals( 1, soqlCalls, 'clearCacheFor against a none cache, does not affect the number of SOQL statements issued' ); + } - @isTest - private static void clearCacheFor_none_whenTheUserDoesNotHaveAccessToTheCache_throwsAnException() // NOPMD: Test method name format - { - String soqlStatement = 'SELECT Id FROM Account'; + @isTest + private static void clearCacheFor_none_whenTheUserDoesNotHaveAccessToTheCache_throwsAnException() // NOPMD: Test method name format + { + String soqlStatement = 'SELECT Id FROM Account'; - setupAccessToSoqlCache( false ); + setupAccessToSoqlCache( false ); - CachedSoqlExecutor executor = new CachedSoqlExecutor().setScope( CachedSoqlExecutor.CacheScope.NONE ); + CachedSoqlExecutor executor = new CachedSoqlExecutor().setScope( CachedSoqlExecutor.CacheScope.NONE ); - Test.startTest(); - executor.clearCacheFor( soqlStatement ); - Test.stopTest(); + Test.startTest(); + executor.clearCacheFor( soqlStatement ); + Test.stopTest(); - System.assert( true, 'clearCacheFor against a none cache, when called by a user that does not have access to the org cache, will not throw an exception' ); - } + System.assert( true, 'clearCacheFor against a none cache, when called by a user that does not have access to the org cache, will not throw an exception' ); + } - @isTest - private static void query_none_whenRanFor100Queries_willNotThrowAnException() - { - List soqlStatements = new List(); - for ( Integer i=1; i<=100; i++ ) - { - soqlStatements.add( 'SELECT Id FROM Account LIMIT ' + i ); - } + @isTest + private static void query_none_whenRanFor100Queries_willNotThrowAnException() + { + List soqlStatements = new List(); + for ( Integer i=1; i<=100; i++ ) + { + soqlStatements.add( 'SELECT Id FROM Account LIMIT ' + i ); + } - setupAccessToSoqlCache( true ); + setupAccessToSoqlCache( true ); - CachedSoqlExecutor executor = new CachedSoqlExecutor().setScope( CachedSoqlExecutor.CacheScope.NONE ); + CachedSoqlExecutor executor = new CachedSoqlExecutor().setScope( CachedSoqlExecutor.CacheScope.NONE ); - Test.startTest(); - // Run each statement once - this is the maximum we can do - for ( String thisSoqlStatement : soqlStatements ) - { - executor.query( thisSoqlStatement ); - } - Test.stopTest(); + Test.startTest(); + // Run each statement once - this is the maximum we can do + for ( String thisSoqlStatement : soqlStatements ) + { + executor.query( thisSoqlStatement ); + } + Test.stopTest(); - System.assert( true, 'query against a none cache, when run for 100 queries, will not throw an exception' ); - } + System.assert( true, 'query against a none cache, when run for 100 queries, will not throw an exception' ); + } - private static void setupAccessToSoqlCache( Boolean accessToCache ) - { - ApplicationMockRegistrar.registerMockService( IPermissionsService.class ) - .when( 'hasAccessToCorePlatformCache' ) - .returns( accessToCache ); - } + private static void setupAccessToSoqlCache( Boolean accessToCache ) + { + ApplicationMockRegistrar.registerMockService( IPermissionsService.class ) + .when( 'hasAccessToCorePlatformCache' ) + .returns( accessToCache ); + } } \ No newline at end of file diff --git a/framework/default/ortoo-core/default/classes/null-objects/NullAction.cls b/framework/default/ortoo-core/default/classes/null-objects/NullAction.cls index 233f6022f00..2fbc48b8fb0 100644 --- a/framework/default/ortoo-core/default/classes/null-objects/NullAction.cls +++ b/framework/default/ortoo-core/default/classes/null-objects/NullAction.cls @@ -1,7 +1,7 @@ /** * Provides the ability to perform no action in a Process Builder built process */ -public class NullAction +public inherited sharing class NullAction { /** * Allows a Process Builder or Flow action to 'Do Nothing' diff --git a/framework/default/ortoo-core/default/classes/null-objects/NullDomain.cls b/framework/default/ortoo-core/default/classes/null-objects/NullDomain.cls index 9a1a1b3998b..e6b29237397 100644 --- a/framework/default/ortoo-core/default/classes/null-objects/NullDomain.cls +++ b/framework/default/ortoo-core/default/classes/null-objects/NullDomain.cls @@ -1,7 +1,7 @@ /** * Is a Domain object that does nothing other than track that certain overridden methods have been called */ -public class NullDomain extends ortoo_SobjectDomain +public inherited sharing class NullDomain extends ortoo_SobjectDomain { public static Set methodsCalled = new Set();