diff --git a/app/helpers/event_groups_helper.rb b/app/helpers/event_groups_helper.rb
index 554721ade..bcaa14a98 100644
--- a/app/helpers/event_groups_helper.rb
+++ b/app/helpers/event_groups_helper.rb
@@ -30,12 +30,18 @@ def button_to_event_group_make_public(view_object)
end
def button_to_event_group_make_private(view_object)
+ sentences = [t("event_groups.setup.make_private_confirm", event_group_name: view_object.event_group_name)]
+ if view_object.events.any?(&:use_for_projections?)
+ sentences << t("event_groups.setup.make_private_projections_addendum")
+ end
+ sentences << t("event_groups.setup.confirm_proceed")
+ confirm = sentences.join(" ")
+
button_to "Take Private",
organization_event_group_path(view_object.organization, view_object.event_group,
event_group: { concealed: true }),
method: :patch,
- data: { turbo_confirm: t("event_groups.setup.make_private_confirm",
- event_group_name: view_object.event_group_name) },
+ data: { turbo_confirm: confirm },
class: "btn btn-outline-success"
end
diff --git a/app/views/event_groups/_projections_warning.html.erb b/app/views/event_groups/_projections_warning.html.erb
new file mode 100644
index 000000000..cf7238638
--- /dev/null
+++ b/app/views/event_groups/_projections_warning.html.erb
@@ -0,0 +1,21 @@
+<%# locals: (presenter:) -%>
+
+<% projectable_events = presenter.event_group.concealed? ? presenter.events.select(&:use_for_projections?) : [] %>
+<% if projectable_events.present? %>
+
+<% end %>
diff --git a/app/views/event_groups/_setup_summary_status.html.erb b/app/views/event_groups/_setup_summary_status.html.erb
index d7fc29b3e..93b21db40 100644
--- a/app/views/event_groups/_setup_summary_status.html.erb
+++ b/app/views/event_groups/_setup_summary_status.html.erb
@@ -23,6 +23,8 @@
<% end %>
+ <%= render "projections_warning", presenter: presenter %>
+
+ <%= render "projections_warning", presenter: @presenter %>
+
<%= render "event_overview_cards", presenter: @presenter %>
diff --git a/app/views/events/_form.html.erb b/app/views/events/_form.html.erb
index 1aacc8fac..2e596609d 100644
--- a/app/views/events/_form.html.erb
+++ b/app/views/events/_form.html.erb
@@ -206,6 +206,15 @@
data-bs-placement="bottom"
data-bs-original-title="When checked, this event's split times help power pacing plans and live projections for events on this course, even if this event is not public. Uncheck if this event's times are unreliable (for example, unrealistic test data or serious timing problems) and should not influence predictions.">
<%= form.check_box :use_for_projections %>
+ <% if presenter.event_group.concealed? %>
+
+
+ This Event Group is private, but this Event's times will still feed pacing plans
+ and projections for its Course while the box above is checked. If this Event
+ contains (or is expected to contain) test data or unrealistic times, uncheck the box.
+
+
+ <% end %>
diff --git a/config/locales/views.en.yml b/config/locales/views.en.yml
index 08d0628ee..2d692bb8d 100644
--- a/config/locales/views.en.yml
+++ b/config/locales/views.en.yml
@@ -32,12 +32,16 @@ en:
enable_live_confirm: "NOTE: This will enable live entry actions for %{event_group_name}, and will also enable live follower notifications by email and SMS text when new times are added. Are you sure you want to proceed?"
disable_live_confirm: "NOTE: This will suspend all live entry actions for %{event_group_name}, including any that may be in process, and will disable live follower notifications by email and SMS text when new times are added. Are you sure you want to proceed?"
make_public_confirm: "NOTE: This will make %{event_group_name} visible to the public, including all related entrants. Are you sure you want to proceed?"
- make_private_confirm: "NOTE: This will conceal %{event_group_name} from the public, including all related entrants. Are you sure you want to proceed?"
+ make_private_confirm: "NOTE: This will conceal %{event_group_name} from the public, including all related entrants."
+ make_private_projections_addendum: "Even while private, this group's Events will continue to feed pacing plans and projections for their Courses unless you uncheck \"Use this event's times for projections\" on each Event."
+ confirm_proceed: "Are you sure you want to proceed?"
group_is_public_main: "Congratulations, your Event Group is public!"
group_is_public_detail: "Results and Follow pages are now available for your entrants to view."
group_is_private_main: "Your Event Group is still private"
group_is_private_detail: "Once your Events and Courses are ready and you have Entrants loaded, click the \"Go Public\" button to make your Event Group visible to the public."
+ projections_warning_main: "This private group's times feed projections"
+ projections_warning_detail: "This Event Group is not public, but times from the Events listed here will still feed pacing plans and projections for their Courses. That is usually what you want for real events being set up. If an Event contains test data or unrealistic times, uncheck \"Use this event's times for projections\" on that Event:"
group_is_live_main: "Your Event Group is available for Live Entry"
group_is_live_detail: "You can now access the Live Entry view and use OST Remote and RaceResult RFID integration to record times."
diff --git a/spec/helpers/event_groups_helper_spec.rb b/spec/helpers/event_groups_helper_spec.rb
new file mode 100644
index 000000000..1c010e013
--- /dev/null
+++ b/spec/helpers/event_groups_helper_spec.rb
@@ -0,0 +1,32 @@
+require "rails_helper"
+
+RSpec.describe EventGroupsHelper do
+ describe "#button_to_event_group_make_private" do
+ subject(:html) { helper.button_to_event_group_make_private(view_object) }
+
+ let(:event_group) { event_groups(:sum) }
+ let(:view_object) do
+ instance_double(EventGroupSetupPresenter,
+ organization: event_group.organization,
+ event_group: event_group,
+ event_group_name: event_group.name,
+ events: event_group.events.to_a)
+ end
+
+ context "when any event feeds projections" do
+ it "includes the projections addendum before the confirmation question" do
+ expect(html).to include("continue to feed pacing plans")
+ expect(html).to include("Are you sure you want to proceed?")
+ end
+ end
+
+ context "when no events feed projections" do
+ before { event_group.events.each { |event| event.update_column(:use_for_projections, false) } }
+
+ it "omits the projections addendum" do
+ expect(html).not_to include("continue to feed pacing plans")
+ expect(html).to include("Are you sure you want to proceed?")
+ end
+ end
+ end
+end
diff --git a/spec/system/event_group_construction/concealed_projections_warning_spec.rb b/spec/system/event_group_construction/concealed_projections_warning_spec.rb
new file mode 100644
index 000000000..a967eec8f
--- /dev/null
+++ b/spec/system/event_group_construction/concealed_projections_warning_spec.rb
@@ -0,0 +1,78 @@
+require "rails_helper"
+
+RSpec.describe "warnings when a concealed event group feeds projections", :js, type: :system do
+ let(:admin) { users(:admin_user) }
+ let(:event_group) { event_groups(:sum) }
+ let(:event) { event_group.events.first }
+
+ before { login_as admin, scope: :user }
+
+ describe "the event group setup page" do
+ context "when the event group is concealed and its events feed projections" do
+ before { event_group.update_column(:concealed, true) }
+
+ scenario "shows the warning with links to the events" do
+ visit setup_event_group_path(event_group)
+
+ expect(page).to have_content("This private group's times feed projections")
+ expect(page).to have_link(event.guaranteed_short_name, href: edit_event_group_event_path(event_group, event))
+ end
+ end
+
+ context "when the event group is visible" do
+ scenario "does not show the warning" do
+ visit setup_event_group_path(event_group)
+
+ expect(page).to have_content(event_group.name)
+ expect(page).not_to have_content("This private group's times feed projections")
+ end
+ end
+
+ context "when the event group is concealed but no events feed projections" do
+ before do
+ event_group.update_column(:concealed, true)
+ event_group.events.each { |e| e.update_column(:use_for_projections, false) }
+ end
+
+ scenario "does not show the warning" do
+ visit setup_event_group_path(event_group)
+
+ expect(page).to have_content(event_group.name)
+ expect(page).not_to have_content("This private group's times feed projections")
+ end
+ end
+ end
+
+ describe "the setup summary page" do
+ context "when the event group is concealed and its events feed projections" do
+ before { event_group.update_column(:concealed, true) }
+
+ scenario "shows the warning" do
+ visit setup_summary_event_group_path(event_group)
+
+ expect(page).to have_content("This private group's times feed projections")
+ end
+ end
+ end
+
+ describe "the edit event page" do
+ context "when the event group is concealed" do
+ before { event_group.update_column(:concealed, true) }
+
+ scenario "shows the inline projections warning" do
+ visit edit_event_group_event_path(event_group, event)
+
+ expect(page).to have_content("This Event Group is private, but this Event's times will still feed")
+ end
+ end
+
+ context "when the event group is visible" do
+ scenario "does not show the inline projections warning" do
+ visit edit_event_group_event_path(event_group, event)
+
+ expect(page).to have_content("Use this event's times for projections")
+ expect(page).not_to have_content("this Event's times will still feed")
+ end
+ end
+ end
+end