1
0
Fork 0
mirror of synced 2024-06-01 18:39:57 +12:00

WIP: Mocked GitHub installation

This commit is contained in:
Khushboo Verma 2023-10-13 01:45:27 +05:30
parent dbd6dbcb5b
commit bb75036efe
5 changed files with 142 additions and 46 deletions

2
.env
View file

@ -96,7 +96,7 @@ _APP_VCS_GITHUB_APP_ID=
_APP_VCS_GITHUB_CLIENT_ID=
_APP_VCS_GITHUB_CLIENT_SECRET=
_APP_VCS_GITHUB_WEBHOOK_SECRET=
_APP_VCS_TEST_INSTALLATION_ID=
_APP_VCS_TEST_GITHUB_INSTALLATION_ID=
_APP_VCS_TEST_PROVIDER_REPOSITORY_ID=
_APP_MIGRATIONS_FIREBASE_CLIENT_ID=
_APP_MIGRATIONS_FIREBASE_CLIENT_SECRET=

View file

@ -22,7 +22,6 @@ use Utopia\Database\Helpers\Permission;
use Utopia\Database\Helpers\Role;
use Utopia\Database\Query;
use Utopia\Database\Validator\Authorization;
use Utopia\Database\Validator\UID;
use Utopia\Detector\Adapter\Bun;
use Utopia\Detector\Adapter\CPP;
use Utopia\Detector\Adapter\Dart;
@ -274,7 +273,7 @@ App::get('/v1/vcs/github/callback')
->label('scope', 'public')
->label('error', __DIR__ . '/../../views/general/error.phtml')
->param('installation_id', '', new Text(256, 0), 'GitHub installation ID', true)
->param('setup_action', '', new Text(256, 0), 'GitHub setup actuon type', true)
->param('setup_action', '', new Text(256, 0), 'GitHub setup action type', true)
->param('state', '', new Text(2048), 'GitHub state. Contains info sent when starting authorization flow.', true)
->param('code', '', new Text(2048, 0), 'OAuth2 code. This is a temporary code that the will be later exchanged for an access token.', true)
->inject('gitHub')

View file

@ -17,6 +17,9 @@ use Utopia\Validator\WhiteList;
use Utopia\Database\Helpers\ID;
use Utopia\Database\Validator\UID;
use Utopia\Validator\Nullable;
use Utopia\VCS\Adapter\Git\GitHub;
use Utopia\Database\Helpers\Permission;
use Utopia\Database\Helpers\Role;
App::get('/v1/mock/tests/foo')
->desc('Get Foo')
@ -646,6 +649,69 @@ App::patch('/v1/mock/functions-v2')
$response->noContent();
});
App::get('/v1/mock/github/callback')
->desc('Create installation document using GitHub installation id')
->groups(['mock', 'api', 'vcs'])
->label('scope', 'public')
->param('installation_id', '', new Text(256, 0), 'GitHub installation ID', true)
->param('projectId', '', new Text(2048), 'Project ID of the project where app is to be installed', true)
->inject('gitHub')
->inject('project')
->inject('response')
->inject('dbForConsole')
->action(function (string $providerInstallationId, string $projectId, GitHub $github, Document $project, Response $response, Database $dbForConsole) {
if (empty($projectId)) {
$error = 'Installation requests from organisation members for the Appwrite GitHub App are currently unsupported. To proceed with the installation, login to the Appwrite Console and install the GitHub App.';
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, $error);
}
$project = $dbForConsole->getDocument('projects', $projectId);
if ($project->isEmpty()) {
$error = 'Project with the ID from state could not be found.';
throw new Exception(Exception::PROJECT_NOT_FOUND, $error);
}
// Create / Update installation
if (!empty($providerInstallationId)) {
$privateKey = App::getEnv('_APP_VCS_GITHUB_PRIVATE_KEY');
$githubAppId = App::getEnv('_APP_VCS_GITHUB_APP_ID');
$github->initializeVariables($providerInstallationId, $privateKey, $githubAppId);
$owner = $github->getOwnerName($providerInstallationId) ?? '';
$projectInternalId = $project->getInternalId();
$teamId = $project->getAttribute('teamId', '');
$installation = new Document([
'$id' => ID::unique(),
'$permissions' => [
Permission::read(Role::team(ID::custom($teamId))),
Permission::update(Role::team(ID::custom($teamId), 'owner')),
Permission::update(Role::team(ID::custom($teamId), 'developer')),
Permission::delete(Role::team(ID::custom($teamId), 'owner')),
Permission::delete(Role::team(ID::custom($teamId), 'developer')),
],
'providerInstallationId' => $providerInstallationId,
'projectId' => $projectId,
'projectInternalId' => $projectInternalId,
'provider' => 'github',
'organization' => $owner,
'personal' => true
]);
$installation = $dbForConsole->createDocument('installations', $installation);
} else {
$error = 'Installation of the Appwrite GitHub App on organization accounts is restricted to organization owners. As a member of the organization, you do not have the necessary permissions to install this GitHub App. Please contact the organization owner to create the installation from the Appwrite console.';
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, $error);
}
$response->json([
'installationId' => $installation->getId(),
]);
});
App::shutdown()
->groups(['mock'])
->inject('utopia')

