require 'rails_helper'

RSpec.describe Bits::Product do
  include ServiceHelper
  include Code::Justin::Tv::Commerce::Petozi

  describe "#all" do
    let(:twirp_response) do
      data = Code::Justin::Tv::Commerce::Petozi::GetBitsProductsResp.new
      data.bits_products << Code::Justin::Tv::Commerce::Petozi::BitsProduct.new(id: "1", platform: :AMAZON)
      data.bits_products << Code::Justin::Tv::Commerce::Petozi::BitsProduct.new(id: "2", platform: :AMAZON)
      data.bits_products << Code::Justin::Tv::Commerce::Petozi::BitsProduct.new(id: "3", platform: :AMAZON)
      Twirp::ClientResp.new(data, nil)
    end

    before(:each) do
      expect(described_class.twirp_client).to(receive(:get_bits_products)).and_return(twirp_response)
    end

    it 'retrieves all bits products' do
      products = described_class.all
      expect(products.size).to eq(3)
    end
  end

  describe "#find" do
    let(:twirp_response) do
      data = Code::Justin::Tv::Commerce::Petozi::GetBitsProductResp.new
      data.bits_product = Code::Justin::Tv::Commerce::Petozi::BitsProduct.new(id: "1", platform: :AMAZON)
      Twirp::ClientResp.new(data, nil)
    end

    before(:each) do
      expect(described_class.twirp_client).to(receive(:get_bits_product)).and_return(twirp_response)
    end

    it 'retrieves bits product by ID and platform' do
      product = described_class.find("1", :AMAZON)
      expect(product.id).to eq(twirp_response.data.bits_product.id)
      expect(product.platform).to eq(twirp_response.data.bits_product.platform)
    end
  end

  describe "#save" do
    let(:product) do
      described_class.new(
        id: "1",
        display_name: "test product",
        platform: :AMAZON,
        bits_type_id: "some bits type DI",
        quantity: 100,
        max_purchasable_quantity: 1,
        promo: Bits::ProductPromo.new(id: "promo ID", type: :FIRST_TIME_PURCHASE, start: Time.now, end: Time.now),
        show_when_logged_out: false,
        pricing_id: "some pricing id"
      )
    end

    describe "when client succeeds" do
      let(:twirp_response) do
        data = Code::Justin::Tv::Commerce::Petozi::PutBitsProductResp.new
        Twirp::ClientResp.new(data, nil)
      end

      before(:each) do
        expect(described_class.twirp_client).to(receive(:put_bits_product)).and_return(twirp_response)
      end

      it "returns true" do
        expect(product.save).to eq(true)
      end
    end

    describe "when client fails" do
      let(:twirp_response) do
        Twirp::ClientResp.new(nil, Twirp::Error.new(:internal, "some error", {}))
      end

      before(:each) do
        expect(described_class.twirp_client).to(receive(:put_bits_product)).and_return(twirp_response)
      end

      it "returns false" do
        expect(product.save).to eq(false)
      end
    end
  end

  describe "#platforms" do
    it "returns all platforms" do
      expect(described_class.platforms.size).to eq(Code::Justin::Tv::Commerce::Petozi::Platform.constants.size)
    end
  end

  describe "#promo_types" do
    it "returns all promo types" do
      expect(described_class.promo_types.size).to eq(Code::Justin::Tv::Commerce::Petozi::PromoType.constants.size)
    end
  end
end
