openfoodfoundation/openfoodnetwork

View on GitHub
engines/order_management/spec/services/order_management/subscriptions/variants_list_spec.rb

Summary

Maintainability
A
0 mins
Test Coverage
# frozen_string_literal: true

require "spec_helper"

module OrderManagement
  module Subscriptions
    RSpec.describe VariantsList do
      describe "variant eligibility for subscription" do
        let!(:shop) { create(:distributor_enterprise) }
        let!(:producer) { create(:supplier_enterprise) }
        let!(:product) { create(:product, supplier: producer) }
        let!(:variant) { product.variants.first }

        let!(:schedule) { create(:schedule, order_cycles: [order_cycle]) }
        let!(:subscription) { create(:subscription, shop:, schedule:) }
        let!(:subscription_line_item) do
          create(:subscription_line_item, subscription:, variant:)
        end

        let(:current_order_cycle) do
          create(:simple_order_cycle, coordinator: shop, orders_open_at: 1.week.ago,
                                      orders_close_at: 1.week.from_now)
        end

        let(:future_order_cycle) do
          create(:simple_order_cycle, coordinator: shop, orders_open_at: 1.week.from_now,
                                      orders_close_at: 2.weeks.from_now)
        end

        let(:past_order_cycle) do
          create(:simple_order_cycle, coordinator: shop, orders_open_at: 2.weeks.ago,
                                      orders_close_at: 1.week.ago)
        end

        let!(:order_cycle) { current_order_cycle }

        context "if the shop is the supplier for the product" do
          let!(:producer) { shop }

          it "is eligible" do
            expect(described_class.eligible_variants(shop)).to include(variant)
          end
        end

        context "if the supplier is permitted for the shop" do
          let!(:enterprise_relationship) {
            create(:enterprise_relationship, child: shop,
                                             parent: product.supplier,
                                             permissions_list: [:add_to_order_cycle])
          }

          it "is eligible" do
            expect(described_class.eligible_variants(shop)).to include(variant)
          end
        end

        context "if the variant is involved in an exchange" do
          let!(:order_cycle) { create(:simple_order_cycle, coordinator: shop) }
          let!(:schedule) { create(:schedule, order_cycles: [order_cycle]) }

          context "if it is an incoming exchange where the shop is the receiver" do
            let!(:incoming_exchange) {
              order_cycle.exchanges.create(sender: product.supplier,
                                           receiver: shop,
                                           incoming: true, variants: [variant])
            }

            it "is not eligible" do
              expect(described_class.eligible_variants(shop)).not_to include(variant)
            end
          end

          context "if it is an outgoing exchange where the shop is the receiver" do
            let!(:outgoing_exchange) {
              order_cycle.exchanges.create(sender: product.supplier,
                                           receiver: shop,
                                           incoming: false,
                                           variants: [variant])
            }

            context "if the order cycle is currently open" do
              let!(:order_cycle) { current_order_cycle }

              it "is eligible" do
                expect(described_class.eligible_variants(shop)).to include(variant)
              end
            end

            context "if the order cycle opens in the future" do
              let!(:order_cycle) { future_order_cycle }

              it "is eligible" do
                expect(described_class.eligible_variants(shop)).to include(variant)
              end
            end

            context "if the order cycle closed in the past" do
              let!(:order_cycle) { past_order_cycle }

              it "is eligible" do
                expect(described_class.eligible_variants(shop)).to include(variant)
              end
            end
          end
        end

        context "if the variant is unrelated" do
          it "is not eligible" do
            expect(described_class.eligible_variants(shop)).not_to include(variant)
          end
        end
      end

      describe "checking if variant in open and upcoming order cycles" do
        let!(:shop) { create(:enterprise) }
        let!(:product) { create(:product) }
        let!(:variant) { product.variants.first }
        let!(:schedule) { create(:schedule) }

        context "if the variant is involved in an exchange" do
          let!(:order_cycle) { create(:simple_order_cycle, coordinator: shop) }
          let!(:schedule) { create(:schedule, order_cycles: [order_cycle]) }

          context "if it is an incoming exchange where the shop is the receiver" do
            let!(:incoming_exchange) {
              order_cycle.exchanges.create(sender: product.supplier,
                                           receiver: shop,
                                           incoming: true,
                                           variants: [variant])
            }

            it "is is false" do
              expect(described_class).not_to be_in_open_and_upcoming_order_cycles(shop,
                                                                                  schedule,
                                                                                  variant)
            end
          end

          context "if it is an outgoing exchange where the shop is the receiver" do
            let!(:outgoing_exchange) {
              order_cycle.exchanges.create(sender: product.supplier,
                                           receiver: shop,
                                           incoming: false,
                                           variants: [variant])
            }

            it "is true" do
              expect(described_class).to be_in_open_and_upcoming_order_cycles(shop,
                                                                              schedule,
                                                                              variant)
            end
          end
        end

        context "if the variant is unrelated" do
          it "is false" do
            expect(described_class).not_to be_in_open_and_upcoming_order_cycles(shop,
                                                                                schedule,
                                                                                variant)
          end
        end
      end
    end
  end
end