Skip to content

Commit ad91009

Browse files
Copilotalexr00
andcommitted
Add support for simplified URL format with uri parameter
Co-authored-by: alexr00 <38270282+alexr00@users.noreply.github.com>
1 parent 976fcb0 commit ad91009

2 files changed

Lines changed: 122 additions & 0 deletions

File tree

src/common/uri.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,27 @@ export function fromOpenOrCheckoutPullRequestWebviewUri(uri: vscode.Uri): OpenPu
685685
return;
686686
}
687687
try {
688+
// Check if the query uses the new simplified format: uri=https://github.com/owner/repo/pull/number
689+
const queryParams = new URLSearchParams(uri.query);
690+
const uriParam = queryParams.get('uri');
691+
if (uriParam) {
692+
// Parse the GitHub PR URL
693+
const match = uriParam.match(/^https?:\/\/github\.com\/([^\/]+)\/([^\/]+)\/pull\/(\d+)/);
694+
if (match) {
695+
const [, owner, repo, pullRequestNumber] = match;
696+
const params = {
697+
owner,
698+
repo,
699+
pullRequestNumber: parseInt(pullRequestNumber, 10)
700+
};
701+
if (!validateOpenWebviewParams(params.owner, params.repo, params.pullRequestNumber.toString())) {
702+
return;
703+
}
704+
return params;
705+
}
706+
}
707+
708+
// Fall back to the old JSON format for backward compatibility
688709
const query = JSON.parse(uri.query.split('&')[0]);
689710
if (!validateOpenWebviewParams(query.owner, query.repo, query.pullRequestNumber)) {
690711
return;

src/test/common/uri.test.ts

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import { default as assert } from 'assert';
7+
import * as vscode from 'vscode';
8+
import { fromOpenOrCheckoutPullRequestWebviewUri } from '../../common/uri';
9+
10+
describe('uri', () => {
11+
describe('fromOpenOrCheckoutPullRequestWebviewUri', () => {
12+
it('should parse the new simplified format with uri parameter', () => {
13+
const uri = vscode.Uri.parse('vscode://github.vscode-pull-request-github/checkout-pull-request?uri=https://github.com/microsoft/vscode-css-languageservice/pull/460');
14+
const result = fromOpenOrCheckoutPullRequestWebviewUri(uri);
15+
16+
assert.strictEqual(result?.owner, 'microsoft');
17+
assert.strictEqual(result?.repo, 'vscode-css-languageservice');
18+
assert.strictEqual(result?.pullRequestNumber, 460);
19+
});
20+
21+
it('should parse the new simplified format with http (not https)', () => {
22+
const uri = vscode.Uri.parse('vscode://github.vscode-pull-request-github/checkout-pull-request?uri=http://github.com/owner/repo/pull/123');
23+
const result = fromOpenOrCheckoutPullRequestWebviewUri(uri);
24+
25+
assert.strictEqual(result?.owner, 'owner');
26+
assert.strictEqual(result?.repo, 'repo');
27+
assert.strictEqual(result?.pullRequestNumber, 123);
28+
});
29+
30+
it('should parse the old JSON format for backward compatibility', () => {
31+
const uri = vscode.Uri.parse('vscode://github.vscode-pull-request-github/checkout-pull-request?%7B%22owner%22%3A%22microsoft%22%2C%22repo%22%3A%22vscode-css-languageservice%22%2C%22pullRequestNumber%22%3A460%7D');
32+
const result = fromOpenOrCheckoutPullRequestWebviewUri(uri);
33+
34+
assert.strictEqual(result?.owner, 'microsoft');
35+
assert.strictEqual(result?.repo, 'vscode-css-languageservice');
36+
assert.strictEqual(result?.pullRequestNumber, 460);
37+
});
38+
39+
it('should work for open-pull-request-webview path', () => {
40+
const uri = vscode.Uri.parse('vscode://github.vscode-pull-request-github/open-pull-request-webview?uri=https://github.com/test/example/pull/789');
41+
const result = fromOpenOrCheckoutPullRequestWebviewUri(uri);
42+
43+
assert.strictEqual(result?.owner, 'test');
44+
assert.strictEqual(result?.repo, 'example');
45+
assert.strictEqual(result?.pullRequestNumber, 789);
46+
});
47+
48+
it('should return undefined for invalid authority', () => {
49+
const uri = vscode.Uri.parse('vscode://invalid-authority/checkout-pull-request?uri=https://github.com/owner/repo/pull/1');
50+
const result = fromOpenOrCheckoutPullRequestWebviewUri(uri);
51+
52+
assert.strictEqual(result, undefined);
53+
});
54+
55+
it('should return undefined for invalid path', () => {
56+
const uri = vscode.Uri.parse('vscode://github.vscode-pull-request-github/invalid-path?uri=https://github.com/owner/repo/pull/1');
57+
const result = fromOpenOrCheckoutPullRequestWebviewUri(uri);
58+
59+
assert.strictEqual(result, undefined);
60+
});
61+
62+
it('should return undefined for invalid GitHub URL format', () => {
63+
const uri = vscode.Uri.parse('vscode://github.vscode-pull-request-github/checkout-pull-request?uri=https://example.com/owner/repo/pull/1');
64+
const result = fromOpenOrCheckoutPullRequestWebviewUri(uri);
65+
66+
assert.strictEqual(result, undefined);
67+
});
68+
69+
it('should return undefined for non-numeric pull request number', () => {
70+
const uri = vscode.Uri.parse('vscode://github.vscode-pull-request-github/checkout-pull-request?uri=https://github.com/owner/repo/pull/abc');
71+
const result = fromOpenOrCheckoutPullRequestWebviewUri(uri);
72+
73+
assert.strictEqual(result, undefined);
74+
});
75+
76+
it('should handle repos with dots and dashes', () => {
77+
const uri = vscode.Uri.parse('vscode://github.vscode-pull-request-github/checkout-pull-request?uri=https://github.com/my-org/my.awesome-repo/pull/42');
78+
const result = fromOpenOrCheckoutPullRequestWebviewUri(uri);
79+
80+
assert.strictEqual(result?.owner, 'my-org');
81+
assert.strictEqual(result?.repo, 'my.awesome-repo');
82+
assert.strictEqual(result?.pullRequestNumber, 42);
83+
});
84+
85+
it('should handle repos with underscores', () => {
86+
const uri = vscode.Uri.parse('vscode://github.vscode-pull-request-github/checkout-pull-request?uri=https://github.com/owner/repo_name/pull/1');
87+
const result = fromOpenOrCheckoutPullRequestWebviewUri(uri);
88+
89+
assert.strictEqual(result?.owner, 'owner');
90+
assert.strictEqual(result?.repo, 'repo_name');
91+
assert.strictEqual(result?.pullRequestNumber, 1);
92+
});
93+
94+
it('should validate owner and repo names', () => {
95+
// Invalid owner (empty)
96+
const uri1 = vscode.Uri.parse('vscode://github.vscode-pull-request-github/checkout-pull-request?uri=https://github.com//repo/pull/1');
97+
const result1 = fromOpenOrCheckoutPullRequestWebviewUri(uri1);
98+
assert.strictEqual(result1, undefined);
99+
});
100+
});
101+
});

0 commit comments

Comments
 (0)