Completed
Push — master ( b75e3a...6d849d )
by Michal
02:59
created

GithubControllerTest::testLinkIssue()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 68
Code Lines 40

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 68
rs 9.2447
c 1
b 0
f 0
cc 1
eloc 40
nc 1
nop 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/* vim: set expandtab sw=4 ts=4 sts=4: */
3
4
/**
5
 * Tests for Github Controller actions
6
 *
7
 * phpMyAdmin Error reporting server
8
 * Copyright (c) phpMyAdmin project (https://www.phpmyadmin.net/)
9
 *
10
 * Licensed under The MIT License
11
 * For full copyright and license information, please see the LICENSE.txt
12
 * Redistributions of files must retain the above copyright notice.
13
 *
14
 * @copyright Copyright (c) phpMyAdmin project (https://www.phpmyadmin.net/)
15
 * @license   https://opensource.org/licenses/mit-license.php MIT License
16
 *
17
 * @see      https://www.phpmyadmin.net/
18
 */
19
20
namespace App\Test\TestCase\Controller;
21
22
use App\Controller\GithubController;
23
use Cake\Core\Configure;
24
use Cake\ORM\TableRegistry;
25
use Cake\TestSuite\IntegrationTestCase;
26
27
/**
28
 * App\Controller\GithubController Test Case
29
 */
