Passed
Push — main ( bce8dd...f4f8ca )
by Sílvio
56s
created

DatabaseOptionBuilderTTLAndFlushTest   A

Complexity

Total Complexity 5

Size/Duplication

Total Lines 82
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 44
dl 0
loc 82
rs 10
c 1
b 0
f 0
wmc 5

4 Methods

Rating   Name   Duplication   Size   Complexity  
A test_flush_after_from_options_triggers_auto_flush() 0 22 1
A test_expiration_time_from_options_sets_default_ttl() 0 23 1
A setUp() 0 17 1
A tearDown() 0 9 2
1
<?php
2
3
use PHPUnit\Framework\TestCase;
4
use Silviooosilva\CacheerPhp\Cacheer;
5
use Silviooosilva\CacheerPhp\Config\Option\Builder\OptionBuilder;
6
use Silviooosilva\CacheerPhp\Helpers\FlushHelper;
7
8
class DatabaseOptionBuilderTTLAndFlushTest extends TestCase
9
{
10
  private string $table = 'cache_items_ttl_flush';
11
12
  protected function setUp(): void
13
  {
14
    // Ensure the custom table exists (SQLite-compatible DDL)
15
    $pdo = Silviooosilva\CacheerPhp\Core\Connect::getInstance();
16
    $pdo->exec("CREATE TABLE IF NOT EXISTS {$this->table} (
17
        id INTEGER PRIMARY KEY AUTOINCREMENT,
18
        cacheKey VARCHAR(255) NOT NULL,
19
        cacheData TEXT NOT NULL,
20
        cacheNamespace VARCHAR(255),
21
        expirationTime DATETIME NOT NULL,
22
        created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
23
        UNIQUE(cacheKey, cacheNamespace)
24
    );
25
    CREATE INDEX IF NOT EXISTS idx_{$this->table}_cacheKey ON {$this->table} (cacheKey);
26
    CREATE INDEX IF NOT EXISTS idx_{$this->table}_cacheNamespace ON {$this->table} (cacheNamespace);
27
    CREATE INDEX IF NOT EXISTS idx_{$this->table}_expirationTime ON {$this->table} (expirationTime);
28
    CREATE INDEX IF NOT EXISTS idx_{$this->table}_key_namespace ON {$this->table} (cacheKey, cacheNamespace);
29
    ");
30
  }
31
32
  protected function tearDown(): void
33
  {
34
    // clean up flush file
35
    $path = FlushHelper::pathFor('db', $this->table);
36
    if (file_exists($path)) {
37
      @unlink($path);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for unlink(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

37
      /** @scrutinizer ignore-unhandled */ @unlink($path);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
38
    }
39
    $pdo = Silviooosilva\CacheerPhp\Core\Connect::getInstance();
40
    $pdo->exec("DROP TABLE IF EXISTS {$this->table}");
41
  }
42
43
  public function test_expiration_time_from_options_sets_default_ttl()
44
  {
45
    $options = OptionBuilder::forDatabase()
46
      ->table($this->table)
47
      ->expirationTime('-1 seconds')
48
      ->build();
49
50
    $cache = new Cacheer($options);
51
    $cache->setDriver()->useDatabaseDriver();
52
53
    $key = 'db_opt_ttl_key';
54
    $data = ['a' => 1];
55
    $cache->putCache($key, $data); // default ttl should be overridden to past time
56
    $this->assertTrue($cache->isSuccess());
57
58
    $pdo = Silviooosilva\CacheerPhp\Core\Connect::getInstance();
59
    $nowFunction = "DATETIME('now', 'localtime')";
0 ignored issues
show
Unused Code introduced by
The assignment to $nowFunction is dead and can be removed.
Loading history...
60
    $stmt = $pdo->prepare("SELECT expirationTime FROM {$this->table} WHERE cacheKey = :k LIMIT 1");
61
    $stmt->bindValue(':k', $key);
62
    $stmt->execute();
63
    $row = $stmt->fetch(PDO::FETCH_ASSOC);
64
    $this->assertNotFalse($row);
65
    $this->assertLessThanOrEqual(time(), strtotime($row['expirationTime']));
66
  }
67
68
  public function test_flush_after_from_options_triggers_auto_flush()
69
  {
70
    $options = OptionBuilder::forDatabase()
71
      ->table($this->table)
72
      ->flushAfter('1 seconds')
73
      ->build();
74
75
    // Pre-create an old last flush file to force a flush on init
76
    $flushFile = FlushHelper::pathFor('db', $this->table);
77
    file_put_contents($flushFile, (string) (time() - 3600));
78
79
    // Seed data using a cache without flushAfter
80
    $seed = new Cacheer(OptionBuilder::forDatabase()->table($this->table)->build());
81
    $seed->setDriver()->useDatabaseDriver();
82
    $seed->putCache('to_be_flushed', 'x');
83
    $this->assertTrue($seed->isSuccess());
84
85
    // New instance with auto-flush should clear table on construct
86
    $cache = new Cacheer($options);
87
    $cache->setDriver()->useDatabaseDriver();
88
89
    $this->assertEmpty($cache->getAll());
90
  }
91
}
92