Limita una diretta attiva per account e valorizza la copertina Premium Full.
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>
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe "Admin stream concurrency violations", type: :request do
|
||||
let!(:admin) { AdminAccount.create!(username: "ops-abuse", password: "Password123") }
|
||||
let!(:user) { User.create!(email: "abuse@test.it", name: "Abuser", password: "Password123", role: "coach") }
|
||||
let!(:club) { Club.create!(name: "Abuse Club", sport: "volleyball") }
|
||||
let!(:team) { club.teams.create!(name: "U16", sport: "volleyball") }
|
||||
let!(:match_a) { team.matches.create!(opponent_name: "Rival A", sport: "volleyball") }
|
||||
let!(:match_b) { team.matches.create!(opponent_name: "Rival B", sport: "volleyball") }
|
||||
let!(:live) do
|
||||
StreamSession.create!(match: match_a, user: user, platform: "matchlivetv", status: "live")
|
||||
end
|
||||
let!(:idle) do
|
||||
StreamSession.create!(match: match_b, user: user, platform: "matchlivetv", status: "idle")
|
||||
end
|
||||
let!(:violation) do
|
||||
StreamConcurrencyViolation.record!(attempted: idle, occupying: live, action: "start")
|
||||
end
|
||||
|
||||
before do
|
||||
post admin_login_path, params: { username: admin.username, password: "Password123" }
|
||||
end
|
||||
|
||||
it "mostra l'elenco abusi" do
|
||||
get admin_stream_concurrency_violations_path
|
||||
expect(response).to have_http_status(:ok)
|
||||
expect(response.body).to include("abuse@test.it")
|
||||
expect(response.body).to include("Abuse Club")
|
||||
expect(response.body).to include("Rival A")
|
||||
expect(response.body).to include("Rival B")
|
||||
end
|
||||
|
||||
it "mostra il badge in dashboard" do
|
||||
get admin_root_path
|
||||
expect(response).to have_http_status(:ok)
|
||||
expect(response.body).to include("abuse@test.it")
|
||||
end
|
||||
|
||||
it "mostra i tentativi nella scheda società" do
|
||||
get admin_club_path(club)
|
||||
expect(response).to have_http_status(:ok)
|
||||
expect(response.body).to include("abuse@test.it")
|
||||
expect(response.body).to include("Rival B")
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,61 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe "API start seconda diretta stesso account", type: :request do
|
||||
let!(:user) { User.create!(email: "conc@test.it", name: "C", password: "Password123", role: "coach") }
|
||||
let!(:club) { Club.create!(name: "Conc Club", sport: "volleyball") }
|
||||
let!(:membership) { club.club_memberships.create!(user: user, role: "owner") }
|
||||
let!(:team) { club.teams.create!(name: "Tigers", sport: "volleyball") }
|
||||
let!(:match_a) { team.matches.create!(opponent_name: "A", sport: "volleyball") }
|
||||
let!(:match_b) { team.matches.create!(opponent_name: "B", sport: "volleyball") }
|
||||
let!(:live) do
|
||||
StreamSession.create!(
|
||||
match: match_a,
|
||||
user: user,
|
||||
platform: "matchlivetv",
|
||||
status: "live",
|
||||
started_at: 5.minutes.ago,
|
||||
device_model: "Pixel 8",
|
||||
client_os: "android"
|
||||
)
|
||||
end
|
||||
let!(:idle) do
|
||||
StreamSession.create!(
|
||||
match: match_b,
|
||||
user: user,
|
||||
platform: "matchlivetv",
|
||||
status: "idle",
|
||||
device_model: "iPhone 15",
|
||||
client_os: "ios"
|
||||
)
|
||||
end
|
||||
|
||||
def auth_headers
|
||||
post "/api/v1/auth/login", params: { email: user.email, password: "Password123" }
|
||||
token = response.parsed_body["access_token"]
|
||||
{ "Authorization" => "Bearer #{token}", "Content-Type" => "application/json" }
|
||||
end
|
||||
|
||||
before do
|
||||
plan = Plan.find_or_initialize_by(slug: "premium_full")
|
||||
plan.name ||= "Premium Full"
|
||||
plan.features = (plan.features || {}).merge(
|
||||
"platforms" => %w[matchlivetv],
|
||||
"concurrent_streams_limit" => 10
|
||||
)
|
||||
plan.save!
|
||||
club.create_subscription!(plan: plan, status: "active") if club.subscription.blank?
|
||||
allow(SessionChannel).to receive(:broadcast_message)
|
||||
end
|
||||
|
||||
it "restituisce 403 user_concurrent_stream e salva l'evidenza" do
|
||||
patch "/api/v1/sessions/#{idle.id}/start", headers: auth_headers
|
||||
|
||||
expect(response).to have_http_status(:forbidden)
|
||||
body = response.parsed_body
|
||||
expect(body["error_code"]).to eq("user_concurrent_stream")
|
||||
expect(body["error"]).to be_present
|
||||
expect(StreamConcurrencyViolation.where(attempted_session_id: idle.id, occupying_session_id: live.id)).to exist
|
||||
end
|
||||
end
|
||||
@@ -16,7 +16,17 @@ RSpec.describe "Public features page", type: :request do
|
||||
expect(response.body).to include("Chi filma, filma")
|
||||
expect(response.body).to include("Accesso con link")
|
||||
expect(response.body).to include("La diretta resta della tua società")
|
||||
expect(response.body).to include("La partita finisce. Il ricordo resta.")
|
||||
expect(response.body).to include("Dai visibilità ai tuoi sponsor")
|
||||
expect(response.body).to include("Copertina caricata per ogni partita")
|
||||
expect(response.body).to include("Scopri Premium Full")
|
||||
expect(response.body).to include("Team MLTV")
|
||||
expect(response.body).to include("Squadra ospite")
|
||||
expect(response.body).to include("Copertina personalizzata")
|
||||
expect(response.body).not_to include("Lupi Santa Croce")
|
||||
expect(response.body).not_to include("Rossi vs Neri")
|
||||
expect(response.body).not_to include("Tigers Volley")
|
||||
expect(response.body).not_to include("MAIN SPONSOR")
|
||||
expect(response.body).not_to include("CON IL SUPPORTO DI")
|
||||
expect(response.body).to include("Inizia gratis")
|
||||
expect(response.body).to include("Confronta i piani")
|
||||
expect(response.body).to include(public_signup_path)
|
||||
|
||||
@@ -10,6 +10,10 @@ RSpec.describe "Public home page", type: :request do
|
||||
expect(response.body).to include(I18n.t("home.stores_label", locale: :it))
|
||||
expect(response.body).to include(I18n.t("home.store_app_store_name", locale: :it))
|
||||
expect(response.body).to include(I18n.t("home.store_play_name", locale: :it))
|
||||
expect(response.body).to include("Dai visibilità ai tuoi sponsor")
|
||||
expect(response.body).to include("Team MLTV")
|
||||
expect(response.body).not_to include("Lupi Santa Croce")
|
||||
expect(response.body).to include("Scopri Premium Full")
|
||||
expect(response.body.scan(MatchLiveTv.app_store_url).size).to eq(3)
|
||||
expect(response.body.scan(MatchLiveTv.play_store_url).size).to eq(3)
|
||||
end
|
||||
|
||||
@@ -26,6 +26,14 @@ RSpec.describe "Public pricing page", type: :request do
|
||||
expect(response.body).to include("Account trasmettitori")
|
||||
expect(response.body).to include("Niente password condivise")
|
||||
expect(response.body).to include("plan-card--featured")
|
||||
expect(response.body).to include("Copertina personalizzabile")
|
||||
expect(response.body).to include("con sponsor")
|
||||
expect(response.body).to include("Copertina personalizzata")
|
||||
expect(response.body).to include("Dai visibilità ai tuoi sponsor")
|
||||
expect(response.body).to include("Team MLTV")
|
||||
expect(response.body).not_to include("Lupi Santa Croce")
|
||||
expect(response.body).not_to include("MAIN SPONSOR")
|
||||
expect(response.body).not_to include("CON IL SUPPORTO DI")
|
||||
expect(response.body).to include("Soddisfatti o rimborsati")
|
||||
expect(response.body).to include("30 giorni soddisfatti o rimborsati")
|
||||
expect(response.body).to include("ti rimborsiamo il 100%")
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe "Public team page", type: :request do
|
||||
let(:club) { Club.create!(name: "ASD Eagles", sport: "volleyball", primary_color: "#e53935", secondary_color: "#ffffff") }
|
||||
let(:club) { Club.create!(name: "Team MLTV", sport: "volleyball", primary_color: "#e53935", secondary_color: "#ffffff") }
|
||||
let!(:team) do
|
||||
club.teams.create!(
|
||||
name: "Tigers Volley U17",
|
||||
name: "Team MLTV U15",
|
||||
sport_key: "pallavolo",
|
||||
description: "Squadra giovanile under 17.",
|
||||
description: "Squadra giovanile under 15.",
|
||||
roster_public: true
|
||||
)
|
||||
end
|
||||
@@ -15,9 +15,9 @@ RSpec.describe "Public team page", type: :request do
|
||||
get public_team_page_path(team.slug)
|
||||
|
||||
expect(response).to have_http_status(:ok)
|
||||
expect(response.body).to include("Tigers Volley U17")
|
||||
expect(response.body).to include("ASD Eagles")
|
||||
expect(response.body).to include("Squadra giovanile under 17")
|
||||
expect(response.body).to include("Team MLTV U15")
|
||||
expect(response.body).to include("Team MLTV")
|
||||
expect(response.body).to include("Squadra giovanile under 15")
|
||||
end
|
||||
|
||||
it "restituisce 404 per slug inesistente" do
|
||||
@@ -41,13 +41,13 @@ RSpec.describe "Public team page", type: :request do
|
||||
end
|
||||
|
||||
RSpec.describe "Public team directory", type: :request do
|
||||
let(:club) { Club.create!(name: "ASD Eagles", sport: "volleyball", primary_color: "#e53935", secondary_color: "#ffffff") }
|
||||
let(:club) { Club.create!(name: "Team MLTV", sport: "volleyball", primary_color: "#e53935", secondary_color: "#ffffff") }
|
||||
let(:user) { User.create!(email: "dir2@test.com", name: "Coach", password: "Password123", role: "coach") }
|
||||
let!(:team) { club.teams.create!(name: "Tigers Volley U17", sport_key: "pallavolo") }
|
||||
let!(:team) { club.teams.create!(name: "Team MLTV U15", sport_key: "pallavolo") }
|
||||
|
||||
before do
|
||||
club.club_memberships.create!(user: user, role: "owner")
|
||||
match = team.matches.create!(opponent_name: "Rival", sport_key: "pallavolo", scheduled_at: 1.day.from_now)
|
||||
match = team.matches.create!(opponent_name: MatchLiveTv::Demo::AWAY_TEAM, sport_key: "pallavolo", scheduled_at: 1.day.from_now)
|
||||
StreamSession.create!(
|
||||
match: match, user: user, status: "live", platform: "matchlivetv",
|
||||
privacy_status: "public", publish_token: "tok-dir", started_at: Time.current
|
||||
@@ -58,13 +58,13 @@ RSpec.describe "Public team directory", type: :request do
|
||||
get public_team_pages_path
|
||||
|
||||
expect(response).to have_http_status(:ok)
|
||||
expect(response.body).to include("Tigers Volley U17")
|
||||
expect(response.body).to include("Team MLTV U15")
|
||||
expect(response.body).to include("In diretta")
|
||||
end
|
||||
|
||||
it "filtra per sport via query string" do
|
||||
get public_team_pages_path(sport: "basket")
|
||||
|
||||
expect(response.body).not_to include("Tigers Volley U17")
|
||||
expect(response.body).not_to include("Team MLTV U15")
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user