require 'rails_helper'

module Substwirp
  describe RevenueConfig do
    include ServiceHelper

    describe 'get_configs_for_product_id' do
      let(:product_id) { 'product_id' }
      let(:config) do
        {
          'id' => 'id',
          'product_id' => product_id,
          'rev_split_percent' => 50,
          'start_date' => '2020-02-02T00:00:00.000Z',
          'created_at' => '2020-02-02T00:00:00.000Z',
          'updated_at' => '2020-02-02T00:00:00.000Z'
        }
      end
      let(:revenue_config_data) { double(revenue_configs: [config]) }
      let(:get_revenue_configs_by_id_response) { double(error: error, data: revenue_config_data) }

      subject { RevenueConfig.get_configs_for_product_id(product_id) }

      context 'with successful revenue_config response' do
        let(:error) { nil }

        it 'should call twirp_client get_revenue_configs_by_product_i_d and returns revenue_config object' do
          expect_any_instance_of(::Code::Justin::Tv::Revenue::Subscriptions::SubscriptionsClient).to receive(:get_revenue_configs_by_product_i_d).with({product_id: product_id}).and_return(get_revenue_configs_by_id_response)
          expect(subject[0]).to have_attributes(
            id: config['id'],
            product_id: config['product_id'],
            rev_split_percent: config['rev_split_percent'],
            start_date: config['start_date'],
            created_at: config['created_at'],
            updated_at: config['updated_at']
          )
        end
      end

      context 'with error revenue_config response' do
        let(:error) { double(msg: 'failed something') }

        it 'should raise error' do
          expect_any_instance_of(::Code::Justin::Tv::Revenue::Subscriptions::SubscriptionsClient).to receive(:get_revenue_configs_by_product_i_d).with({product_id: product_id}).and_return(get_revenue_configs_by_id_response)
          expect {subject}.to raise_error(error.msg)
        end
      end
    end

    describe 'get_by_id' do
      let(:id) { 'id' }
      let(:config) do
        {
          'id' => id,
          'product_id' => 'product_id',
          'rev_split_percent' => 50,
          'start_date' => '2020-02-02T00:00:00.000Z'
        }
      end
      let(:revenue_config_data) { double(revenue_config: config)}
      let(:get_revenue_config_response) { double(error: error, data: revenue_config_data) }

      subject { RevenueConfig.get_by_id(id) }

      context 'with successful revenue_config response' do
        let(:error) { nil }

        it 'should call twirp_client get_revenue_config and returns revenue_config object' do
          expect_any_instance_of(::Code::Justin::Tv::Revenue::Subscriptions::SubscriptionsClient).to receive(:get_revenue_config).with({revenue_config_id: id}).and_return(get_revenue_config_response)
          expect(subject).to have_attributes(
            id: config['id'],
            product_id: config['product_id'],
            rev_split_percent: config['rev_split_percent'],
            start_date: config['start_date']
          )
        end
      end

      context 'with error revenue_config response' do
        let(:error) { double(msg: 'failed something') }

        it 'should raise error' do
          expect_any_instance_of(::Code::Justin::Tv::Revenue::Subscriptions::SubscriptionsClient).to receive(:get_revenue_config).with({revenue_config_id: id}).and_return(get_revenue_config_response)
          expect {subject}.to raise_error(error.msg)
        end
      end
    end

    describe 'delete' do
      let(:id) { 'id' }
      let(:config) { { 'id' => id } }
      let(:revenue_config_data) { double(revenue_config: config) }
      let(:delete_revenue_config_response) { double(error: error, data: revenue_config_data) }

      subject { RevenueConfig.delete(id) }

      context 'with successful revenue_config response' do
        let(:error) { nil }

        it 'should call twirp_client delete_revenue_config and returns revenue_config object' do
          expect_any_instance_of(::Code::Justin::Tv::Revenue::Subscriptions::SubscriptionsClient).to receive(:delete_revenue_config).with({revenue_config_id: id}).and_return(delete_revenue_config_response)
          expect(subject).to have_attributes(id: config['id'])
        end
      end

      context 'with error revenue_config response' do
        let(:error) { double(msg: 'failed something') }

        it 'should raise error' do
          expect_any_instance_of(::Code::Justin::Tv::Revenue::Subscriptions::SubscriptionsClient).to receive(:delete_revenue_config).with({revenue_config_id: id}).and_return(delete_revenue_config_response)
          expect {subject}.to raise_error(error.msg)
        end
      end
    end

    describe 'create' do
      let(:id) { 'id' }
      let(:product_id) { 'product_id' }
      let(:start_date) { '2020-02-02T00:00:00.000Z' }
      let(:rev_split_percent) { '30' }
      let(:revenue_config_data) do
        double(revenue_config: {
          'id' => id,
          'product_id' => product_id,
          'start_date' => start_date,
          'rev_split_percent' => rev_split_percent
        })
      end
      let(:create_revenue_config_response) { double(error: error, data: revenue_config_data) }

      let(:params) do
        {
          product_id: product_id,
          start_date: RevenueConfig.time_to_protobuf_timestamp(start_date),
          rev_split_percent: rev_split_percent.to_i
        }
      end

      subject { RevenueConfig.create(product_id, start_date, rev_split_percent) }

      context 'with successful revenue_config response' do
        let(:error) { nil }

        it 'should call twirp_client create_revenue_config and returns revenue_config object' do
          expect_any_instance_of(::Code::Justin::Tv::Revenue::Subscriptions::SubscriptionsClient).to receive(:create_revenue_config).with(params).and_return(create_revenue_config_response)
          expect(subject).to have_attributes(id: id, product_id: product_id, start_date: start_date, rev_split_percent: rev_split_percent)
        end
      end

      context 'with error revenue_config response' do
        let(:error) { double(msg: 'failed something') }

        it 'should raise error' do
          expect_any_instance_of(::Code::Justin::Tv::Revenue::Subscriptions::SubscriptionsClient).to receive(:create_revenue_config).with(params).and_return(create_revenue_config_response)
          expect {subject}.to raise_error(error.msg)
        end
      end
    end

    describe 'update' do
      let(:id) { 'id' }
      let(:product_id) { 'product_id' }
      let(:start_date) { '2020-02-02T00:00:00.000Z' }
      let(:rev_split_percent) { '30' }

      let(:revenue_config_data) do
        double(revenue_config: {
          'id' => id,
          'product_id' => product_id,
          'start_date' => start_date,
          'rev_split_percent' => rev_split_percent
        })
      end

      let(:update_revenue_config_response) {double(error: error, data: revenue_config_data)}
      let(:params) do
        {
          revenue_config_id: id,
          start_date: RevenueConfig.time_to_protobuf_timestamp(start_date),
          rev_split_percent: rev_split_percent.to_i
        }
      end

      subject { RevenueConfig.update(id, start_date, rev_split_percent) }

      context 'with successful revenue_config response' do
        let(:error) { nil }

        it 'should call twirp_client update_revenue_config and returns revenue_config object' do
          expect_any_instance_of(::Code::Justin::Tv::Revenue::Subscriptions::SubscriptionsClient).to receive(:update_revenue_config).with(params).and_return(update_revenue_config_response)
          expect(subject).to have_attributes(id: id, product_id: product_id, start_date: start_date, rev_split_percent: rev_split_percent)
        end
      end

      context 'with error revenue_config response' do
        let(:error) { double(msg: 'failed something') }

        it 'should raise error' do
          expect_any_instance_of(::Code::Justin::Tv::Revenue::Subscriptions::SubscriptionsClient).to receive(:update_revenue_config).with(params).and_return(update_revenue_config_response)
          expect {subject}.to raise_error(error.msg)
        end
      end
    end
  end
end
