Scrutinizer GitHub App not installed

We could not synchronize checks via GitHub's checks API since Scrutinizer's GitHub App is not installed for this repository.

Install GitHub App

GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Passed
Pull Request — dev-extbase-fluid (#756)
by
unknown
03:51
created

OaiPmhTest::canUseResumptionToken()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 53
Code Lines 31

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 31
c 1
b 0
f 0
nc 2
nop 0
dl 0
loc 53
rs 9.424

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
3
namespace Kitodo\Dlf\Tests\Functional\Api;
4
5
use DateTime;
6
use GuzzleHttp\Client as HttpClient;
7
use Kitodo\Dlf\Common\Solr;
8
use Kitodo\Dlf\Domain\Repository\SolrCoreRepository;
9
use Kitodo\Dlf\Tests\Functional\FunctionalTestCase;
10
use Phpoaipmh\Endpoint;
11
use Phpoaipmh\Exception\OaipmhException;
12
use SimpleXMLElement;
13
use TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager;
14
15
class OaiPmhTest extends FunctionalTestCase
16
{
17
    protected $disableJsonWrappedResponse = true;
18
19
    protected $coreExtensionsToLoad = [
20
        'fluid',
21
        'fluid_styled_content',
22
    ];
23
24
    /** @var int */
25
    protected $oaiPage = 20001;
26
27
    /** @var string */
28
    protected $oaiUrl;
29
30
    /** @var int */
31
    protected $oaiPageNoStoragePid = 20002;
32
33
    /** @var string */
34
    protected $oaiUrlNoStoragePid;
35
36
    public function setUp(): void
37
    {
38
        parent::setUp();
39
40
        $this->oaiUrl = $this->baseUrl . '/index.php?id=' . $this->oaiPage;
41
        $this->oaiUrlNoStoragePid = $this->baseUrl . '/index.php?id=' . $this->oaiPageNoStoragePid;
42
43
        $this->importDataSet(__DIR__ . '/../../Fixtures/Common/documents_1.xml');
44
        $this->importDataSet(__DIR__ . '/../../Fixtures/Common/metadata.xml');
45
        $this->importDataSet(__DIR__ . '/../../Fixtures/Common/libraries.xml');
46
        $this->importDataSet(__DIR__ . '/../../Fixtures/Common/pages.xml');
47
        $this->importDataSet(__DIR__ . '/../../Fixtures/OaiPmh/pages.xml');
48
        $this->importDataSet(__DIR__ . '/../../Fixtures/OaiPmh/solrcores.xml');
49
50
        $this->persistenceManager = $this->objectManager->get(PersistenceManager::class);
0 ignored issues
show
Deprecated Code introduced by
The function TYPO3\CMS\Extbase\Object\ObjectManager::get() has been deprecated: since TYPO3 10.4, will be removed in version 12.0 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

50
        $this->persistenceManager = /** @scrutinizer ignore-deprecated */ $this->objectManager->get(PersistenceManager::class);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
Bug Best Practice introduced by
The property persistenceManager does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
51
        $this->solrCoreRepository = $this->initializeRepository(SolrCoreRepository::class, 20000);
0 ignored issues
show
Bug Best Practice introduced by
The property solrCoreRepository does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
52
53
        $this->setUpOaiSolr();
54
    }
55
56
    protected function setUpOaiSolr()
57
    {
58
        // Setup Solr only once for all tests in this suite
59
        static $solr = null;
60
61
        if ($solr === null) {
62
            $coreName = Solr::createCore();
63
            $solr = Solr::getInstance($coreName);
64
65
            $this->importSolrDocuments($solr, __DIR__ . '/../../Fixtures/Common/documents_1.solr.json');
66
        }
67
68
        $oaiCoreModel = $this->solrCoreRepository->findByUid(11001);
69
        $oaiCoreModel->setIndexName($solr->core);
70
        $this->solrCoreRepository->update($oaiCoreModel);
71
        $this->persistenceManager->persistAll();
72
    }
73
74
    protected function importSolrDocuments(Solr $solr, string $path)
75
    {
76
        $jsonDocuments = json_decode(file_get_contents($path), true);
77
78
        $updateQuery = $solr->service->createUpdate();
79
        $documents = array_map(function ($jsonDoc) use ($updateQuery) {
80
            $document = $updateQuery->createDocument();
81
            foreach ($jsonDoc as $key => $value) {
82
                $document->setField($key, $value);
0 ignored issues
show
Bug introduced by
The method setField() does not exist on Solarium\Core\Query\DocumentInterface. It seems like you code against a sub-type of Solarium\Core\Query\DocumentInterface such as Solarium\Plugin\MinimumScoreFilter\Document or Solarium\QueryType\Update\Query\Document. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

82
                $document->/** @scrutinizer ignore-call */ 
83
                           setField($key, $value);
Loading history...
83
            }
84
            return $document;
85
        }, $jsonDocuments);
86
        $updateQuery->addDocuments($documents);
87
        $updateQuery->addCommit();
88
        $solr->service->update($updateQuery);
89
    }
90
91
    /**
92
     * @test
93
     */
94
    public function correctlyRespondsOnBadVerb()
95
    {
96
        $client = new HttpClient();
97
        $response = $client->get($this->baseUrl, [
98
            'query' => [
99
                'id' => $this->oaiPage,
100
                'verb' => 'nastyVerb',
101
            ],
102
        ]);
103
        $xml = new SimpleXMLElement((string) $response->getBody());
104
105
        $this->assertEquals('badVerb', (string) $xml->error['code']);
106
107
        // The base URL may be different from the one used that we actually used,
108
        // but it shouldn't contain the verb argument
109
        $this->assertStringNotContainsString('nastyVerb', (string) $xml->request);
110
111
        // For bad verbs, the <request> element must not contain any attributes
112
        // - http://www.openarchives.org/OAI/openarchivesprotocol.html#XMLResponse
113
        // - http://www.openarchives.org/OAI/openarchivesprotocol.html#ErrorConditions
114
        $this->assertEmpty($xml->request->attributes());
115
    }
116
117
    /**
118
     * @test
119
     */
120
    public function canIdentify()
121
    {
122
        $oai = Endpoint::build($this->oaiUrl);
123
        $identity = $oai->identify();
124
125
        $this->assertEquals('Identify', (string) $identity->request['verb']);
126
        $this->assertEquals('Default Library - OAI Repository', (string) $identity->Identify->repositoryName);
127
        $this->assertUtcDateString((string) $identity->Identify->earliestDatestamp);
128
        $this->assertEquals('[email protected]', (string) $identity->Identify->adminEmail);
129
    }
130
131
    /**
132
     * @test
133
     */
134
    public function identifyGivesFallbackDatestampWhenNoDocuments()
135
    {
136
        $oai = Endpoint::build($this->oaiUrlNoStoragePid);
137
        $identity = $oai->identify();
138
139
        $this->assertUtcDateString((string) $identity->Identify->earliestDatestamp);
140
    }
141
142
    /**
143
     * @test
144
     */
145
    public function canListMetadataFormats()
146
    {
147
        $oai = Endpoint::build($this->oaiUrl);
148
        $formats = $oai->listMetadataFormats();
149
150
        $formatMap = [];
151
        foreach ($formats as $format) {
152
            $formatMap[(string) $format->metadataPrefix] = $format;
153
        }
154
155
        $this->assertEquals('http://www.loc.gov/METS/', (string) $formatMap['mets']->metadataNamespace);
156
    }
157
158
    /**
159
     * @test
160
     */
161
    public function canListRecords()
162
    {
163
        $oai = Endpoint::build($this->oaiUrl);
164
        $result = $oai->listRecords('mets');
165
166
        $record = $result->current();
167
        $metsRoot = $record->metadata->children('http://www.loc.gov/METS/')[0];
168
        $this->assertNotNull($metsRoot);
169
        $this->assertEquals('mets', $metsRoot->getName());
170
    }
171
172
    /**
173
     * @test
174
     */
175
    public function noRecordsUntil1900()
176
    {
177
        $this->expectException(OaipmhException::class);
178
        $this->expectExceptionMessage('empty list');
179
180
        $oai = Endpoint::build($this->oaiUrl);
181
        $result = $oai->listRecords('mets', null, (new DateTime())->setDate(1900, 1, 1));
182
183
        $result->current();
184
    }
185
186
    /**
187
     * @test
188
     */
189
    public function canUseResumptionToken()
190
    {
191
        // NOTE: cursor and expirationDate are optional by the specification,
192
        //       but we include them in our implementation
193
194
        $client = new HttpClient();
195
196
        // The general handling of resumption tokens should be the same for these verbs
197
        foreach (['ListIdentifiers', 'ListRecords'] as $verb) {
198
            // Check that we get a proper resumption token when starting a list
199
            $response = $client->get($this->baseUrl, [
200
                'query' => [
201
                    'id' => $this->oaiPage,
202
                    'verb' => $verb,
203
                    'metadataPrefix' => 'mets',
204
                ],
205
            ]);
206
            $xml = new SimpleXMLElement((string) $response->getBody());
207
208
            $resumptionToken = $xml->$verb->resumptionToken;
209
            $this->assertEquals('0', (string) $resumptionToken['cursor']);
210
            $this->assertInFuture((string) $resumptionToken['expirationDate']);
211
            $this->assertNotEmpty((string) $resumptionToken);
212
213
            // Store list size to check that it remains constant (and check its sanity)
214
            $completeListSize = (int) $resumptionToken['completeListSize'];
215
            $this->assertGreaterThan(2, $completeListSize); // we have more than two documents in document set
216
217
            // Check that we can resume and get a proper cursor value
218
            $cursor = 1;
219
            do {
220
                $response = $client->get($this->baseUrl, [
221
                    'query' => [
222
                        'id' => $this->oaiPage,
223
                        'verb' => $verb,
224
                        'resumptionToken' => (string) $resumptionToken,
225
                    ],
226
                ]);
227
                $xml = new SimpleXMLElement((string) $response->getBody());
228
229
                $resumptionToken = $xml->$verb->resumptionToken;
230
                $tokenStr = (string) $resumptionToken;
231
232
                $this->assertEquals($cursor, (string) $resumptionToken['cursor']); // settings.limit = 1
233
                $this->assertEquals($completeListSize, (string) $resumptionToken['completeListSize']);
234
235
                // The last resumptionToken is empty and doesn't have expirationDate
236
                $isLastBatch = $cursor + 1 >= $completeListSize;
237
                $this->assertEquals($isLastBatch, empty((string) $resumptionToken['expirationDate']));
238
                $this->assertEquals($isLastBatch, empty($tokenStr));
239
240
                $cursor++;
241
            } while ($tokenStr);
242
        }
243
    }
244
245
    /**
246
     * @test
247
     */
248
    public function noResumptionTokenForCompleteList()
249
    {
250
        $client = new HttpClient();
251
252
        foreach (['ListIdentifiers', 'ListRecords'] as $verb) {
253
            $response = $client->get($this->baseUrl, [
254
                'query' => [
255
                    'id' => $this->oaiPage,
256
                    'verb' => $verb,
257
                    'metadataPrefix' => 'mets',
258
                    'set' => 'collection-with-single-document',
259
                ],
260
            ]);
261
            $xml = new SimpleXMLElement((string) $response->getBody());
262
263
            $this->assertEquals(1, count($xml->$verb->children()));
264
            $this->assertEmpty($xml->$verb->resumptionToken);
265
        }
266
    }
267
268
    /**
269
     * @test
270
     */
271
    public function canListAndResumeIdentifiers()
272
    {
273
        $oai = Endpoint::build($this->oaiUrl);
274
        $result = $oai->listIdentifiers('mets');
275
276
        $record = $result->current();
277
        $this->assertEquals('oai:de:slub-dresden:db:id-476251419', $record->identifier);
278
        $this->assertEquals(['collection-with-single-document', 'music'], (array) $record->setSpec);
279
280
        // This should use a resumption token because settings.limit is 1
281
        $record = $result->next();
282
        $this->assertEquals('oai:de:slub-dresden:db:id-476248086', $record->identifier);
283
    }
284
285
    protected function parseUtc(string $dateTime)
286
    {
287
        return DateTime::createFromFormat('Y-m-d\TH:i:s\Z', $dateTime);
288
    }
289
290
    protected function assertUtcDateString(string $dateTime)
291
    {
292
        $this->assertInstanceOf(DateTime::class, $this->parseUtc($dateTime));
293
    }
294
295
    protected function assertInFuture(string $dateTime)
296
    {
297
        $this->assertGreaterThan(new DateTime(), $this->parseUtc($dateTime));
298
    }
299
}
300