Files
michaelschiemer/tests/debug/test-presave-service.php
Michael Schiemer fc3d7e6357 feat(Production): Complete production deployment infrastructure
- Add comprehensive health check system with multiple endpoints
- Add Prometheus metrics endpoint
- Add production logging configurations (5 strategies)
- Add complete deployment documentation suite:
  * QUICKSTART.md - 30-minute deployment guide
  * DEPLOYMENT_CHECKLIST.md - Printable verification checklist
  * DEPLOYMENT_WORKFLOW.md - Complete deployment lifecycle
  * PRODUCTION_DEPLOYMENT.md - Comprehensive technical reference
  * production-logging.md - Logging configuration guide
  * ANSIBLE_DEPLOYMENT.md - Infrastructure as Code automation
  * README.md - Navigation hub
  * DEPLOYMENT_SUMMARY.md - Executive summary
- Add deployment scripts and automation
- Add DEPLOYMENT_PLAN.md - Concrete plan for immediate deployment
- Update README with production-ready features

All production infrastructure is now complete and ready for deployment.
2025-10-25 19:18:37 +02:00

278 lines
8.5 KiB
PHP

<?php
declare(strict_types=1);
require_once __DIR__ . '/../../vendor/autoload.php';
use App\Domain\PreSave\PreSaveCampaign;
use App\Domain\PreSave\PreSaveCampaignRepositoryInterface;
use App\Domain\PreSave\PreSaveRegistration;
use App\Domain\PreSave\PreSaveRegistrationRepositoryInterface;
use App\Domain\PreSave\Services\PreSaveCampaignService;
use App\Domain\PreSave\ValueObjects\CampaignStatus;
use App\Domain\PreSave\ValueObjects\RegistrationStatus;
use App\Domain\PreSave\ValueObjects\StreamingPlatform;
use App\Domain\PreSave\ValueObjects\TrackUrl;
use App\Framework\Core\ValueObjects\Timestamp;
use App\Framework\OAuth\OAuthServiceInterface;
// In-Memory Campaign Repository
class InMemoryCampaignRepository implements PreSaveCampaignRepositoryInterface
{
private array $campaigns = [];
public function save(PreSaveCampaign $campaign): PreSaveCampaign
{
$id = $campaign->id ?? count($this->campaigns) + 1;
$saved = new PreSaveCampaign(
id: $id,
status: $campaign->status,
title: $campaign->title,
artistName: $campaign->artistName,
coverImageUrl: $campaign->coverImageUrl,
releaseDate: $campaign->releaseDate,
trackUrls: $campaign->trackUrls,
description: $campaign->description,
startDate: $campaign->startDate,
createdAt: $campaign->createdAt,
updatedAt: $campaign->updatedAt
);
$this->campaigns[$id] = $saved;
return $saved;
}
public function findById(int $id): ?PreSaveCampaign
{
return $this->campaigns[$id] ?? null;
}
public function findAll(array $filters = []): array
{
return array_values($this->campaigns);
}
public function findReadyForRelease(): array
{
return [];
}
public function findReadyForProcessing(): array
{
return [];
}
public function delete(int $id): bool
{
unset($this->campaigns[$id]);
return true;
}
public function getStatistics(int $campaignId): array
{
return [
'total_registrations' => 10,
'completed' => 5,
'pending' => 3,
'failed' => 2,
];
}
}
// In-Memory Registration Repository
class InMemoryRegistrationRepository implements PreSaveRegistrationRepositoryInterface
{
private array $registrations = [];
public function save(PreSaveRegistration $registration): PreSaveRegistration
{
$id = $registration->id ?? count($this->registrations) + 1;
$saved = new PreSaveRegistration(
id: $id,
campaignId: $registration->campaignId,
userId: $registration->userId,
platform: $registration->platform,
status: $registration->status,
registeredAt: $registration->registeredAt,
processedAt: $registration->processedAt,
errorMessage: $registration->errorMessage,
retryCount: $registration->retryCount
);
$this->registrations[$id] = $saved;
return $saved;
}
public function findForUserAndCampaign(string $userId, int $campaignId, StreamingPlatform $platform): ?PreSaveRegistration
{
foreach ($this->registrations as $reg) {
if ($reg->userId === $userId && $reg->campaignId === $campaignId && $reg->platform === $platform) {
return $reg;
}
}
return null;
}
public function findByUserId(string $userId): array
{
return array_values(array_filter($this->registrations, fn($r) => $r->userId === $userId));
}
public function findPendingByCampaign(int $campaignId): array
{
return [];
}
public function findRetryable(int $campaignId, int $maxRetries): array
{
return [];
}
public function getStatusCounts(int $campaignId): array
{
return [
'pending' => 3,
'completed' => 5,
'failed' => 2,
];
}
public function delete(int $id): bool
{
unset($this->registrations[$id]);
return true;
}
public function hasRegistered(string $userId, int $campaignId, StreamingPlatform $platform): bool
{
return $this->findForUserAndCampaign($userId, $campaignId, $platform) !== null;
}
}
// In-Memory OAuth Service
class InMemoryOAuthService implements OAuthServiceInterface
{
private array $providers = [];
public function addProvider(string $userId, string $provider): void
{
$this->providers[$userId . '_' . $provider] = true;
}
public function getProvider(string $name): \App\Framework\OAuth\OAuthProvider
{
throw new \RuntimeException('Not implemented in test');
}
public function getAuthorizationUrl(string $provider, array $options = []): string
{
throw new \RuntimeException('Not implemented in test');
}
public function handleCallback(string $userId, string $provider, string $code, ?string $state = null): \App\Framework\OAuth\Storage\StoredOAuthToken
{
throw new \RuntimeException('Not implemented in test');
}
public function getTokenForUser(string $userId, string $provider): \App\Framework\OAuth\Storage\StoredOAuthToken
{
throw new \RuntimeException('Not implemented in test');
}
public function refreshToken(\App\Framework\OAuth\Storage\StoredOAuthToken $storedToken): \App\Framework\OAuth\Storage\StoredOAuthToken
{
throw new \RuntimeException('Not implemented in test');
}
public function revokeToken(string $userId, string $provider): bool
{
throw new \RuntimeException('Not implemented in test');
}
public function getUserProfile(string $userId, string $provider): array
{
throw new \RuntimeException('Not implemented in test');
}
public function hasProvider(string $userId, string $provider): bool
{
return isset($this->providers[$userId . '_' . $provider]);
}
public function getUserProviders(string $userId): array
{
throw new \RuntimeException('Not implemented in test');
}
public function refreshExpiringTokens(int $withinSeconds = 300): int
{
throw new \RuntimeException('Not implemented in test');
}
public function cleanupExpiredTokens(): int
{
throw new \RuntimeException('Not implemented in test');
}
}
// Test the service
echo "Testing PreSaveCampaignService...\n\n";
$campaignRepo = new InMemoryCampaignRepository();
$registrationRepo = new InMemoryRegistrationRepository();
$oauthService = new InMemoryOAuthService();
$service = new PreSaveCampaignService(
$campaignRepo,
$registrationRepo,
$oauthService
);
// Test 1: Register user successfully
echo "Test 1: Register user for campaign\n";
$campaign = PreSaveCampaign::create(
title: 'New Album',
artistName: 'Test Artist',
coverImageUrl: 'https://example.com/cover.jpg',
releaseDate: Timestamp::fromDateTime(new DateTimeImmutable('+7 days')),
trackUrls: [TrackUrl::create(StreamingPlatform::SPOTIFY, 'track123')]
);
$campaign = $campaignRepo->save($campaign->publish());
$oauthService->addProvider('user123', StreamingPlatform::SPOTIFY->getOAuthProvider());
try {
$registration = $service->registerUser('user123', $campaign->id, StreamingPlatform::SPOTIFY);
echo "✓ User registered successfully\n";
echo " - User ID: {$registration->userId}\n";
echo " - Campaign ID: {$registration->campaignId}\n";
echo " - Platform: {$registration->platform->value}\n";
echo " - Status: {$registration->status->value}\n";
} catch (\Exception $e) {
echo "✗ Registration failed: {$e->getMessage()}\n";
}
echo "\n";
// Test 2: Check if user can register
echo "Test 2: Check if user can register\n";
$canRegister = $service->canUserRegister('user123', $campaign->id, StreamingPlatform::SPOTIFY);
echo "Can register (should be false - already registered): " . ($canRegister ? 'YES' : 'NO') . "\n";
echo "\n";
// Test 3: Get campaign stats
echo "Test 3: Get campaign statistics\n";
try {
$stats = $service->getCampaignStats($campaign->id);
echo "✓ Statistics retrieved\n";
echo " - Total registrations: {$stats['total_registrations']}\n";
echo " - Completed: {$stats['completed']}\n";
echo " - Pending: {$stats['pending']}\n";
echo " - Failed: {$stats['failed']}\n";
echo " - Days until release: {$stats['days_until_release']}\n";
} catch (\Exception $e) {
echo "✗ Stats failed: {$e->getMessage()}\n";
}
echo "\n";
echo "All manual tests completed successfully!\n";