Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
50 / 50
n/a
0 / 0
CRAP
n/a
0 / 0
1<?php
2
3// ╔════════════════════════════════════════════════════════════╗
4// ║ MIT Licence (#Expat) - https://opensource.org/licenses/MIT ║
5// ║ Copyright 2026 Frederic Poeydomenge <dyno@phexium.com>     ║
6// ╚════════════════════════════════════════════════════════════╝
7
8declare(strict_types=1);
9
10pest()->group('integration');
11
12use Phexium\Plugin\PasswordHasher\Adapter\Argon2idPasswordHasher;
13
14beforeEach(function (): void {
15    $this->hasher = new Argon2idPasswordHasher(memoryCost: 1024, timeCost: 1, threads: 1);
16});
17
18describe('Hashing', function (): void {
19    it('produces a hash that differs from the plain password', function (): void {
20        $plainPassword = 'SecurePassword123';
21
22        $hash = $this->hasher->hash($plainPassword);
23
24        expect($hash)->toBeString();
25        expect($hash)->not->toBe($plainPassword);
26        expect($hash)->toStartWith('$argon2id$');
27    });
28
29    it('produces different hashes for the same password', function (): void {
30        $plainPassword = 'SecurePassword123';
31
32        $hash1 = $this->hasher->hash($plainPassword);
33        $hash2 = $this->hasher->hash($plainPassword);
34
35        expect($hash1)->not->toBe($hash2);
36        expect($this->hasher->verify($plainPassword, $hash1))->toBeTrue();
37        expect($this->hasher->verify($plainPassword, $hash2))->toBeTrue();
38    });
39
40    it('uses default options when none are specified', function (): void {
41        $hasher = new Argon2idPasswordHasher();
42        $hash = $hasher->hash('test');
43
44        expect($hash)->toStartWith('$argon2id$v=19$m=65536,t=4,p=1$');
45    });
46
47    it('applies custom options', function (): void {
48        $hasher = new Argon2idPasswordHasher(memoryCost: 2048, timeCost: 2, threads: 1);
49        $hash = $hasher->hash('test');
50
51        expect($hash)->toStartWith('$argon2id$v=19$m=2048,t=2,p=1$');
52    });
53});
54
55describe('Verification', function (): void {
56    it('returns true for the correct password', function (): void {
57        $plainPassword = 'SecurePassword123';
58        $hash = $this->hasher->hash($plainPassword);
59
60        expect($this->hasher->verify($plainPassword, $hash))->toBeTrue();
61    });
62
63    it('returns false for an incorrect password', function (): void {
64        $wrongPassword = 'WrongPassword456';
65        $plainPassword = 'SecurePassword123';
66        $hash = $this->hasher->hash($plainPassword);
67
68        expect($this->hasher->verify($wrongPassword, $hash))->toBeFalse();
69    });
70
71    it('treats passwords as case sensitive', function (): void {
72        $wrongPassword = 'securepassword123';
73        $plainPassword = 'SecurePassword123';
74        $hash = $this->hasher->hash($plainPassword);
75
76        expect($this->hasher->verify($wrongPassword, $hash))->toBeFalse();
77    });
78});