From fb1c825fbccca76c95357be5e1da147b5ea5b6cc Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 11 Feb 2020 17:47:38 +0000 Subject: [PATCH] Move both subscription summarizer and subscription summary to order management engine --- .rubocop_manual_todo.yml | 1 - .rubocop_todo.yml | 12 +- app/jobs/subscription_confirm_job.rb | 4 +- app/jobs/subscription_placement_job.rb | 4 +- .../subscriptions/subscription_summarizer.rb | 55 ++++++++ .../subscriptions/subscription_summary.rb | 53 +++++++ .../subscription_summarizer_spec.rb | 132 ++++++++++++++++++ .../subscription_summary_spec.rb | 127 +++++++++++++++++ .../subscription_summarizer.rb | 53 ------- lib/open_food_network/subscription_summary.rb | 49 ------- .../subscription_summarizer_spec.rb | 126 ----------------- .../subscription_summary_spec.rb | 125 ----------------- 12 files changed, 377 insertions(+), 364 deletions(-) create mode 100644 engines/order_management/app/services/order_management/subscriptions/subscription_summarizer.rb create mode 100644 engines/order_management/app/services/order_management/subscriptions/subscription_summary.rb create mode 100644 engines/order_management/spec/services/order_management/subscriptions/subscription_summarizer_spec.rb create mode 100644 engines/order_management/spec/services/order_management/subscriptions/subscription_summary_spec.rb delete mode 100644 lib/open_food_network/subscription_summarizer.rb delete mode 100644 lib/open_food_network/subscription_summary.rb delete mode 100644 spec/lib/open_food_network/subscription_summarizer_spec.rb delete mode 100644 spec/lib/open_food_network/subscription_summary_spec.rb diff --git a/.rubocop_manual_todo.yml b/.rubocop_manual_todo.yml index f61d3a9148..9b0fd3b537 100644 --- a/.rubocop_manual_todo.yml +++ b/.rubocop_manual_todo.yml @@ -241,7 +241,6 @@ Layout/LineLength: - spec/lib/open_food_network/products_and_inventory_report_spec.rb - spec/lib/open_food_network/proxy_order_syncer_spec.rb - spec/lib/open_food_network/scope_variant_to_hub_spec.rb - - spec/lib/open_food_network/subscription_summarizer_spec.rb - spec/lib/open_food_network/tag_rule_applicator_spec.rb - spec/lib/open_food_network/users_and_enterprises_report_spec.rb - spec/lib/open_food_network/xero_invoices_report_spec.rb diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 33970eb805..323426fda9 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -70,8 +70,8 @@ Lint/DuplicateHashKey: # Offense count: 4 Lint/DuplicateMethods: Exclude: + - 'engines/order_management/app/services/order_management/subscriptions/subscription_summary.rb' - 'lib/discourse/single_sign_on.rb' - - 'lib/open_food_network/subscription_summary.rb' # Offense count: 10 Lint/IneffectiveAccessModifier: @@ -882,6 +882,8 @@ Style/FrozenStringLiteralComment: - 'engines/order_management/app/services/order_management/reports/enterprise_fee_summary/report_service.rb' - 'engines/order_management/app/services/order_management/reports/enterprise_fee_summary/scope.rb' - 'engines/order_management/app/services/order_management/reports/enterprise_fee_summary/summarizer.rb' + - 'engines/order_management/app/services/order_management/subscriptions/subscription_summarizer.rb' + - 'engines/order_management/app/services/order_management/subscriptions/subscription_summary.rb' - 'engines/order_management/app/services/reports.rb' - 'engines/order_management/app/services/reports/authorizer.rb' - 'engines/order_management/app/services/reports/parameters/base.rb' @@ -900,6 +902,8 @@ Style/FrozenStringLiteralComment: - 'engines/order_management/spec/services/order_management/reports/enterprise_fee_summary/renderers/html_renderer_spec.rb' - 'engines/order_management/spec/services/order_management/reports/enterprise_fee_summary/report_data/enterprise_fee_type_total_spec.rb' - 'engines/order_management/spec/services/order_management/reports/enterprise_fee_summary/report_service_spec.rb' + - 'engines/order_management/spec/services/order_management/subscriptions/subscription_summizer_spec.rb' + - 'engines/order_management/spec/services/order_management/subscriptions/subscription_summary_spec.rb' - 'engines/order_management/spec/spec_helper.rb' - 'engines/web/app/controllers/web/angular_templates_controller.rb' - 'engines/web/app/controllers/web/api/cookies_consent_controller.rb' @@ -967,8 +971,6 @@ Style/FrozenStringLiteralComment: - 'lib/open_food_network/scope_variants_for_search.rb' - 'lib/open_food_network/spree_api_key_loader.rb' - 'lib/open_food_network/subscription_payment_updater.rb' - - 'lib/open_food_network/subscription_summarizer.rb' - - 'lib/open_food_network/subscription_summary.rb' - 'lib/open_food_network/tag_rule_applicator.rb' - 'lib/open_food_network/user_balance_calculator.rb' - 'lib/open_food_network/users_and_enterprises_report.rb' @@ -1219,8 +1221,6 @@ Style/FrozenStringLiteralComment: - 'spec/lib/open_food_network/scope_variant_to_hub_spec.rb' - 'spec/lib/open_food_network/scope_variants_to_search_spec.rb' - 'spec/lib/open_food_network/subscription_payment_updater_spec.rb' - - 'spec/lib/open_food_network/subscription_summarizer_spec.rb' - - 'spec/lib/open_food_network/subscription_summary_spec.rb' - 'spec/lib/open_food_network/tag_rule_applicator_spec.rb' - 'spec/lib/open_food_network/user_balance_calculator_spec.rb' - 'spec/lib/open_food_network/users_and_enterprises_report_spec.rb' @@ -1542,6 +1542,7 @@ Style/Send: Exclude: - 'app/controllers/spree/checkout_controller.rb' - 'app/models/spree/shipping_method_decorator.rb' + - 'engines/order_management/spec/services/order_management/subscriptions/subscription_summarizer_spec.rb' - 'spec/controllers/admin/subscriptions_controller_spec.rb' - 'spec/controllers/checkout_controller_spec.rb' - 'spec/controllers/spree/admin/base_controller_spec.rb' @@ -1559,7 +1560,6 @@ Style/Send: - 'spec/lib/open_food_network/products_and_inventory_report_spec.rb' - 'spec/lib/open_food_network/sales_tax_report_spec.rb' - 'spec/lib/open_food_network/subscription_payment_updater_spec.rb' - - 'spec/lib/open_food_network/subscription_summarizer_spec.rb' - 'spec/lib/open_food_network/tag_rule_applicator_spec.rb' - 'spec/lib/open_food_network/xero_invoices_report_spec.rb' - 'spec/lib/stripe/webhook_handler_spec.rb' diff --git a/app/jobs/subscription_confirm_job.rb b/app/jobs/subscription_confirm_job.rb index 2d40b02539..9b1ae7a79f 100644 --- a/app/jobs/subscription_confirm_job.rb +++ b/app/jobs/subscription_confirm_job.rb @@ -1,4 +1,4 @@ -require 'open_food_network/subscription_summarizer' +require 'order_management/subscriptions/subscription_summarizer' # Confirms orders of unconfirmed proxy orders in recently closed Order Cycles class SubscriptionConfirmJob @@ -12,7 +12,7 @@ class SubscriptionConfirmJob delegate :record_and_log_error, :send_confirmation_summary_emails, to: :summarizer def summarizer - @summarizer ||= OpenFoodNetwork::SubscriptionSummarizer.new + @summarizer ||= OrderManagement::Subscriptions::SubscriptionSummarizer.new end def confirm_proxy_orders! diff --git a/app/jobs/subscription_placement_job.rb b/app/jobs/subscription_placement_job.rb index ecaa9208ef..8a77367217 100644 --- a/app/jobs/subscription_placement_job.rb +++ b/app/jobs/subscription_placement_job.rb @@ -1,4 +1,4 @@ -require 'open_food_network/subscription_summarizer' +require 'order_management/subscriptions/subscription_summarizer' class SubscriptionPlacementJob def perform @@ -17,7 +17,7 @@ class SubscriptionPlacementJob delegate :record_and_log_error, :send_placement_summary_emails, to: :summarizer def summarizer - @summarizer ||= OpenFoodNetwork::SubscriptionSummarizer.new + @summarizer ||= OrderManagement::Subscriptions::SubscriptionSummarizer.new end def proxy_orders diff --git a/engines/order_management/app/services/order_management/subscriptions/subscription_summarizer.rb b/engines/order_management/app/services/order_management/subscriptions/subscription_summarizer.rb new file mode 100644 index 0000000000..dbffcb96ab --- /dev/null +++ b/engines/order_management/app/services/order_management/subscriptions/subscription_summarizer.rb @@ -0,0 +1,55 @@ +# frozen_string_literal: true + +# Used by for SubscriptionPlacementJob and SubscriptionConfirmJob to summarize the +# result of automatic processing of subscriptions for the relevant shop owners. +module OrderManagement + module Subscriptions + class SubscriptionSummarizer + def initialize + @summaries = {} + end + + def record_order(order) + summary_for(order).record_order(order) + end + + def record_success(order) + summary_for(order).record_success(order) + end + + def record_issue(type, order, message = nil) + Rails.logger.info "Issue in Subscription Order #{order.id}: #{type}" + summary_for(order).record_issue(type, order, message) + end + + def record_and_log_error(type, order) + return record_issue(type, order) unless order.errors.any? + + error = "Subscription#{type.to_s.camelize}Error" + line1 = "#{error}: Cannot process order #{order.number} due to errors" + line2 = "Errors: #{order.errors.full_messages.join(', ')}" + Rails.logger.info("#{line1}\n#{line2}") + record_issue(type, order, line2) + end + + def send_placement_summary_emails + @summaries.values.each do |summary| + SubscriptionMailer.placement_summary_email(summary).deliver + end + end + + def send_confirmation_summary_emails + @summaries.values.each do |summary| + SubscriptionMailer.confirmation_summary_email(summary).deliver + end + end + + private + + def summary_for(order) + shop_id = order.distributor_id + @summaries[shop_id] ||= SubscriptionSummary.new(shop_id) + end + end + end +end diff --git a/engines/order_management/app/services/order_management/subscriptions/subscription_summary.rb b/engines/order_management/app/services/order_management/subscriptions/subscription_summary.rb new file mode 100644 index 0000000000..aa9a61c469 --- /dev/null +++ b/engines/order_management/app/services/order_management/subscriptions/subscription_summary.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +module OrderManagement + module Subscriptions + class SubscriptionSummary + attr_reader :shop_id, :order_count, :success_count, :issues + + def initialize(shop_id) + @shop_id = shop_id + @order_ids = [] + @success_ids = [] + @issues = {} + end + + def record_order(order) + @order_ids << order.id + end + + def record_success(order) + @success_ids << order.id + end + + def record_issue(type, order, message) + issues[type] ||= {} + issues[type][order.id] = message + end + + def order_count + @order_ids.count + end + + def success_count + @success_ids.count + end + + def issue_count + (@order_ids - @success_ids).count + end + + def orders_affected_by(type) + case type + when :other then Spree::Order.where(id: unrecorded_ids) + else Spree::Order.where(id: issues[type].keys) + end + end + + def unrecorded_ids + recorded_ids = issues.values.map(&:keys).flatten + @order_ids - @success_ids - recorded_ids + end + end + end +end diff --git a/engines/order_management/spec/services/order_management/subscriptions/subscription_summarizer_spec.rb b/engines/order_management/spec/services/order_management/subscriptions/subscription_summarizer_spec.rb new file mode 100644 index 0000000000..26a79af4d1 --- /dev/null +++ b/engines/order_management/spec/services/order_management/subscriptions/subscription_summarizer_spec.rb @@ -0,0 +1,132 @@ +# frozen_string_literal: true + +require 'spec_helper' + +module OrderManagement + module Subscriptions + describe SubscriptionSummarizer do + let(:order) { create(:order) } + let(:summarizer) { OrderManagement::Subscriptions::SubscriptionSummarizer.new } + + before { allow(Rails.logger).to receive(:info) } + + describe "#summary_for" do + let(:order) { double(:order, distributor_id: 123) } + + context "when a summary for the order's distributor doesn't already exist" do + it "initializes a new summary object, and returns it" do + expect(summarizer.instance_variable_get(:@summaries).count).to be 0 + summary = summarizer.send(:summary_for, order) + expect(summary.shop_id).to be 123 + expect(summarizer.instance_variable_get(:@summaries).count).to be 1 + end + end + + context "when a summary for the order's distributor already exists" do + let(:summary) { double(:summary) } + + before do + summarizer.instance_variable_set(:@summaries, 123 => summary) + end + + it "returns the existing summary object" do + expect(summarizer.instance_variable_get(:@summaries).count).to be 1 + expect(summarizer.send(:summary_for, order)).to eq summary + expect(summarizer.instance_variable_get(:@summaries).count).to be 1 + end + end + end + + describe "recording events" do + let(:order) { double(:order) } + let(:summary) { double(:summary) } + before { allow(summarizer).to receive(:summary_for).with(order) { summary } } + + describe "#record_order" do + it "requests a summary for the order and calls #record_order on it" do + expect(summary).to receive(:record_order).with(order).once + summarizer.record_order(order) + end + end + + describe "#record_success" do + it "requests a summary for the order and calls #record_success on it" do + expect(summary).to receive(:record_success).with(order).once + summarizer.record_success(order) + end + end + + describe "#record_issue" do + it "requests a summary for the order and calls #record_issue on it" do + expect(order).to receive(:id) + expect(summary).to receive(:record_issue).with(:type, order, "message").once + summarizer.record_issue(:type, order, "message") + end + end + + describe "#record_and_log_error" do + before do + allow(order).to receive(:number) { "123" } + end + + context "when errors exist on the order" do + before do + allow(order).to receive(:errors) { + double(:errors, any?: true, full_messages: ["Some error"]) + } + end + + it "sends error info to rails logger and calls #record_issue with an error message" do + expect(summarizer).to receive(:record_issue).with(:processing, + order, "Errors: Some error") + summarizer.record_and_log_error(:processing, order) + end + end + + context "when no errors exist on the order" do + before do + allow(order).to receive(:errors) { double(:errors, any?: false) } + end + + it "falls back to calling record_issue" do + expect(summarizer).to receive(:record_issue).with(:processing, order) + summarizer.record_and_log_error(:processing, order) + end + end + end + end + + describe "#send_placement_summary_emails" do + let(:summary1) { double(:summary) } + let(:summary2) { double(:summary) } + let(:summaries) { { 1 => summary1, 2 => summary2 } } + let(:mail_mock) { double(:mail, deliver: true) } + + before do + summarizer.instance_variable_set(:@summaries, summaries) + end + + it "sends a placement summary email for each summary" do + expect(SubscriptionMailer).to receive(:placement_summary_email).twice { mail_mock } + summarizer.send_placement_summary_emails + end + end + + describe "#send_confirmation_summary_emails" do + let(:summary1) { double(:summary) } + let(:summary2) { double(:summary) } + let(:summaries) { { 1 => summary1, 2 => summary2 } } + let(:mail_mock) { double(:mail, deliver: true) } + + before do + summarizer.instance_variable_set(:@summaries, summaries) + end + + it "sends a placement summary email for each summary" do + expect(SubscriptionMailer).to receive(:confirmation_summary_email).twice { mail_mock } + summarizer.send_confirmation_summary_emails + end + end + end + end +end diff --git a/engines/order_management/spec/services/order_management/subscriptions/subscription_summary_spec.rb b/engines/order_management/spec/services/order_management/subscriptions/subscription_summary_spec.rb new file mode 100644 index 0000000000..e24aa6449b --- /dev/null +++ b/engines/order_management/spec/services/order_management/subscriptions/subscription_summary_spec.rb @@ -0,0 +1,127 @@ +# frozen_string_literal: true + +module OrderManagement + module Subscriptions + describe SubscriptionSummary do + let(:summary) { OrderManagement::Subscriptions::SubscriptionSummary.new(123) } + + describe "#initialize" do + it "initializes instance variables: shop_id, order_count, success_count and issues" do + expect(summary.shop_id).to be 123 + expect(summary.order_count).to be 0 + expect(summary.success_count).to be 0 + expect(summary.issues).to be_a Hash + end + end + + describe "#record_order" do + let(:order) { double(:order, id: 37) } + it "adds the order id to the order_ids array" do + summary.record_order(order) + expect(summary.instance_variable_get(:@order_ids)).to eq [order.id] + end + end + + describe "#record_success" do + let(:order) { double(:order, id: 37) } + it "adds the order id to the success_ids array" do + summary.record_success(order) + expect(summary.instance_variable_get(:@success_ids)).to eq [order.id] + end + end + + describe "#record_issue" do + let(:order) { double(:order, id: 1) } + + context "when no issues of the same type have been recorded yet" do + it "adds a new type to the issues hash, and stores a new issue against it" do + summary.record_issue(:some_type, order, "message") + expect(summary.issues.keys).to include :some_type + expect(summary.issues[:some_type][order.id]).to eq "message" + end + end + + context "when an issue of the same type has already been recorded" do + let(:existing_issue) { double(:existing_issue) } + + before { summary.issues[:some_type] = [existing_issue] } + + it "stores a new issue against the existing type" do + summary.record_issue(:some_type, order, "message") + expect(summary.issues[:some_type]).to include existing_issue + expect(summary.issues[:some_type][order.id]).to eq "message" + end + end + end + + describe "#order_count" do + let(:order_ids) { [1, 2, 3, 4, 5, 6, 7] } + it "counts the number of items in the order_ids instance_variable" do + summary.instance_variable_set(:@order_ids, order_ids) + expect(summary.order_count).to be 7 + end + end + + describe "#success_count" do + let(:success_ids) { [1, 2, 3, 4, 5, 6, 7] } + it "counts the number of items in the success_ids instance_variable" do + summary.instance_variable_set(:@success_ids, success_ids) + expect(summary.success_count).to be 7 + end + end + + describe "#issue_count" do + let(:order_ids) { [1, 3, 5, 7, 9] } + let(:success_ids) { [1, 2, 3, 4, 5] } + + it "counts the number of items in order_ids that are not in success_ids" do + summary.instance_variable_set(:@order_ids, order_ids) + summary.instance_variable_set(:@success_ids, success_ids) + expect(summary.issue_count).to be 2 # 7 & 9 + end + end + + describe "#orders_affected_by" do + let(:order1) { create(:order) } + let(:order2) { create(:order) } + + before do + allow(summary).to receive(:unrecorded_ids) { [order1.id] } + allow(summary).to receive(:issues) { { failure: { order2.id => "A message" } } } + end + + context "when the issue type is :other" do + let(:orders) { summary.orders_affected_by(:other) } + + it "returns orders specified by unrecorded_ids" do + expect(orders).to include order1 + expect(orders).to_not include order2 + end + end + + context "when the issue type is :other" do + let(:orders) { summary.orders_affected_by(:failure) } + + it "returns orders specified by the relevant issue hash" do + expect(orders).to include order2 + expect(orders).to_not include order1 + end + end + end + + describe "#unrecorded_ids" do + let(:issues) { { type: { 7 => "message", 8 => "message" } } } + + before do + summary.instance_variable_set(:@order_ids, [1, 3, 5, 7, 9]) + summary.instance_variable_set(:@success_ids, [1, 2, 3, 4, 5]) + summary.instance_variable_set(:@issues, issues) + end + + it "returns order_ids that are not marked as an issue or a success" do + expect(summary.unrecorded_ids).to eq [9] + end + end + end + end +end diff --git a/lib/open_food_network/subscription_summarizer.rb b/lib/open_food_network/subscription_summarizer.rb deleted file mode 100644 index 6e4b95da8b..0000000000 --- a/lib/open_food_network/subscription_summarizer.rb +++ /dev/null @@ -1,53 +0,0 @@ -require 'open_food_network/subscription_summary' - -# Used by for SubscriptionPlacementJob and SubscriptionConfirmJob to summarize the -# result of automatic processing of subscriptions for the relevant shop owners. -module OpenFoodNetwork - class SubscriptionSummarizer - def initialize - @summaries = {} - end - - def record_order(order) - summary_for(order).record_order(order) - end - - def record_success(order) - summary_for(order).record_success(order) - end - - def record_issue(type, order, message = nil) - Rails.logger.info "Issue in Subscription Order #{order.id}: #{type}" - summary_for(order).record_issue(type, order, message) - end - - def record_and_log_error(type, order) - return record_issue(type, order) unless order.errors.any? - - error = "Subscription#{type.to_s.camelize}Error" - line1 = "#{error}: Cannot process order #{order.number} due to errors" - line2 = "Errors: #{order.errors.full_messages.join(', ')}" - Rails.logger.info("#{line1}\n#{line2}") - record_issue(type, order, line2) - end - - def send_placement_summary_emails - @summaries.values.each do |summary| - SubscriptionMailer.placement_summary_email(summary).deliver - end - end - - def send_confirmation_summary_emails - @summaries.values.each do |summary| - SubscriptionMailer.confirmation_summary_email(summary).deliver - end - end - - private - - def summary_for(order) - shop_id = order.distributor_id - @summaries[shop_id] ||= SubscriptionSummary.new(shop_id) - end - end -end diff --git a/lib/open_food_network/subscription_summary.rb b/lib/open_food_network/subscription_summary.rb deleted file mode 100644 index fb2a1dc066..0000000000 --- a/lib/open_food_network/subscription_summary.rb +++ /dev/null @@ -1,49 +0,0 @@ -module OpenFoodNetwork - class SubscriptionSummary - attr_reader :shop_id, :order_count, :success_count, :issues - - def initialize(shop_id) - @shop_id = shop_id - @order_ids = [] - @success_ids = [] - @issues = {} - end - - def record_order(order) - @order_ids << order.id - end - - def record_success(order) - @success_ids << order.id - end - - def record_issue(type, order, message) - issues[type] ||= {} - issues[type][order.id] = message - end - - def order_count - @order_ids.count - end - - def success_count - @success_ids.count - end - - def issue_count - (@order_ids - @success_ids).count - end - - def orders_affected_by(type) - case type - when :other then Spree::Order.where(id: unrecorded_ids) - else Spree::Order.where(id: issues[type].keys) - end - end - - def unrecorded_ids - recorded_ids = issues.values.map(&:keys).flatten - @order_ids - @success_ids - recorded_ids - end - end -end diff --git a/spec/lib/open_food_network/subscription_summarizer_spec.rb b/spec/lib/open_food_network/subscription_summarizer_spec.rb deleted file mode 100644 index a0d2b3f7bf..0000000000 --- a/spec/lib/open_food_network/subscription_summarizer_spec.rb +++ /dev/null @@ -1,126 +0,0 @@ -require 'spec_helper' -require 'open_food_network/subscription_summarizer' - -module OpenFoodNetwork - describe SubscriptionSummarizer do - let(:order) { create(:order) } - let(:summarizer) { OpenFoodNetwork::SubscriptionSummarizer.new } - - before { allow(Rails.logger).to receive(:info) } - - describe "#summary_for" do - let(:order) { double(:order, distributor_id: 123) } - - context "when a summary for the order's distributor doesn't already exist" do - it "initializes a new summary object, and returns it" do - expect(summarizer.instance_variable_get(:@summaries).count).to be 0 - summary = summarizer.send(:summary_for, order) - expect(summary.shop_id).to be 123 - expect(summarizer.instance_variable_get(:@summaries).count).to be 1 - end - end - - context "when a summary for the order's distributor already exists" do - let(:summary) { double(:summary) } - - before do - summarizer.instance_variable_set(:@summaries, 123 => summary) - end - - it "returns the existing summary object" do - expect(summarizer.instance_variable_get(:@summaries).count).to be 1 - expect(summarizer.send(:summary_for, order)).to eq summary - expect(summarizer.instance_variable_get(:@summaries).count).to be 1 - end - end - end - - describe "recording events" do - let(:order) { double(:order) } - let(:summary) { double(:summary) } - before { allow(summarizer).to receive(:summary_for).with(order) { summary } } - - describe "#record_order" do - it "requests a summary for the order and calls #record_order on it" do - expect(summary).to receive(:record_order).with(order).once - summarizer.record_order(order) - end - end - - describe "#record_success" do - it "requests a summary for the order and calls #record_success on it" do - expect(summary).to receive(:record_success).with(order).once - summarizer.record_success(order) - end - end - - describe "#record_issue" do - it "requests a summary for the order and calls #record_issue on it" do - expect(order).to receive(:id) - expect(summary).to receive(:record_issue).with(:type, order, "message").once - summarizer.record_issue(:type, order, "message") - end - end - - describe "#record_and_log_error" do - before do - allow(order).to receive(:number) { "123" } - end - - context "when errors exist on the order" do - before do - allow(order).to receive(:errors) { double(:errors, any?: true, full_messages: ["Some error"]) } - end - - it "sends error info to the rails logger and calls #record_issue on itself with an error message" do - expect(summarizer).to receive(:record_issue).with(:processing, order, "Errors: Some error") - summarizer.record_and_log_error(:processing, order) - end - end - - context "when no errors exist on the order" do - before do - allow(order).to receive(:errors) { double(:errors, any?: false) } - end - - it "falls back to calling record_issue" do - expect(summarizer).to receive(:record_issue).with(:processing, order) - summarizer.record_and_log_error(:processing, order) - end - end - end - end - - describe "#send_placement_summary_emails" do - let(:summary1) { double(:summary) } - let(:summary2) { double(:summary) } - let(:summaries) { { 1 => summary1, 2 => summary2 } } - let(:mail_mock) { double(:mail, deliver: true) } - - before do - summarizer.instance_variable_set(:@summaries, summaries) - end - - it "sends a placement summary email for each summary" do - expect(SubscriptionMailer).to receive(:placement_summary_email).twice { mail_mock } - summarizer.send_placement_summary_emails - end - end - - describe "#send_confirmation_summary_emails" do - let(:summary1) { double(:summary) } - let(:summary2) { double(:summary) } - let(:summaries) { { 1 => summary1, 2 => summary2 } } - let(:mail_mock) { double(:mail, deliver: true) } - - before do - summarizer.instance_variable_set(:@summaries, summaries) - end - - it "sends a placement summary email for each summary" do - expect(SubscriptionMailer).to receive(:confirmation_summary_email).twice { mail_mock } - summarizer.send_confirmation_summary_emails - end - end - end -end diff --git a/spec/lib/open_food_network/subscription_summary_spec.rb b/spec/lib/open_food_network/subscription_summary_spec.rb deleted file mode 100644 index f5b0cd8d71..0000000000 --- a/spec/lib/open_food_network/subscription_summary_spec.rb +++ /dev/null @@ -1,125 +0,0 @@ -require 'open_food_network/subscription_summary' - -module OpenFoodNetwork - describe SubscriptionSummary do - let(:summary) { OpenFoodNetwork::SubscriptionSummary.new(123) } - - describe "#initialize" do - it "initializes instance variables: shop_id, order_count, success_count and issues" do - expect(summary.shop_id).to be 123 - expect(summary.order_count).to be 0 - expect(summary.success_count).to be 0 - expect(summary.issues).to be_a Hash - end - end - - describe "#record_order" do - let(:order) { double(:order, id: 37) } - it "adds the order id to the order_ids array" do - summary.record_order(order) - expect(summary.instance_variable_get(:@order_ids)).to eq [order.id] - end - end - - describe "#record_success" do - let(:order) { double(:order, id: 37) } - it "adds the order id to the success_ids array" do - summary.record_success(order) - expect(summary.instance_variable_get(:@success_ids)).to eq [order.id] - end - end - - describe "#record_issue" do - let(:order) { double(:order, id: 1) } - - context "when no issues of the same type have been recorded yet" do - it "adds a new type to the issues hash, and stores a new issue against it" do - summary.record_issue(:some_type, order, "message") - expect(summary.issues.keys).to include :some_type - expect(summary.issues[:some_type][order.id]).to eq "message" - end - end - - context "when an issue of the same type has already been recorded" do - let(:existing_issue) { double(:existing_issue) } - - before { summary.issues[:some_type] = [existing_issue] } - - it "stores a new issue against the existing type" do - summary.record_issue(:some_type, order, "message") - expect(summary.issues[:some_type]).to include existing_issue - expect(summary.issues[:some_type][order.id]).to eq "message" - end - end - end - - describe "#order_count" do - let(:order_ids) { [1, 2, 3, 4, 5, 6, 7] } - it "counts the number of items in the order_ids instance_variable" do - summary.instance_variable_set(:@order_ids, order_ids) - expect(summary.order_count).to be 7 - end - end - - describe "#success_count" do - let(:success_ids) { [1, 2, 3, 4, 5, 6, 7] } - it "counts the number of items in the success_ids instance_variable" do - summary.instance_variable_set(:@success_ids, success_ids) - expect(summary.success_count).to be 7 - end - end - - describe "#issue_count" do - let(:order_ids) { [1, 3, 5, 7, 9] } - let(:success_ids) { [1, 2, 3, 4, 5] } - - it "counts the number of items in order_ids that are not in success_ids" do - summary.instance_variable_set(:@order_ids, order_ids) - summary.instance_variable_set(:@success_ids, success_ids) - expect(summary.issue_count).to be 2 # 7 & 9 - end - end - - describe "#orders_affected_by" do - let(:order1) { create(:order) } - let(:order2) { create(:order) } - - before do - allow(summary).to receive(:unrecorded_ids) { [order1.id] } - allow(summary).to receive(:issues) { { failure: { order2.id => "A message" } } } - end - - context "when the issue type is :other" do - let(:orders) { summary.orders_affected_by(:other) } - - it "returns orders specified by unrecorded_ids" do - expect(orders).to include order1 - expect(orders).to_not include order2 - end - end - - context "when the issue type is :other" do - let(:orders) { summary.orders_affected_by(:failure) } - - it "returns orders specified by the relevant issue hash" do - expect(orders).to include order2 - expect(orders).to_not include order1 - end - end - end - - describe "#unrecorded_ids" do - let(:issues) { { type: { 7 => "message", 8 => "message" } } } - - before do - summary.instance_variable_set(:@order_ids, [1, 3, 5, 7, 9]) - summary.instance_variable_set(:@success_ids, [1, 2, 3, 4, 5]) - summary.instance_variable_set(:@issues, issues) - end - - it "returns order_ids that are not marked as an issue or a success" do - expect(summary.unrecorded_ids).to eq [9] - end - end - end -end