diff --git a/app/lib/batch_submissions_selector.rb b/app/lib/batch_submissions_selector.rb index 99efa7268..6e045b87d 100644 --- a/app/lib/batch_submissions_selector.rb +++ b/app/lib/batch_submissions_selector.rb @@ -1,15 +1,26 @@ class BatchSubmissionsSelector Batch = Data.define(:form_id, :mode, :submissions) + # TODO: we can remove checking the send_daily_submission_batch and send_weekly_submission_batch in September 2026 + # when all Submissions without delivery_configurations on the form document have been deleted. + DAILY_BATCH_FORM_DOCUMENT_CONDITION = <<~SQL.squish + (form_document->>'send_daily_submission_batch')::boolean = true + OR form_document->'delivery_configurations' @> '[{"delivery_schedule":"daily"}]'::jsonb + SQL + WEEKLY_BATCH_FORM_DOCUMENT_CONDITION = <<~SQL.squish + (form_document->>'send_weekly_submission_batch')::boolean = true + OR form_document->'delivery_configurations' @> '[{"delivery_schedule":"weekly"}]'::jsonb + SQL + class << self def daily_batches(date) Enumerator.new do |yielder| form_ids_and_modes_with_send_daily_submission_batch(date).each do |form_id, mode| submissions = Submission.for_form_and_mode(form_id, mode).on_day(date).order(created_at: :desc) - # If the send_daily_submission_batch is true for the most recent submission, include all submissions on that - # day in the batch. If it is false do not return a batch for any of the submissions on that day. - next unless submissions.any? && submissions.first.form_document["send_daily_submission_batch"] == true + # If the most recent submission is configured for daily batching, include all submissions on that day in the + # batch. If it is not, do not return a batch for any of the submissions on that day. + next unless submissions.any? && batch_enabled_for_daily_submission?(submissions.first.form_document) yielder << Batch.new(form_id, mode, submissions) end @@ -21,9 +32,9 @@ def weekly_batches(time_in_week) form_ids_and_modes_with_send_weekly_submission_batch(time_in_week).each do |form_id, mode| submissions = Submission.for_form_and_mode(form_id, mode).in_week(time_in_week).order(created_at: :desc) - # If the send_weekly_submission_batch is true for the most recent submission, include all submissions in that - # week in the batch. If it is false do not return a batch for any of the submissions in that week. - next unless submissions.any? && submissions.first.form_document["send_weekly_submission_batch"] == true + # If the most recent submission is configured for weekly batching, include all submissions in that week in + # the batch. If it is not, do not return a batch for any of the submissions in that week. + next unless submissions.any? && batch_enabled_for_weekly_submission?(submissions.first.form_document) yielder << Batch.new(form_id, mode, submissions) end @@ -33,21 +44,37 @@ def weekly_batches(time_in_week) private def form_ids_and_modes_with_send_daily_submission_batch(date) - # Get all form_ids and modes that have at least one submission on the date with send_daily_submission_batch - # set to true. + # Get all form_ids and modes that have at least one submission on the date with daily batches enabled Submission.on_day(date) - .where("(form_document->>'send_daily_submission_batch')::boolean = true") + .where(DAILY_BATCH_FORM_DOCUMENT_CONDITION) .distinct .pluck(:form_id, :mode) end def form_ids_and_modes_with_send_weekly_submission_batch(begin_at) - # Get all form_ids and modes that have at least one submission in the week with send_weekly_submission_batch - # set to true. + # Get all form_ids and modes that have at least one submission in the week with weekly batches enabled Submission.in_week(begin_at) - .where("(form_document->>'send_weekly_submission_batch')::boolean = true") + .where(WEEKLY_BATCH_FORM_DOCUMENT_CONDITION) .distinct .pluck(:form_id, :mode) end + + def batch_enabled_for_daily_submission?(form_document) + form_document["send_daily_submission_batch"] == true || + daily_delivery_configuration?(form_document) + end + + def batch_enabled_for_weekly_submission?(form_document) + form_document["send_weekly_submission_batch"] == true || + weekly_delivery_configuration?(form_document) + end + + def daily_delivery_configuration?(form_document) + form_document["delivery_configurations"]&.any? { |configuration| configuration["delivery_schedule"] == "daily" } + end + + def weekly_delivery_configuration?(form_document) + form_document["delivery_configurations"]&.any? { |configuration| configuration["delivery_schedule"] == "weekly" } + end end end diff --git a/spec/lib/batch_submissions_selector_spec.rb b/spec/lib/batch_submissions_selector_spec.rb index 979a18874..e7b3ee19f 100644 --- a/spec/lib/batch_submissions_selector_spec.rb +++ b/spec/lib/batch_submissions_selector_spec.rb @@ -7,119 +7,240 @@ subject(:daily_batches) { described_class.daily_batches(date) } let(:date) { Time.zone.local(2022, 12, 1) } - let(:form_document_with_batch_enabled) { build(:v2_form_document, send_daily_submission_batch: true) } - let(:form_document_with_batch_disabled) { build(:v2_form_document, send_daily_submission_batch: false) } - it "returns an enumerator" do - expect(daily_batches).to be_an(Enumerator) - end - - context "when send_daily_submission_batch is enabled for the form document" do - context "when the date is during BST" do - let(:date) { Time.zone.local(2022, 6, 1) } - - let!(:form_submission) do - create(:submission, form_id: form_id, mode: "form", reference: "INCLUDED1", created_at: Time.utc(2022, 5, 31, 23, 0, 0), form_document: form_document_with_batch_enabled) - end - let!(:preview_draft_submission) do - create(:submission, form_id: form_id, mode: "preview-draft", reference: "INCLUDED2", created_at: Time.utc(2022, 6, 1, 22, 59, 59), form_document: form_document_with_batch_enabled) + context "when the form document does not have delivery_configurations (Backwards compatibility)" do + let(:form_document_with_batch_enabled) { build(:v2_form_document, send_daily_submission_batch: true) } + let(:form_document_with_batch_disabled) { build(:v2_form_document, send_daily_submission_batch: false) } + + context "when send_daily_submission_batch is enabled for the form document" do + context "when the date is during BST" do + let(:date) { Time.zone.local(2022, 6, 1) } + + let!(:form_submission) do + create(:submission, form_id: form_id, mode: "form", reference: "INCLUDED1", created_at: Time.utc(2022, 5, 31, 23, 0, 0), form_document: form_document_with_batch_enabled) + end + let!(:preview_draft_submission) do + create(:submission, form_id: form_id, mode: "preview-draft", reference: "INCLUDED2", created_at: Time.utc(2022, 6, 1, 22, 59, 59), form_document: form_document_with_batch_enabled) + end + + before do + # create form/mode combinations that only have submissions outside the BST day + create(:submission, form_id: form_id, mode: "preview-archived", reference: "OMITTED1", created_at: Time.utc(2022, 5, 31, 22, 59, 59), form_document: form_document_with_batch_enabled) + create(:submission, form_id: 102, mode: "form", reference: "OMITTED2", created_at: Time.utc(2022, 6, 1, 23, 0, 0), form_document: form_document_with_batch_enabled) + + # create submissions for the form/mode included in a batch outside the BST day to ensure they are excluded + create(:submission, form_id: form_id, mode: "form", reference: "OMITTED3", created_at: Time.utc(2022, 5, 31, 22, 59, 59), form_document: form_document_with_batch_enabled) + create(:submission, form_id: form_id, mode: "form", reference: "OMITTED4", created_at: Time.utc(2022, 6, 1, 23, 0, 0), form_document: form_document_with_batch_enabled) + end + + it "includes only forms/modes with submissions on the date" do + expect(daily_batches.map(&:to_h)).to contain_exactly( + a_hash_including(form_id: form_id, mode: "form"), + a_hash_including(form_id: form_id, mode: "preview-draft"), + ) + end + + it "includes only submissions on the day in the batches" do + expect(daily_batches.to_a[0].submissions.pluck(:reference)).to contain_exactly(form_submission.reference) + expect(daily_batches.to_a[1].submissions.pluck(:reference)).to contain_exactly(preview_draft_submission.reference) + end end - before do - # create form/mode combinations that only have submissions outside the BST day - create(:submission, form_id: form_id, mode: "preview-archived", reference: "OMITTED1", created_at: Time.utc(2022, 5, 31, 22, 59, 59), form_document: form_document_with_batch_enabled) - create(:submission, form_id: 102, mode: "form", reference: "OMITTED2", created_at: Time.utc(2022, 6, 1, 23, 0, 0), form_document: form_document_with_batch_enabled) + context "when the date is not in BST" do + let(:date) { Time.zone.local(2022, 12, 1) } + + let!(:form_submission) do + create(:submission, form_id: form_id, mode: "form", reference: "INCLUDED1", created_at: Time.utc(2022, 12, 1, 0, 0, 0), form_document: form_document_with_batch_enabled) + end + let!(:preview_draft_submission) do + create(:submission, form_id: form_id, mode: "preview-draft", reference: "INCLUDED2", created_at: Time.utc(2022, 12, 1, 23, 59, 59), form_document: form_document_with_batch_enabled) + end + + before do + # create form/mode combinations that only have submissions outside the day + create(:submission, form_id: form_id, mode: "preview-archived", reference: "OMITTED1", created_at: Time.utc(2022, 11, 30, 23, 59, 59), form_document: form_document_with_batch_enabled) + create(:submission, form_id: 102, mode: "form", reference: "OMITTED2", created_at: Time.utc(2022, 12, 2, 0, 0, 0), form_document: form_document_with_batch_enabled) + + # create submissions for the form/mode included in a batch outside the day to ensure they are excluded + create(:submission, form_id: form_id, mode: "form", reference: "OMITTED3", created_at: Time.utc(2022, 11, 30, 23, 59, 59), form_document: form_document_with_batch_enabled) + create(:submission, form_id: form_id, mode: "form", reference: "OMITTED4", created_at: Time.utc(2022, 12, 2, 0, 0, 0), form_document: form_document_with_batch_enabled) + end + + it "includes only forms/modes with submissions on the date" do + expect(daily_batches.map(&:to_h)).to contain_exactly( + a_hash_including(form_id: form_id, mode: "form"), + a_hash_including(form_id: form_id, mode: "preview-draft"), + ) + end + + it "includes only submissions on the day in the batches" do + expect(daily_batches.to_a[0].submissions.pluck(:reference)).to contain_exactly(form_submission.reference) + expect(daily_batches.to_a[1].submissions.pluck(:reference)).to contain_exactly(preview_draft_submission.reference) + end + end + end - # create submissions for the form/mode included in a batch outside the BST day to ensure they are excluded - create(:submission, form_id: form_id, mode: "form", reference: "OMITTED3", created_at: Time.utc(2022, 5, 31, 22, 59, 59), form_document: form_document_with_batch_enabled) - create(:submission, form_id: form_id, mode: "form", reference: "OMITTED4", created_at: Time.utc(2022, 6, 1, 23, 0, 0), form_document: form_document_with_batch_enabled) + context "when send_daily_submission_batch is enabled part-way through the day for the form document" do + let!(:latest_submission) do + create(:submission, form_id: form_id, mode: "form", reference: "INCLUDED1", created_at: Time.utc(2022, 12, 1, 10, 0, 0), form_document: form_document_with_batch_enabled) + end + let!(:earlier_submission) do + create(:submission, form_id: form_id, mode: "form", reference: "INCLUDED2", created_at: Time.utc(2022, 12, 1, 9, 0, 0), form_document: form_document_with_batch_disabled) end - it "includes only forms/modes with submissions on the date" do + it "includes a batch for the form and mode" do expect(daily_batches.map(&:to_h)).to contain_exactly( a_hash_including(form_id: form_id, mode: "form"), - a_hash_including(form_id: form_id, mode: "preview-draft"), ) end - it "includes only submissions on the day in the batches" do - expect(daily_batches.to_a[0].submissions.pluck(:reference)).to contain_exactly(form_submission.reference) - expect(daily_batches.to_a[1].submissions.pluck(:reference)).to contain_exactly(preview_draft_submission.reference) + it "includes all the submissions in the batch" do + submissions = daily_batches.first.submissions + expect(submissions.pluck(:reference)).to contain_exactly(latest_submission.reference, earlier_submission.reference) end end - context "when the date is not in BST" do - let(:date) { Time.zone.local(2022, 12, 1) } - - let!(:form_submission) do - create(:submission, form_id: form_id, mode: "form", reference: "INCLUDED1", created_at: Time.utc(2022, 12, 1, 0, 0, 0), form_document: form_document_with_batch_enabled) - end - let!(:preview_draft_submission) do - create(:submission, form_id: form_id, mode: "preview-draft", reference: "INCLUDED2", created_at: Time.utc(2022, 12, 1, 23, 59, 59), form_document: form_document_with_batch_enabled) - end - + context "when send_daily_submission_batch is disabled for the form document" do before do - # create form/mode combinations that only have submissions outside the day - create(:submission, form_id: form_id, mode: "preview-archived", reference: "OMITTED1", created_at: Time.utc(2022, 11, 30, 23, 59, 59), form_document: form_document_with_batch_enabled) - create(:submission, form_id: 102, mode: "form", reference: "OMITTED2", created_at: Time.utc(2022, 12, 2, 0, 0, 0), form_document: form_document_with_batch_enabled) + create(:submission, form_id: form_id, mode: "form", created_at: Time.utc(2022, 12, 1, 10, 0, 0), form_document: form_document_with_batch_disabled) + end - # create submissions for the form/mode included in a batch outside the day to ensure they are excluded - create(:submission, form_id: form_id, mode: "form", reference: "OMITTED3", created_at: Time.utc(2022, 11, 30, 23, 59, 59), form_document: form_document_with_batch_enabled) - create(:submission, form_id: form_id, mode: "form", reference: "OMITTED4", created_at: Time.utc(2022, 12, 2, 0, 0, 0), form_document: form_document_with_batch_enabled) + it "does not include a batch for the form and mode" do + expect(daily_batches.to_a).to be_empty end + end - it "includes only forms/modes with submissions on the date" do - expect(daily_batches.map(&:to_h)).to contain_exactly( - a_hash_including(form_id: form_id, mode: "form"), - a_hash_including(form_id: form_id, mode: "preview-draft"), - ) + context "when send_daily_submission_batch is disabled part-way through the day for the form document" do + before do + create(:submission, form_id: form_id, mode: "form", created_at: Time.utc(2022, 12, 1, 10, 0, 0), form_document: form_document_with_batch_disabled) + create(:submission, form_id: form_id, mode: "form", created_at: Time.utc(2022, 12, 1, 9, 0, 0), form_document: form_document_with_batch_enabled) end - it "includes only submissions on the day in the batches" do - expect(daily_batches.to_a[0].submissions.pluck(:reference)).to contain_exactly(form_submission.reference) - expect(daily_batches.to_a[1].submissions.pluck(:reference)).to contain_exactly(preview_draft_submission.reference) + it "does not include a batch for the form and mode" do + expect(daily_batches.to_a).to be_empty end end end - context "when send_daily_submission_batch is enabled part-way through the day for the form document" do - let!(:latest_submission) do - create(:submission, form_id: form_id, mode: "form", reference: "INCLUDED1", created_at: Time.utc(2022, 12, 1, 10, 0, 0), form_document: form_document_with_batch_enabled) + context "when the form document has delivery_configurations" do + let(:form_document_with_batch_enabled) do + build(:v2_form_document, send_daily_submission_batch: false, delivery_configurations: [ + build(:v2_delivery_configuration, :daily_email), + ]) end - let!(:earlier_submission) do - create(:submission, form_id: form_id, mode: "form", reference: "INCLUDED2", created_at: Time.utc(2022, 12, 1, 9, 0, 0), form_document: form_document_with_batch_disabled) + let(:form_document_with_batch_disabled) do + build(:v2_form_document, send_daily_submission_batch: false, delivery_configurations: [ + build(:v2_delivery_configuration, :immediate_email), + ]) end - it "includes a batch for the form and mode" do - expect(daily_batches.map(&:to_h)).to contain_exactly( - a_hash_including(form_id: form_id, mode: "form"), - ) - end + context "when the form document has a daily delivery_configuration" do + context "when the date is during BST" do + let(:date) { Time.zone.local(2022, 6, 1) } + + let!(:form_submission) do + create(:submission, form_id: form_id, mode: "form", reference: "INCLUDED1", created_at: Time.utc(2022, 5, 31, 23, 0, 0), form_document: form_document_with_batch_enabled) + end + let!(:preview_draft_submission) do + create(:submission, form_id: form_id, mode: "preview-draft", reference: "INCLUDED2", created_at: Time.utc(2022, 6, 1, 22, 59, 59), form_document: form_document_with_batch_enabled) + end + + before do + # create form/mode combinations that only have submissions outside the BST day + create(:submission, form_id: form_id, mode: "preview-archived", reference: "OMITTED1", created_at: Time.utc(2022, 5, 31, 22, 59, 59), form_document: form_document_with_batch_enabled) + create(:submission, form_id: 102, mode: "form", reference: "OMITTED2", created_at: Time.utc(2022, 6, 1, 23, 0, 0), form_document: form_document_with_batch_enabled) + + # create submissions for the form/mode included in a batch outside the BST day to ensure they are excluded + create(:submission, form_id: form_id, mode: "form", reference: "OMITTED3", created_at: Time.utc(2022, 5, 31, 22, 59, 59), form_document: form_document_with_batch_enabled) + create(:submission, form_id: form_id, mode: "form", reference: "OMITTED4", created_at: Time.utc(2022, 6, 1, 23, 0, 0), form_document: form_document_with_batch_enabled) + end + + it "includes only forms/modes with submissions on the date" do + expect(daily_batches.map(&:to_h)).to contain_exactly( + a_hash_including(form_id: form_id, mode: "form"), + a_hash_including(form_id: form_id, mode: "preview-draft"), + ) + end + + it "includes only submissions on the day in the batches" do + expect(daily_batches.to_a[0].submissions.pluck(:reference)).to contain_exactly(form_submission.reference) + expect(daily_batches.to_a[1].submissions.pluck(:reference)).to contain_exactly(preview_draft_submission.reference) + end + end - it "includes all the submissions in the batch" do - submissions = daily_batches.first.submissions - expect(submissions.pluck(:reference)).to contain_exactly(latest_submission.reference, earlier_submission.reference) + context "when the date is not in BST" do + let(:date) { Time.zone.local(2022, 12, 1) } + + let!(:form_submission) do + create(:submission, form_id: form_id, mode: "form", reference: "INCLUDED1", created_at: Time.utc(2022, 12, 1, 0, 0, 0), form_document: form_document_with_batch_enabled) + end + let!(:preview_draft_submission) do + create(:submission, form_id: form_id, mode: "preview-draft", reference: "INCLUDED2", created_at: Time.utc(2022, 12, 1, 23, 59, 59), form_document: form_document_with_batch_enabled) + end + + before do + # create form/mode combinations that only have submissions outside the day + create(:submission, form_id: form_id, mode: "preview-archived", reference: "OMITTED1", created_at: Time.utc(2022, 11, 30, 23, 59, 59), form_document: form_document_with_batch_enabled) + create(:submission, form_id: 102, mode: "form", reference: "OMITTED2", created_at: Time.utc(2022, 12, 2, 0, 0, 0), form_document: form_document_with_batch_enabled) + + # create submissions for the form/mode included in a batch outside the day to ensure they are excluded + create(:submission, form_id: form_id, mode: "form", reference: "OMITTED3", created_at: Time.utc(2022, 11, 30, 23, 59, 59), form_document: form_document_with_batch_enabled) + create(:submission, form_id: form_id, mode: "form", reference: "OMITTED4", created_at: Time.utc(2022, 12, 2, 0, 0, 0), form_document: form_document_with_batch_enabled) + end + + it "includes only forms/modes with submissions on the date" do + expect(daily_batches.map(&:to_h)).to contain_exactly( + a_hash_including(form_id: form_id, mode: "form"), + a_hash_including(form_id: form_id, mode: "preview-draft"), + ) + end + + it "includes only submissions on the day in the batches" do + expect(daily_batches.to_a[0].submissions.pluck(:reference)).to contain_exactly(form_submission.reference) + expect(daily_batches.to_a[1].submissions.pluck(:reference)).to contain_exactly(preview_draft_submission.reference) + end + end end - end - context "when send_daily_submission_batch is disabled for the form document" do - before do - create(:submission, form_id: form_id, mode: "form", created_at: Time.utc(2022, 12, 1, 10, 0, 0), form_document: form_document_with_batch_disabled) - end + context "when a daily delivery_configuration is added part-way through the day for the form document" do + let!(:latest_submission) do + create(:submission, form_id: form_id, mode: "form", reference: "INCLUDED1", created_at: Time.utc(2022, 12, 1, 10, 0, 0), form_document: form_document_with_batch_enabled) + end + let!(:earlier_submission) do + create(:submission, form_id: form_id, mode: "form", reference: "INCLUDED2", created_at: Time.utc(2022, 12, 1, 9, 0, 0), form_document: form_document_with_batch_disabled) + end - it "does not include a batch for the form and mode" do - expect(daily_batches.to_a).to be_empty + it "includes a batch for the form and mode" do + expect(daily_batches.map(&:to_h)).to contain_exactly( + a_hash_including(form_id: form_id, mode: "form"), + ) + end + + it "includes all the submissions in the batch" do + submissions = daily_batches.first.submissions + expect(submissions.pluck(:reference)).to contain_exactly(latest_submission.reference, earlier_submission.reference) + end end - end - context "when send_daily_submission_batch is disabled part-way through the day for the form document" do - before do - create(:submission, form_id: form_id, mode: "form", created_at: Time.utc(2022, 12, 1, 10, 0, 0), form_document: form_document_with_batch_disabled) - create(:submission, form_id: form_id, mode: "form", created_at: Time.utc(2022, 12, 1, 9, 0, 0), form_document: form_document_with_batch_enabled) + context "when a daily delivery_configuration does not exist for the form document" do + before do + create(:submission, form_id: form_id, mode: "form", created_at: Time.utc(2022, 12, 1, 10, 0, 0), form_document: form_document_with_batch_disabled) + end + + it "does not include a batch for the form and mode" do + expect(daily_batches.to_a).to be_empty + end end - it "does not include a batch for the form and mode" do - expect(daily_batches.to_a).to be_empty + context "when a daily delivery_configuration is removed part-way through the day for the form document" do + before do + create(:submission, form_id: form_id, mode: "form", created_at: Time.utc(2022, 12, 1, 10, 0, 0), form_document: form_document_with_batch_disabled) + create(:submission, form_id: form_id, mode: "form", created_at: Time.utc(2022, 12, 1, 9, 0, 0), form_document: form_document_with_batch_enabled) + end + + it "does not include a batch for the form and mode" do + expect(daily_batches.to_a).to be_empty + end end end end @@ -128,125 +249,252 @@ subject(:weekly_batches) { described_class.weekly_batches(date) } let(:date) { Time.zone.local(2025, 5, 19) } - let(:form_document_with_batch_enabled) { build(:v2_form_document, send_weekly_submission_batch: true) } - let(:form_document_with_batch_disabled) { build(:v2_form_document, send_weekly_submission_batch: false) } - - it "returns an enumerator" do - expect(weekly_batches).to be_an(Enumerator) - end - - context "when send_weekly_submission_batch is enabled for the form document" do - context "when the week is during BST" do - let(:date) { Time.zone.local(2025, 5, 19) } - let!(:form_submission) do - create(:submission, form_id: form_id, mode: "form", reference: "INCLUDED1", created_at: Time.utc(2025, 5, 18, 23, 0, 0), form_document: form_document_with_batch_enabled) + context "when the form document does not have delivery_configurations (Backwards compatibility)" do + let(:form_document_with_batch_enabled) { build(:v2_form_document, send_weekly_submission_batch: true) } + let(:form_document_with_batch_disabled) { build(:v2_form_document, send_weekly_submission_batch: false) } + + context "when send_weekly_submission_batch is enabled for the form document" do + context "when the week is during BST" do + let(:date) { Time.zone.local(2025, 5, 19) } + + let!(:form_submission) do + create(:submission, form_id: form_id, mode: "form", reference: "INCLUDED1", created_at: Time.utc(2025, 5, 18, 23, 0, 0), form_document: form_document_with_batch_enabled) + end + let!(:preview_draft_submission) do + create(:submission, form_id: form_id, mode: "preview-draft", reference: "INCLUDED2", created_at: Time.utc(2025, 5, 25, 22, 59, 59), form_document: form_document_with_batch_enabled) + end + + before do + # create form/mode combinations that only have submissions outside the BST week + create(:submission, form_id: form_id, mode: "preview-archived", reference: "OMITTED1", created_at: Time.utc(2025, 5, 18, 22, 59, 59), form_document: form_document_with_batch_enabled) + create(:submission, form_id: 102, mode: "form", reference: "OMITTED2", created_at: Time.utc(2025, 5, 25, 23, 0, 0), form_document: form_document_with_batch_enabled) + + # create submissions for the form/mode included in a batch outside the BST week to ensure they are excluded + create(:submission, form_id: form_id, mode: "form", reference: "OMITTED3", created_at: Time.utc(2025, 5, 18, 22, 59, 59), form_document: form_document_with_batch_enabled) + create(:submission, form_id: form_id, mode: "form", reference: "OMITTED4", created_at: Time.utc(2025, 5, 25, 23, 0, 0), form_document: form_document_with_batch_enabled) + end + + it "includes only forms/modes with submissions in the week" do + expect(weekly_batches.map(&:to_h)).to contain_exactly( + a_hash_including(form_id: form_id, mode: "form"), + a_hash_including(form_id: form_id, mode: "preview-draft"), + ) + end + + it "includes only submissions in the week in the batches" do + expect(weekly_batches.to_a[0].submissions.pluck(:reference)).to contain_exactly(form_submission.reference) + expect(weekly_batches.to_a[1].submissions.pluck(:reference)).to contain_exactly(preview_draft_submission.reference) + end end - let!(:preview_draft_submission) do - create(:submission, form_id: form_id, mode: "preview-draft", reference: "INCLUDED2", created_at: Time.utc(2025, 5, 25, 22, 59, 59), form_document: form_document_with_batch_enabled) + + context "when the week is not in BST" do + let(:date) { Time.zone.local(2025, 11, 3) } + + let!(:form_submission) do + create(:submission, form_id: form_id, mode: "form", reference: "INCLUDED1", created_at: Time.utc(2025, 11, 3, 0, 0, 0), form_document: form_document_with_batch_enabled) + end + let!(:preview_draft_submission) do + create(:submission, form_id: form_id, mode: "preview-draft", reference: "INCLUDED2", created_at: Time.utc(2025, 11, 9, 23, 59, 59), form_document: form_document_with_batch_enabled) + end + + before do + # create form/mode combinations that only have submissions outside the week + create(:submission, form_id: form_id, mode: "preview-archived", reference: "OMITTED1", created_at: Time.utc(2025, 11, 2, 23, 59, 59), form_document: form_document_with_batch_enabled) + create(:submission, form_id: 102, mode: "form", reference: "OMITTED2", created_at: Time.utc(2025, 11, 10, 0, 0, 0), form_document: form_document_with_batch_enabled) + + # create submissions for the form/mode included in a batch outside the week to ensure they are excluded + create(:submission, form_id: form_id, mode: "form", reference: "OMITTED3", created_at: Time.utc(2025, 11, 2, 23, 59, 59), form_document: form_document_with_batch_enabled) + create(:submission, form_id: form_id, mode: "form", reference: "OMITTED4", created_at: Time.utc(2025, 11, 10, 0, 0, 0), form_document: form_document_with_batch_enabled) + end + + it "includes only forms/modes with submissions in the week" do + expect(weekly_batches.map(&:to_h)).to contain_exactly( + a_hash_including(form_id: form_id, mode: "form"), + a_hash_including(form_id: form_id, mode: "preview-draft"), + ) + end + + it "includes only submissions in the week in the batches" do + expect(weekly_batches.to_a[0].submissions.pluck(:reference)).to contain_exactly(form_submission.reference) + expect(weekly_batches.to_a[1].submissions.pluck(:reference)).to contain_exactly(preview_draft_submission.reference) + end end + end - before do - # create form/mode combinations that only have submissions outside the BST week - create(:submission, form_id: form_id, mode: "preview-archived", reference: "OMITTED1", created_at: Time.utc(2025, 5, 18, 22, 59, 59), form_document: form_document_with_batch_enabled) - create(:submission, form_id: 102, mode: "form", reference: "OMITTED2", created_at: Time.utc(2025, 5, 25, 23, 0, 0), form_document: form_document_with_batch_enabled) + context "when send_weekly_submission_batch is enabled part-way through the week for the form document" do + let(:date) { Time.zone.local(2025, 11, 3) } - # create submissions for the form/mode included in a batch outside the BST week to ensure they are excluded - create(:submission, form_id: form_id, mode: "form", reference: "OMITTED3", created_at: Time.utc(2025, 5, 18, 22, 59, 59), form_document: form_document_with_batch_enabled) - create(:submission, form_id: form_id, mode: "form", reference: "OMITTED4", created_at: Time.utc(2025, 5, 25, 23, 0, 0), form_document: form_document_with_batch_enabled) + let!(:latest_submission) do + create(:submission, form_id: form_id, mode: "form", reference: "INCLUDED1", created_at: Time.utc(2025, 11, 5, 0, 0, 0), form_document: form_document_with_batch_enabled) + end + let!(:earlier_submission) do + create(:submission, form_id: form_id, mode: "form", reference: "INCLUDED2", created_at: Time.utc(2025, 11, 4, 0, 0, 0), form_document: form_document_with_batch_disabled) end - it "includes only forms/modes with submissions in the week" do + it "includes a batch for the form and mode" do expect(weekly_batches.map(&:to_h)).to contain_exactly( a_hash_including(form_id: form_id, mode: "form"), - a_hash_including(form_id: form_id, mode: "preview-draft"), ) end - it "includes only submissions in the week in the batches" do - expect(weekly_batches.to_a[0].submissions.pluck(:reference)).to contain_exactly(form_submission.reference) - expect(weekly_batches.to_a[1].submissions.pluck(:reference)).to contain_exactly(preview_draft_submission.reference) + it "includes all the submissions in the batch" do + submissions = weekly_batches.first.submissions + expect(submissions.pluck(:reference)).to contain_exactly(latest_submission.reference, earlier_submission.reference) end end - context "when the week is not in BST" do + context "when send_weekly_submission_batch is disabled for the form document" do let(:date) { Time.zone.local(2025, 11, 3) } - let!(:form_submission) do - create(:submission, form_id: form_id, mode: "form", reference: "INCLUDED1", created_at: Time.utc(2025, 11, 3, 0, 0, 0), form_document: form_document_with_batch_enabled) - end - let!(:preview_draft_submission) do - create(:submission, form_id: form_id, mode: "preview-draft", reference: "INCLUDED2", created_at: Time.utc(2025, 11, 9, 23, 59, 59), form_document: form_document_with_batch_enabled) - end - before do - # create form/mode combinations that only have submissions outside the week - create(:submission, form_id: form_id, mode: "preview-archived", reference: "OMITTED1", created_at: Time.utc(2025, 11, 2, 23, 59, 59), form_document: form_document_with_batch_enabled) - create(:submission, form_id: 102, mode: "form", reference: "OMITTED2", created_at: Time.utc(2025, 11, 10, 0, 0, 0), form_document: form_document_with_batch_enabled) + create(:submission, form_id: form_id, mode: "form", created_at: Time.utc(2025, 11, 5, 10, 0, 0), form_document: form_document_with_batch_disabled) + end - # create submissions for the form/mode included in a batch outside the week to ensure they are excluded - create(:submission, form_id: form_id, mode: "form", reference: "OMITTED3", created_at: Time.utc(2025, 11, 2, 23, 59, 59), form_document: form_document_with_batch_enabled) - create(:submission, form_id: form_id, mode: "form", reference: "OMITTED4", created_at: Time.utc(2025, 11, 10, 0, 0, 0), form_document: form_document_with_batch_enabled) + it "does not include a batch for the form and mode" do + expect(weekly_batches.to_a).to be_empty end + end - it "includes only forms/modes with submissions in the week" do - expect(weekly_batches.map(&:to_h)).to contain_exactly( - a_hash_including(form_id: form_id, mode: "form"), - a_hash_including(form_id: form_id, mode: "preview-draft"), - ) + context "when send_weekly_submission_batch is disabled part-way through the week for the form document" do + let(:date) { Time.zone.local(2025, 11, 3) } + + before do + create(:submission, form_id: form_id, mode: "form", created_at: Time.utc(2025, 11, 5, 0, 0, 0), form_document: form_document_with_batch_disabled) + create(:submission, form_id: form_id, mode: "form", created_at: Time.utc(2025, 11, 4, 0, 0, 0), form_document: form_document_with_batch_enabled) end - it "includes only submissions in the week in the batches" do - expect(weekly_batches.to_a[0].submissions.pluck(:reference)).to contain_exactly(form_submission.reference) - expect(weekly_batches.to_a[1].submissions.pluck(:reference)).to contain_exactly(preview_draft_submission.reference) + it "does not include a batch for the form and mode" do + expect(weekly_batches.to_a).to be_empty end end end - context "when send_weekly_submission_batch is enabled part-way through the week for the form document" do - let(:date) { Time.zone.local(2025, 11, 3) } - - let!(:latest_submission) do - create(:submission, form_id: form_id, mode: "form", reference: "INCLUDED1", created_at: Time.utc(2025, 11, 5, 0, 0, 0), form_document: form_document_with_batch_enabled) + context "when the form document has delivery_configurations" do + let(:form_document_with_batch_enabled) do + build(:v2_form_document, send_weekly_submission_batch: false, delivery_configurations: [ + build(:v2_delivery_configuration, :weekly_email), + ]) end - let!(:earlier_submission) do - create(:submission, form_id: form_id, mode: "form", reference: "INCLUDED2", created_at: Time.utc(2025, 11, 4, 0, 0, 0), form_document: form_document_with_batch_disabled) + let(:form_document_with_batch_disabled) do + build(:v2_form_document, send_weekly_submission_batch: false, delivery_configurations: [ + build(:v2_delivery_configuration, :immediate_email), + ]) end - it "includes a batch for the form and mode" do - expect(weekly_batches.map(&:to_h)).to contain_exactly( - a_hash_including(form_id: form_id, mode: "form"), - ) - end + context "when the form document has a weekly delivery_configuration" do + context "when the week is during BST" do + let(:date) { Time.zone.local(2025, 5, 19) } + + let!(:form_submission) do + create(:submission, form_id: form_id, mode: "form", reference: "INCLUDED1", created_at: Time.utc(2025, 5, 18, 23, 0, 0), form_document: form_document_with_batch_enabled) + end + let!(:preview_draft_submission) do + create(:submission, form_id: form_id, mode: "preview-draft", reference: "INCLUDED2", created_at: Time.utc(2025, 5, 25, 22, 59, 59), form_document: form_document_with_batch_enabled) + end + + before do + # create form/mode combinations that only have submissions outside the BST week + create(:submission, form_id: form_id, mode: "preview-archived", reference: "OMITTED1", created_at: Time.utc(2025, 5, 18, 22, 59, 59), form_document: form_document_with_batch_enabled) + create(:submission, form_id: 102, mode: "form", reference: "OMITTED2", created_at: Time.utc(2025, 5, 25, 23, 0, 0), form_document: form_document_with_batch_enabled) + + # create submissions for the form/mode included in a batch outside the BST week to ensure they are excluded + create(:submission, form_id: form_id, mode: "form", reference: "OMITTED3", created_at: Time.utc(2025, 5, 18, 22, 59, 59), form_document: form_document_with_batch_enabled) + create(:submission, form_id: form_id, mode: "form", reference: "OMITTED4", created_at: Time.utc(2025, 5, 25, 23, 0, 0), form_document: form_document_with_batch_enabled) + end + + it "includes only forms/modes with submissions in the week" do + expect(weekly_batches.map(&:to_h)).to contain_exactly( + a_hash_including(form_id: form_id, mode: "form"), + a_hash_including(form_id: form_id, mode: "preview-draft"), + ) + end + + it "includes only submissions in the week in the batches" do + expect(weekly_batches.to_a[0].submissions.pluck(:reference)).to contain_exactly(form_submission.reference) + expect(weekly_batches.to_a[1].submissions.pluck(:reference)).to contain_exactly(preview_draft_submission.reference) + end + end - it "includes all the submissions in the batch" do - submissions = weekly_batches.first.submissions - expect(submissions.pluck(:reference)).to contain_exactly(latest_submission.reference, earlier_submission.reference) + context "when the week is not in BST" do + let(:date) { Time.zone.local(2025, 11, 3) } + + let!(:form_submission) do + create(:submission, form_id: form_id, mode: "form", reference: "INCLUDED1", created_at: Time.utc(2025, 11, 3, 0, 0, 0), form_document: form_document_with_batch_enabled) + end + let!(:preview_draft_submission) do + create(:submission, form_id: form_id, mode: "preview-draft", reference: "INCLUDED2", created_at: Time.utc(2025, 11, 9, 23, 59, 59), form_document: form_document_with_batch_enabled) + end + + before do + # create form/mode combinations that only have submissions outside the week + create(:submission, form_id: form_id, mode: "preview-archived", reference: "OMITTED1", created_at: Time.utc(2025, 11, 2, 23, 59, 59), form_document: form_document_with_batch_enabled) + create(:submission, form_id: 102, mode: "form", reference: "OMITTED2", created_at: Time.utc(2025, 11, 10, 0, 0, 0), form_document: form_document_with_batch_enabled) + + # create submissions for the form/mode included in a batch outside the week to ensure they are excluded + create(:submission, form_id: form_id, mode: "form", reference: "OMITTED3", created_at: Time.utc(2025, 11, 2, 23, 59, 59), form_document: form_document_with_batch_enabled) + create(:submission, form_id: form_id, mode: "form", reference: "OMITTED4", created_at: Time.utc(2025, 11, 10, 0, 0, 0), form_document: form_document_with_batch_enabled) + end + + it "includes only forms/modes with submissions in the week" do + expect(weekly_batches.map(&:to_h)).to contain_exactly( + a_hash_including(form_id: form_id, mode: "form"), + a_hash_including(form_id: form_id, mode: "preview-draft"), + ) + end + + it "includes only submissions in the week in the batches" do + expect(weekly_batches.to_a[0].submissions.pluck(:reference)).to contain_exactly(form_submission.reference) + expect(weekly_batches.to_a[1].submissions.pluck(:reference)).to contain_exactly(preview_draft_submission.reference) + end + end end - end - context "when send_weekly_submission_batch is disabled for the form document" do - let(:date) { Time.zone.local(2025, 11, 3) } + context "when a weekly delivery_configuration is added part-way through the day for the form document" do + let(:date) { Time.zone.local(2025, 11, 3) } - before do - create(:submission, form_id: form_id, mode: "form", created_at: Time.utc(2025, 11, 5, 10, 0, 0), form_document: form_document_with_batch_disabled) - end + let!(:latest_submission) do + create(:submission, form_id: form_id, mode: "form", reference: "INCLUDED1", created_at: Time.utc(2025, 11, 5, 0, 0, 0), form_document: form_document_with_batch_enabled) + end + let!(:earlier_submission) do + create(:submission, form_id: form_id, mode: "form", reference: "INCLUDED2", created_at: Time.utc(2025, 11, 4, 0, 0, 0), form_document: form_document_with_batch_disabled) + end - it "does not include a batch for the form and mode" do - expect(weekly_batches.to_a).to be_empty + it "includes a batch for the form and mode" do + expect(weekly_batches.map(&:to_h)).to contain_exactly( + a_hash_including(form_id: form_id, mode: "form"), + ) + end + + it "includes all the submissions in the batch" do + submissions = weekly_batches.first.submissions + expect(submissions.pluck(:reference)).to contain_exactly(latest_submission.reference, earlier_submission.reference) + end end - end - context "when send_weekly_submission_batch is disabled part-way through the week for the form document" do - let(:date) { Time.zone.local(2025, 11, 3) } + context "when a weekly delivery_configuration does not exist for the form document" do + let(:date) { Time.zone.local(2025, 11, 3) } - before do - create(:submission, form_id: form_id, mode: "form", created_at: Time.utc(2025, 11, 5, 0, 0, 0), form_document: form_document_with_batch_disabled) - create(:submission, form_id: form_id, mode: "form", created_at: Time.utc(2025, 11, 4, 0, 0, 0), form_document: form_document_with_batch_enabled) + before do + create(:submission, form_id: form_id, mode: "form", created_at: Time.utc(2025, 11, 5, 10, 0, 0), form_document: form_document_with_batch_disabled) + end + + it "does not include a batch for the form and mode" do + expect(weekly_batches.to_a).to be_empty + end end - it "does not include a batch for the form and mode" do - expect(weekly_batches.to_a).to be_empty + context "when a weekly delivery_configuration is removed part-way through the week for the form document" do + let(:date) { Time.zone.local(2025, 11, 3) } + + before do + create(:submission, form_id: form_id, mode: "form", created_at: Time.utc(2025, 11, 5, 0, 0, 0), form_document: form_document_with_batch_disabled) + create(:submission, form_id: form_id, mode: "form", created_at: Time.utc(2025, 11, 4, 0, 0, 0), form_document: form_document_with_batch_enabled) + end + + it "does not include a batch for the form and mode" do + expect(weekly_batches.to_a).to be_empty + end end end end