Skip to content

Commit 9f9b46e

Browse files
committed
add code reference integration tests
Signed-off-by: Julien Veyssier <julien-nc@posteo.net>
1 parent fe86add commit 9f9b46e

1 file changed

Lines changed: 250 additions & 0 deletions

File tree

Lines changed: 250 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
7+
* SPDX-License-Identifier: AGPL-3.0-or-later
8+
*/
9+
10+
namespace OCA\Github\Tests\Integration;
11+
12+
use OCA\Github\Reference\GithubCodeReferenceProvider;
13+
use OCA\Github\Service\SecretService;
14+
use OCP\Collaboration\Reference\IReference;
15+
use OCP\IConfig;
16+
use OCP\Server;
17+
use PHPUnit\Framework\Attributes\DependsExternal;
18+
use PHPUnit\Framework\Attributes\Group;
19+
use Test\TestCase;
20+
21+
#[Group('DB')]
22+
class GitHubCodeReferenceIntegrationTest extends TestCase {
23+
private GithubCodeReferenceProvider $referenceProvider;
24+
private SecretService $secretService;
25+
private IConfig $config;
26+
27+
protected function setUp(): void {
28+
parent::setUp();
29+
30+
$this->referenceProvider = Server::get(GithubCodeReferenceProvider::class);
31+
$this->secretService = Server::get(SecretService::class);
32+
$this->config = Server::get(IConfig::class);
33+
}
34+
35+
#[DependsExternal(GithubOauthIntegrationTest::class, 'testOAuthLogin')]
36+
public function testResolveSingleLineCodeReference(array $oauthData): void {
37+
$this->assertIsArray($oauthData, 'oauthData should be an array from OAuth test');
38+
$this->assertArrayHasKey('userId', $oauthData, 'oauthData must contain userId');
39+
$userId = $oauthData['userId'];
40+
41+
$token = $this->secretService->getEncryptedUserValue($userId, 'token');
42+
$this->assertNotSame('', $token, 'Token should be stored after OAuth flow');
43+
44+
$referenceUrl = 'https://github.com/nextcloud/server/blob/master/lib/base.php#L1';
45+
$reference = $this->referenceProvider->resolveReference($referenceUrl);
46+
47+
$this->assertInstanceOf(IReference::class, $reference, 'Should resolve code reference');
48+
49+
$richObject = $reference->getRichObject();
50+
$this->assertIsArray($richObject, 'Rich object should be an array');
51+
$this->assertCodeRichObjectStructure($richObject);
52+
}
53+
54+
private function assertCodeRichObjectStructure(array $richObject): void {
55+
$this->assertArrayHasKey('github_type', $richObject, 'Must have github_type');
56+
$this->assertContains($richObject['github_type'], ['code', 'code-error'], 'github_type should be code or code-error');
57+
58+
if ($richObject['github_type'] === 'code-error') {
59+
$this->assertArrayHasKey('error', $richObject, 'Error type should have error info');
60+
return;
61+
}
62+
63+
$this->assertArrayHasKey('owner', $richObject, 'Must have owner');
64+
$this->assertArrayHasKey('repo', $richObject, 'Must have repo');
65+
$this->assertArrayHasKey('filePath', $richObject, 'Must have filePath');
66+
$this->assertArrayHasKey('link', $richObject, 'Must have link');
67+
$this->assertArrayHasKey('html_url', $richObject, 'Must have html_url');
68+
69+
$this->assertArrayHasKey('ref', $richObject, 'Must have ref');
70+
$this->assertIsArray($richObject['ref'], 'ref should be an array');
71+
$this->assertArrayHasKey('original_ref', $richObject['ref'], 'ref must have original_ref');
72+
$this->assertArrayHasKey('sha', $richObject['ref'], 'ref must have sha');
73+
74+
$this->assertArrayHasKey('lineBegin', $richObject, 'Must have lineBegin');
75+
$this->assertIsInt($richObject['lineBegin'], 'lineBegin should be an integer');
76+
$this->assertGreaterThan(0, $richObject['lineBegin'], 'lineBegin should be positive');
77+
78+
$this->assertArrayHasKey('lines', $richObject, 'Must have lines array');
79+
$this->assertIsArray($richObject['lines'], 'lines should be an array');
80+
$this->assertNotEmpty($richObject['lines'], 'lines should not be empty');
81+
82+
$this->assertStringContainsString('github.com', $richObject['link'], 'link should contain github.com');
83+
}
84+
85+
#[DependsExternal(GithubOauthIntegrationTest::class, 'testOAuthLogin')]
86+
public function testResolveMultiLineCodeReference(array $oauthData): void {
87+
$this->assertIsArray($oauthData, 'oauthData should be an array from OAuth test');
88+
$this->assertArrayHasKey('userId', $oauthData, 'oauthData must contain userId');
89+
90+
$referenceUrl = 'https://github.com/nextcloud/server/blob/master/lib/base.php#L1-L5';
91+
$reference = $this->referenceProvider->resolveReference($referenceUrl);
92+
93+
$this->assertInstanceOf(IReference::class, $reference, 'Should resolve multi-line code reference');
94+
95+
$richObject = $reference->getRichObject();
96+
97+
if ($richObject['github_type'] === 'code-error') {
98+
$this->markTestSkipped('GitHub API error for multi-line reference');
99+
}
100+
101+
$this->assertArrayHasKey('lineEnd', $richObject, 'Must have lineEnd for multi-line');
102+
$this->assertIsInt($richObject['lineEnd'], 'lineEnd should be an integer');
103+
$this->assertGreaterThan($richObject['lineBegin'], $richObject['lineEnd'], 'lineEnd should be greater than lineBegin');
104+
105+
$expectedLineCount = $richObject['lineEnd'] - $richObject['lineBegin'] + 1;
106+
$this->assertCount($expectedLineCount, $richObject['lines'], 'lines array should have correct count');
107+
}
108+
109+
#[DependsExternal(GithubOauthIntegrationTest::class, 'testOAuthLogin')]
110+
public function testMatchReference(array $oauthData): void {
111+
$this->assertIsArray($oauthData, 'oauthData should be an array from OAuth test');
112+
113+
$validSingleLine = 'https://github.com/nextcloud/server/blob/master/lib/base.php#L1';
114+
$validMultiLine = 'https://github.com/nextcloud/server/blob/abc123/lib/base.php#L1-L10';
115+
$invalidNoLine = 'https://github.com/nextcloud/server/blob/master/lib/base.php';
116+
$invalidWrongUrl = 'https://github.com/nextcloud/server';
117+
118+
$this->assertTrue($this->referenceProvider->matchReference($validSingleLine), 'Should match single line URL');
119+
$this->assertTrue($this->referenceProvider->matchReference($validMultiLine), 'Should match multi-line URL');
120+
$this->assertFalse($this->referenceProvider->matchReference($invalidNoLine), 'Should not match URL without line');
121+
$this->assertFalse($this->referenceProvider->matchReference($invalidWrongUrl), 'Should not match non-blob URL');
122+
}
123+
124+
#[DependsExternal(GithubOauthIntegrationTest::class, 'testOAuthLogin')]
125+
public function testReferenceTitle(array $oauthData): void {
126+
$this->assertIsArray($oauthData, 'oauthData should be an array from OAuth test');
127+
$this->assertArrayHasKey('userId', $oauthData, 'oauthData must contain userId');
128+
129+
$referenceUrl = 'https://github.com/nextcloud/server/blob/master/lib/base.php#L1';
130+
$reference = $this->referenceProvider->resolveReference($referenceUrl);
131+
132+
$this->assertInstanceOf(IReference::class, $reference, 'Should resolve code reference');
133+
134+
$title = $reference->getTitle();
135+
$this->assertNotEmpty($title, 'Reference should have a title');
136+
$this->assertStringContainsString('permalink', strtolower($title), 'Title should mention permalink');
137+
}
138+
139+
#[DependsExternal(GithubOauthIntegrationTest::class, 'testOAuthLogin')]
140+
public function testReferenceDescription(array $oauthData): void {
141+
$this->assertIsArray($oauthData, 'oauthData should be an array from OAuth test');
142+
$this->assertArrayHasKey('userId', $oauthData, 'oauthData must contain userId');
143+
144+
$referenceUrl = 'https://github.com/nextcloud/server/blob/master/lib/base.php#L1';
145+
$reference = $this->referenceProvider->resolveReference($referenceUrl);
146+
147+
$this->assertInstanceOf(IReference::class, $reference, 'Should resolve code reference');
148+
149+
$richObject = $reference->getRichObject();
150+
151+
if ($richObject['github_type'] !== 'code-error') {
152+
$description = $reference->getDescription();
153+
$this->assertNotEmpty($description, 'Reference should have a description with code content');
154+
}
155+
}
156+
157+
#[DependsExternal(GithubOauthIntegrationTest::class, 'testOAuthLogin')]
158+
public function testShortRefFormat(array $oauthData): void {
159+
$this->assertIsArray($oauthData, 'oauthData should be an array from OAuth test');
160+
$this->assertArrayHasKey('userId', $oauthData, 'oauthData must contain userId');
161+
162+
$referenceUrl = 'https://github.com/nextcloud/server/blob/master/lib/base.php#L1';
163+
$reference = $this->referenceProvider->resolveReference($referenceUrl);
164+
165+
$this->assertInstanceOf(IReference::class, $reference, 'Should resolve code reference');
166+
167+
$richObject = $reference->getRichObject();
168+
169+
if ($richObject['github_type'] !== 'code-error') {
170+
$this->assertArrayHasKey('ref', $richObject);
171+
$this->assertArrayHasKey('original_ref', $richObject['ref']);
172+
$this->assertArrayHasKey('sha', $richObject['ref']);
173+
174+
if ($richObject['ref']['sha'] !== '') {
175+
$this->assertMatchesRegularExpression('/^[0-9a-f]{7,40}$/', $richObject['ref']['sha'], 'sha should be a valid git hash');
176+
}
177+
}
178+
}
179+
180+
#[DependsExternal(GithubOauthIntegrationTest::class, 'testOAuthLogin')]
181+
public function testVcsCodePermalinkStructure(array $oauthData): void {
182+
$this->assertIsArray($oauthData, 'oauthData should be an array from OAuth test');
183+
$this->assertArrayHasKey('userId', $oauthData, 'oauthData must contain userId');
184+
185+
$referenceUrl = 'https://github.com/nextcloud/server/blob/master/lib/base.php#L1';
186+
$reference = $this->referenceProvider->resolveReference($referenceUrl);
187+
188+
$this->assertInstanceOf(IReference::class, $reference, 'Should resolve code reference');
189+
190+
$richObject = $reference->getRichObject();
191+
192+
if ($richObject['github_type'] !== 'code-error') {
193+
$this->assertArrayHasKey('vcs_code_permalink', $richObject, 'Must have vcs_code_permalink');
194+
$vcsCode = $richObject['vcs_code_permalink'];
195+
196+
$this->assertIsArray($vcsCode, 'vcs_code_permalink should be an array');
197+
$this->assertArrayHasKey('line_begin', $vcsCode, 'vcs_code_permalink must have line_begin');
198+
$this->assertArrayHasKey('line_end', $vcsCode, 'vcs_code_permalink must have line_end');
199+
$this->assertArrayHasKey('lines', $vcsCode, 'vcs_code_permalink must have lines');
200+
$this->assertArrayHasKey('file_url', $vcsCode, 'vcs_code_permalink must have file_url');
201+
$this->assertArrayHasKey('file_path', $vcsCode, 'vcs_code_permalink must have file_path');
202+
$this->assertArrayHasKey('file_name', $vcsCode, 'vcs_code_permalink must have file_name');
203+
204+
$this->assertSame($richObject['lineBegin'], $vcsCode['line_begin'], 'line_begin should match lineBegin');
205+
$this->assertSame($richObject['filePath'], $vcsCode['file_path'], 'file_path should match filePath');
206+
$this->assertSame(basename($richObject['filePath']), $vcsCode['file_name'], 'file_name should be basename of filePath');
207+
}
208+
}
209+
210+
#[DependsExternal(GithubOauthIntegrationTest::class, 'testOAuthLogin')]
211+
public function testCodeLinesContent(array $oauthData): void {
212+
$this->assertIsArray($oauthData, 'oauthData should be an array from OAuth test');
213+
$this->assertArrayHasKey('userId', $oauthData, 'oauthData must contain userId');
214+
215+
$referenceUrl = 'https://github.com/nextcloud/server/blob/master/lib/base.php#L1-L3';
216+
$reference = $this->referenceProvider->resolveReference($referenceUrl);
217+
218+
$this->assertInstanceOf(IReference::class, $reference, 'Should resolve code reference');
219+
220+
$richObject = $reference->getRichObject();
221+
222+
if ($richObject['github_type'] !== 'code-error') {
223+
$this->assertArrayHasKey('lines', $richObject);
224+
$this->assertCount(3, $richObject['lines'], 'Should have 3 lines');
225+
226+
foreach ($richObject['lines'] as $line) {
227+
$this->assertIsString($line, 'Each line should be a string');
228+
}
229+
}
230+
}
231+
232+
#[DependsExternal(GithubOauthIntegrationTest::class, 'testOAuthLogin')]
233+
public function testFilePathExtraction(array $oauthData): void {
234+
$this->assertIsArray($oauthData, 'oauthData should be an array from OAuth test');
235+
$this->assertArrayHasKey('userId', $oauthData, 'oauthData must contain userId');
236+
237+
$referenceUrl = 'https://github.com/nextcloud/server/blob/master/lib/base.php#L1';
238+
$reference = $this->referenceProvider->resolveReference($referenceUrl);
239+
240+
$this->assertInstanceOf(IReference::class, $reference, 'Should resolve code reference');
241+
242+
$richObject = $reference->getRichObject();
243+
244+
if ($richObject['github_type'] !== 'code-error') {
245+
$this->assertArrayHasKey('filePath', $richObject);
246+
$this->assertStringEndsWith('.php', $richObject['filePath'], 'filePath should end with .php');
247+
$this->assertStringContainsString('lib', $richObject['filePath'], 'filePath should contain lib');
248+
}
249+
}
250+
}

0 commit comments

Comments
 (0)