require 'spec_helper'


describe Order do
  let(:supplier) { create :supplier }
  let(:user) { create :user }
  let(:section) { create :section, supplier: supplier}
  let(:table) { create :table, supplier: supplier}
  let(:list){ create :list, supplier: supplier, table: table, user_ids: [user.id] }
  let(:order_options){ {supplier: supplier, list: list, state: 'placed' } }
  let(:order) {create :order, order_options }
  subject { order }

  its(:placed?) { should be true }
  its(:active?) { should be false }

  describe 'count_active_for_supplier_and_list' do
    before { order }
    it 'counts active orders for a list with objects' do
      Order.count_active_for_supplier_and_list(supplier, list).should == 1
    end
    it 'counts active orders for a list with ids' do
      Order.count_active_for_supplier_and_list(supplier.id, list.id).should == 1
    end
    it 'does not count inactive orders' do
      order.close!
      Order.count_active_for_supplier_and_list(supplier, list).should == 0
    end
  end


  describe '.for_supplier' do
    before { order }
    it 'works' do
      Order.for_supplier(supplier).should == [order]
    end

    it 'paginates'
  end

  describe '#is_being_processed!' do
    describe 'broadcasting' do

      it 'broadcasts order info to the user' do
        order_options[:state] = 'placed'
        expect{ order.is_being_processed! }.to broadcast_to_user(user.id).message( 'order_being_processed' ).with(id: order.id, list_id: list.id)
      end

      describe 'counters' do
        before do
          # hack some initial values
          Qwaiter::Counter.set "supplier_counter:#{supplier.id}:orders_placed", 11
          Qwaiter::Counter.set "supplier_counter:#{supplier.id}:orders_in_process", 7
        end

        it 'reduces the orders_placed count and communicates it to user' do
          order_options[:state] = 'placed'
          expect{ order.is_being_processed! }.to broadcast_to_user(user.id).message( 'orders_placed_count' ).with(count: 10)
        end

        it 'increases the orders_in_process count and communicates it to user' do
          order_options[:state] = 'placed'
          expect{ order.is_being_processed! }.to broadcast_to_user(user.id).message( 'orders_in_process_count' ).with(count: 8)
        end

        it 'reduces the orders_placed count and communicates it to supplier' do
          order_options[:state] = 'placed'
          expect{ order.is_being_processed! }.to broadcast_to_supplier(supplier.id).message( 'orders_placed_count' ).with(count: 10)
        end

        it 'increases the orders_in_process count and communicates it to supplier' do
          order_options[:state] = 'placed'
          expect{ order.is_being_processed! }.to broadcast_to_supplier(supplier.id).message( 'orders_in_process_count' ).with(count: 8)
        end

      end

      it 'broadcasts order info to the supplier' do
        order_options[:state] = 'placed'
        expect{ order.is_being_processed! }.to broadcast_to_supplier(supplier.id).message( 'order_being_processed' ).with(id: order.id, list_id: list.id)
      end

    end

  end

  describe '#is_delivered!' do
    describe 'broadcasting' do
      describe 'counters' do
        before do
          # hack some initial values
          Qwaiter::Counter.set "supplier_counter:#{supplier.id}:orders_placed", 11
          Qwaiter::Counter.set "supplier_counter:#{supplier.id}:orders_in_process", 7
        end

        it 'decreases the orders_in_process count and communicates it to user' do
          expect{ order.is_delivered! }.to broadcast_to_user(user.id).message( 'orders_placed_count' ).with(count: 10)
          supplier.orders_in_process_count.should == 7 # should not be reduced
        end

        it 'decreases the orders_in_process count and communicates it to supplier' do
          expect{ order.is_delivered! }.to broadcast_to_supplier(supplier.id).message( 'orders_placed_count' ).with(count: 10)
          supplier.orders_in_process_count.should == 7 # should not be reduced
        end

        it 'does not decreases the placed orders count if the order is not placed' do
          order = create :order, :active, supplier: supplier, list: list
          order.is_delivered!
          supplier.orders_placed_count.should == 11
          supplier.orders_in_process_count.should == 6
        end
      end
    end
  end

  describe "cancel!" do
    it 'changes the state to cancelled' do
      order_options[:state] = 'active'
      order.cancel!
      expect(order.state).to eq 'cancelled'
    end
    describe 'broadcasting' do
      describe 'counters' do
        before do
          # hack some initial values
          Qwaiter::Counter.set "supplier_counter:#{supplier.id}:orders_placed", 11
          Qwaiter::Counter.set "supplier_counter:#{supplier.id}:orders_in_process", 7
        end

        it 'decreases the placed count and communicates it to user when state is placed through the order_cancelled broadcast message' do
          order_options[:state] = 'placed'
          expect{ order.cancel! }.to broadcast_to_user(user.id).message( 'order_cancelled' ).with(id: order.id, supplier_orders_placed_count: 10)
          supplier.orders_in_process_count.should == 7 # should not be reduced
        end

        it 'decreases the placed count and communicates it to supplier when the state is placed through the order_cancelled broadcast message' do
          order_options[:state] = 'placed'
          expect{ order.cancel! }.to broadcast_to_supplier(supplier.id).message( 'order_cancelled' ).with(id: order.id, supplier_orders_placed_count: 10)
          supplier.orders_in_process_count.should == 7 # should not be reduced
        end

        it 'decreases the orders_in_process count and communicates it to user when state is active through the order_cancelled broadcast message' do
          order_options[:state] = 'active'
          expect{ order.cancel! }.to broadcast_to_user(user.id).message( 'order_cancelled' ).with(id: order.id, supplier_orders_in_process_count: 6)
          supplier.orders_placed_count.should == 11 # should not be reduced
        end

        it 'decreases the orders_in_process count and communicates it to supplier when the state is active through the order_cancelled broadcast message' do
          order_options[:state] = 'active'
          expect{ order.cancel! }.to broadcast_to_supplier(supplier.id).message( 'order_cancelled' ).with(id: order.id, supplier_orders_in_process_count: 6)
          supplier.orders_placed_count.should == 11 # should not be reduced
        end
      end
    end
  end
  describe '#close!' do
    describe 'counters' do
      before do
        # hack some initial values
        Qwaiter::Counter.set "supplier_counter:#{supplier.id}:orders_placed", 11
        Qwaiter::Counter.set "supplier_counter:#{supplier.id}:orders_in_process", 7
      end

      it "decrements the orders_placed_count for when a placed order is closed" do
        order.close!
        supplier.orders_placed_count.should == 10
        supplier.orders_in_process_count.should == 7
      end

      it "decrements the orders_in_process_count for when an active order is closed" do
        order_options[:state] = 'active'
        order.close!
        supplier.orders_placed_count.should == 11
        supplier.orders_in_process_count.should == 6
      end
    end
  end
end