30
class GithubControllerTest extends IntegrationTestCase
31
{
32
33
    use \phpmock\phpunit\PHPMock;
34
    /**
35
     * Fixtures
36
     *
37
     * @var array
38
     */
39
    public $fixtures = [
40
        'app.reports',
41
        'app.developers',
42
        'app.incidents',
43
        'app.notifications'
44
    ];
45
46
    public function setUp()
47
    {
48
        $this->session(array('Developer.id' => 1, 'access_token' => 'abc'));
49
        $this->Reports = TableRegistry::get('Reports');
0 ignored issues
show
Bug introduced by
The property Reports does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
50
    }
51
52
    /**
53
     * Test create_issue method
54
     *
55
     * @return void
56
     */
57
    public function testCreateIssue()
58
    {
59
        // Mock functions `curl_exec` and `curl_getinfo` in GithubApiComponent
60
        // so that we don't actually hit the Github Api
61
        $curlExecMock = $this->getFunctionMock('\App\Controller\Component', 'curl_exec');
62
        $curlGetInfoMock = $this->getFunctionMock('\App\Controller\Component', 'curl_getinfo');
63
64
        // Case 1. Test with an invalid reportId
65
        $this->get('github/create_issue/123');
66
        $this->assertResponseContains('Invalid report');
67
68
        // Case 2. Test form with valid reportId
69
        $this->get('github/create_issue/5');
70
        $this->assertResponseContains('3.8'); // phpMyAdmin version
71
        $this->assertResponseContains('Lorem ipsum dolor sit amet'); // Description
72
73
        $issueResponse = file_get_contents(TESTS . 'Fixture' . DS . 'issue_response.json');
74
75
        // Github unsuccessful response followed by successful response
76
        $curlExecMock->expects($this->exactly(2))->willReturnOnConsecutiveCalls(
77
            $issueResponse, $issueResponse
78
        );
79
        $curlGetInfoMock->expects($this->exactly(2))->willReturnOnConsecutiveCalls(
80
            403, 201
81
        );
82
83
        // Case 3. Test submission of form with unsuccessful github response
84
        $this->post(
85
            'github/create_issue/5',
86
            array(
87
                'summary' => 'Error testing',
88
                'milestone' => '3.8',
89
                'description' => 'Lorem ipsum dolor sit amet',
90
                'labels' => 'test-pma'
91
            )
92
        );
93
94
        $this->enableRetainFlashMessages();
95
        $report = $this->Reports->get(5);
96
        $this->assertEquals(null, $report->sourceforge_bug_id);
97
        $this->assertEquals('new', $report->status);
98
        $this->assertSession(
99
            'Unauthorised access to Github. github credentials may be out of date.'
100
            . ' Please check and try again later.',
101
            'Flash.flash.0.message'
102
        );
103
104
        // Case 4. Test submission of form with successful Github response
105
        $this->post(
106
            'github/create_issue/5',
107
            array(
108
                'summary' => 'Error testing',
109
                'milestone' => '3.8',
110
                'description' => 'Lorem ipsum dolor sit amet',
111
                'labels' => 'test-pma'
112
            )
113
        );
114
115
        $report = $this->Reports->get(5);
116
        $this->assertEquals(1347, $report->sourceforge_bug_id);
117
        $this->assertEquals('forwarded', $report->status);
118
    }
119
120
    /**
121
     * Test link_issue method
122
     *
123
     * @return void
124
     */
125
    public function testLinkIssue()
126
    {
127
        // Mock functions `curl_exec` and `curl_getinfo` in GithubApiComponent
128
        // so that we don't actually hit the Github Api
129
        $curlExecMock = $this->getFunctionMock('\App\Controller\Component', 'curl_exec');
130
        $curlGetInfoMock = $this->getFunctionMock('\App\Controller\Component', 'curl_getinfo');
131
132
        // Case 1.1 Test with an invalid reportId
133
        $this->get('github/link_issue/123?ticket_id=1');
134
        $this->assertResponseContains('Invalid report');
135
136
        // Case 1.2 Test with an invalid ticketId
137
        $this->get('github/link_issue/5?ticket_id=');
138
        $this->assertResponseContains('Invalid Ticket ID');
139
140
        $issueResponse = file_get_contents(TESTS . 'Fixture' . DS . 'issue_response.json');
141
        $decodedResponse = json_decode($issueResponse, true);
142
        $decodedResponse['state'] = 'closed';
143
        $issueResponseWithClosed = json_encode($decodedResponse);
144
145
        $commentResponse = file_get_contents(TESTS . 'Fixture' . DS . 'comment_response.json');
0 ignored issues
show
Unused Code introduced by
$commentResponse is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
146
147
148
        // Github response unsuccessful followed by successful (open) and successful (closed)
149
        $curlExecMock->expects($this->exactly(5))->willReturnOnConsecutiveCalls(
150
            $issueResponse,
151
            $issueResponse, $issueResponse,
152
            $issueResponseWithClosed, $issueResponseWithClosed
153
        );
154
        $curlGetInfoMock->expects($this->exactly(5))->willReturnOnConsecutiveCalls(
155
            404,
156
            201, 200,
157
            201, 200
158
        );
159
160
        // Case 2. Test submission of form with unsuccessful github response
161
        $this->get(
162
            'github/link_issue/5?ticket_id=9999999'
163
        );
164
165
        $this->enableRetainFlashMessages();
166
        $report = $this->Reports->get(5);
167
        $this->assertEquals(null, $report->sourceforge_bug_id);
168
        $this->assertEquals('new', $report->status);
169
        $this->assertSession(
170
            'Bug Issue not found on Github. Are you sure the issue number is correct? '
171
            . 'Please check and try again!',
172
            'Flash.flash.0.message'
173
        );
174
175
        // Case 3. Test submission of form with successful Github response (with issue open)
176
        $this->get(
177
            'github/link_issue/5?ticket_id=1387'
178
        );
179
180
        $report = $this->Reports->get(5);
181
        $this->assertEquals(1387, $report->sourceforge_bug_id);
182
        $this->assertEquals('forwarded', $report->status);
183
184
        // Case 4. Test submission of form with successful Github response (with issue closed)
185
        $this->get(
186
            'github/link_issue/5?ticket_id=1387'
187
        );
188
189
        $report = $this->Reports->get(5);
190
        $this->assertEquals(1387, $report->sourceforge_bug_id);
191
        $this->assertEquals('resolved', $report->status);
192
    }
193
194
    /**
195
     * Test unlink_issue method
196
     *
197
     * @return void
198
     */
199
    public function testUnlinkIssue()
200
    {
201
        // Mock functions `curl_exec` and `curl_getinfo` in GithubApiComponent
202
        // so that we don't actually hit the Github Api
203
        $curlExecMock = $this->getFunctionMock('\App\Controller\Component', 'curl_exec');
204
        $curlGetInfoMock = $this->getFunctionMock('\App\Controller\Component', 'curl_getinfo');
205
206
        // Case 1.1 Test with an invalid reportId
207
        $this->get('github/unlink_issue/123');
208
        $this->assertResponseContains('Invalid report');
209
210
        // Case 1.2 Test unlinked with an already unlinked issue
211
        $this->get('github/unlink_issue/5');
212
        $this->assertResponseContains('Invalid Ticket ID');
213
214
        $commentResponse = file_get_contents(TESTS . 'Fixture' . DS . 'comment_response.json');
215
216
        // Github response unsuccessful followed by successful
217
        $curlExecMock->expects($this->exactly(2))->willReturnOnConsecutiveCalls(
218
            json_encode(array('message' => 'Unauthorised access')),
219
            $commentResponse
220
        );
221
        $curlGetInfoMock->expects($this->exactly(2))->willReturnOnConsecutiveCalls(
222
            401,
223
            201
224
        );
225
226
        // Link the report before trying to unlink
227
        $report = $this->Reports->get(5);
228
        $report->sourceforge_bug_id = 1387;
229
        $report->status = 'forwarded';
230
        $this->Reports->save($report);
231
232
        // Case 2. Test submission of form with unsuccessful and unexpected github response
233
        $this->get(
234
            'github/unlink_issue/5'
235
        );
236
237
        $this->enableRetainFlashMessages();
238
        $report = $this->Reports->get(5);
239
        $this->assertEquals(1387, $report->sourceforge_bug_id);
240
        $this->assertEquals('forwarded', $report->status);
241
        $this->assertSession(
242
            'Unhandled response code recieved: 401',
243
            'Flash.flash.0.message'
244
        );
245
246
        // Case 3. Test submission of form with successful Github response
247
        $this->get(
248
            'github/unlink_issue/5'
249
        );
250
251
        $report = $this->Reports->get(5);
252
        $this->assertEquals(null, $report->sourceforge_bug_id);
253
        $this->assertEquals('new', $report->status);
254
255
    }
256
257
    /**
258
     * Test sync_issue_status method
259
     *
260
     * @return void
261
     */
262
    public function testSyncIssueStatus()
263
    {
264
        // Mock functions `curl_exec` and `curl_getinfo` in GithubApiComponent
265
        // so that we don't actually hit the Github Api
266
        $curlExecMock = $this->getFunctionMock('\App\Controller\Component', 'curl_exec');
267
        $curlGetInfoMock = $this->getFunctionMock('\App\Controller\Component', 'curl_getinfo');
268
269
        // Test via web interface
270
        $this->enableRetainFlashMessages();
271
        $this->get('github/sync_issue_status');
272
        $this->assertRedirect('/');
273
274
        $issueResponse = file_get_contents(TESTS . 'Fixture' . DS . 'issue_response.json');
275
        $decodedResponse = json_decode($issueResponse, true);
276
        $decodedResponse['state'] = 'closed';
277
        $issueResponseWithClosed = json_encode($decodedResponse);
278
279
        // Github response unsuccessful followed by two successful responses
280
        $curlExecMock->expects($this->exactly(3))->willReturnOnConsecutiveCalls(
281
            json_encode(array('message' => 'Unauthorised access')),
282
            $issueResponse,
283
            $issueResponseWithClosed
284
        );
285
        $curlGetInfoMock->expects($this->exactly(3))->willReturnOnConsecutiveCalls(
286
            401,
287
            200,
288
            200
289
        );
290
291
        // Test via cli (i.e. the constant CRON_DISPATCHER should be defined)
292
        define('CRON_DISPATCHER', true);
293
        $this->get('github/sync_issue_status');
294
295
        // 401
296
        $report = $this->Reports->get(1);
297
        $this->assertEquals('forwarded', $report->status);
298
299
        // 200 (open state)
300
        $report = $this->Reports->get(2);
301
        $this->assertEquals('forwarded', $report->status);
302
303
        // 200 (closed state)
304
        $report = $this->Reports->get(4);
305
        $this->assertEquals('resolved', $report->status);
306
    }
307
}
308