Skip to content

Commit fb6e477

Browse files
committed
:octocat: test overhaul
1 parent dc1c337 commit fb6e477

File tree

5 files changed

+123
-88
lines changed

5 files changed

+123
-88
lines changed

tests/AuthenticatorTest.php

Lines changed: 6 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,9 @@
1212
namespace chillerlan\AuthenticatorTest;
1313

1414
use chillerlan\Authenticator\{Authenticator, AuthenticatorOptions};
15-
use chillerlan\Authenticator\Authenticators\AuthenticatorInterface;
16-
use InvalidArgumentException;
15+
use PHPUnit\Framework\Attributes\Test;
1716
use PHPUnit\Framework\TestCase;
18-
use function sprintf;
17+
use InvalidArgumentException;
1918

2019
class AuthenticatorTest extends TestCase{
2120

@@ -31,61 +30,15 @@ protected function setUp():void{
3130
$this->authenticator = new Authenticator($this->options);
3231
}
3332

34-
public function testSetSecretViaConstruct():void{
33+
#[Test]
34+
public function setSecretViaConstruct():void{
3535
$this->authenticator = new Authenticator(secret: self::secret);
3636

3737
$this::assertSame(self::secret, $this->authenticator->getSecret());
3838
}
3939

40-
public function testGetUri():void{
41-
$this->authenticator->setSecret(self::secret);
42-
43-
$label = rawurlencode(self::label);
44-
$issuer = rawurlencode(self::issuer);
45-
46-
$this->options->omitUriSettings = false;
47-
$this::assertSame(
48-
sprintf('otpauth://totp/%s?secret=%s&issuer=%s&digits=6&algorithm=SHA1&period=30', $label, self::secret, $issuer),
49-
$this->authenticator->getUri(self::label, self::issuer),
50-
);
51-
52-
$this->options->digits = 8;
53-
$this::assertSame(
54-
sprintf('otpauth://totp/%s?secret=%s&issuer=%s&digits=8&algorithm=SHA1&period=30', $label, self::secret, $issuer),
55-
$this->authenticator->getUri(self::label, self::issuer),
56-
);
57-
58-
$this->options->period = 45;
59-
$this::assertSame(
60-
sprintf('otpauth://totp/%s?secret=%s&issuer=%s&digits=8&algorithm=SHA1&period=45', $label, self::secret, $issuer),
61-
$this->authenticator->getUri(self::label, self::issuer),
62-
);
63-
64-
$this->options->mode = AuthenticatorInterface::HOTP;
65-
// changing the mode resets the AuthenticatorInterface instance
66-
$this->authenticator
67-
->setOptions($this->options)
68-
->setSecret(self::secret);
69-
70-
$this::assertSame(
71-
sprintf('otpauth://hotp/%s?secret=%s&issuer=%s&counter=42&digits=8&algorithm=SHA1', $label, self::secret, $issuer),
72-
$this->authenticator->getUri(self::label, self::issuer, 42),
73-
);
74-
75-
$this->options->algorithm = AuthenticatorInterface::ALGO_SHA512;
76-
$this::assertSame(
77-
sprintf('otpauth://hotp/%s?secret=%s&issuer=%s&counter=0&digits=8&algorithm=SHA512', $label, self::secret, $issuer),
78-
$this->authenticator->getUri(self::label, self::issuer, 0),
79-
);
80-
81-
// test omit settings
82-
$this::assertSame(
83-
sprintf('otpauth://%s/%s?secret=%s&issuer=%s&counter=42', 'hotp', $label, self::secret, $issuer),
84-
$this->authenticator->getUri(self::label, self::issuer, 42, true),
85-
);
86-
}
87-
88-
public function testGetUriEmptyLabelException():void{
40+
#[Test]
41+
public function getUriEmptyLabelException():void{
8942
$this->expectException(InvalidArgumentException::class);
9043
$this->expectExceptionMessage('$label and $issuer cannot be empty');
9144

tests/Authenticators/AuthenticatorInterfaceTestAbstract.php

Lines changed: 56 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@
1414
use chillerlan\Authenticator\AuthenticatorOptions;
1515
use chillerlan\Authenticator\Authenticators\AuthenticatorInterface;
1616
use chillerlan\Authenticator\Common\Base32;
17-
use InvalidArgumentException;
1817
use PHPUnit\Framework\TestCase;
19-
use RuntimeException;
20-
use function strlen;
18+
use PHPUnit\Framework\Attributes\{DataProvider, Test};
19+
use InvalidArgumentException, RuntimeException;
20+
use function rawurlencode, sprintf, strlen;
2121

2222
abstract class AuthenticatorInterfaceTestAbstract extends TestCase{
2323

@@ -27,14 +27,18 @@ abstract class AuthenticatorInterfaceTestAbstract extends TestCase{
2727
protected const rawsecret = '12345678901234567890';
2828
protected const secret = 'GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ';
2929

30+
protected const label = 'some test-label';
31+
protected const issuer = 'chillerlan.net';
32+
3033
abstract protected function getInstance(AuthenticatorOptions $options):AuthenticatorInterface;
3134

3235
protected function setUp():void{
3336
$this->options = new AuthenticatorOptions;
3437
$this->authenticatorInterface = $this->getInstance($this->options);
3538
}
3639

37-
public function testSetGetSecret():void{
40+
#[Test]
41+
public function setGetSecret():void{
3842
$this->authenticatorInterface->setSecret($this::secret);
3943

4044
$secret = $this->authenticatorInterface->getSecret();
@@ -43,34 +47,39 @@ public function testSetGetSecret():void{
4347
$this::assertSame($this::rawsecret, Base32::decode($secret));
4448
}
4549

46-
public function testSetEmptySecretException():void{
50+
#[Test]
51+
public function setEmptySecretException():void{
4752
$this->expectException(InvalidArgumentException::class);
4853
$this->expectExceptionMessage('The given secret string is empty');
4954

5055
$this->authenticatorInterface->setSecret('');
5156
}
5257

53-
public function testSetInvalidSecretException():void{
58+
#[Test]
59+
public function setInvalidSecretException():void{
5460
$this->expectException(InvalidArgumentException::class);
5561

5662
$this->authenticatorInterface->setSecret('This_is_an_invalid_secret_phrase!');
5763
}
5864

59-
public function testGetSecretException():void{
65+
#[Test]
66+
public function getSecretException():void{
6067
$this->expectException(RuntimeException::class);
6168
$this->expectExceptionMessage('No secret set');
6269

6370
$this->authenticatorInterface->getSecret();
6471
}
6572

66-
public function testCreateSecretDefaultLength():void{
73+
#[Test]
74+
public function createSecretDefaultLength():void{
6775
$this::assertSame(
6876
$this->options->secret_length,
6977
strlen(Base32::decode($this->authenticatorInterface->createSecret())),
7078
);
7179
}
7280

73-
public function testCreateSecretWithLength():void{
81+
#[Test]
82+
public function createSecretWithLength():void{
7483

7584
for($secretLength = 16; $secretLength <= 512; $secretLength += 8){
7685
$secret = Base32::decode($this->authenticatorInterface->createSecret($secretLength));
@@ -80,28 +89,32 @@ public function testCreateSecretWithLength():void{
8089

8190
}
8291

83-
public function testCreateSecretCheckCharacterSet():void{
92+
#[Test]
93+
public function createSecretCheckCharacterSet():void{
8494
$secret = $this->authenticatorInterface->createSecret(32);
8595

8696
$this::assertMatchesRegularExpression('/^['.Base32::CHARSET.']+$/', $secret);
8797
}
8898

89-
public function testCreateSecretException():void{
99+
#[Test]
100+
public function createSecretException():void{
90101
$this->expectException(InvalidArgumentException::class);
91102
$this->expectExceptionMessage('Invalid secret length');
92103

93104
$this->authenticatorInterface->createSecret(10);
94105
}
95106

96-
public function testGetHMACWithoutSecretException():void{
107+
#[Test]
108+
public function getHMACWithoutSecretException():void{
97109
$this->expectException(RuntimeException::class);
98110
$this->expectExceptionMessage('No secret given');
99111

100112
$this->authenticatorInterface->getHMAC(69);
101113
}
102114

103115
// https://github.com/PHPGangsta/GoogleAuthenticator/pull/25
104-
public function testVerifyCodeWithLeadingZero():void{
116+
#[Test]
117+
public function verifyCodeWithLeadingZero():void{
105118
$this->authenticatorInterface->setSecret($this::secret);
106119

107120
$code = $this->authenticatorInterface->code();
@@ -111,7 +124,8 @@ public function testVerifyCodeWithLeadingZero():void{
111124
}
112125

113126
// coverage
114-
public function testGetServertime():void{
127+
#[Test]
128+
public function getServertime():void{
115129
$this->options->useLocalTime = false;
116130

117131
$servertime = $this->authenticatorInterface->getServerTime();
@@ -123,4 +137,32 @@ public function testGetServertime():void{
123137
$this::assertMatchesRegularExpression('/^\d+$/', (string)$servertime);
124138
}
125139

140+
abstract public static function uriSettingsProvider():array;
141+
142+
/**
143+
* @param array<string, mixed> $options
144+
*/
145+
#[Test]
146+
#[DataProvider('uriSettingsProvider')]
147+
public function getUri(array $options, string $expected):void{
148+
149+
$this->authenticatorInterface
150+
->setOptions($options)
151+
->setSecret(self::secret)
152+
;
153+
154+
$this::assertSame(
155+
sprintf(
156+
'otpauth://%s/%s?secret=%s&issuer=%s%s',
157+
$this->authenticatorInterface::MODE,
158+
rawurlencode(self::label),
159+
self::secret,
160+
rawurlencode(self::issuer),
161+
$expected,
162+
),
163+
$this->authenticatorInterface->getUri(self::label, self::issuer, 42),
164+
);
165+
166+
}
167+
126168
}

tests/Authenticators/HOTPTest.php

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,9 @@
1313

1414
use chillerlan\Authenticator\AuthenticatorOptions;
1515
use chillerlan\Authenticator\Authenticators\{AuthenticatorInterface, HOTP};
16+
use PHPUnit\Framework\Attributes\{DataProvider, Test};
1617
use Generator;
17-
use PHPUnit\Framework\Attributes\DataProvider;
18-
use function bin2hex;
19-
use function sprintf;
18+
use function bin2hex, sprintf;
2019

2120
class HOTPTest extends AuthenticatorInterfaceTestAbstract{
2221

@@ -49,8 +48,9 @@ public static function hotpVectors():Generator{
4948
/**
5049
* @link https://github.com/winauth/winauth/issues/449#issuecomment-353670105
5150
*/
51+
#[Test]
5252
#[DataProvider('hotpVectors')]
53-
public function testHOTP(int $counter, string $hmac, int $code, string $hotp):void{
53+
public function HOTP(int $counter, string $hmac, int $code, string $hotp):void{
5454
$this->authenticatorInterface->setSecret($this::secret);
5555

5656
$hmac_intermediate = $this->authenticatorInterface->getHMAC($counter);
@@ -62,4 +62,16 @@ public function testHOTP(int $counter, string $hmac, int $code, string $hotp):vo
6262
$this::assertTrue($this->authenticatorInterface->verify($hotp, $counter));
6363
}
6464

65+
public static function uriSettingsProvider():array{
66+
return [
67+
'default' => [['omitUriSettings' => false], '&counter=42&digits=6&algorithm=SHA1'],
68+
'digits' => [['omitUriSettings' => false, 'digits' => 8], '&counter=42&digits=8&algorithm=SHA1'],
69+
'algo' => [
70+
['omitUriSettings' => false, 'algorithm' => AuthenticatorInterface::ALGO_SHA512],
71+
'&counter=42&digits=6&algorithm=SHA512',
72+
],
73+
'omit' => [['omitUriSettings' => true], '&counter=42'],
74+
];
75+
}
76+
6577
}

tests/Authenticators/SteamGuardTest.php

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,9 @@
1414
use chillerlan\Authenticator\AuthenticatorOptions;
1515
use chillerlan\Authenticator\Authenticators\{AuthenticatorInterface, SteamGuard};
1616
use chillerlan\Authenticator\Common\Base64;
17+
use PHPUnit\Framework\Attributes\{DataProvider, Test};
1718
use Generator;
18-
use PHPUnit\Framework\Attributes\DataProvider;
19-
use function date;
20-
use function dechex;
21-
use function is_int;
22-
use function strlen;
19+
use function date, dechex, is_int, strlen;
2320
use const PHP_INT_SIZE;
2421

2522
/**
@@ -44,7 +41,8 @@ protected function getInstance(AuthenticatorOptions $options):AuthenticatorInter
4441
return new SteamGuard($options);
4542
}
4643

47-
public function testSetGetSecret():void{
44+
#[Test]
45+
public function setGetSecret():void{
4846
$this->authenticatorInterface->setSecret($this::secret);
4947

5048
$secret = $this->authenticatorInterface->getSecret();
@@ -53,14 +51,16 @@ public function testSetGetSecret():void{
5351
$this::assertSame($this::rawsecret, Base64::decode($secret));
5452
}
5553

56-
public function testCreateSecretDefaultLength():void{
54+
#[Test]
55+
public function createSecretDefaultLength():void{
5756
$this::assertSame(
5857
$this->options->secret_length,
5958
strlen(Base64::decode($this->authenticatorInterface->createSecret())),
6059
);
6160
}
6261

63-
public function testCreateSecretWithLength():void{
62+
#[Test]
63+
public function createSecretWithLength():void{
6464

6565
for($secretLength = 16; $secretLength <= 512; $secretLength += 8){
6666
$secret = Base64::decode($this->authenticatorInterface->createSecret($secretLength));
@@ -70,7 +70,8 @@ public function testCreateSecretWithLength():void{
7070

7171
}
7272

73-
public function testCreateSecretCheckCharacterSet():void{
73+
#[Test]
74+
public function createSecretCheckCharacterSet():void{
7475
$secret = $this->authenticatorInterface->createSecret(32);
7576

7677
$this::assertMatchesRegularExpression('#^['.Base64::CHARSET.']+$#', $secret);
@@ -128,4 +129,19 @@ public function testAdjacent(int $timestamp, string $timeslice, string $totp):vo
128129

129130
}
130131

132+
public static function uriSettingsProvider():array{
133+
return [
134+
[[], ''],
135+
];
136+
}
137+
138+
/**
139+
* @param array<string, mixed> $options
140+
*/
141+
#[Test]
142+
#[DataProvider('uriSettingsProvider')]
143+
public function getUri(array $options, string $expected):void{
144+
$this::markTestSkipped('N/A');
145+
}
146+
131147
}

0 commit comments

Comments
 (0)