require "rails_helper"

RSpec.describe Bits::ProductsController do
  include_context "mocked permissions"

  let(:permission) { 'bits_catalog' }
  let(:mock_service) { Bits::Product.new(id: '123') }
  let(:params) do
    {
      platform: "AMAZON",
      id: "test 222",
      bits_product: {
        id: "test 222",
        display_name: "test 555",
        platform: "ANDROID",
        bits_type_id: "BitsForAds",
        quantity: "1",
        max_purchasable_quantity: "400",
        pricing_id: "NO_PRICING_ID",
        show_when_logged_out: "false",
        include_promo: "true",
        promo: {
          id: "5555",
          type: "PRIME_SINGLE_PURCHASE",
          start: "2019-04-21T10:00",
          end: "2019-10-30T22:00"
        }
      }
    }
  end
  class SuccessResponse
    attr_accessor :body
    def initialize(options = {})
      @body = options[:body]
    end

    def success?
      true
    end
  end

  describe "#index" do
    context "a user without permission" do
      include_context "an unauthorized user"

      before do
        get :index
      end
      it_behaves_like "it redirects the user and displays an error"
    end

    context 'a user with permission' do
      include_context 'an authorized user'

      let(:permission) { ['bits_catalog'] }

      before do
        expect(Bits::Product).to receive(:all).and_return(SuccessResponse.new)
        get :index
      end

      it_behaves_like 'it returns a success response'
    end
  end

  describe "#new" do
    context "a user without permission" do
      include_context "an unauthorized user"

      before do
        get :new
      end
      it_behaves_like "it redirects the user and displays an error"
    end

    context 'a user with permission' do
      include_context 'an authorized user'

      let(:permission) { ['bits_catalog'] }

      before do
        expect(Bits::Type).to receive(:all).and_return(SuccessResponse.new)
        get :new
      end

      it_behaves_like 'it returns a success response'
    end
  end

  describe "#create" do
    context "a user without permission" do
      include_context "an unauthorized user"

      before do
        put :create, params: params
      end
      it_behaves_like "it redirects the user and displays an error"
    end

    context 'a user with permission' do
      include_context 'an authorized user'

      let(:permission) { ['bits_catalog'] }

      before do
        expect(Bits::Type).to receive(:all).and_return(SuccessResponse.new)
        expect(Bits::Product).to receive(:new).and_return(mock_service)
        expect(mock_service).to receive(:save).and_return(true)
        put :create, params: params
      end

      it_behaves_like 'it redirects the user and displays a success message'
    end
  end

  describe "#edit" do
    context "a user without permission" do
      include_context "an unauthorized user"

      let(:permission) { ['bits_catalog'] }

      before do
        expect(Bits::Product).to receive(:find).and_return(mock_service)
        get :edit, params: { platform: "AMAZON", id: "123" }
      end
      it_behaves_like "it redirects the user and displays an error"
    end

    context 'a user with permission' do
      include_context 'an authorized user'

      let(:permission) { ['bits_catalog'] }

      before do
        expect(Bits::Product).to receive(:find).and_return(mock_service)
        expect(Bits::Type).to receive(:all).and_return(SuccessResponse.new)
        get :edit, params: { platform: "AMAZON", id: "123" }
      end

      it_behaves_like 'it returns a success response'
    end
  end

  describe "#update" do
    context "a user without permission" do
      include_context "an unauthorized user"

      before do
        put :update, params: params
      end
      it_behaves_like "it redirects the user and displays an error"
    end

    context 'a user with permission' do
      include_context 'an authorized user'

      let(:permission) { ['bits_catalog'] }

      before do
        expect(Bits::Product).to receive(:new).and_return(mock_service)
        expect(mock_service).to receive(:save).and_return(true)
        put :update, params: params
      end

      it_behaves_like 'it redirects the user and displays a success message'
    end
  end
end
