Aggiunge i18n IT/EN/FR/DE/ES, pagine pubbliche squadre e UX archivio.
Il selettore lingua funziona sul web e sulle app native; su Android la preferenza è persistita e applicata al riavvio. Incluse anche eliminazione replay a scope e campi pagina pubblica squadra. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe LocaleResolver do
|
||||
describe ".normalize" do
|
||||
it "accetta lingue supportate" do
|
||||
expect(described_class.normalize("en")).to eq(:en)
|
||||
expect(described_class.normalize("fr-FR")).to eq(:fr)
|
||||
expect(described_class.normalize("de_DE")).to eq(:de)
|
||||
end
|
||||
|
||||
it "rifiuta lingue non supportate" do
|
||||
expect(described_class.normalize("pt")).to be_nil
|
||||
expect(described_class.normalize("")).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
describe ".from_accept_language" do
|
||||
it "prende la prima lingua supportata" do
|
||||
expect(described_class.from_accept_language("fr-FR,fr;q=0.9,en;q=0.8")).to eq(:fr)
|
||||
expect(described_class.from_accept_language("pt-BR,en-US;q=0.8")).to eq(:en)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -16,15 +16,21 @@ RSpec.describe Recordings::Delete do
|
||||
privacy_status: "public",
|
||||
expires_at: 10.days.from_now,
|
||||
storage_key: "teams/#{team.id}/sessions/#{session.id}/replay.mp4",
|
||||
youtube_video_id: "abc123xyz"
|
||||
youtube_video_id: "abc123xyz",
|
||||
youtube_published_at: Time.current
|
||||
)
|
||||
end
|
||||
|
||||
it "elimina storage e revoca youtube_video_id" do
|
||||
def stub_delete_deps
|
||||
storage = instance_double(Recordings::Storage, delete: true)
|
||||
allow(Recordings::Storage).to receive(:new).and_return(storage)
|
||||
yt = instance_double(Youtube::VideoLifecycleService, delete!: true)
|
||||
allow(Youtube::VideoLifecycleService).to receive(:new).with(recording).and_return(yt)
|
||||
[storage, yt]
|
||||
end
|
||||
|
||||
it "elimina storage e YouTube (scope both)" do
|
||||
storage, yt = stub_delete_deps
|
||||
|
||||
described_class.new(recording).call
|
||||
|
||||
@@ -35,4 +41,32 @@ RSpec.describe Recordings::Delete do
|
||||
expect(recording.youtube_video_id).to be_nil
|
||||
expect(recording.storage_key).to be_nil
|
||||
end
|
||||
|
||||
it "elimina solo dal sito lasciando YouTube" do
|
||||
storage, yt = stub_delete_deps
|
||||
|
||||
described_class.new(recording, scope: :site).call
|
||||
|
||||
expect(yt).not_to have_received(:delete!)
|
||||
expect(storage).to have_received(:delete).at_least(:once)
|
||||
recording.reload
|
||||
expect(recording.deleted_at).to be_present
|
||||
expect(recording.storage_key).to be_nil
|
||||
expect(recording.youtube_video_id).to eq("abc123xyz")
|
||||
end
|
||||
|
||||
it "elimina solo da YouTube lasciando il replay sul sito" do
|
||||
storage, yt = stub_delete_deps
|
||||
|
||||
described_class.new(recording, scope: :youtube).call
|
||||
|
||||
expect(yt).to have_received(:delete!)
|
||||
expect(storage).not_to have_received(:delete)
|
||||
recording.reload
|
||||
expect(recording.deleted_at).to be_nil
|
||||
expect(recording.status).to eq("ready")
|
||||
expect(recording.storage_key).to be_present
|
||||
expect(recording.youtube_video_id).to be_nil
|
||||
expect(recording.youtube_published_at).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe Teams::GenerateSlug do
|
||||
let(:club) { Club.create!(name: "Test Club", sport: "volleyball", primary_color: "#e53935", secondary_color: "#ffffff") }
|
||||
|
||||
it "genera uno slug dal nome" do
|
||||
team = club.teams.build(name: "Crazy Volley U17B", sport_key: "pallavolo")
|
||||
expect(described_class.call(team)).to eq("crazy-volley-u17b")
|
||||
end
|
||||
|
||||
it "aggiunge un suffisso se lo slug esiste già" do
|
||||
club.teams.create!(name: "Tigers", sport_key: "pallavolo")
|
||||
team = club.teams.build(name: "Tigers", sport_key: "pallavolo")
|
||||
expect(described_class.call(team)).to eq("tigers-2")
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,84 @@
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe Teams::PublicDirectory do
|
||||
let(:user) { User.create!(email: "dir-#{SecureRandom.hex(4)}@test.com", name: "Dir", password: "password123", role: "coach") }
|
||||
let(:club) { Club.create!(name: "ASD Directory #{SecureRandom.hex(3)}", sport: "volleyball", primary_color: "#e53935", secondary_color: "#ffffff") }
|
||||
let!(:team_live) { club.teams.create!(name: "Live Team", sport_key: "pallavolo") }
|
||||
let!(:team_replay) { club.teams.create!(name: "Replay Team", sport_key: "basket") }
|
||||
let!(:team_upcoming) { club.teams.create!(name: "Future Team", sport_key: "pallavolo") }
|
||||
let!(:team_empty) { club.teams.create!(name: "Empty Team", sport_key: "pallavolo") }
|
||||
|
||||
before do
|
||||
club.club_memberships.create!(user: user, role: "owner")
|
||||
Billing::AssignPlan.call(club: club, plan_slug: "premium_full")
|
||||
|
||||
live_match = team_live.matches.create!(opponent_name: "Rival A", sport_key: "pallavolo", scheduled_at: 1.hour.from_now)
|
||||
StreamSession.create!(
|
||||
match: live_match, user: user, status: "live", platform: "matchlivetv",
|
||||
privacy_status: "public", publish_token: "tok-live", started_at: Time.current
|
||||
)
|
||||
|
||||
replay_match = team_replay.matches.create!(opponent_name: "Rival B", sport_key: "basket")
|
||||
replay_session = StreamSession.create!(
|
||||
match: replay_match, user: user, status: "ended", platform: "matchlivetv",
|
||||
privacy_status: "public", publish_token: "tok-replay", started_at: 2.days.ago, ended_at: 1.day.ago
|
||||
)
|
||||
team_replay.recordings.create!(
|
||||
stream_session: replay_session,
|
||||
team: team_replay,
|
||||
status: "ready",
|
||||
privacy_status: "public",
|
||||
storage_backend: "local",
|
||||
storage_key: "teams/#{team_replay.id}/test.mp4",
|
||||
recorded_at: 1.day.ago
|
||||
)
|
||||
|
||||
team_upcoming.matches.create!(
|
||||
opponent_name: "Rival C",
|
||||
sport_key: "pallavolo",
|
||||
scheduled_at: 2.days.from_now,
|
||||
location: "VenueUnique42"
|
||||
)
|
||||
end
|
||||
|
||||
it "include solo squadre con presenza pubblica" do
|
||||
ids = club_entries.map { |e| e.team.id }
|
||||
|
||||
expect(ids).to include(team_live.id, team_replay.id, team_upcoming.id)
|
||||
expect(ids).not_to include(team_empty.id)
|
||||
end
|
||||
|
||||
it "filtra per sport" do
|
||||
ids = club_entries(sport: "basket").map { |e| e.team.id }
|
||||
|
||||
expect(ids).to contain_exactly(team_replay.id)
|
||||
end
|
||||
|
||||
it "filtra per testo libero" do
|
||||
ids = club_entries(q: "VenueUnique42").map { |e| e.team.id }
|
||||
|
||||
expect(ids).to contain_exactly(team_upcoming.id)
|
||||
end
|
||||
|
||||
it "filtra per diretta in corso" do
|
||||
ids = club_entries(live: true).map { |e| e.team.id }
|
||||
|
||||
expect(ids).to contain_exactly(team_live.id)
|
||||
end
|
||||
|
||||
it "filtra per replay" do
|
||||
ids = club_entries(replays: true).map { |e| e.team.id }
|
||||
|
||||
expect(ids).to contain_exactly(team_replay.id)
|
||||
end
|
||||
|
||||
it "ordina le dirette per prime" do
|
||||
slugs = club_entries.map { |e| e.team.slug }
|
||||
|
||||
expect(slugs.first).to eq(team_live.slug)
|
||||
end
|
||||
|
||||
def club_entries(**params)
|
||||
described_class.call(**params).select { |e| e.team.club_id == club.id }
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user