# frozen_string_literal: true namespace :replay do desc "Test end-to-end: segmenti finti → merge → upload Garage → verifica S3" task e2e_garage: :environment do abort "Garage non configurato: imposta REPLAY_STORAGE_ENDPOINT in infra/.env" if MatchLiveTv.replay_storage_local? team = Team.joins(:club).find { |t| t.entitlements.can_access_recordings? } abort "Nessuna squadra Premium nel DB" unless team user = User.where(role: %w[coach admin]).first || User.first abort "Nessun utente nel DB" unless user match = team.matches.create!( opponent_name: "E2E Garage Test", scheduled_at: Time.current ) session = StreamSession.create!( match: match, user: user, platform: "matchlivetv", status: "ended", privacy_status: "public", started_at: 5.minutes.ago, ended_at: Time.current ) recording = Recordings::FinalizeSession.new(session).call abort "FinalizeSession non ha creato recording" unless recording segment_dir = File.join(MatchLiveTv.recordings_local_path, session.mediamtx_path_name) FileUtils.mkdir_p(segment_dir) segment = File.join(segment_dir, "segment-001.mp4") ok = system( "ffmpeg", "-y", "-f", "lavfi", "-i", "testsrc=duration=8:size=320x240:rate=10", "-f", "lavfi", "-i", "sine=frequency=440:duration=8", "-c:v", "libx264", "-preset", "ultrafast", "-pix_fmt", "yuv420p", "-c:a", "aac", "-shortest", segment, out: File::NULL, err: File::NULL ) abort "ffmpeg non ha creato il segmento di test" unless ok && File.exist?(segment) puts "[e2e] Session #{session.id} — upload in corso..." Recordings::UploadFromSession.new(session).call recording.reload unless recording.status == "ready" && recording.storage_backend == "s3" abort "Recording non ready/s3: status=#{recording.status} backend=#{recording.storage_backend} err=#{recording.error_message}" end require "aws-sdk-s3" client = Aws::S3::Client.new( access_key_id: MatchLiveTv.replay_storage_access_key_id, secret_access_key: MatchLiveTv.replay_storage_secret_access_key, endpoint: MatchLiveTv.replay_storage_endpoint, region: MatchLiveTv.replay_storage_region, force_path_style: MatchLiveTv.replay_storage_force_path_style? ) head = client.head_object(bucket: recording.storage_bucket, key: recording.storage_key) url = Recordings::Storage.new.presigned_get_url(key: recording.storage_key, expires_in: 120) puts "[e2e] OK" puts " recording_id: #{recording.id}" puts " storage_key: #{recording.storage_key}" puts " byte_size: #{recording.byte_size} (S3: #{head.content_length})" puts " thumbnail: #{recording.thumbnail_storage_key || '(nessuna)'}" puts " presigned: #{url[0, 80]}..." if recording.thumbnail_storage_key.present? client.head_object(bucket: recording.storage_bucket, key: recording.thumbnail_storage_key) puts " thumbnail su Garage: OK" end end end