require 'rails_helper'

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

  let(:permission) { "bits_catalog"}
  let(:mock_service) { Bits::Type.new(id: "123") }
  let(:params) do
    {
      id: "test 123",
      bits_type: {
        id: "test 123",
        display_name: "test 123 name",
        is_paid: "true",
        is_promotional: "false",
        cost_per_bits_usc: "1.2",
        entitlement_source_type: "REDEEMED_CODE",
        business_attribution: "EXTENSIONS"
      }
    }
  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'] }

      describe "when service succeeds" do
        before do
          expect(Bits::Type).to receive(:all).and_return(SuccessResponse.new)
          get :index
        end

        it_behaves_like 'it returns a success response'
      end

      describe "when service fails" do
        before do
          expect(Bits::Type).to receive(:all).and_raise("some error")
          get :index
        end

        it_behaves_like 'it returns a success response'
        it "sets an empty collection of types" do
          expect(@controller.view_assigns['types']).to eq([])
        end
      end
    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(:new).and_return(mock_service)
        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'] }

      describe "when save succeeds" do
        before do
          expect(Bits::Type).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
  end

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

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

      before do
        expect(Bits::Type).to receive(:find).and_return(mock_service)
        get :edit, 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(:find).and_return(mock_service)
        get :edit, params: params
      end

      it_behaves_like 'it returns a success response'
    end
  end

end
