Blocca la seconda diretta sullo stesso utente, registra gli abusi in admin e presenta la copertina come grafica caricata dalla società, con demo Team MLTV. Co-authored-by: Cursor <cursoragent@cursor.com>
100 lines
3.4 KiB
Ruby
100 lines
3.4 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require "rails_helper"
|
|
|
|
RSpec.describe Sessions::Start, "one live per user" do
|
|
let(:user) { User.create!(email: "tx@test.it", name: "Tx", password: "Password123", role: "coach") }
|
|
let(:club) { Club.create!(name: "Club A", sport: "volleyball") }
|
|
let(:team) { club.teams.create!(name: "Team A", sport: "volleyball") }
|
|
let(:match_a) { team.matches.create!(opponent_name: "Opp A", sport: "volleyball") }
|
|
let(:match_b) { team.matches.create!(opponent_name: "Opp B", sport: "volleyball") }
|
|
|
|
before do
|
|
club.club_memberships.create!(user: user, role: "owner")
|
|
plan = Plan.find_or_initialize_by(slug: "premium_full")
|
|
plan.name ||= "Premium Full"
|
|
plan.features = (plan.features || {}).merge(
|
|
"platforms" => %w[matchlivetv youtube],
|
|
"concurrent_streams_limit" => 10
|
|
)
|
|
plan.save!
|
|
club.create_subscription!(plan: plan, status: "active") if club.subscription.blank?
|
|
allow(SessionChannel).to receive(:broadcast_message)
|
|
end
|
|
|
|
def session_for(match, status:, device_model: "Pixel 8")
|
|
StreamSession.create!(
|
|
match: match,
|
|
user: user,
|
|
platform: "matchlivetv",
|
|
status: status,
|
|
device_manufacturer: "Google",
|
|
device_model: device_model,
|
|
client_os: "android"
|
|
)
|
|
end
|
|
|
|
it "avvia la prima diretta" do
|
|
session = session_for(match_a, status: "idle")
|
|
described_class.new(session).call
|
|
expect(session.reload.status).to eq("connecting")
|
|
expect(StreamConcurrencyViolation.count).to eq(0)
|
|
end
|
|
|
|
it "blocca la seconda diretta dello stesso account e registra l'abuso" do
|
|
live = session_for(match_a, status: "live", device_model: "Pixel 8")
|
|
live.update!(started_at: 10.minutes.ago)
|
|
second = session_for(match_b, status: "idle", device_model: "iPhone 15")
|
|
second.update!(client_os: "ios", device_manufacturer: "Apple")
|
|
|
|
expect {
|
|
described_class.new(second).call
|
|
}.to raise_error(Teams::EntitlementError) { |e|
|
|
expect(e.code).to eq("user_concurrent_stream")
|
|
}
|
|
|
|
expect(second.reload.status).to eq("idle")
|
|
violation = StreamConcurrencyViolation.last
|
|
expect(violation).to be_present
|
|
expect(violation.user_email).to eq(user.email)
|
|
expect(violation.occupying_session_id).to eq(live.id)
|
|
expect(violation.attempted_session_id).to eq(second.id)
|
|
expect(violation.devices_differ).to be(true)
|
|
expect(violation.attempt_action).to eq("start")
|
|
end
|
|
|
|
it "non blocca un secondo account sulla stessa società" do
|
|
other = User.create!(email: "tx2@test.it", name: "Tx2", password: "Password123", role: "coach")
|
|
club.club_memberships.create!(user: other, role: "owner")
|
|
session_for(match_a, status: "live")
|
|
other_session = StreamSession.create!(
|
|
match: match_b,
|
|
user: other,
|
|
platform: "matchlivetv",
|
|
status: "idle"
|
|
)
|
|
|
|
described_class.new(other_session).call
|
|
expect(other_session.reload.status).to eq("connecting")
|
|
end
|
|
|
|
it "considera occupante anche una sessione in pausa" do
|
|
session_for(match_a, status: "paused")
|
|
second = session_for(match_b, status: "idle")
|
|
|
|
expect {
|
|
described_class.new(second).call
|
|
}.to raise_error(Teams::EntitlementError) { |e|
|
|
expect(e.code).to eq("user_concurrent_stream")
|
|
}
|
|
end
|
|
|
|
it "non considera occupante una sessione idle" do
|
|
session_for(match_a, status: "idle")
|
|
second = session_for(match_b, status: "idle")
|
|
|
|
described_class.new(second).call
|
|
expect(second.reload.status).to eq("connecting")
|
|
end
|
|
end
|