-
Notifications
You must be signed in to change notification settings - Fork 0
Add integration tests for DevPullCommand #19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
2dc875a
c60079d
3ccdccb
f9deadd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,274 @@ | ||||||||||||||||||||||
| <?php | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| declare(strict_types=1); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| namespace Notur\Tests\Integration\Console; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| use GuzzleHttp\Client; | ||||||||||||||||||||||
| use GuzzleHttp\Exception\RequestException; | ||||||||||||||||||||||
| use GuzzleHttp\Psr7\Request; | ||||||||||||||||||||||
| use GuzzleHttp\Psr7\Response; | ||||||||||||||||||||||
| use Mockery; | ||||||||||||||||||||||
| use Notur\NoturServiceProvider; | ||||||||||||||||||||||
| use Orchestra\Testbench\TestCase; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| class DevPullCommandTest extends TestCase | ||||||||||||||||||||||
| { | ||||||||||||||||||||||
| protected function getPackageProviders($app): array | ||||||||||||||||||||||
| { | ||||||||||||||||||||||
| return [NoturServiceProvider::class]; | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| protected function getEnvironmentSetUp($app): void | ||||||||||||||||||||||
| { | ||||||||||||||||||||||
| $app['config']->set('database.default', 'testing'); | ||||||||||||||||||||||
| $app['config']->set('database.connections.testing', [ | ||||||||||||||||||||||
| 'driver' => 'sqlite', | ||||||||||||||||||||||
| 'database' => ':memory:', | ||||||||||||||||||||||
| 'prefix' => '', | ||||||||||||||||||||||
| ]); | ||||||||||||||||||||||
| $app['config']->set('notur.repository', 'sak0a/notur'); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| protected function setUp(): void | ||||||||||||||||||||||
| { | ||||||||||||||||||||||
| parent::setUp(); | ||||||||||||||||||||||
| $this->loadMigrationsFrom(__DIR__ . '/../../../database/migrations'); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| protected function tearDown(): void | ||||||||||||||||||||||
| { | ||||||||||||||||||||||
| Mockery::close(); | ||||||||||||||||||||||
| parent::tearDown(); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| public function test_dry_run_shows_what_would_be_done_without_making_changes(): void | ||||||||||||||||||||||
| { | ||||||||||||||||||||||
| // Mock the GitHub API response for commit info | ||||||||||||||||||||||
| $mockClient = Mockery::mock(Client::class); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| $mockResponse = new Response(200, [], json_encode([ | ||||||||||||||||||||||
| 'sha' => 'abc123def456abc123def456abc123def456abc1', | ||||||||||||||||||||||
| 'commit' => [ | ||||||||||||||||||||||
| 'message' => 'Test commit message', | ||||||||||||||||||||||
| 'author' => [ | ||||||||||||||||||||||
| 'name' => 'Test Author', | ||||||||||||||||||||||
| 'date' => '2024-01-15T10:30:00Z', | ||||||||||||||||||||||
| ], | ||||||||||||||||||||||
| ], | ||||||||||||||||||||||
| ])); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| $mockClient->shouldReceive('get') | ||||||||||||||||||||||
| ->once() | ||||||||||||||||||||||
| ->with('https://api.github.com/repos/sak0a/notur/commits/master') | ||||||||||||||||||||||
| ->andReturn($mockResponse); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| // Bind the mock client to the service container | ||||||||||||||||||||||
| $this->app->bind(Client::class, function () use ($mockClient) { | ||||||||||||||||||||||
| return $mockClient; | ||||||||||||||||||||||
| }); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| $this->artisan('notur:dev:pull', ['--dry-run' => true]) | ||||||||||||||||||||||
| ->expectsOutput('[DRY RUN] Would download and extract commit abc123de to ' . base_path('vendor/notur/notur')) | ||||||||||||||||||||||
| ->expectsOutput('[DRY RUN] Would rebuild frontend bridge') | ||||||||||||||||||||||
| ->expectsOutput('[DRY RUN] Would copy bridge.js and tailwind.css to public/notur/') | ||||||||||||||||||||||
| ->assertExitCode(0); | ||||||||||||||||||||||
|
Comment on lines
+71
to
+75
|
||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| public function test_dry_run_with_no_rebuild_option(): void | ||||||||||||||||||||||
| { | ||||||||||||||||||||||
| $mockClient = Mockery::mock(Client::class); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| $mockResponse = new Response(200, [], json_encode([ | ||||||||||||||||||||||
| 'sha' => 'abc123def456abc123def456abc123def456abc1', | ||||||||||||||||||||||
| 'commit' => [ | ||||||||||||||||||||||
| 'message' => 'Test commit message', | ||||||||||||||||||||||
| 'author' => [ | ||||||||||||||||||||||
| 'name' => 'Test Author', | ||||||||||||||||||||||
| 'date' => '2024-01-15T10:30:00Z', | ||||||||||||||||||||||
| ], | ||||||||||||||||||||||
| ], | ||||||||||||||||||||||
| ])); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| $mockClient->shouldReceive('get') | ||||||||||||||||||||||
| ->once() | ||||||||||||||||||||||
| ->with('https://api.github.com/repos/sak0a/notur/commits/master') | ||||||||||||||||||||||
| ->andReturn($mockResponse); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| $this->app->bind(Client::class, function () use ($mockClient) { | ||||||||||||||||||||||
| return $mockClient; | ||||||||||||||||||||||
| }); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| $this->artisan('notur:dev:pull', ['--dry-run' => true, '--no-rebuild' => true]) | ||||||||||||||||||||||
| ->expectsOutput('[DRY RUN] Would download and extract commit abc123de to ' . base_path('vendor/notur/notur')) | ||||||||||||||||||||||
| ->doesntExpectOutput('[DRY RUN] Would rebuild frontend bridge') | ||||||||||||||||||||||
| ->assertExitCode(0); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| public function test_dry_run_with_specific_commit(): void | ||||||||||||||||||||||
| { | ||||||||||||||||||||||
| $mockClient = Mockery::mock(Client::class); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| $mockResponse = new Response(200, [], json_encode([ | ||||||||||||||||||||||
| 'sha' => 'abcd1234567890abcdef1234567890abcdef1234', | ||||||||||||||||||||||
| 'commit' => [ | ||||||||||||||||||||||
| 'message' => 'Specific commit message', | ||||||||||||||||||||||
| 'author' => [ | ||||||||||||||||||||||
| 'name' => 'Test Author', | ||||||||||||||||||||||
| 'date' => '2024-01-15T10:30:00Z', | ||||||||||||||||||||||
| ], | ||||||||||||||||||||||
| ], | ||||||||||||||||||||||
| ])); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| $mockClient->shouldReceive('get') | ||||||||||||||||||||||
| ->once() | ||||||||||||||||||||||
| ->with('https://api.github.com/repos/sak0a/notur/commits/specific123') | ||||||||||||||||||||||
| ->andReturn($mockResponse); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| $this->app->bind(Client::class, function () use ($mockClient) { | ||||||||||||||||||||||
| return $mockClient; | ||||||||||||||||||||||
| }); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| $this->artisan('notur:dev:pull', ['commit' => 'specific123', '--dry-run' => true]) | ||||||||||||||||||||||
| ->expectsOutput('[DRY RUN] Would download and extract commit abcd1234 to ' . base_path('vendor/notur/notur')) | ||||||||||||||||||||||
| ->assertExitCode(0); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| public function test_handles_invalid_ref_error(): void | ||||||||||||||||||||||
| { | ||||||||||||||||||||||
| $mockClient = Mockery::mock(Client::class); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| $request = new Request('GET', 'https://api.github.com/repos/sak0a/notur/commits/invalid-ref'); | ||||||||||||||||||||||
| $exception = new RequestException( | ||||||||||||||||||||||
| 'Not Found', | ||||||||||||||||||||||
| $request, | ||||||||||||||||||||||
| new Response(404, [], '{"message":"Not Found"}') | ||||||||||||||||||||||
| ); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| $mockClient->shouldReceive('get') | ||||||||||||||||||||||
| ->once() | ||||||||||||||||||||||
| ->with('https://api.github.com/repos/sak0a/notur/commits/invalid-ref') | ||||||||||||||||||||||
| ->andThrow($exception); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| $this->app->bind(Client::class, function () use ($mockClient) { | ||||||||||||||||||||||
| return $mockClient; | ||||||||||||||||||||||
| }); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| $this->artisan('notur:dev:pull', ['branch' => 'invalid-ref', '--dry-run' => true]) | ||||||||||||||||||||||
| ->expectsOutputToContain('Failed to fetch commit info') | ||||||||||||||||||||||
| ->assertExitCode(1); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| public function test_handles_network_error_on_commit_fetch(): void | ||||||||||||||||||||||
| { | ||||||||||||||||||||||
| $mockClient = Mockery::mock(Client::class); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| $request = new Request('GET', 'https://api.github.com/repos/sak0a/notur/commits/master'); | ||||||||||||||||||||||
| $exception = new RequestException( | ||||||||||||||||||||||
| 'Connection timeout', | ||||||||||||||||||||||
| $request | ||||||||||||||||||||||
| ); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| $mockClient->shouldReceive('get') | ||||||||||||||||||||||
| ->once() | ||||||||||||||||||||||
| ->with('https://api.github.com/repos/sak0a/notur/commits/master') | ||||||||||||||||||||||
| ->andThrow($exception); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| $this->app->bind(Client::class, function () use ($mockClient) { | ||||||||||||||||||||||
| return $mockClient; | ||||||||||||||||||||||
| }); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| $this->artisan('notur:dev:pull', ['--dry-run' => true]) | ||||||||||||||||||||||
| ->expectsOutputToContain('Failed to fetch commit info') | ||||||||||||||||||||||
| ->assertExitCode(1); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| public function test_handles_malformed_api_response(): void | ||||||||||||||||||||||
| { | ||||||||||||||||||||||
| $mockClient = Mockery::mock(Client::class); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| // Response missing 'sha' field | ||||||||||||||||||||||
| $mockResponse = new Response(200, [], json_encode([ | ||||||||||||||||||||||
| 'commit' => [ | ||||||||||||||||||||||
| 'message' => 'Test commit message', | ||||||||||||||||||||||
| ], | ||||||||||||||||||||||
| ])); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| $mockClient->shouldReceive('get') | ||||||||||||||||||||||
| ->once() | ||||||||||||||||||||||
| ->with('https://api.github.com/repos/sak0a/notur/commits/master') | ||||||||||||||||||||||
| ->andReturn($mockResponse); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| $this->app->bind(Client::class, function () use ($mockClient) { | ||||||||||||||||||||||
| return $mockClient; | ||||||||||||||||||||||
| }); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| $this->artisan('notur:dev:pull', ['--dry-run' => true]) | ||||||||||||||||||||||
| ->expectsOutputToContain('Failed to fetch commit info') | ||||||||||||||||||||||
| ->assertExitCode(1); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| public function test_displays_commit_information(): void | ||||||||||||||||||||||
| { | ||||||||||||||||||||||
| $mockClient = Mockery::mock(Client::class); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| $mockResponse = new Response(200, [], json_encode([ | ||||||||||||||||||||||
| 'sha' => 'abc123def456abc123def456abc123def456abc1', | ||||||||||||||||||||||
| 'commit' => [ | ||||||||||||||||||||||
| 'message' => "Add new feature\n\nDetailed description here", | ||||||||||||||||||||||
| 'author' => [ | ||||||||||||||||||||||
| 'name' => 'Jane Developer', | ||||||||||||||||||||||
| 'date' => '2024-01-15T10:30:00Z', | ||||||||||||||||||||||
| ], | ||||||||||||||||||||||
| ], | ||||||||||||||||||||||
| ])); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| $mockClient->shouldReceive('get') | ||||||||||||||||||||||
| ->once() | ||||||||||||||||||||||
| ->with('https://api.github.com/repos/sak0a/notur/commits/develop') | ||||||||||||||||||||||
| ->andReturn($mockResponse); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| $this->app->bind(Client::class, function () use ($mockClient) { | ||||||||||||||||||||||
| return $mockClient; | ||||||||||||||||||||||
| }); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| $this->artisan('notur:dev:pull', ['branch' => 'develop', '--dry-run' => true]) | ||||||||||||||||||||||
| ->expectsOutput(' Branch: develop') | ||||||||||||||||||||||
| ->expectsOutput(' Commit: abc123de') | ||||||||||||||||||||||
| ->expectsOutput(' Author: Jane Developer') | ||||||||||||||||||||||
| ->expectsOutput(' Date: 2024-01-15T10:30:00Z') | ||||||||||||||||||||||
| ->expectsOutput(' Message: Add new feature') | ||||||||||||||||||||||
|
Comment on lines
+236
to
+240
|
||||||||||||||||||||||
| ->expectsOutput(' Branch: develop') | |
| ->expectsOutput(' Commit: abc123de') | |
| ->expectsOutput(' Author: Jane Developer') | |
| ->expectsOutput(' Date: 2024-01-15T10:30:00Z') | |
| ->expectsOutput(' Message: Add new feature') | |
| ->expectsOutputToContain(' Branch: develop') | |
| ->expectsOutputToContain(' Commit: abc123de') | |
| ->expectsOutputToContain(' Author: Jane Developer') | |
| ->expectsOutputToContain(' Date: 2024-01-15T10:30:00Z') | |
| ->expectsOutputToContain(' Message: Add new feature') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These tests invoke
notur:dev:pull, but the command exits early unlessbase_path('vendor/notur/notur')exists and is writable. The test setup doesn’t currently create that directory, so the tests will fail before hitting the mocked HTTP client. Create the directory (and ensure it’s writable) insetUp()and clean it up intearDown()(or use a temporary base path override if your testbench setup supports it).