require 'rails_helper'

RSpec.describe Ads::SettingsController do
  include_context 'mocked permissions'

  let(:fake_siosa_client) { double(:error => 'hello') }
  let(:permission) { 'broadcaster_ad_settings' }
  let(:random_id) { "id" }
  let(:save_response) { double(:error => nil) }
  let(:test_response) {
    double(
      :error => nil,
      :data => 
        double(
          :channel_id => "12345",
          :valid_responses => 
            double(
              :properties => [
                double(
                  :prerolls_disabled => false,
                  :postrolls_disabled => false,
                  :frequency => 0,
                  :max_ad_break_length => 0,
                  :vod_ads_enabled => false,
                  :vod_archive_midrolls => "",
                  :vod_archive_midrolls_frequency => 0,
                  :vod_archive_midrolls_break_length => 0,
                  :turbo_disabled => false,
                  :force_server_ads => false,
                  :guarantee_ads => false,
                  :ad_server_default => "VAES",
                  :force_client_ads => false,
                  :required_age => 0,
                  :campaign_type => "",
                  :tracking_pixels => nil,
                  :pbyp_disabled => false,
                  :disable_prerolls_feature_enabled => false,
                  :disable_prerolls_feature_admin_enabled => false,
                  :disable_prerolls_feature_values => nil,
                  :costreamers => nil
                ),
                double(
                  :prerolls_disabled => true,
                  :postrolls_disabled => false,
                  :frequency => 5,
                  :max_ad_break_length => 0,
                  :vod_ads_enabled => false,
                  :vod_archive_midrolls => "",
                  :vod_archive_midrolls_frequency => 0,
                  :vod_archive_midrolls_break_length => 0,
                  :turbo_disabled => false,
                  :force_server_ads => false,
                  :guarantee_ads => false,
                  :ad_server_default => "VAES",
                  :force_client_ads => false,
                  :required_age => 0,
                  :campaign_type => "",
                  :tracking_pixels => nil,
                  :pbyp_disabled => false,
                  :disable_prerolls_feature_enabled => false,
                  :disable_prerolls_feature_admin_enabled => false,
                  :disable_prerolls_feature_values => nil,
                  :costreamers => nil
                ),
                double(
                  :prerolls_disabled => false,
                  :postrolls_disabled => false,
                  :frequency => 0,
                  :max_ad_break_length => 0,
                  :vod_ads_enabled => false,
                  :vod_archive_midrolls => "",
                  :vod_archive_midrolls_frequency => 0,
                  :vod_archive_midrolls_break_length => 0,
                  :turbo_disabled => false,
                  :force_server_ads => false,
                  :guarantee_ads => true,
                  :ad_server_default => "VAES",
                  :force_client_ads => false,
                  :required_age => 0,
                  :campaign_type => "",
                  :tracking_pixels => nil,
                  :pbyp_disabled => false,
                  :disable_prerolls_feature_enabled => false,
                  :disable_prerolls_feature_admin_enabled => false,
                  :disable_prerolls_feature_values => nil,
                  :costreamers => nil
                )
              ]
            )
        ) 
    )
  }

  describe 'find' do
    context 'successful' do
      before do
        allow(Ads::Setting).to receive(:twirp_client).and_return(fake_siosa_client)
        allow(fake_siosa_client).to receive(:get_channel_ad_properties).and_return(test_response)
      end

      it 'sets the right properties' do
        settings = Ads::Setting.find(random_id)

        expect(settings.ad_server_default).to eq("VAES")
        expect(settings.prerolls_disabled).to eq(true)
        expect(settings.frequency).to eq(5)
        expect(settings.guarantee_ads).to eq(true)
      end
    end
  end

  describe 'update' do
    describe 'permissions' do
      let(:action) { :update }
      let(:dummy_setting) { Ads::Setting.new :channel_id => 'foo' }
      let(:vod_setting) { Ads::Setting.new :channel_id => 'foo', :vod_archive_midrolls_break_length => 60 }
      let(:populated_setting) do
        ad_setting_options = {
          :channel_id => 'foo',
          :vod_archive_midrolls_frequency => 10,
          :vod_archive_midrolls_break_length => 30
        }
        Ads::Setting.new ad_setting_options
      end
      let(:ad_break_properties) {({:frequency => 40, :max_break_length => 50}).to_json}
      let(:vod_archive_midrolls_settings) {({:frequency => 10, :break_length => 30}).to_json}
      let(:prerolls_disabled) { false }
      let(:postrolls_disabled) { false }
      let(:turbo_disabled) { false }
      let(:ad_server_default) { "VAES" }
      let(:force_client_ads) { false }
      let(:force_server_ads) { false }
      let(:guarantee_ads) { false }
      let(:pbyp_disabled) { true }
      let(:required_age) { 18 }
      let(:campaign_type) { "" }

      context 'a user with appropriate permissions' do
        include_context 'an authorized user'

        before do
          expect(fake_siosa_client).to receive(:set_channel_ad_properties).and_return(save_response)
          expect(Ads::Setting).to receive(:find).with('foo').and_return(dummy_setting, vod_setting).at_least(:once)
          expect(Ads::Setting).to receive(:twirp_client).and_return(fake_siosa_client).at_least(:once)
          params = {
            id: 'foo',
            ad_break_settings: ad_break_properties,
            ad_server_default: ad_server_default,
            vod_archive_midrolls_settings: vod_archive_midrolls_settings,
            prerolls_disabled: prerolls_disabled,
            postrolls_disabled: postrolls_disabled,
            required_age: required_age,
            campaign_type: campaign_type,
            turbo_disabled: turbo_disabled,
            force_client_ads: force_client_ads,
            force_server_ads: force_server_ads,
            guarantee_ads: guarantee_ads,
            pbyp_disabled: pbyp_disabled,
          }
          post action, :params => params
        end

        it_behaves_like 'it redirects the user and does not display an error'
      end

      context 'the update fails' do
        include_context 'an authorized user'

        before do
          expect(Ads::Setting).to receive(:find).with('foo').and_return(dummy_setting)
          expect(dummy_setting).to receive(:save).and_return(false)
          params = {
            id: 'foo',
            ad_break_settings: ad_break_properties,
            ad_server_default: ad_server_default,
            vod_archive_midrolls_settings: vod_archive_midrolls_settings,
            prerolls_disabled: prerolls_disabled, 
            postrolls_disabled: postrolls_disabled,
            required_age: required_age,
            campaign_type: campaign_type,
            turbo_disabled: turbo_disabled,
            force_client_ads: force_client_ads,
            force_server_ads: force_server_ads,
            guarantee_ads: guarantee_ads,
            pbyp_disabled: pbyp_disabled,
          }
          post action, :params => params
        end

        it_behaves_like 'it redirects the user and displays an error'
      end

      context 'a user without appropriate permissions' do
          include_context 'an unauthorized user'

        before do
          expect(Ads::Setting).to receive(:find).with('foo').and_return(dummy_setting)
          post action, :params => {:id => 'foo'}
        end

        it_behaves_like 'it redirects the user and displays an error'
      end
    end
  end
end
