Una gara con punteggio non resta più «In programma» solo perché l'orario è futuro, e i replay usano le squadre del match invece della squadra di trasmissione. Co-authored-by: Cursor <cursoragent@cursor.com>
820 lines
30 KiB
Ruby
820 lines
30 KiB
Ruby
require "rails_helper"
|
||
require "base64"
|
||
|
||
RSpec.describe "Tournaments", type: :request do
|
||
let!(:coach) do
|
||
User.create!(email: "torneo-owner@test.it", name: "Owner", password: "Password123", role: "coach")
|
||
end
|
||
let!(:club) do
|
||
c = Club.create!(name: "Torneo Club", sport: "volleyball", primary_color: "#e53935", secondary_color: "#ffffff")
|
||
ClubMembership.create!(user: coach, club: c, role: "owner")
|
||
c
|
||
end
|
||
let!(:team) { club.teams.create!(name: "U15", sport: "volleyball") }
|
||
|
||
def login!
|
||
post public_login_path, params: { email: coach.email, password: "Password123" }
|
||
end
|
||
|
||
def assign_plan!(slug)
|
||
Billing::AssignPlan.call(club: club, plan_slug: slug)
|
||
club.reload
|
||
end
|
||
|
||
it "non crea tornei senza Premium Full" do
|
||
assign_plan!("premium_light")
|
||
login!
|
||
expect {
|
||
post public_club_tournaments_path(club), params: {
|
||
tournament: {
|
||
name: "Memorial",
|
||
sport_key: "pallavolo",
|
||
starts_on: Date.current,
|
||
ends_on: Date.current + 1,
|
||
format_kind: "mixed"
|
||
}
|
||
}
|
||
}.not_to change(Tournament, :count)
|
||
expect(response).to redirect_to(public_club_billing_path(club))
|
||
end
|
||
|
||
it "sulla società Free il pulsante Tornei ha il nastrino FULL" do
|
||
assign_plan!("free")
|
||
login!
|
||
get public_club_path(club)
|
||
expect(response).to have_http_status(:ok)
|
||
expect(response.body).to include("btn-gated__ribbon")
|
||
expect(response.body).to include(">FULL<")
|
||
expect(response.body).to include(public_club_billing_path(club))
|
||
expect(response.body).not_to include(%(href="#{public_club_tournaments_path(club)}"))
|
||
end
|
||
|
||
it "dalla società apre l'elenco tornei, non in dashboard" do
|
||
assign_plan!("premium_full")
|
||
login!
|
||
tournament = Tournaments::Create.call(
|
||
club: club,
|
||
attrs: {
|
||
name: "Open Elenco",
|
||
sport_key: "pallavolo",
|
||
starts_on: Date.current,
|
||
ends_on: Date.current + 1,
|
||
format_kind: "free"
|
||
}
|
||
)
|
||
|
||
get public_club_path(club)
|
||
expect(response.body).to include(public_club_tournaments_path(club))
|
||
expect(response.body).not_to include("btn-gated__ribbon")
|
||
expect(response.body).not_to include("Open Elenco")
|
||
expect(response.body).not_to include(public_new_club_tournament_path(club))
|
||
|
||
get public_club_tournaments_path(club)
|
||
expect(response).to have_http_status(:ok)
|
||
expect(response.body).to include("Open Elenco")
|
||
expect(response.body).to include(public_new_club_tournament_path(club))
|
||
expect(response.body).to include(public_tournament_path(tournament))
|
||
end
|
||
|
||
it "crea il torneo, iscrive squadre, genera gironi e pubblica la pagina" do
|
||
assign_plan!("premium_full")
|
||
login!
|
||
|
||
expect {
|
||
post public_club_tournaments_path(club), params: {
|
||
tournament: {
|
||
name: "Memorial Estate",
|
||
sport_key: "pallavolo",
|
||
venue: "Palestra A",
|
||
starts_on: Date.current,
|
||
ends_on: Date.current + 1,
|
||
format_kind: "mixed",
|
||
courts: "Campo 1\nCampo 2",
|
||
knockout_size: 4
|
||
}
|
||
}
|
||
}.to change(Tournament, :count).by(1)
|
||
|
||
tournament = Tournament.order(:created_at).last
|
||
expect(tournament.broadcast_team).to be_present
|
||
expect(tournament.broadcast_team.tournament_broadcast?).to be(true)
|
||
expect(tournament.groups.count).to eq(2)
|
||
expect(response).to redirect_to(public_tournament_path(tournament))
|
||
|
||
a = tournament.groups.order(:position).first
|
||
b = tournament.groups.order(:position).last
|
||
post public_tournament_participants_path(tournament), params: { tournament_participant: { name: "Alfa", group_id: a.id } }
|
||
post public_tournament_participants_path(tournament), params: { tournament_participant: { name: "Beta", group_id: a.id } }
|
||
post public_tournament_participants_path(tournament), params: { tournament_participant: { name: "Gamma", group_id: b.id } }
|
||
post public_tournament_participants_path(tournament), params: { tournament_participant: { name: "Delta", group_id: b.id } }
|
||
expect(tournament.participants.count).to eq(4)
|
||
|
||
post public_generate_group_matches_tournament_path(tournament)
|
||
expect(tournament.matches.count).to be > 0
|
||
expect(club.teams.visible.map(&:id)).to include(team.id)
|
||
expect(club.teams.visible.map(&:id)).not_to include(tournament.broadcast_team_id)
|
||
|
||
match = tournament.matches.first
|
||
home = match.home_participant
|
||
away = match.away_participant
|
||
post public_tournament_match_result_path(tournament, match), params: { home_score: 2, away_score: 0, tab: "calendario" }
|
||
expect(match.reload.played?).to be(true)
|
||
expect(match.winner_participant_id).to eq(home.id)
|
||
|
||
standings = Tournaments::Standings.call(match.tournament_group)
|
||
expect(standings.first.participant).to eq(home)
|
||
expect(standings.first.points).to eq(3)
|
||
|
||
tournament.matches.where.associated(:tournament_group).where.not(id: match.id).find_each do |other|
|
||
post public_tournament_match_result_path(tournament, other),
|
||
params: { home_score: 2, away_score: 0, tab: "calendario" }
|
||
end
|
||
post public_propose_knockout_tournament_path(tournament)
|
||
final = tournament.rounds.find_by(kind: "final").matches.first
|
||
expect(final).to be_present
|
||
expect(final.home_source_kind).to eq("winner_match")
|
||
expect(final.away_source_kind).to eq("winner_match")
|
||
|
||
get public_tournament_path(tournament, tab: "tabellone")
|
||
expect(response.body).to include("Semifinali e finali")
|
||
expect(response.body).to include("Compila tabellone")
|
||
expect(response.body).to include("match[home_participant_id]")
|
||
|
||
semi = tournament.rounds.find_by(kind: "semifinal").matches.first
|
||
patch public_tournament_match_path(tournament, semi), params: {
|
||
tab: "tabellone",
|
||
match: {
|
||
home_participant_id: tournament.participants.find_by!(name: "Alfa").id,
|
||
away_participant_id: tournament.participants.find_by!(name: "Gamma").id
|
||
}
|
||
}
|
||
expect(response).to redirect_to(public_tournament_path(tournament, tab: "tabellone"))
|
||
expect(semi.reload.home_participant.name).to eq("Alfa")
|
||
expect(semi.away_participant.name).to eq("Gamma")
|
||
|
||
tournament.rounds.find_by(kind: "semifinal").matches.each do |semi|
|
||
post public_tournament_match_result_path(tournament, semi),
|
||
params: { home_score: 2, away_score: 0, tab: "tabellone" }
|
||
end
|
||
expect(final.reload.home_participant).to be_present
|
||
expect(final.away_participant).to be_present
|
||
expect(final.home_participant_id).not_to eq(final.away_participant_id)
|
||
|
||
delete public_logout_path
|
||
get public_tournament_page_path(tournament.slug)
|
||
expect(response).to have_http_status(:not_found)
|
||
|
||
login!
|
||
post public_publish_tournament_path(tournament)
|
||
get public_tournament_page_path(tournament.slug)
|
||
expect(response).to have_http_status(:ok)
|
||
expect(response.body).to include("Memorial Estate")
|
||
expect(response.body).to include(home.name)
|
||
expect(response.body).to include("Risultati")
|
||
expect(response.body).to include("Tabellone")
|
||
|
||
get public_tournament_page_path(tournament.slug, tab: "tabellone")
|
||
expect(response.body).to include("Classifica")
|
||
expect(response.body).to include(home.name)
|
||
|
||
get public_tournament_pages_path
|
||
expect(response).to have_http_status(:ok)
|
||
expect(response.body).to include("Memorial Estate")
|
||
expect(response.body).to include(public_tournament_page_path(tournament.slug))
|
||
|
||
get public_live_index_path
|
||
expect(response.body).to include("Memorial Estate")
|
||
expect(response.body).to include("Segui il cartellone")
|
||
end
|
||
|
||
it "delega per campo/giornata e accetta l'invito" do
|
||
assign_plan!("premium_full")
|
||
login!
|
||
post public_club_tournaments_path(club), params: {
|
||
tournament: {
|
||
name: "Open Day",
|
||
sport_key: "pallavolo",
|
||
starts_on: Date.current,
|
||
ends_on: Date.current,
|
||
format_kind: "free",
|
||
courts: "Campo 2"
|
||
}
|
||
}
|
||
tournament = Tournament.order(:created_at).last
|
||
home = tournament.participants.create!(name: "Casa")
|
||
away = tournament.participants.create!(name: "Ospite")
|
||
match = Tournaments::ScheduleMatch.call(
|
||
tournament: tournament,
|
||
attrs: {
|
||
home_participant_id: home.id,
|
||
away_participant_id: away.id,
|
||
court: "Campo 2",
|
||
scheduled_at: Time.zone.now.change(hour: 10)
|
||
}
|
||
)
|
||
|
||
expect {
|
||
post public_tournament_invitations_path(tournament), params: {
|
||
email: "volontario@test.it",
|
||
note: "Porta il treppiede",
|
||
email_html: "<p>Testo personalizzato campo 2</p><p>{{link_invito}}</p>",
|
||
scope_kind: "court_day",
|
||
court: "Campo 2",
|
||
on_date: Date.current
|
||
}
|
||
}.to change { tournament.broadcast_invitations.count }.by(1)
|
||
.and change { ActionMailer::Base.deliveries.size }.by(1)
|
||
|
||
invitation = tournament.broadcast_invitations.last
|
||
expect(invitation.note).to eq("Porta il treppiede")
|
||
expect(invitation.email_html).to include("Testo personalizzato campo 2")
|
||
|
||
mail = ActionMailer::Base.deliveries.last
|
||
html = (mail.html_part || mail).body.decoded
|
||
expect(html).to include("Testo personalizzato campo 2")
|
||
expect(html).to include("/join/")
|
||
|
||
token = nil
|
||
follow_redirect!
|
||
expect(response.body).to include("/join/")
|
||
token = flash[:invite_url].to_s.split("/join/").last
|
||
token = CGI.unescapeHTML(response.body[/\/join\/([^"<\s]+)/, 1]) if token.blank?
|
||
expect(token).to be_present
|
||
|
||
volunteer = User.create!(email: "volontario@test.it", name: "Volo", password: "Password123", role: "volunteer")
|
||
invitation = tournament.broadcast_invitations.last
|
||
invitation.accept!(volunteer)
|
||
expect(volunteer.can_broadcast_match?(match)).to be(true)
|
||
expect(volunteer.can_broadcast_match?(Match.new(team: team))).to be(false)
|
||
end
|
||
|
||
it "aggiorna orario, campo e logo squadra" do
|
||
assign_plan!("premium_full")
|
||
login!
|
||
post public_club_tournaments_path(club), params: {
|
||
tournament: {
|
||
name: "Memorial Logo",
|
||
sport_key: "pallavolo",
|
||
venue: "Palestra A",
|
||
starts_on: Date.current,
|
||
ends_on: Date.current + 1,
|
||
format_kind: "groups",
|
||
courts: "Campo 1\nCampo 2"
|
||
}
|
||
}
|
||
tournament = Tournament.order(:created_at).last
|
||
group = tournament.groups.order(:position).first
|
||
alfa = tournament.participants.create!(name: "Alfa", group: group)
|
||
beta = tournament.participants.create!(name: "Beta", group: group)
|
||
post public_generate_group_matches_tournament_path(tournament)
|
||
match = tournament.matches.first
|
||
|
||
new_at = Time.zone.local(Date.current.year, Date.current.month, Date.current.day, 16, 30)
|
||
patch public_tournament_match_path(tournament, match), params: {
|
||
match: { court: "Campo 2", scheduled_at: new_at.strftime("%Y-%m-%dT%H:%M") }
|
||
}
|
||
match.reload
|
||
expect(match.court).to eq("Campo 2")
|
||
expect(match.scheduled_at).to eq(new_at)
|
||
expect(match.location).to include("Campo 2")
|
||
|
||
png = nil
|
||
png = Tempfile.new(["logo", ".png"])
|
||
png.binmode
|
||
png.write(Base64.decode64("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg=="))
|
||
png.rewind
|
||
patch public_tournament_participant_path(tournament, alfa), params: {
|
||
tournament_participant: {
|
||
name: "Alfa Blu",
|
||
group_id: group.id,
|
||
logo_file: Rack::Test::UploadedFile.new(png.path, "image/png", original_filename: "logo.png")
|
||
}
|
||
}
|
||
alfa.reload
|
||
expect(alfa.name).to eq("Alfa Blu")
|
||
expect(alfa.logo_file).to be_attached
|
||
expect(alfa.effective_logo_url).to be_present
|
||
if match.away_participant_id == alfa.id
|
||
expect(match.reload.opponent_name).to eq("Alfa Blu")
|
||
end
|
||
ensure
|
||
png&.close!
|
||
end
|
||
|
||
it "carica il logo del torneo e lo mostra in pubblico" do
|
||
assign_plan!("premium_full")
|
||
login!
|
||
tournament = Tournaments::Create.call(
|
||
club: club,
|
||
attrs: {
|
||
name: "Open Logo",
|
||
sport_key: "pallavolo",
|
||
starts_on: Date.current,
|
||
ends_on: Date.current,
|
||
format_kind: "free"
|
||
}
|
||
)
|
||
png = Tempfile.new(["torneo-logo", ".png"])
|
||
png.binmode
|
||
png.write(Base64.decode64("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg=="))
|
||
png.rewind
|
||
|
||
patch public_tournament_path(tournament), params: {
|
||
tournament: { logo_file: Rack::Test::UploadedFile.new(png.path, "image/png", original_filename: "torneo.png") }
|
||
}
|
||
expect(tournament.reload.logo_file).to be_attached
|
||
expect(tournament.effective_logo_url).to be_present
|
||
|
||
post public_publish_tournament_path(tournament)
|
||
get public_tournament_page_path(tournament.slug)
|
||
expect(response.body).to include("tournament-public-hero__logo")
|
||
expect(response.body).to include(tournament.effective_logo_url)
|
||
|
||
get public_tournament_pages_path
|
||
expect(response.body).to include("tournament-directory-card")
|
||
expect(response.body).to include(tournament.effective_logo_url)
|
||
ensure
|
||
png&.close!
|
||
end
|
||
|
||
it "inverte casa e ospite con un click" do
|
||
assign_plan!("premium_full")
|
||
login!
|
||
tournament = Tournaments::Create.call(
|
||
club: club,
|
||
attrs: {
|
||
name: "Memorial Swap",
|
||
sport_key: "pallavolo",
|
||
starts_on: Date.current,
|
||
ends_on: Date.current,
|
||
format_kind: "free",
|
||
courts: "Campo 1"
|
||
}
|
||
)
|
||
home = tournament.participants.create!(name: "Casa")
|
||
away = tournament.participants.create!(name: "Ospite")
|
||
match = Tournaments::ScheduleMatch.call(
|
||
tournament: tournament,
|
||
attrs: {
|
||
home_participant_id: home.id,
|
||
away_participant_id: away.id,
|
||
court: "Campo 1",
|
||
scheduled_at: Time.zone.now.change(hour: 11)
|
||
}
|
||
)
|
||
Tournaments::RecordResult.call(match: match, home_score: 2, away_score: 0, source: "manual")
|
||
|
||
get public_tournament_path(tournament, tab: "calendario")
|
||
expect(response.body).to include("tournament-match-swap__btn")
|
||
expect(response.body).to include(public_swap_tournament_match_path(tournament, match))
|
||
expect(response.body).to include("tournament-calendar.js")
|
||
|
||
post public_swap_tournament_match_path(tournament, match), as: :json
|
||
expect(response).to have_http_status(:ok)
|
||
expect(response).not_to be_redirect
|
||
json = JSON.parse(response.body)
|
||
expect(json["ok"]).to be(true)
|
||
expect(json["matchup_label"]).to include("Ospite")
|
||
expect(json["matchup_label"]).to include("Casa")
|
||
|
||
match.reload
|
||
expect(match.home_participant_id).to eq(away.id)
|
||
expect(match.away_participant_id).to eq(home.id)
|
||
expect(match.home_score).to eq(0)
|
||
expect(match.away_score).to eq(2)
|
||
expect(match.winner_participant_id).to eq(home.id)
|
||
expect(match.opponent_name).to eq("Casa")
|
||
end
|
||
|
||
it "invita e gestisce lo streaming dal piano dirette" do
|
||
assign_plan!("premium_full")
|
||
login!
|
||
tournament = Tournaments::Create.call(
|
||
club: club,
|
||
attrs: {
|
||
name: "Memorial Streaming",
|
||
sport_key: "pallavolo",
|
||
starts_on: Date.current,
|
||
ends_on: Date.current,
|
||
format_kind: "free",
|
||
courts: "Campo 1"
|
||
}
|
||
)
|
||
tournament.update!(
|
||
invite_draft_email: "bozza@test.it",
|
||
invite_draft_html: "<p>Bozza salvata</p><p>{{link_invito}}</p>",
|
||
invite_draft_saved_at: Time.current
|
||
)
|
||
home = tournament.participants.create!(name: "Casa")
|
||
away = tournament.participants.create!(name: "Ospite")
|
||
match = Tournaments::ScheduleMatch.call(
|
||
tournament: tournament,
|
||
attrs: {
|
||
home_participant_id: home.id,
|
||
away_participant_id: away.id,
|
||
court: "Campo 1",
|
||
scheduled_at: Time.zone.now.change(hour: 11)
|
||
}
|
||
)
|
||
other = Tournaments::ScheduleMatch.call(
|
||
tournament: tournament,
|
||
attrs: {
|
||
home_participant_id: away.id,
|
||
away_participant_id: home.id,
|
||
court: "Campo 1",
|
||
scheduled_at: Time.zone.now.change(hour: 13)
|
||
}
|
||
)
|
||
|
||
get public_tournament_path(tournament, tab: "delega")
|
||
expect(response).to redirect_to(public_tournament_path(tournament, tab: "dirette"))
|
||
|
||
get public_tournament_path(tournament, tab: "dirette")
|
||
expect(response.body).to include("Piano dirette")
|
||
expect(response.body).to include("Invita selezionate")
|
||
expect(response.body).to include("plan_match_#{match.id}")
|
||
expect(response.body).to include("2 da coprire")
|
||
|
||
get public_tournament_path(tournament, tab: "calendario")
|
||
expect(response.body).not_to include("Da coprire")
|
||
expect(response.body).not_to include(">Streaming<")
|
||
|
||
expect {
|
||
post public_tournament_invitations_path(tournament), params: {
|
||
email: "op.cal@test.it",
|
||
tab: "dirette",
|
||
match_ids: [match.id]
|
||
}
|
||
}.to change { tournament.broadcast_invitations.count }.by(1)
|
||
.and change { ActionMailer::Base.deliveries.size }.by(1)
|
||
|
||
invitation = tournament.broadcast_invitations.last
|
||
expect(invitation.scope_kind).to eq("matches")
|
||
expect(invitation.email_html).to include("Bozza salvata")
|
||
expect(invitation.covers_match?(match)).to be(true)
|
||
expect(invitation.covers_match?(other)).to be(false)
|
||
|
||
follow_redirect!
|
||
expect(response.body).to include("Piano dirette")
|
||
expect(response.body).to include("tournament-streaming-chip--pending")
|
||
expect(response.body).to include("tournament-live-status--waiting_operator")
|
||
expect(response.body).not_to include("plan_match_#{match.id}")
|
||
expect(response.body).to include("plan_match_#{other.id}")
|
||
|
||
volunteer = User.create!(email: "op.cal@test.it", name: "Operatore Cal", password: "Password123", role: "volunteer")
|
||
invitation.accept!(volunteer)
|
||
expect(volunteer.can_broadcast_match?(match)).to be(true)
|
||
expect(volunteer.can_broadcast_match?(other)).to be(false)
|
||
|
||
get public_tournament_path(tournament, tab: "dirette")
|
||
expect(response.body).to include("Operatore Cal")
|
||
expect(response.body).not_to include("tournament-streaming-chip--pending")
|
||
|
||
session = StreamSession.create!(match: match, user: volunteer, platform: "matchlivetv", status: "live")
|
||
get public_tournament_path(tournament, tab: "dirette")
|
||
expect(response.body).to include("tournament-live-status--live")
|
||
expect(response.body).to include("In diretta")
|
||
|
||
session.update_columns(status: "ended", ended_at: Time.current)
|
||
get public_tournament_path(tournament, tab: "dirette")
|
||
expect(response.body).to include("tournament-live-status--ended")
|
||
|
||
get public_tournament_path(tournament, tab: "calendario")
|
||
expect(response.body).not_to include("Operatore Cal")
|
||
expect(response.body).not_to include("Invita selezionate")
|
||
|
||
assignment = match.broadcast_assignments.find_by!(user: volunteer)
|
||
delete public_tournament_assignment_path(tournament, assignment)
|
||
follow_redirect!
|
||
expect(volunteer.reload.can_broadcast_match?(match)).to be(false)
|
||
expect(response.body).to include("Piano dirette")
|
||
expect(response.body).to include("tournament-live-status--ended")
|
||
expect(response.body).not_to include("Operatore Cal")
|
||
end
|
||
|
||
it "revoca un assegnamento senza togliere le altre gare della stessa delega" do
|
||
assign_plan!("premium_full")
|
||
login!
|
||
tournament = Tournaments::Create.call(
|
||
club: club,
|
||
attrs: {
|
||
name: "Memorial Court Day",
|
||
sport_key: "pallavolo",
|
||
starts_on: Date.current,
|
||
ends_on: Date.current,
|
||
format_kind: "free",
|
||
courts: "Campo 2"
|
||
}
|
||
)
|
||
home = tournament.participants.create!(name: "Casa")
|
||
away = tournament.participants.create!(name: "Ospite")
|
||
match = Tournaments::ScheduleMatch.call(
|
||
tournament: tournament,
|
||
attrs: {
|
||
home_participant_id: home.id,
|
||
away_participant_id: away.id,
|
||
court: "Campo 2",
|
||
scheduled_at: Time.zone.now.change(hour: 10)
|
||
}
|
||
)
|
||
other = Tournaments::ScheduleMatch.call(
|
||
tournament: tournament,
|
||
attrs: {
|
||
home_participant_id: away.id,
|
||
away_participant_id: home.id,
|
||
court: "Campo 2",
|
||
scheduled_at: Time.zone.now.change(hour: 12)
|
||
}
|
||
)
|
||
post public_tournament_invitations_path(tournament), params: {
|
||
email: "campo@test.it",
|
||
scope_kind: "court_day",
|
||
court: "Campo 2",
|
||
on_date: Date.current
|
||
}
|
||
volunteer = User.create!(email: "campo@test.it", name: "Campo Op", password: "Password123", role: "volunteer")
|
||
invitation = tournament.broadcast_invitations.last
|
||
invitation.accept!(volunteer)
|
||
expect(volunteer.can_broadcast_match?(match)).to be(true)
|
||
expect(volunteer.can_broadcast_match?(other)).to be(true)
|
||
|
||
assignment = match.broadcast_assignments.find_by!(user: volunteer)
|
||
delete public_tournament_assignment_path(tournament, assignment)
|
||
expect(volunteer.reload.can_broadcast_match?(match)).to be(false)
|
||
expect(volunteer.can_broadcast_match?(other)).to be(true)
|
||
expect(invitation.reload.scope_kind).to eq("matches")
|
||
expect(invitation.match_ids.map(&:to_s)).to contain_exactly(other.id.to_s)
|
||
end
|
||
|
||
it "carica un'immagine per la mail di delega" do
|
||
assign_plan!("premium_full")
|
||
login!
|
||
post public_club_tournaments_path(club), params: {
|
||
tournament: {
|
||
name: "Memorial Mail",
|
||
sport_key: "pallavolo",
|
||
starts_on: Date.current,
|
||
ends_on: Date.current,
|
||
format_kind: "free",
|
||
courts: "Campo 1"
|
||
}
|
||
}
|
||
tournament = Tournament.order(:created_at).last
|
||
png = Tempfile.new(["invite", ".png"])
|
||
png.binmode
|
||
png.write(Base64.decode64("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg=="))
|
||
png.rewind
|
||
post public_tournament_invite_images_path(tournament), params: {
|
||
file: Rack::Test::UploadedFile.new(png.path, "image/png", original_filename: "logo.png")
|
||
}
|
||
expect(response).to have_http_status(:ok)
|
||
json = JSON.parse(response.body)
|
||
expect(json["url"]).to include("/rails/active_storage")
|
||
expect(tournament.reload.invite_email_images).to be_attached
|
||
ensure
|
||
png&.close!
|
||
end
|
||
|
||
it "salva la bozza della mail senza inviarla" do
|
||
assign_plan!("premium_full")
|
||
login!
|
||
post public_club_tournaments_path(club), params: {
|
||
tournament: {
|
||
name: "Memorial Bozza",
|
||
sport_key: "pallavolo",
|
||
starts_on: Date.current,
|
||
ends_on: Date.current,
|
||
format_kind: "free",
|
||
courts: "Campo 1"
|
||
}
|
||
}
|
||
tournament = Tournament.order(:created_at).last
|
||
|
||
expect {
|
||
post public_tournament_invite_draft_path(tournament), params: {
|
||
email: "dopo@test.it",
|
||
note: "Porta il treppiede",
|
||
email_html: %(<p>Testo bozza con {{link_invito}}</p><p><img src="https://www.example.com/logo.png" alt=""></p>)
|
||
}
|
||
}.not_to change { ActionMailer::Base.deliveries.size }
|
||
|
||
tournament.reload
|
||
expect(tournament.invite_draft_note).to eq("Porta il treppiede")
|
||
expect(tournament.invite_draft_email).to eq("dopo@test.it")
|
||
expect(tournament.invite_draft_html).to include("Testo bozza")
|
||
expect(tournament.invite_draft_html).to include("{{link_invito}}")
|
||
expect(tournament.invite_draft_html).to include("logo.png")
|
||
expect(tournament.invite_draft_saved_at).to be_present
|
||
|
||
get public_tournament_path(tournament, tab: "dirette")
|
||
expect(response.body).to include("Testo bozza")
|
||
expect(response.body).to include("Porta il treppiede")
|
||
expect(response.body).to include("dopo@test.it")
|
||
expect(response.body).to include("Salva bozza")
|
||
expect(response.body).to include("Piano dirette")
|
||
expect(response.body).to include("Testo della mail")
|
||
expect(response.body).to include("Invita un operatore")
|
||
end
|
||
|
||
it "elimina il torneo, le partite e il team interno" do
|
||
assign_plan!("premium_full")
|
||
login!
|
||
tournament = Tournaments::Create.call(
|
||
club: club,
|
||
attrs: {
|
||
name: "Memorial da cancellare",
|
||
sport_key: "pallavolo",
|
||
starts_on: Date.current,
|
||
ends_on: Date.current,
|
||
format_kind: "free",
|
||
courts: "Campo 1"
|
||
}
|
||
)
|
||
home = tournament.participants.create!(name: "Casa")
|
||
away = tournament.participants.create!(name: "Ospite")
|
||
match = Tournaments::ScheduleMatch.call(
|
||
tournament: tournament,
|
||
attrs: {
|
||
home_participant_id: home.id,
|
||
away_participant_id: away.id,
|
||
court: "Campo 1",
|
||
scheduled_at: Time.zone.now.change(hour: 10)
|
||
}
|
||
)
|
||
session = StreamSession.create!(
|
||
match: match, user: coach, platform: "matchlivetv", status: "ended", ended_at: 1.hour.ago
|
||
)
|
||
Recording.create!(
|
||
stream_session: session, team: tournament.broadcast_team, status: "ready", privacy_status: "public",
|
||
title: "Replay torneo",
|
||
storage_key: "teams/#{tournament.broadcast_team_id}/sessions/#{session.id}/replay.mp4"
|
||
)
|
||
team_id = tournament.broadcast_team_id
|
||
match_id = match.id
|
||
|
||
get public_tournament_path(tournament)
|
||
expect(response.body).to include("Elimina")
|
||
|
||
expect {
|
||
delete public_tournament_path(tournament)
|
||
}.to change(Tournament, :count).by(-1)
|
||
.and change(Match, :count).by(-1)
|
||
.and change(Team, :count).by(-1)
|
||
|
||
expect(response).to redirect_to(public_club_tournaments_path(club))
|
||
expect(Tournament.find_by(id: tournament.id)).to be_nil
|
||
expect(Match.find_by(id: match_id)).to be_nil
|
||
expect(Team.find_by(id: team_id)).to be_nil
|
||
expect(Recording.find_by(stream_session_id: session.id)).to be_nil
|
||
|
||
get public_tournament_path(tournament.id)
|
||
expect(response).to have_http_status(:not_found)
|
||
end
|
||
|
||
it "non elimina il torneo se una diretta è in corso" do
|
||
assign_plan!("premium_full")
|
||
login!
|
||
tournament = Tournaments::Create.call(
|
||
club: club,
|
||
attrs: {
|
||
name: "Memorial live",
|
||
sport_key: "pallavolo",
|
||
starts_on: Date.current,
|
||
ends_on: Date.current,
|
||
format_kind: "free",
|
||
courts: "Campo 1"
|
||
}
|
||
)
|
||
home = tournament.participants.create!(name: "Casa")
|
||
away = tournament.participants.create!(name: "Ospite")
|
||
match = Tournaments::ScheduleMatch.call(
|
||
tournament: tournament,
|
||
attrs: {
|
||
home_participant_id: home.id,
|
||
away_participant_id: away.id,
|
||
court: "Campo 1",
|
||
scheduled_at: Time.zone.now.change(hour: 18)
|
||
}
|
||
)
|
||
StreamSession.create!(match: match, user: coach, platform: "matchlivetv", status: "live")
|
||
|
||
expect {
|
||
delete public_tournament_path(tournament)
|
||
}.not_to change(Tournament, :count)
|
||
expect(response).to redirect_to(public_tournament_path(tournament))
|
||
follow_redirect!
|
||
expect(response.body).to include("Chiudi le dirette")
|
||
end
|
||
|
||
it "l'owner elimina il torneo anche senza Premium Full" do
|
||
assign_plan!("premium_full")
|
||
tournament = Tournaments::Create.call(
|
||
club: club,
|
||
attrs: {
|
||
name: "Memorial declassato",
|
||
sport_key: "pallavolo",
|
||
starts_on: Date.current,
|
||
ends_on: Date.current,
|
||
format_kind: "free"
|
||
}
|
||
)
|
||
assign_plan!("premium_light")
|
||
login!
|
||
|
||
expect {
|
||
delete public_tournament_path(tournament)
|
||
}.to change(Tournament, :count).by(-1)
|
||
expect(response).to redirect_to(public_club_tournaments_path(club))
|
||
end
|
||
|
||
it "mostra sul cartellone i link a diretta e replay" do
|
||
assign_plan!("premium_full")
|
||
login!
|
||
tournament = Tournaments::Create.call(
|
||
club: club,
|
||
attrs: {
|
||
name: "Open Cartellone",
|
||
sport_key: "pallavolo",
|
||
starts_on: Date.current,
|
||
ends_on: Date.current + 1,
|
||
format_kind: "free",
|
||
courts: "Campo 1"
|
||
}
|
||
)
|
||
home = tournament.participants.create!(name: "Alfa")
|
||
away = tournament.participants.create!(name: "Beta")
|
||
match = Tournaments::ScheduleMatch.call(
|
||
tournament: tournament,
|
||
attrs: {
|
||
home_participant_id: home.id,
|
||
away_participant_id: away.id,
|
||
court: "Campo 1",
|
||
scheduled_at: 2.hours.from_now
|
||
}
|
||
)
|
||
post public_publish_tournament_path(tournament)
|
||
|
||
session = StreamSession.create!(
|
||
match: match, user: coach, platform: "matchlivetv", status: "live", privacy_status: "public"
|
||
)
|
||
get public_tournament_page_path(tournament.slug)
|
||
expect(response).to have_http_status(:ok)
|
||
expect(response.body).to include("Risultati")
|
||
expect(response.body).to include("Guarda diretta")
|
||
expect(response.body).to include(public_live_path(session))
|
||
expect(response.body).to include("tournament-live-status--live")
|
||
|
||
session.update_columns(status: "ended", ended_at: Time.current)
|
||
Recording.create!(
|
||
stream_session: session, team: tournament.broadcast_team, status: "ready", privacy_status: "public",
|
||
title: "#{tournament.broadcast_team.name} vs #{away.name}",
|
||
storage_key: "teams/#{tournament.broadcast_team_id}/sessions/#{session.id}/replay.mp4"
|
||
)
|
||
|
||
get public_tournament_page_path(tournament.slug)
|
||
expect(response.body).to include("Guarda replay")
|
||
expect(response.body).to include(public_replay_path(session.id))
|
||
expect(response.body).to include("tournament-live-status--replay")
|
||
expect(response.body).to include("#{home.name} vs #{away.name}")
|
||
expect(response.body).not_to include("#{tournament.broadcast_team.name} vs #{away.name}")
|
||
|
||
get public_club_tournaments_path(club)
|
||
expect(response.body).to include(public_tournament_page_path(tournament.slug))
|
||
end
|
||
|
||
it "marca Terminata una gara con risultato anche se l'orario è ancora futuro" do
|
||
assign_plan!("premium_full")
|
||
login!
|
||
tournament = Tournaments::Create.call(
|
||
club: club,
|
||
attrs: {
|
||
name: "Open Risultato Anticipato",
|
||
sport_key: "pallavolo",
|
||
starts_on: Date.current,
|
||
ends_on: Date.current + 1,
|
||
format_kind: "free",
|
||
courts: "Campo 1"
|
||
}
|
||
)
|
||
home = tournament.participants.create!(name: "Alfa")
|
||
away = tournament.participants.create!(name: "Delta")
|
||
match = Tournaments::ScheduleMatch.call(
|
||
tournament: tournament,
|
||
attrs: {
|
||
home_participant_id: home.id,
|
||
away_participant_id: away.id,
|
||
court: "Campo 1",
|
||
scheduled_at: 6.hours.from_now
|
||
}
|
||
)
|
||
Tournaments::RecordResult.call(match: match, home_score: 2, away_score: 0, source: "manual")
|
||
post public_publish_tournament_path(tournament)
|
||
|
||
get public_tournament_page_path(tournament.slug, tab: "risultati")
|
||
expect(response.body).to include("2–0")
|
||
expect(response.body).to include("tournament-live-status--ended")
|
||
expect(response.body).to include("Terminata")
|
||
expect(response.body).not_to include("tournament-live-status--scheduled")
|
||
end
|
||
end
|