1
|
|
|
<?php |
2
|
|
|
/* |
3
|
|
|
* This file is part of the KleijnWeb\JwtBundle package. |
4
|
|
|
* |
5
|
|
|
* For the full copyright and license information, please view the LICENSE |
6
|
|
|
* file that was distributed with this source code. |
7
|
|
|
*/ |
8
|
|
|
namespace KleijnWeb\JwtBundle\Tests\Authenticator; |
9
|
|
|
|
10
|
|
|
use KleijnWeb\JwtBundle\Authenticator\JwtToken; |
11
|
|
|
|
12
|
|
|
/** |
13
|
|
|
* @author John Kleijn <[email protected]> |
14
|
|
|
*/ |
15
|
|
|
class JwtTokenTest extends \PHPUnit_Framework_TestCase |
16
|
|
|
{ |
17
|
|
|
// @codingStandardsIgnoreStart |
18
|
|
|
const EXAMPLE_TOKEN = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ'; |
19
|
|
|
const KID_TOKEN = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImtleU9uZSJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.Zhhr_UtsTzjrBZmi8AAgJYqCINiiEc45v94_3nvxW1A'; |
20
|
|
|
// @codingStandardsIgnoreEnd |
21
|
|
|
|
22
|
|
|
/** |
23
|
|
|
* @test |
24
|
|
|
*/ |
25
|
|
|
public function willDecodeClaimsOnConstruction() |
26
|
|
|
{ |
27
|
|
|
$token = new JwtToken(self::EXAMPLE_TOKEN); |
28
|
|
|
$this->assertSame([ |
29
|
|
|
'sub' => '1234567890', |
30
|
|
|
'name' => 'John Doe', |
31
|
|
|
'admin' => true, |
32
|
|
|
], $token->getClaims()); |
33
|
|
|
} |
34
|
|
|
|
35
|
|
|
/** |
36
|
|
|
* @test |
37
|
|
|
*/ |
38
|
|
|
public function willDecodeHeadersOnConstruction() |
39
|
|
|
{ |
40
|
|
|
$token = new JwtToken(self::EXAMPLE_TOKEN); |
41
|
|
|
$this->assertSame([ |
42
|
|
|
'alg' => 'HS256', |
43
|
|
|
'typ' => 'JWT', |
44
|
|
|
], $token->getHeader()); |
45
|
|
|
} |
46
|
|
|
|
47
|
|
|
/** |
48
|
|
|
* @test |
49
|
|
|
* @return JwtToken |
50
|
|
|
*/ |
51
|
|
|
public function willDecodeWithArray() |
52
|
|
|
{ |
53
|
|
|
$token = new JwtToken([ |
54
|
|
|
'header' => [ |
55
|
|
|
'alg' => 'HS256', |
56
|
|
|
'typ' => 'JWT', |
57
|
|
|
], |
58
|
|
|
'claims' => [ |
59
|
|
|
'sub' => '1234567890', |
60
|
|
|
'name' => 'John Doe', |
61
|
|
|
'admin' => true, |
62
|
|
|
], |
63
|
|
|
'secret' => 'secret' |
64
|
|
|
]); |
65
|
|
|
|
66
|
|
|
$this->assertSame(self::EXAMPLE_TOKEN, $token->getTokenString()); |
67
|
|
|
|
68
|
|
|
return $token; |
69
|
|
|
} |
70
|
|
|
|
71
|
|
|
|
72
|
|
|
/** |
73
|
|
|
* @test |
74
|
|
|
*/ |
75
|
|
|
public function willResultNullWhenKidOmitted() |
76
|
|
|
{ |
77
|
|
|
$token = new JwtToken(self::EXAMPLE_TOKEN); |
78
|
|
|
$this->assertNull($token->getKeyId()); |
79
|
|
|
} |
80
|
|
|
|
81
|
|
|
/** |
82
|
|
|
* @test |
83
|
|
|
*/ |
84
|
|
|
public function canGetKidWhenPresent() |
85
|
|
|
{ |
86
|
|
|
$token = new JwtToken(self::KID_TOKEN); |
87
|
|
|
$this->assertSame('keyOne', $token->getKeyId()); |
88
|
|
|
} |
89
|
|
|
|
90
|
|
|
/** |
91
|
|
|
* @test |
92
|
|
|
*/ |
93
|
|
|
public function canGetSubject() |
94
|
|
|
{ |
95
|
|
|
$this->assertSame('1234567890', $this->willDecodeWithArray()->getSubject()); |
96
|
|
|
} |
97
|
|
|
|
98
|
|
|
|
99
|
|
|
/** |
100
|
|
|
* @test |
101
|
|
|
* @expectedException \InvalidArgumentException |
102
|
|
|
*/ |
103
|
|
View Code Duplication |
public function willFailWhenSignatureValidationIsUnsuccessful() |
|
|
|
|
104
|
|
|
{ |
105
|
|
|
$validator = $this |
106
|
|
|
->getMockBuilder( |
107
|
|
|
'KleijnWeb\JwtBundle\Authenticator\SignatureValidator\SignatureValidator' |
108
|
|
|
) |
109
|
|
|
->getMockForAbstractClass(); |
110
|
|
|
|
111
|
|
|
$token = new JwtToken(self::EXAMPLE_TOKEN); |
112
|
|
|
$validator->expects($this->once())->method('isValid')->willReturn(false); |
113
|
|
|
$token->validateSignature('foobar', $validator); |
114
|
|
|
} |
115
|
|
|
|
116
|
|
|
|
117
|
|
|
/** |
118
|
|
|
* @test |
119
|
|
|
*/ |
120
|
|
View Code Duplication |
public function willNitFailWhenSignatureValidationIsSuccessful() |
|
|
|
|
121
|
|
|
{ |
122
|
|
|
$validator = $this |
123
|
|
|
->getMockBuilder( |
124
|
|
|
'KleijnWeb\JwtBundle\Authenticator\SignatureValidator\SignatureValidator' |
125
|
|
|
) |
126
|
|
|
->getMockForAbstractClass(); |
127
|
|
|
|
128
|
|
|
$token = new JwtToken(self::EXAMPLE_TOKEN); |
129
|
|
|
|
130
|
|
|
$validator->expects($this->once())->method('isValid')->willReturn(true); |
131
|
|
|
$token->validateSignature('foobar', $validator); |
132
|
|
|
} |
133
|
|
|
|
134
|
|
|
/** |
135
|
|
|
* @test |
136
|
|
|
* @expectedException \InvalidArgumentException |
137
|
|
|
*/ |
138
|
|
|
public function willFailWhenTokenDoesNotContain3Segments() |
139
|
|
|
{ |
140
|
|
|
$segments = explode('.', self::EXAMPLE_TOKEN); |
141
|
|
|
|
142
|
|
|
new JwtToken("{$segments[0]}.{$segments[1]}"); |
143
|
|
|
} |
144
|
|
|
} |
145
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.