mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-24 20:36:49 +00:00
Move both subscription summarizer and subscription summary to order management engine
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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!
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user