fix(github): preserve custom app API URLs

This commit is contained in:
Andras Bacsai
2026-07-03 12:01:16 +02:00
parent a7dddccd2e
commit 1adeed2a48
6 changed files with 101 additions and 25 deletions
+40 -11
View File
@@ -1,6 +1,7 @@
<?php
use App\Models\GithubApp;
use App\Models\InstanceSettings;
use App\Models\PrivateKey;
use App\Models\Team;
use App\Models\User;
@@ -10,19 +11,22 @@ use Illuminate\Support\Facades\Http;
uses(RefreshDatabase::class);
beforeEach(function () {
InstanceSettings::forceCreate(['id' => 0, 'is_api_enabled' => true]);
// Create a team with owner
$this->team = Team::factory()->create();
$this->user = User::factory()->create();
$this->team->members()->attach($this->user->id, ['role' => 'owner']);
session(['currentTeam' => $this->team]);
// Create an API token for the user
$this->token = $this->user->createToken('test-token', ['*'], $this->team->id);
$this->token = $this->user->createToken('test-token');
$this->bearerToken = $this->token->plainTextToken;
// Create a private key for the team
$this->privateKey = PrivateKey::create([
'name' => 'Test Key',
'private_key' => 'test-private-key-content',
'private_key' => validGithubAppsApiPrivateKey(),
'team_id' => $this->team->id,
]);
});
@@ -139,7 +143,8 @@ describe('GET /api/v1/github-apps', function () {
$otherTeam = Team::factory()->create();
$otherUser = User::factory()->create();
$otherTeam->members()->attach($otherUser->id, ['role' => 'owner']);
$otherToken = $otherUser->createToken('other-token', ['*'], $otherTeam->id);
session(['currentTeam' => $otherTeam]);
$otherToken = $otherUser->createToken('other-token');
// System-wide apps should be visible to other teams
$response = $this->withHeaders([
@@ -173,7 +178,7 @@ describe('GET /api/v1/github-apps', function () {
$otherTeam = Team::factory()->create();
$otherPrivateKey = PrivateKey::create([
'name' => 'Other Key',
'private_key' => 'other-key',
'private_key' => validGithubAppsApiPrivateKey(),
'team_id' => $otherTeam->id,
]);
GithubApp::create([
@@ -249,7 +254,7 @@ describe('GitHub app API url normalization', function () {
])->postJson('/api/v1/github-apps', [
'name' => 'GHE App',
'organization' => '/octocorp/',
'html_url' => 'https://octocorp.ghe.com',
'html_url' => 'https://github.ghe.com',
'app_id' => 12345,
'installation_id' => 67890,
'client_id' => 'test-client-id',
@@ -261,12 +266,36 @@ describe('GitHub app API url normalization', function () {
$response->assertCreated()
->assertJsonFragment([
'organization' => 'octocorp',
'api_url' => 'https://api.octocorp.ghe.com',
'html_url' => 'https://octocorp.ghe.com',
'api_url' => 'https://api.github.ghe.com',
'html_url' => 'https://github.ghe.com',
]);
});
test('normalizes ghe dot com api url when updating github apps', function () {
test('preserves provided api url when creating github apps', function () {
$response = $this->withHeaders([
'Authorization' => 'Bearer '.$this->bearerToken,
])->postJson('/api/v1/github-apps', [
'name' => 'GHE App',
'organization' => '/octocorp/',
'api_url' => 'https://github.com/api/v3',
'html_url' => 'https://github.com',
'app_id' => 12345,
'installation_id' => 67890,
'client_id' => 'test-client-id',
'client_secret' => 'test-client-secret',
'webhook_secret' => 'test-webhook-secret',
'private_key_uuid' => $this->privateKey->uuid,
]);
$response->assertCreated()
->assertJsonFragment([
'organization' => 'octocorp',
'api_url' => 'https://github.com/api/v3',
'html_url' => 'https://github.com',
]);
});
test('preserves provided api url when updating github apps', function () {
$githubApp = GithubApp::create([
'name' => 'GHE App',
'api_url' => 'https://github.company.internal/api/v3',
@@ -285,12 +314,12 @@ describe('GitHub app API url normalization', function () {
$response = $this->withHeaders([
'Authorization' => 'Bearer '.$this->bearerToken,
])->patchJson("/api/v1/github-apps/{$githubApp->id}", [
'html_url' => 'https://octocorp.ghe.com',
'api_url' => 'https://octocorp.ghe.com/api/v3',
'html_url' => 'https://github.com',
'api_url' => 'https://github.com/api/v3',
]);
$response->assertSuccessful()
->assertJsonPath('data.api_url', 'https://api.octocorp.ghe.com');
->assertJsonPath('data.api_url', 'https://github.com/api/v3');
});
test('rejects invalid organization when creating github apps', function () {
@@ -419,7 +419,7 @@ describe('GitHub Source Change Component', function () {
expect($githubApp->private_key_id)->toBe($privateKey->id);
});
test('normalizes resolvable ghe dot com api url when saving github app settings', function () {
test('preserves custom ghe api url when saving github app settings', function () {
$githubApp = GithubApp::create([
'name' => 'Test GitHub App',
'api_url' => 'https://github.ghe.com/api/v3',
@@ -437,10 +437,10 @@ describe('GitHub Source Change Component', function () {
->set('apiUrl', 'https://github.ghe.com/api/v3')
->call('submit')
->assertDispatched('success')
->assertSet('apiUrl', 'https://api.github.ghe.com');
->assertSet('apiUrl', 'https://github.ghe.com/api/v3');
$githubApp->refresh();
expect($githubApp->api_url)->toBe('https://api.github.ghe.com');
expect($githubApp->api_url)->toBe('https://github.ghe.com/api/v3');
});
test('rejects invalid github organization values', function () {
@@ -72,8 +72,8 @@ describe('GitHub Source Create Component', function () {
Livewire::test(Create::class)
->assertSuccessful()
->set('name', 'enterprise-app')
->set('api_url', 'https://github.enterprise.com/api/v3')
->set('html_url', 'https://github.enterprise.com')
->set('api_url', 'https://github.ghe.com/api/v3')
->set('html_url', 'https://github.ghe.com')
->set('custom_user', 'git-custom')
->set('custom_port', 2222)
->call('createGitHubApp')
@@ -82,12 +82,28 @@ describe('GitHub Source Create Component', function () {
$githubApp = GithubApp::where('name', 'enterprise-app')->first();
expect($githubApp)->not->toBeNull();
expect($githubApp->api_url)->toBe('https://github.enterprise.com/api/v3');
expect($githubApp->html_url)->toBe('https://github.enterprise.com');
expect($githubApp->api_url)->toBe('https://github.ghe.com/api/v3');
expect($githubApp->html_url)->toBe('https://github.ghe.com');
expect($githubApp->custom_user)->toBe('git-custom');
expect($githubApp->custom_port)->toBe(2222);
});
test('preserves custom github enterprise api url when creating github app', function () {
Livewire::test(Create::class)
->assertSuccessful()
->set('name', 'ghe-custom-api-app')
->set('api_url', 'https://github.ghe.com/api/v3')
->set('html_url', 'https://github.ghe.com')
->call('createGitHubApp')
->assertRedirect();
$githubApp = GithubApp::where('name', 'ghe-custom-api-app')->first();
expect($githubApp)->not->toBeNull();
expect($githubApp->api_url)->toBe('https://github.ghe.com/api/v3');
expect($githubApp->html_url)->toBe('https://github.ghe.com');
});
test('validates required fields', function () {
Livewire::test(Create::class)
->assertSuccessful()