View file

@ -185,7 +185,7 @@ services:
- _APP_VCS_GITHUB_WEBHOOK_SECRET
- _APP_VCS_GITHUB_CLIENT_SECRET
- _APP_VCS_GITHUB_CLIENT_ID
- _APP_VCS_TEST_INSTALLATION_ID
- _APP_VCS_TEST_GITHUB_INSTALLATION_ID
- _APP_VCS_TEST_PROVIDER_REPOSITORY_ID
- _APP_MIGRATIONS_FIREBASE_CLIENT_ID
- _APP_MIGRATIONS_FIREBASE_CLIENT_SECRET

View file

@ -13,27 +13,65 @@ class VCSConsoleClientTest extends Scope
use ProjectCustom;
use SideConsole;
public ?string $installationId = null;
public ?string $providerRepositoryId = null;
protected function setUp(): void
{
parent::setUp();
$this->installationId = App::getEnv('_APP_VCS_TEST_INSTALLATION_ID');
$this->providerRepositoryId = App::getEnv('_APP_VCS_TEST_PROVIDER_REPOSITORY_ID');
}
public function testDetectRuntime()
public function testGitHubAuthorize()
{
/**
* Test for SUCCESS
*/
$response = $this->client->call(Client::METHOD_GET, '/mock/github/callback', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'installation_id' => App::getEnv('_APP_VCS_TEST_GITHUB_INSTALLATION_ID'),
'projectId' => $this->getProject()['$id'],
]);
$this->assertNotEmpty($response['body']['installationId']);
$installationId = $response['body']['installationId'];
return $installationId;
}
/**
* @depends testGitHubAuthorize
*/
public function testGetInstallation(string $installationId)
{
/**
* Test for SUCCESS
*/
$runtime = $this->client->call(Client::METHOD_POST, '/vcs/github/installations/' . $this->installationId . '/providerRepositories/' . $this->providerRepositoryId . '/detection', array_merge([
$installation = $this->client->call(Client::METHOD_GET, '/vcs/installations/' . $installationId, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'installationId' => $this->installationId,
'installationId' => $installationId
]);
$this->assertEquals(200, $installation['headers']['status-code']);
}
/**
* @depends testGitHubAuthorize
*/
public function testDetectRuntime(string $installationId)
{
/**
* Test for SUCCESS
*/
$runtime = $this->client->call(Client::METHOD_POST, '/vcs/github/installations/' . $installationId . '/providerRepositories/' . $this->providerRepositoryId . '/detection', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'installationId' => $installationId,
'providerRepositoryId' => $this->providerRepositoryId
]);
@ -44,22 +82,22 @@ class VCSConsoleClientTest extends Scope
* Test for FAILURE
*/
// $runtime = $this->client->call(Client::METHOD_POST, '/vcs/github/installations/' . $this->installationId . '/providerRepositories/1234/detection', array_merge([
// $runtime = $this->client->call(Client::METHOD_POST, '/vcs/github/installations/' . $installationId . '/providerRepositories/1234/detection', array_merge([
// 'content-type' => 'application/json',
// 'x-appwrite-project' => $this->getProject()['$id'],
// ], $this->getHeaders()), [
// 'installationId' => $this->installationId,
// 'installationId' => $installationId,
// 'providerRepositoryId' => 1234
// ]);
// $this->assertEquals(404, $runtime['headers']['status-code']);
// TODO: throw 404 from GitHub.php if repo not found
// $runtime = $this->client->call(Client::METHOD_POST, '/vcs/github/installations/' . $this->installationId . '/providerRepositories/' . $this->providerRepositoryId .'/detection', array_merge([
// $runtime = $this->client->call(Client::METHOD_POST, '/vcs/github/installations/' . $installationId . '/providerRepositories/' . $this->providerRepositoryId .'/detection', array_merge([
// 'content-type' => 'application/json',
// 'x-appwrite-project' => $this->getProject()['$id'],
// ], $this->getHeaders()), [
// 'installationId' => $this->installationId,
// 'installationId' => $installationId,
// 'providerRepositoryId' => $this->providerRepositoryId,
// 'providerRootDirectory' => ''̦
// ]);
@ -67,27 +105,30 @@ class VCSConsoleClientTest extends Scope
// $this->assertEquals(404, $runtime['headers']['status-code']);
}
public function testListRepositories()
/**
* @depends testGitHubAuthorize
*/
public function testListRepositories(string $installationId)
{
/**
* Test for SUCCESS
*/
$repositories = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $this->installationId . '/providerRepositories', array_merge([
$repositories = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $installationId . '/providerRepositories', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'installationId' => $this->installationId
'installationId' => $installationId
]);
$this->assertEquals(200, $repositories['headers']['status-code']);
$this->assertEquals($repositories['body']['total'], 3);
$searchedRepositories = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $this->installationId . '/providerRepositories', array_merge([
$searchedRepositories = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $installationId . '/providerRepositories', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'installationId' => $this->installationId,
'installationId' => $installationId,
'search' => 'func'
]);
@ -108,28 +149,31 @@ class VCSConsoleClientTest extends Scope
$this->assertEquals(404, $repositories['headers']['status-code']);
}
public function testGetRepository(string $providerRepositoryId2 = '700020051')
/**
* @depends testGitHubAuthorize
*/
public function testGetRepository(string $installationId, string $providerRepositoryId2 = '700020051')
{
/**
* Test for SUCCESS
*/
$repository = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $this->installationId . '/providerRepositories/' . $this->providerRepositoryId, array_merge([
$repository = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $installationId . '/providerRepositories/' . $this->providerRepositoryId, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'installationId' => $this->installationId,
'installationId' => $installationId,
'providerRepositoryId' => $this->providerRepositoryId
]);
$this->assertEquals(200, $repository['headers']['status-code']);
$this->assertEquals($repository['body']['name'], 'ruby-starter');
$repository = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $this->installationId . '/providerRepositories/' . $providerRepositoryId2, array_merge([
$repository = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $installationId . '/providerRepositories/' . $providerRepositoryId2, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'installationId' => $this->installationId,
'installationId' => $installationId,
'providerRepositoryId' => $providerRepositoryId2
]);
@ -140,11 +184,11 @@ class VCSConsoleClientTest extends Scope
* Test for FAILURE
*/
// $repository = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $this->installationId . '/providerRepositories/1234', array_merge([
// $repository = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $installationId . '/providerRepositories/1234', array_merge([
// 'content-type' => 'application/json',
// 'x-appwrite-project' => $this->getProject()['$id'],
// ], $this->getHeaders()), [
// 'installationId' => $this->installationId,
// 'installationId' => $installationId,
// 'providerRepositoryId' => 1234
// ]);
@ -152,17 +196,20 @@ class VCSConsoleClientTest extends Scope
// TODO: Throw 404 if repository not found
}
public function testListRepositoryBranches()
/**
* @depends testGitHubAuthorize
*/
public function testListRepositoryBranches(string $installationId)
{
/**
* Test for SUCCESS
*/
$repositoryBranches = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $this->installationId . '/providerRepositories/' . $this->providerRepositoryId . '/branches', array_merge([
$repositoryBranches = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $installationId . '/providerRepositories/' . $this->providerRepositoryId . '/branches', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'installationId' => $this->installationId,
'installationId' => $installationId,
'providerRepositoryId' => $this->providerRepositoryId
]);
@ -175,31 +222,15 @@ class VCSConsoleClientTest extends Scope
* Test for FAILURE
*/
// $repositoryBranches = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $this->installationId . '/providerRepositories/1234/branches', array_merge([
// $repositoryBranches = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $installationId . '/providerRepositories/1234/branches', array_merge([
// 'content-type' => 'application/json',
// 'x-appwrite-project' => $this->getProject()['$id'],
// ], $this->getHeaders()), [
// 'installationId' => $this->installationId,
// 'installationId' => $installationId,
// 'providerRepositoryId' => 1234
// ]);
// $this->assertEquals(404, $repositoryBranches['headers']['status-code']);
// TODO: Check why it's throwing 500 server error
}
// public function testGetInstallation()
// {
// /**
// * Test for SUCCESS
// */
// $installation = $this->client->call(Client::METHOD_GET, '/vcs/installations/' . $this->installationId, array_merge([
// 'content-type' => 'application/json',
// 'x-appwrite-project' => $this->getProject()['$id'],
// ], $this->getHeaders()), [
// 'installationId' => $this->installationId
// ]);
// $this->assertEquals(200, $installation['headers']['status-code']);
// }
}