Passed
Push — main ( 82ed03...16f015 )
by Sebastian
04:07
created

BlockSecretsTest::testExecuteAllow()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 18
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 12
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 18
rs 9.8666
1
<?php
2
3
/**
4
 * This file is part of CaptainHook
5
 *
6
 * (c) Sebastian Feldmann <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace CaptainHook\App\Hook\Diff\Action;
13
14
use CaptainHook\App\Config;
15
use CaptainHook\App\Console\IO\NullIO;
16
use CaptainHook\App\Hook\Debug;
17
use CaptainHook\App\Mockery as AppMockery;
18
use CaptainHook\App\Console\IO\Mockery as IOMockery;
19
use CaptainHook\Secrets\Regex\Supplier\Aws;
20
use CaptainHook\Secrets\Regex\Supplier\GitHub;
21
use CaptainHook\Secrets\Regex\Supplier\Google;
22
use CaptainHook\Secrets\Regex\Supplier\Password;
23
use CaptainHook\Secrets\Regex\Supplier\Stripe;
24
use Exception;
25
use PHPUnit\Framework\TestCase;
26
use SebastianFeldmann\Git\Diff\Change;
27
use SebastianFeldmann\Git\Diff\File;
28
use SebastianFeldmann\Git\Diff\Line;
29
30
class BlockSecretsTest extends TestCase
31
{
32
    use AppMockery;
33
    use IOMockery;
34
35
    /**
36
     * Tests BlockSecrets::getRestriction
37
     */
38
    public function testConstraint(): void
39
    {
40
        $this->assertTrue(BlockSecrets::getRestriction()->isApplicableFor('pre-commit'));
41
        $this->assertTrue(BlockSecrets::getRestriction()->isApplicableFor('pre-push'));
42
        $this->assertFalse(BlockSecrets::getRestriction()->isApplicableFor('post-merge'));
43
    }
44
45
    /**
46
     * Tests BlockSecrets::execute
47
     *
48
     * @throws \Exception
49
     */
50
    public function testExecuteSuccess(): void
51
    {
52
        $diffOperator = $this->createGitDiffOperator();
53
        $diffOperator->method('compareIndexTo')->willReturn(
54
            $this->createChanges('fail.txt', ['foo', 'bar', 'baz'])
55
        );
56
57
        $io     = new NullIO();
58
        $config = new Config(CH_PATH_FILES . '/captainhook.json');
59
        $action = new Config\Action(BlockSecrets::class, ['entropyThreshold' => 10.0]);
60
        $repo   = $this->createRepositoryMock();
61
        $repo->method('getDiffOperator')->willReturn($diffOperator);
62
63
        $standard = new BlockSecrets();
64
        $standard->execute($config, $io, $repo, $action);
65
66
        $this->assertTrue(true);
67
    }
68
69
    /**
70
     * Tests BlockSecrets::execute
71
     *
72
     * @throws \Exception
73
     */
74
    public function testExecuteSuccessOnPush(): void
75
    {
76
        $diffOperator = $this->createGitDiffOperator();
77
        $diffOperator->method('compareIndexTo')->willReturn(
78
            $this->createChanges('fail.txt', ['foo', 'bar', 'baz'])
79
        );
80
81
        $io = $this->createIOMock();
82
        $io->method('getArgument')->willReturn('hook:pre-push');
83
        $io->method('getStandardInput')->willReturn(['main 12345 main 98765']);
84
        $config = new Config(CH_PATH_FILES . '/captainhook.json');
85
        $action = new Config\Action(BlockSecrets::class, ['entropyThreshold' => 10.0]);
86
        $repo   = $this->createRepositoryMock();
87
        $repo->method('getDiffOperator')->willReturn($diffOperator);
88
89
        $standard = new BlockSecrets();
90
        $standard->execute($config, $io, $repo, $action);
91
92
        $this->assertTrue(true);
93
    }
94
95
96
    /**
97
     * Tests BlockSecrets::execute
98
     *
99
     * @throws \Exception
100
     */
101
    public function testExecuteSuccessWithEntropyCheck(): void
102
    {
103
        $diffOperator = $this->createGitDiffOperator();
104
        $diffOperator->method('compareIndexTo')->willReturn(
105
            $this->createChanges('fail.php', ['foo', 'bar', 'baz'])
106
        );
107
108
        $io     = new NullIO();
109
        $config = new Config(CH_PATH_FILES . '/captainhook.json');
110
        $action = new Config\Action(BlockSecrets::class, ['entropyThreshold' => 10.0]);
111
        $repo   = $this->createRepositoryMock();
112
        $repo->method('getDiffOperator')->willReturn($diffOperator);
113
114
        $standard = new BlockSecrets();
115
        $standard->execute($config, $io, $repo, $action);
116
117
        $this->assertTrue(true);
118
    }
119
120
    /**
121
     * Tests BlockSecrets::execute
122
     *
123
     * @throws \Exception
124
     */
125
    public function testExecuteFailure(): void
