sslService = Mockery::mock(SslCertificateService::class); $this->environment = Mockery::mock(Environment::class); // Setup environment mock $this->environment->shouldReceive('get') ->with('DOMAIN_NAME', 'michaelschiemer.de') ->andReturn('example.com'); $this->environment->shouldReceive('get') ->with('SSL_EMAIL', 'mail@michaelschiemer.de') ->andReturn('admin@example.com'); $this->environment->shouldReceive('get') ->with('LETSENCRYPT_STAGING', '0') ->andReturn('1'); $this->command = new SslInitCommand( $this->sslService, $this->environment ); $this->input = Mockery::mock(ConsoleInput::class); }); afterEach(function () { Mockery::close(); }); it('executes successfully when test and obtain succeed', function () { // Mock test success $this->sslService->shouldReceive('test') ->once() ->andReturn(true); // Mock obtain success $status = new CertificateStatus( exists: true, isValid: true, notBefore: new DateTimeImmutable('-30 days'), notAfter: new DateTimeImmutable('+60 days'), issuer: 'Let\'s Encrypt', subject: 'example.com', daysUntilExpiry: 60, isExpiring: false, isExpired: false ); $this->sslService->shouldReceive('obtain') ->once() ->andReturn($status); $exitCode = $this->command->execute($this->input); expect($exitCode)->toBe(ExitCode::SUCCESS); }); it('fails when test fails', function () { // Mock test failure $this->sslService->shouldReceive('test') ->once() ->andReturn(false); // obtain should not be called $this->sslService->shouldNotReceive('obtain'); $exitCode = $this->command->execute($this->input); expect($exitCode)->toBe(ExitCode::FAILURE); }); it('fails when obtain throws exception', function () { // Mock test success $this->sslService->shouldReceive('test') ->once() ->andReturn(true); // Mock obtain exception $this->sslService->shouldReceive('obtain') ->once() ->andThrow(new \RuntimeException('Failed to obtain certificate')); $exitCode = $this->command->execute($this->input); expect($exitCode)->toBe(ExitCode::FAILURE); }); it('uses staging mode from environment', function () { $this->sslService->shouldReceive('test') ->once() ->with(Mockery::on(function ($config) { return $config->mode === CertificateMode::STAGING; })) ->andReturn(true); $this->sslService->shouldReceive('obtain') ->once() ->with(Mockery::on(function ($config) { return $config->mode === CertificateMode::STAGING; })) ->andReturn(new CertificateStatus( exists: true, isValid: true, notBefore: null, notAfter: null, issuer: null, subject: null, daysUntilExpiry: 60, isExpiring: false, isExpired: false )); $this->command->execute($this->input); }); it('displays certificate information after obtain', function () { $this->sslService->shouldReceive('test') ->once() ->andReturn(true); $status = new CertificateStatus( exists: true, isValid: true, notBefore: new DateTimeImmutable('2024-01-01'), notAfter: new DateTimeImmutable('2024-12-31'), issuer: 'Let\'s Encrypt Authority X3', subject: 'example.com', daysUntilExpiry: 90, isExpiring: false, isExpired: false ); $this->sslService->shouldReceive('obtain') ->once() ->andReturn($status); $exitCode = $this->command->execute($this->input); expect($exitCode)->toBe(ExitCode::SUCCESS); }); });