From 9a7be504c6579c40272a2945a914d7fc8457af0b Mon Sep 17 00:00:00 2001 From: Miguel Angel Date: Fri, 6 Dec 2024 16:53:40 -0400 Subject: [PATCH] feat: invalidate settings cache --- .../Cache/Settings/SettingCacheManager.php | 21 ++++++- ProcessMaker/Observers/SettingObserver.php | 13 ++++ tests/Feature/Cache/SettingCacheTest.php | 61 +++++++++++++++++++ 3 files changed, 94 insertions(+), 1 deletion(-) diff --git a/ProcessMaker/Cache/Settings/SettingCacheManager.php b/ProcessMaker/Cache/Settings/SettingCacheManager.php index eec30615a6..eb7b56281e 100644 --- a/ProcessMaker/Cache/Settings/SettingCacheManager.php +++ b/ProcessMaker/Cache/Settings/SettingCacheManager.php @@ -3,6 +3,7 @@ namespace ProcessMaker\Cache\Settings; use Illuminate\Cache\CacheManager; +use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Redis; use ProcessMaker\Cache\CacheInterface; @@ -156,7 +157,7 @@ public function clearBy(string $pattern): void Redis::connection($connection)->del($matchedKeys); } } catch (\Exception $e) { - \Log::error('SettingCacheException' . $e->getMessage()); + Log::error('SettingCacheException' . $e->getMessage()); throw new SettingCacheException('Failed to delete keys.'); } @@ -185,4 +186,22 @@ public function missing(string $key): bool { return !$this->has($key); } + + /** + * Invalidate a value in the settings cache. + * + * @param string $key + * + * @return void + */ + public function invalidate(string $key): void + { + try { + $this->cacheManager->forget($key); + } catch (\Exception $e) { + Log::error($e->getMessage()); + + throw new SettingCacheException('Failed to invalidate cache KEY:' . $key); + } + } } diff --git a/ProcessMaker/Observers/SettingObserver.php b/ProcessMaker/Observers/SettingObserver.php index 181913c41e..6815d67bc7 100644 --- a/ProcessMaker/Observers/SettingObserver.php +++ b/ProcessMaker/Observers/SettingObserver.php @@ -65,5 +65,18 @@ public function saving(Setting $setting) $setting->config = $return; break; } + + \SettingCache::invalidate($setting->key); + } + + /** + * Handle the setting "deleted" event. + * + * @param \ProcessMaker\Models\Setting $setting + * @return void + */ + public function deleted(Setting $setting): void + { + \SettingCache::invalidate($setting->key); } } diff --git a/tests/Feature/Cache/SettingCacheTest.php b/tests/Feature/Cache/SettingCacheTest.php index cc05304f7b..da2e9f588a 100644 --- a/tests/Feature/Cache/SettingCacheTest.php +++ b/tests/Feature/Cache/SettingCacheTest.php @@ -257,4 +257,65 @@ public function testClearOnlySettings() config()->set('cache.default', 'array'); $this->assertEquals(3, Cache::get('password-policies.uppercase')); } + + public function testInvalidateOnSaved() + { + $setting = Setting::factory()->create([ + 'key' => 'password-policies.users_can_change', + 'config' => 1, + 'format' => 'boolean', + ]); + + \SettingCache::set($setting->key, $setting); + $settingCache = \SettingCache::get($setting->key); + + $this->assertEquals(1, $settingCache->config); + + $setting->update(['config' => 0]); + $settingCache = \SettingCache::get($setting->key); + $this->assertNull($settingCache); + } + + public function testInvalidateOnDeleted() + { + $setting = Setting::factory()->create([ + 'key' => 'password-policies.users_can_change', + 'config' => 1, + 'format' => 'boolean', + ]); + + \SettingCache::set($setting->key, $setting); + $settingCache = \SettingCache::get($setting->key); + + $this->assertEquals(1, $settingCache->config); + + $setting->delete(); + $settingCache = \SettingCache::get($setting->key); + $this->assertNull($settingCache); + } + + public function testInvalidateWithException() + { + $setting = Setting::factory()->create([ + 'key' => 'password-policies.numbers', + 'config' => 1, + 'format' => 'boolean', + ]); + + \SettingCache::set($setting->key, $setting); + $settingCache = \SettingCache::get($setting->key); + + $this->assertEquals(1, $settingCache->config); + + \SettingCache::shouldReceive('invalidate') + ->with($setting->key) + ->andThrow(new SettingCacheException('Failed to invalidate cache KEY:' . $setting->key)) + ->once(); + $this->expectException(SettingCacheException::class); + $this->expectExceptionMessage('Failed to invalidate cache KEY:' . $setting->key); + + \SettingCache::shouldReceive('clear')->once()->andReturn(true); + + $setting->delete(); + } }