Aggiunge modulo Replay, Garage dev e YouTube a livello società.
Pipeline registrazione/upload con storage S3, archivio web e app, proxy replay per il browser, OAuth YouTube sulla pagina club (Premium Full) e footer legale. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
35
backend/spec/services/recordings/access_policy_spec.rb
Normal file
35
backend/spec/services/recordings/access_policy_spec.rb
Normal file
@@ -0,0 +1,35 @@
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe Recordings::AccessPolicy do
|
||||
let!(:club) { Club.create!(name: "Club", sport: "volleyball", primary_color: "#e53935", secondary_color: "#ffffff") }
|
||||
let!(:team) { club.teams.create!(name: "Team", sport: "volleyball") }
|
||||
let!(:user) { User.create!(email: "coach@test.com", name: "Coach", password: "password123", role: "coach") }
|
||||
let!(:match) { team.matches.create!(opponent_name: "Rival", scheduled_at: 1.day.from_now) }
|
||||
let!(:session) do
|
||||
StreamSession.create!(match: match, user: user, platform: "matchlivetv", status: "ended")
|
||||
end
|
||||
let!(:recording) do
|
||||
Recording.create!(
|
||||
stream_session: session,
|
||||
team: team,
|
||||
status: "ready",
|
||||
privacy_status: "unlisted",
|
||||
expires_at: 10.days.from_now,
|
||||
storage_key: "key"
|
||||
)
|
||||
end
|
||||
|
||||
it "allows unlisted replay without login" do
|
||||
expect(described_class.new(recording, viewer: nil).allowed?).to be true
|
||||
end
|
||||
|
||||
it "allows public replay without login" do
|
||||
recording.update!(privacy_status: "public")
|
||||
expect(described_class.new(recording, viewer: nil).allowed?).to be true
|
||||
end
|
||||
|
||||
it "denies expired replay" do
|
||||
recording.update!(expires_at: 1.day.ago)
|
||||
expect(described_class.new(recording, viewer: nil).allowed?).to be false
|
||||
end
|
||||
end
|
||||
26
backend/spec/services/recordings/club_stats_spec.rb
Normal file
26
backend/spec/services/recordings/club_stats_spec.rb
Normal file
@@ -0,0 +1,26 @@
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe Recordings::ClubStats do
|
||||
let!(:club) { Club.create!(name: "Club", sport: "volleyball", primary_color: "#e53935", secondary_color: "#ffffff") }
|
||||
let!(:team) { club.teams.create!(name: "Team", sport: "volleyball") }
|
||||
let!(:user) { User.create!(email: "coach@test.com", name: "Coach", password: "password123", role: "coach") }
|
||||
let!(:match) { team.matches.create!(opponent_name: "Rival", scheduled_at: 1.day.from_now) }
|
||||
let!(:session) do
|
||||
StreamSession.create!(match: match, user: user, platform: "matchlivetv", status: "ended")
|
||||
end
|
||||
|
||||
it "aggregates ready replays" do
|
||||
Recording.create!(
|
||||
stream_session: session,
|
||||
team: team,
|
||||
status: "ready",
|
||||
byte_size: 100.megabytes,
|
||||
expires_at: 3.days.from_now,
|
||||
storage_key: "a"
|
||||
)
|
||||
stats = described_class.new(club).call
|
||||
expect(stats[:available_count]).to eq(1)
|
||||
expect(stats[:expiring_soon_count]).to eq(1)
|
||||
expect(stats[:total_bytes]).to eq(100.megabytes)
|
||||
end
|
||||
end
|
||||
35
backend/spec/services/recordings/finalize_session_spec.rb
Normal file
35
backend/spec/services/recordings/finalize_session_spec.rb
Normal file
@@ -0,0 +1,35 @@
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe Recordings::FinalizeSession do
|
||||
let!(:club) { Club.create!(name: "Club", sport: "volleyball", primary_color: "#e53935", secondary_color: "#ffffff") }
|
||||
let!(:team) { club.teams.create!(name: "Team", sport: "volleyball") }
|
||||
let!(:user) { User.create!(email: "coach@test.com", name: "Coach", password: "password123", role: "coach") }
|
||||
let!(:match) { team.matches.create!(opponent_name: "Rival", scheduled_at: 1.day.from_now) }
|
||||
let!(:session) do
|
||||
StreamSession.create!(
|
||||
match: match,
|
||||
user: user,
|
||||
platform: "matchlivetv",
|
||||
status: "ended",
|
||||
privacy_status: "public",
|
||||
ended_at: Time.current
|
||||
)
|
||||
end
|
||||
|
||||
before do
|
||||
load Rails.root.join("db/seeds/plans.rb")
|
||||
Billing::AssignPlan.call(club: club, plan_slug: "premium_light")
|
||||
end
|
||||
|
||||
it "creates processing recording with retention" do
|
||||
rec = described_class.new(session).call
|
||||
expect(rec.status).to eq("processing")
|
||||
expect(rec.privacy_status).to eq("public")
|
||||
expect(rec.expires_at).to be > 29.days.from_now
|
||||
end
|
||||
|
||||
it "skips free plan" do
|
||||
Billing::AssignPlan.call(club: club, plan_slug: "free")
|
||||
expect(described_class.new(session).call).to be_nil
|
||||
end
|
||||
end
|
||||
24
backend/spec/services/recordings/increment_views_spec.rb
Normal file
24
backend/spec/services/recordings/increment_views_spec.rb
Normal file
@@ -0,0 +1,24 @@
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe Recordings::IncrementViews do
|
||||
let!(:club) { Club.create!(name: "Club", sport: "volleyball", primary_color: "#e53935", secondary_color: "#ffffff") }
|
||||
let!(:team) { club.teams.create!(name: "Team", sport: "volleyball") }
|
||||
let!(:user) { User.create!(email: "c@test.com", name: "C", password: "password123", role: "coach") }
|
||||
let!(:match) { team.matches.create!(opponent_name: "Rival", scheduled_at: 1.day.from_now) }
|
||||
let!(:session) { StreamSession.create!(match: match, user: user, platform: "matchlivetv", status: "ended") }
|
||||
let!(:recording) do
|
||||
Recording.create!(
|
||||
stream_session: session,
|
||||
team: team,
|
||||
status: "ready",
|
||||
expires_at: 10.days.from_now,
|
||||
storage_key: "key",
|
||||
view_count: 2
|
||||
)
|
||||
end
|
||||
|
||||
it "increments view_count" do
|
||||
described_class.new(recording).call
|
||||
expect(recording.reload.view_count).to eq(3)
|
||||
end
|
||||
end
|
||||
30
backend/spec/services/recordings/notify_ready_spec.rb
Normal file
30
backend/spec/services/recordings/notify_ready_spec.rb
Normal file
@@ -0,0 +1,30 @@
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe Recordings::NotifyReady do
|
||||
let!(:club) { Club.create!(name: "Club", sport: "volleyball", primary_color: "#e53935", secondary_color: "#ffffff") }
|
||||
let!(:owner) { User.create!(email: "owner@test.com", name: "Owner", password: "password123", role: "coach") }
|
||||
let!(:team) { club.teams.create!(name: "Team", sport: "volleyball") }
|
||||
let!(:user) { User.create!(email: "c@test.com", name: "C", password: "password123", role: "coach") }
|
||||
let!(:match) { team.matches.create!(opponent_name: "Rival", scheduled_at: 1.day.from_now) }
|
||||
let!(:session) { StreamSession.create!(match: match, user: user, platform: "matchlivetv", status: "ended") }
|
||||
|
||||
before do
|
||||
ClubMembership.create!(club: club, user: owner, role: "owner")
|
||||
end
|
||||
|
||||
it "sends email and marks notified" do
|
||||
recording = Recording.create!(
|
||||
stream_session: session,
|
||||
team: team,
|
||||
status: "ready",
|
||||
expires_at: 10.days.from_now,
|
||||
storage_key: "key"
|
||||
)
|
||||
|
||||
expect {
|
||||
described_class.new(recording).call
|
||||
}.to change { ActionMailer::Base.deliveries.size }.by(1)
|
||||
|
||||
expect(recording.reload.ready_notified_at).to be_present
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user