126
    {
127
        $this->expectException(Exception::class);
128
129
        $options = [
130
            'suppliers' => [
131
                Aws::class,
132
                Password::class,
133
                Google::class,
134
                GitHub::class,
135
                Stripe::class
136
            ]
137
        ];
138
139
        $diffOperator = $this->createGitDiffOperator();
140
        $diffOperator->method('compareIndexTo')->willReturn(
141
            $this->createChanges('fail.txt', ['foo', 'AKIAIOSFODNN7EXAMPLE', 'bar'])
142
        );
143
144
        $io     = new NullIO();
145
        $config = new Config(CH_PATH_FILES . '/captainhook.json');
146
        $action = new Config\Action(BlockSecrets::class, $options);
147
        $repo   = $this->createRepositoryMock();
148
        $repo->method('getDiffOperator')->willReturn($diffOperator);
149
150
        $standard = new BlockSecrets();
151
        $standard->execute($config, $io, $repo, $action);
152
    }
153
154
    /**
155
     * Tests BlockSecrets::execute
156
     *
157
     * @throws \Exception
158
     */
159
    public function testExecuteFailureByEntropy(): void
160
    {
161
        $this->expectException(Exception::class);
162
163
        $options = ['entropyThreshold' => 1];
164
165
        $diffOperator = $this->createGitDiffOperator();
166
        $diffOperator->method('compareIndexTo')->willReturn(
167
            $this->createChanges('fail.php', ['foo', '$password = "5ad7$-9Op0-x2§d"', 'bar'])
168
        );
169
170
        $io     = new NullIO();
171
        $config = new Config(CH_PATH_FILES . '/captainhook.json');
172
        $action = new Config\Action(BlockSecrets::class, $options);
173
        $repo   = $this->createRepositoryMock();
174
        $repo->method('getDiffOperator')->willReturn($diffOperator);
175
176
        $standard = new BlockSecrets();
177
        $standard->execute($config, $io, $repo, $action);
178
    }
179
180
    /**
181
     * Tests BlockSecrets::execute
182
     *
183
     * @throws \Exception
184
     */
185
    public function testExecuteProviderNotFound(): void
186
    {
187
        $this->expectException(Exception::class);
188
189
        $options = [
190
            'suppliers' => [
191
                'Fooooooooooooo'
192
            ]
193
        ];
194
195
        $io     = new NullIO();
196
        $config = new Config(CH_PATH_FILES . '/captainhook.json');
197
        $action = new Config\Action(BlockSecrets::class, $options);
198
        $repo   = $this->createRepositoryMock();
199
        $repo->method('getDiffOperator')->willReturn($this->createGitDiffOperator());
200
201
        $standard = new BlockSecrets();
202
        $standard->execute($config, $io, $repo, $action);
203
    }
204
205
    /**
206
     * Tests BlockSecrets::execute
207
     *
208
     * @throws \Exception
209
     */
210
    public function testExecuteInvalidProvider(): void
211
    {
212
        $this->expectException(Exception::class);
213
214
        $options = [
215
            'suppliers' => [
216
                Debug::class
217
            ]
218
        ];
219
220
        $io     = new NullIO();
221
        $config = new Config(CH_PATH_FILES . '/captainhook.json');
222
        $action = new Config\Action(BlockSecrets::class, $options);
223
        $repo   = $this->createRepositoryMock();
224
        $repo->method('getDiffOperator')->willReturn($this->createGitDiffOperator());
225
226
        $standard = new BlockSecrets();
227
        $standard->execute($config, $io, $repo, $action);
228
    }
229
230
    /**
231
     * Tests BlockSecrets::execute
232
     */
233
    public function testExecuteAllow(): void
234
    {
235
        $diffOperator = $this->createGitDiffOperator();
236
        $diffOperator->method('compareIndexTo')->willReturn(
237
            $this->createChanges('fail.txt', ['foo', 'bar'])
238
        );
239
240
        $io     = new NullIO();
241
        $config = new Config(CH_PATH_FILES . '/captainhook.json');
242
        $action = new Config\Action(BlockSecrets::class, [
243
            'blocked' => ['#f[a-z]+#'],
244
            'allowed' => ['#foo#']
245
        ]);
246
        $repo = $this->createRepositoryMock();
247
        $repo->expects($this->atLeast(1))->method('getDiffOperator')->willReturn($diffOperator);
248
249
        $standard = new BlockSecrets();
250
        $standard->execute($config, $io, $repo, $action);
251
    }
252
253
    /**
254
     * @param string        $fileName
255
     * @param array<string> $lines
256
     * @return array<File>
257
     */
258
    private function createChanges(string $fileName, array $lines): array
259
    {
260
        $diffChange = new Change('+123,456 -789,012', '');
261
        foreach ($lines as $line) {
262
            $diffChange->addLine(new Line('added', $line));
263
        }
264
        $diffFile = new File($fileName, 'new');
265
        $diffFile->addChange($diffChange);
266
267
        return [$diffFile];
268
    }
269
}
270