store/tests/Feature/CacheTest.php

295 lines
9.8 KiB
PHP

<?php
use App\Models\Category;
use App\Models\Customer;
use App\Models\Supplier;
use App\Services\Concerns\CachesQuery;
use App\Services\Master\CategoryService;
use App\Services\Master\CustomerService;
use App\Services\Master\SupplierService;
use Database\Seeders\RolePermissionSeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Cache;
uses(RefreshDatabase::class);
beforeEach(function () {
$this->seed(RolePermissionSeeder::class);
});
// ─── CachesQuery Trait ─────────────────────────────────────
describe('CachesQuery Trait', function () {
test('cacheRemember stores and retrieves value', function () {
$service = new class
{
use CachesQuery;
public function callRemember(): array
{
return $this->cacheRemember('test:key', 60, function () {
return ['foo' => 'bar'];
});
}
};
$result = $service->callRemember();
expect($result)->toBe(['foo' => 'bar']);
expect(Cache::has('test:key'))->toBeTrue();
});
test('cacheRemember returns cached value on second call', function () {
$service = new class
{
use CachesQuery;
public int $callCount = 0;
public function callRemember(): array
{
return $this->cacheRemember('test:counter', 60, function () {
$this->callCount++;
return ['count' => $this->callCount];
});
}
};
$first = $service->callRemember();
$second = $service->callRemember();
expect($first)->toBe(['count' => 1]);
expect($second)->toBe(['count' => 1]);
expect($service->callCount)->toBe(1);
});
test('cacheForget removes cached value', function () {
$service = new class
{
use CachesQuery;
public function callRemember(): array
{
return $this->cacheRemember('test:forget', 60, function () {
return ['data' => true];
});
}
public function callForget(): void
{
$this->cacheForget('test:forget');
}
};
$service->callRemember();
expect(Cache::has('test:forget'))->toBeTrue();
$service->callForget();
expect(Cache::has('test:forget'))->toBeFalse();
});
test('cacheForever stores value without expiration', function () {
$service = new class
{
use CachesQuery;
public function callForever(): string
{
return $this->cacheForever('test:forever', function () {
return 'permanent';
});
}
};
$result = $service->callForever();
expect($result)->toBe('permanent');
expect(Cache::has('test:forever'))->toBeTrue();
});
});
// ─── Category Cache ────────────────────────────────────────
describe('Category Caching', function () {
test('getSelectOptions caches results', function () {
Category::factory()->count(3)->create();
$service = app(CategoryService::class);
$first = $service->getSelectOptions();
expect($first)->toHaveCount(3);
expect(Cache::has('master:categories:options'))->toBeTrue();
Category::create(['name' => 'New Category']);
$second = $service->getSelectOptions();
expect($second)->toHaveCount(3);
Cache::forget('master:categories:options');
$third = $service->getSelectOptions();
expect($third)->toHaveCount(4);
});
test('create invalidates category cache', function () {
$service = app(CategoryService::class);
$service->getSelectOptions();
expect(Cache::has('master:categories:options'))->toBeTrue();
$service->create(['name' => 'Test']);
expect(Cache::has('master:categories:options'))->toBeFalse();
});
test('update invalidates category cache', function () {
$category = Category::factory()->create();
$service = app(CategoryService::class);
$service->getSelectOptions();
expect(Cache::has('master:categories:options'))->toBeTrue();
$service->update($category, ['name' => 'Updated']);
expect(Cache::has('master:categories:options'))->toBeFalse();
});
test('delete invalidates category cache', function () {
$category = Category::factory()->create();
$service = app(CategoryService::class);
$service->getSelectOptions();
expect(Cache::has('master:categories:options'))->toBeTrue();
$service->delete($category);
expect(Cache::has('master:categories:options'))->toBeFalse();
});
});
// ─── Supplier Cache ────────────────────────────────────────
describe('Supplier Caching', function () {
test('getSelectOptions caches results', function () {
Supplier::factory()->count(3)->create();
$service = app(SupplierService::class);
$first = $service->getSelectOptions();
expect($first)->toHaveCount(3);
expect(Cache::has('master:suppliers:options'))->toBeTrue();
Cache::forget('master:suppliers:options');
$second = $service->getSelectOptions();
expect($second)->toHaveCount(3);
});
test('create invalidates supplier cache', function () {
$service = app(SupplierService::class);
$service->getSelectOptions();
expect(Cache::has('master:suppliers:options'))->toBeTrue();
$service->create(['name' => 'Test Supplier', 'phone_number' => '08123', 'address' => 'Jl. Test']);
expect(Cache::has('master:suppliers:options'))->toBeFalse();
});
test('update invalidates supplier cache', function () {
$supplier = Supplier::factory()->create();
$service = app(SupplierService::class);
$service->getSelectOptions();
expect(Cache::has('master:suppliers:options'))->toBeTrue();
$service->update($supplier, ['name' => 'Updated']);
expect(Cache::has('master:suppliers:options'))->toBeFalse();
});
test('delete invalidates supplier cache', function () {
$supplier = Supplier::factory()->create();
$service = app(SupplierService::class);
$service->getSelectOptions();
expect(Cache::has('master:suppliers:options'))->toBeTrue();
$service->delete($supplier);
expect(Cache::has('master:suppliers:options'))->toBeFalse();
});
});
// ─── Customer Cache ────────────────────────────────────────
describe('Customer Caching', function () {
test('getSelectOptions caches results', function () {
Customer::factory()->count(3)->create();
$service = app(CustomerService::class);
$first = $service->getSelectOptions();
expect($first)->toHaveCount(3);
expect(Cache::has('master:customers:options'))->toBeTrue();
Cache::forget('master:customers:options');
$second = $service->getSelectOptions();
expect($second)->toHaveCount(3);
});
test('create invalidates customer cache', function () {
$service = app(CustomerService::class);
$service->getSelectOptions();
expect(Cache::has('master:customers:options'))->toBeTrue();
$service->create(['name' => 'Test Customer', 'phone_number' => '08123', 'address' => 'Jl. Test']);
expect(Cache::has('master:customers:options'))->toBeFalse();
});
test('createAndReturn invalidates customer cache', function () {
$service = app(CustomerService::class);
$service->getSelectOptions();
expect(Cache::has('master:customers:options'))->toBeTrue();
$customer = $service->createAndReturn(['name' => 'Test', 'phone_number' => '08123', 'address' => 'Jl. Test']);
expect($customer)->toBeInstanceOf(Customer::class);
expect(Cache::has('master:customers:options'))->toBeFalse();
});
test('update invalidates customer cache', function () {
$customer = Customer::factory()->create();
$service = app(CustomerService::class);
$service->getSelectOptions();
expect(Cache::has('master:customers:options'))->toBeTrue();
$service->update($customer, ['name' => 'Updated']);
expect(Cache::has('master:customers:options'))->toBeFalse();
});
test('delete invalidates customer cache', function () {
$customer = Customer::factory()->create();
$service = app(CustomerService::class);
$service->getSelectOptions();
expect(Cache::has('master:customers:options'))->toBeTrue();
$service->delete($customer);
expect(Cache::has('master:customers:options'))->toBeFalse();
});
});
// ─── Cache Key Isolation ───────────────────────────────────
describe('Cache Key Isolation', function () {
test('different services use different cache keys', function () {
Category::factory()->count(2)->create();
Supplier::factory()->count(3)->create();
app(CategoryService::class)->getSelectOptions();
app(SupplierService::class)->getSelectOptions();
expect(Cache::has('master:categories:options'))->toBeTrue();
expect(Cache::has('master:suppliers:options'))->toBeTrue();
Cache::forget('master:categories:options');
expect(Cache::has('master:categories:options'))->toBeFalse();
expect(Cache::has('master:suppliers:options'))->toBeTrue();
});
});