report_spec.rb - reportable - Fork of reportable required by WarVox, from hdm/reportable.
 (HTM) git clone git://jay.scot/reportable
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
       ---
       report_spec.rb (29936B)
       ---
            1 require File.join(File.dirname(File.dirname(File.expand_path(__FILE__))),'spec_helper')
            2 
            3 describe Saulabs::Reportable::Report do
            4 
            5   before do
            6     @report = Saulabs::Reportable::Report.new(User, :registrations)
            7     @now    = Time.now
            8     DateTime.stub!(:now).and_return(@now)
            9   end
           10 
           11   describe '#options' do
           12 
           13     it 'should be frozen' do
           14       @report.options.should be_frozen
           15     end
           16 
           17   end
           18 
           19   describe '#run' do
           20 
           21     it 'should process the data with the report cache' do
           22       Saulabs::Reportable::ReportCache.should_receive(:process).once.with(
           23         @report,
           24 
           25         { :limit => 100, :grouping => @report.options[:grouping], :conditions => [], :include => [], :live_data => false, :end_date => false, :distinct => false, :cacheable => true }
           26       )
           27 
           28       @report.run
           29     end
           30 
           31     it 'should process the data with the report cache when custom conditions are given' do
           32       Saulabs::Reportable::ReportCache.should_receive(:process).once.with(
           33         @report,
           34         { :limit => 100, :grouping => @report.options[:grouping], :conditions => { :some => :condition }, :include => [], :live_data => false, :end_date => false, :distinct => false, :cacheable => true  }
           35       )
           36 
           37       @report.run(:conditions => { :some => :condition })
           38     end
           39 
           40     it 'should validate the specified options for the :run context' do
           41       @report.should_receive(:ensure_valid_options).once.with({ :limit => 3 }, :run)
           42 
           43       result = @report.run(:limit => 3)
           44     end
           45 
           46     it 'should use a custom grouping if one is specified' do
           47       grouping = Saulabs::Reportable::Grouping.new(:month)
           48       Saulabs::Reportable::Grouping.should_receive(:new).once.with(:month).and_return(grouping)
           49       Saulabs::Reportable::ReportCache.should_receive(:process).once.with(
           50         @report,
           51         { :limit => 100, :grouping => grouping, :conditions => [], :live_data => false, :end_date => false, :distinct => false, :include => [], :cacheable => true  }
           52       )
           53 
           54       @report.run(:grouping => :month)
           55     end
           56 
           57     it 'should return an array of the same length as the specified limit when :live_data is false' do
           58       @report = Saulabs::Reportable::Report.new(User, :cumulated_registrations, :limit => 10, :live_data => false)
           59 
           60       @report.run.to_a.length.should == 10
           61     end
           62 
           63     it 'should return an array of the same length as the specified limit + 1 when :live_data is true' do
           64       @report = Saulabs::Reportable::Report.new(User, :cumulated_registrations, :limit => 10, :live_data => true)
           65 
           66       @report.run.to_a.length.should == 11
           67     end
           68 
           69     %w(hour day week month).each do |grouping|
           70       grouping = grouping.to_sym
           71 
           72       describe "for grouping :#{grouping.to_s}" do
           73 
           74         before(:all) do
           75           User.create!(:login => 'test 1', :created_at => Time.now,                    :profile_visits => 2, :sub_type => "red")
           76           User.create!(:login => 'test 2', :created_at => Time.now - 1.send(grouping), :profile_visits => 1, :sub_type => "red")
           77           User.create!(:login => 'test 3', :created_at => Time.now - 3.send(grouping), :profile_visits => 2, :sub_type => "blue")
           78           User.create!(:login => 'test 4', :created_at => Time.now - 3.send(grouping), :profile_visits => 3, :sub_type => "blue")
           79         end
           80 
           81         describe 'optimized querying with contiguously cached data' do
           82           it "should be optimized with specified end_date" do
           83             @end_date = DateTime.now - 1.send(grouping)
           84             @report = Saulabs::Reportable::Report.new(User, :registrations,
           85               :grouping => grouping,
           86               :limit    => 10,
           87               :end_date => @end_date
           88             )
           89             @result = @report.run
           90 
           91             Saulabs::Reportable::ReportCache.last.delete
           92 
           93             grouping_instance = Saulabs::Reportable::Grouping.new(grouping)
           94             reporting_period = Saulabs::Reportable::ReportingPeriod.new(grouping_instance, @end_date)
           95 
           96             @report.should_receive(:read_data) do |begin_at, end_at, options|
           97               begin_at.should == reporting_period.date_time
           98               end_at.should == reporting_period.last_date_time
           99               [] # without this rspec whines about an ambiguous return value
          100             end
          101 
          102             @result = @report.run
          103           end
          104 
          105           it "should be optimized without specific end_date and live_data" do
          106             @report = Saulabs::Reportable::Report.new(User, :registrations,
          107               :grouping => grouping,
          108               :limit    => 10,
          109               :live_data => true
          110             )
          111             @result = @report.run.to_a
          112 
          113             Saulabs::Reportable::ReportCache.last.delete
          114 
          115             grouping_instance = Saulabs::Reportable::Grouping.new(grouping)
          116             reporting_period = Saulabs::Reportable::ReportingPeriod.new(grouping_instance, DateTime.now).previous
          117 
          118             @report.should_receive(:read_data) do |begin_at, end_at, options|
          119               begin_at.should == reporting_period.date_time
          120               end_at.should == nil
          121               [] # without this rspec whines about an ambiguous return value
          122             end
          123 
          124             @result = @report.run
          125           end
          126 
          127           it "should be optimized without specific end_date and without live_data requested" do
          128             @report = Saulabs::Reportable::Report.new(User, :registrations,
          129               :grouping => grouping,
          130               :limit    => 10
          131             )
          132             @result = @report.run.to_a
          133 
          134             Saulabs::Reportable::ReportCache.last.delete
          135 
          136             grouping_instance = Saulabs::Reportable::Grouping.new(grouping)
          137             reporting_period = Saulabs::Reportable::ReportingPeriod.new(grouping_instance, DateTime.now).previous
          138 
          139             @report.should_receive(:read_data) do |begin_at, end_at, options|
          140               begin_at.should == reporting_period.date_time
          141               end_at.should == nil
          142               [] # without this rspec whines about an ambiguous return value
          143             end
          144 
          145             @result = @report.run
          146           end
          147         end
          148 
          149         describe 'non optimized querying when gaps present in cached data' do
          150           it "should not be optimized with specified end_date" do
          151             @end_date = DateTime.now - 1.send(grouping)
          152             @report = Saulabs::Reportable::Report.new(User, :registrations,
          153               :grouping => grouping,
          154               :limit    => 10,
          155               :end_date => @end_date
          156             )
          157             @result = @report.run
          158 
          159             Saulabs::Reportable::ReportCache.first.delete
          160 
          161             grouping_instance = Saulabs::Reportable::Grouping.new(grouping)
          162             reporting_period = Saulabs::Reportable::ReportingPeriod.new(grouping_instance, @end_date)
          163 
          164             @report.should_receive(:read_data) do |begin_at, end_at, options|
          165               begin_at.should == reporting_period.offset(-9).date_time
          166               end_at.should == reporting_period.last_date_time
          167               [] # without this rspec whines about an ambiguous return value
          168             end
          169 
          170             @result = @report.run
          171           end
          172 
          173           it "should not be optimized without specific end_date and live_data" do
          174             @report = Saulabs::Reportable::Report.new(User, :registrations,
          175               :grouping => grouping,
          176               :limit    => 10,
          177               :live_data => true
          178             )
          179             @result = @report.run.to_a
          180 
          181             Saulabs::Reportable::ReportCache.first.delete
          182 
          183             grouping_instance = Saulabs::Reportable::Grouping.new(grouping)
          184             reporting_period = Saulabs::Reportable::ReportingPeriod.new(grouping_instance, DateTime.now).previous
          185 
          186             @report.should_receive(:read_data) do |begin_at, end_at, options|
          187               begin_at.should == reporting_period.offset(-9).date_time
          188               end_at.should == nil
          189               [] # without this rspec whines about an ambiguous return value
          190             end
          191 
          192             @result = @report.run
          193           end
          194 
          195           it "should not be optimized without specific end_date and without live_data requested" do
          196             @report = Saulabs::Reportable::Report.new(User, :registrations,
          197               :grouping => grouping,
          198               :limit    => 10
          199             )
          200             @result = @report.run.to_a
          201 
          202             Saulabs::Reportable::ReportCache.first.delete
          203 
          204             grouping_instance = Saulabs::Reportable::Grouping.new(grouping)
          205             reporting_period = Saulabs::Reportable::ReportingPeriod.new(grouping_instance, DateTime.now).previous
          206 
          207             @report.should_receive(:read_data) do |begin_at, end_at, options|
          208               begin_at.should == reporting_period.offset(-9).date_time
          209               end_at.should == nil
          210               [] # without this rspec whines about an ambiguous return value
          211             end
          212 
          213             @result = @report.run
          214           end
          215         end
          216 
          217         describe 'when :end_date is specified' do
          218 
          219           it 'should not raise a SQL duplicate key error after multiple runs' do
          220             @report = Saulabs::Reportable::Report.new(User, :registrations,
          221               :limit    => 2,
          222               :grouping => grouping,
          223               :end_date => Date.yesterday.to_datetime
          224             )
          225             @report.run
          226             lambda { @report.run }.should_not raise_error
          227           end
          228 
          229           describe 'the returned result' do
          230 
          231             before do
          232               @end_date = DateTime.now - 1.send(grouping)
          233               @grouping = Saulabs::Reportable::Grouping.new(grouping)
          234               @report = Saulabs::Reportable::Report.new(User, :registrations,
          235                 :grouping => grouping,
          236                 :limit    => 10,
          237                 :end_date => @end_date
          238               )
          239               @result = @report.run.to_a
          240             end
          241 
          242             it "should start with the reporting period (end_date - limit.#{grouping.to_s})" do
          243               @result.first[0].should == Saulabs::Reportable::ReportingPeriod.new(@grouping, @end_date - 9.send(grouping)).date_time
          244             end
          245 
          246             it "should end with the reporting period of the specified end date" do
          247               @result.last[0].should == Saulabs::Reportable::ReportingPeriod.new(@grouping, @end_date).date_time
          248             end
          249 
          250           end
          251 
          252         end
          253 
          254         [true, false].each do |live_data|
          255 
          256           describe "with :live_data = #{live_data}" do
          257 
          258             describe 'the returned result' do
          259 
          260               before do
          261                 Saulabs::Reportable::ReportCache.delete_all
          262                 @grouping = Saulabs::Reportable::Grouping.new(grouping)
          263                 @report = Saulabs::Reportable::Report.new(User, :registrations,
          264                   :grouping  => grouping,
          265                   :limit     => 10,
          266                   :live_data => live_data
          267                 )
          268                 @result = @report.run.to_a
          269               end
          270 
          271               it "should be an array starting reporting period (Time.now - limit.#{grouping.to_s})" do
          272                 @result.first[0].should == Saulabs::Reportable::ReportingPeriod.new(@grouping, Time.now - 10.send(grouping)).date_time
          273               end
          274 
          275               if live_data
          276                 it "should be data ending with the current reporting period" do
          277                   @result.last[0].should == Saulabs::Reportable::ReportingPeriod.new(@grouping).date_time
          278                 end
          279               else
          280                 it "should be data ending with the reporting period before the current" do
          281                   @result.last[0].should == Saulabs::Reportable::ReportingPeriod.new(@grouping).previous.date_time
          282                 end
          283               end
          284 
          285             end
          286 
          287             it 'should return correct data for aggregation :count' do
          288               @report = Saulabs::Reportable::Report.new(User, :registrations,
          289                 :aggregation => :count,
          290                 :grouping    => grouping,
          291                 :limit       => 10,
          292                 :live_data   => live_data
          293               )
          294               result = @report.run.to_a
          295 
          296               result[10][1].should == 1.0 if live_data
          297               result[9][1].should  == 1.0
          298               result[8][1].should  == 0.0
          299               result[7][1].should  == 2.0
          300               result[6][1].should  == 0.0
          301             end
          302 
          303             it 'should return correct data for aggregation :count with distinct: true' do
          304               @report = Saulabs::Reportable::Report.new(User, :registrations,
          305                 :aggregation => :count,
          306                 :grouping    => grouping,
          307                 :value_column => :sub_type,
          308                 :distinct    => true,
          309                 :limit       => 10,
          310                 :live_data   => live_data
          311               )
          312               result = @report.run.to_a
          313 
          314               result[10][1].should == 1.0 if live_data
          315               result[9][1].should  == 1.0
          316               result[8][1].should  == 0.0
          317               result[7][1].should  == 1.0
          318               result[6][1].should  == 0.0
          319             end
          320 
          321             it 'should return correct data for aggregation :sum' do
          322               @report = Saulabs::Reportable::Report.new(User, :registrations,
          323                 :aggregation  => :sum,
          324                 :grouping     => grouping,
          325                 :value_column => :profile_visits,
          326                 :limit        => 10,
          327                 :live_data    => live_data
          328               )
          329               result = @report.run().to_a
          330 
          331               result[10][1].should == 2.0 if live_data
          332               result[9][1].should  == 1.0
          333               result[8][1].should  == 0.0
          334               result[7][1].should  == 5.0
          335               result[6][1].should  == 0.0
          336             end
          337 
          338             it 'should return correct data for aggregation :maximum' do
          339               @report = Saulabs::Reportable::Report.new(User, :registrations,
          340                 :aggregation  => :maximum,
          341                 :grouping     => grouping,
          342                 :value_column => :profile_visits,
          343                 :limit        => 10,
          344                 :live_data    => live_data
          345               )
          346               result = @report.run().to_a
          347 
          348               result[10][1].should == 2.0 if live_data
          349               result[9][1].should  == 1.0
          350               result[8][1].should  == 0.0
          351               result[7][1].should  == 3.0
          352               result[6][1].should  == 0.0
          353             end
          354 
          355             it 'should return correct data for aggregation :minimum' do
          356               @report = Saulabs::Reportable::Report.new(User, :registrations,
          357                 :aggregation  => :minimum,
          358                 :grouping     => grouping,
          359                 :value_column => :profile_visits,
          360                 :limit        => 10,
          361                 :live_data    => live_data
          362               )
          363               result = @report.run().to_a
          364 
          365               result[10][1].should == 2.0 if live_data
          366               result[9][1].should  == 1.0
          367               result[8][1].should  == 0.0
          368               result[7][1].should  == 2.0
          369               result[6][1].should  == 0.0
          370             end
          371 
          372             it 'should return correct data for aggregation :average' do
          373               @report = Saulabs::Reportable::Report.new(User, :registrations,
          374                 :aggregation  => :average,
          375                 :grouping     => grouping,
          376                 :value_column => :profile_visits,
          377                 :limit        => 10,
          378                 :live_data    => live_data
          379               )
          380               result = @report.run().to_a
          381 
          382               result[10][1].should == 2.0 if live_data
          383               result[9][1].should  == 1.0
          384               result[8][1].should  == 0.0
          385               result[7][1].should  == 2.5
          386               result[6][1].should  == 0.0
          387             end
          388 
          389             it 'should return correct data for aggregation :count when custom conditions are specified' do
          390               @report = Saulabs::Reportable::Report.new(User, :registrations,
          391                 :aggregation => :count,
          392                 :grouping    => grouping,
          393                 :limit       => 10,
          394                 :live_data   => live_data
          395               )
          396               result = @report.run(:conditions => ['login IN (?)', ['test 1', 'test 2', 'test 4']]).to_a
          397 
          398               result[10][1].should == 1.0 if live_data
          399               result[9][1].should  == 1.0
          400               result[8][1].should  == 0.0
          401               result[7][1].should  == 1.0
          402               result[6][1].should  == 0.0
          403             end
          404 
          405             it 'should return correct data for aggregation :sum when custom conditions are specified' do
          406               @report = Saulabs::Reportable::Report.new(User, :registrations,
          407                 :aggregation  => :sum,
          408                 :grouping     => grouping,
          409                 :value_column => :profile_visits,
          410                 :limit        => 10,
          411                 :live_data    => live_data
          412               )
          413               result = @report.run(:conditions => ['login IN (?)', ['test 1', 'test 2', 'test 4']]).to_a
          414 
          415               result[10][1].should == 2.0 if live_data
          416               result[9][1].should  == 1.0
          417               result[8][1].should  == 0.0
          418               result[7][1].should  == 3.0
          419               result[6][1].should  == 0.0
          420             end
          421 
          422             it 'should return correct results when run twice in a row with a higher limit on the second run' do
          423               @report = Saulabs::Reportable::Report.new(User, :registrations,
          424                 :aggregation => :count,
          425                 :grouping    => grouping,
          426                 :limit       => 10,
          427                 :live_data   => live_data
          428               )
          429               result = @report.run(:limit => 2).to_a
          430 
          431               result[2][1].should == 1.0 if live_data
          432               result[1][1].should  == 1.0
          433               result[0][1].should  == 0.0
          434 
          435               result = @report.run(:limit => 10).to_a
          436 
          437               result[10][1].should == 1.0 if live_data
          438               result[9][1].should  == 1.0
          439               result[8][1].should  == 0.0
          440               result[7][1].should  == 2.0
          441               result[6][1].should  == 0.0
          442             end
          443 
          444             unless live_data
          445 
          446               it 'should return correct data for aggregation :count when :end_date is specified' do
          447                 @report = Saulabs::Reportable::Report.new(User, :registrations,
          448                   :aggregation => :count,
          449                   :grouping    => grouping,
          450                   :limit       => 10,
          451                   :end_date    => Time.now - 3.send(grouping)
          452                 )
          453                 result = @report.run.to_a
          454 
          455                 result[9][1].should  == 2.0
          456                 result[8][1].should  == 0.0
          457                 result[7][1].should  == 0.0
          458                 result[6][1].should  == 0.0
          459               end
          460 
          461               it 'should return correct data for aggregation :sum when :end_date is specified' do
          462                 @report = Saulabs::Reportable::Report.new(User, :registrations,
          463                   :aggregation  => :sum,
          464                   :grouping     => grouping,
          465                   :value_column => :profile_visits,
          466                   :limit        => 10,
          467                   :end_date     => Time.now - 3.send(grouping)
          468                 )
          469                 result = @report.run.to_a
          470 
          471                 result[9][1].should  == 5.0
          472                 result[8][1].should  == 0.0
          473                 result[7][1].should  == 0.0
          474                 result[6][1].should  == 0.0
          475               end
          476 
          477               it 'should return correct results when run twice in a row with an end date further in the past on the second run' do
          478                 @report = Saulabs::Reportable::Report.new(User, :registrations,
          479                   :aggregation => :count,
          480                   :grouping    => grouping,
          481                   :limit       => 10,
          482                   :live_data   => live_data
          483                 )
          484                 result = @report.run(:end_date => Time.now - 1.send(grouping)).to_a
          485 
          486                 result[9][1].should  == 1.0
          487                 result[8][1].should  == 0.0
          488                 result[7][1].should  == 2.0
          489 
          490                 result = @report.run(:end_date => Time.now - 3.send(grouping)).to_a
          491 
          492                 result[9][1].should  == 2.0
          493                 result[8][1].should  == 0.0
          494                 result[7][1].should  == 0.0
          495               end
          496 
          497             end
          498 
          499           end
          500 
          501         end
          502 
          503         after(:all) do
          504           User.destroy_all
          505         end
          506 
          507       end
          508 
          509     end
          510 
          511     describe 'for grouping week with data ranging over two years' do
          512 
          513       describe 'with the first week of the second year belonging to the first year' do
          514 
          515         before(:all) do
          516           User.create!(:login => 'test 1', :created_at => DateTime.new(2008, 12, 22))
          517           User.create!(:login => 'test 2', :created_at => DateTime.new(2008, 12, 29))
          518           User.create!(:login => 'test 3', :created_at => DateTime.new(2009, 1, 4))
          519           User.create!(:login => 'test 4', :created_at => DateTime.new(2009, 1, 5))
          520           User.create!(:login => 'test 5', :created_at => DateTime.new(2009, 1, 12))
          521 
          522           Time.stub!(:now).and_return(DateTime.new(2009, 1, 25))
          523         end
          524 
          525         it 'should return correct data for aggregation :count' do
          526           @report = Saulabs::Reportable::Report.new(User, :registrations,
          527             :aggregation => :count,
          528             :grouping    => :week,
          529             :limit       => 10
          530           )
          531           result = @report.run.to_a
          532 
          533           result[9][1].should  == 0.0
          534           result[8][1].should  == 1.0
          535           result[7][1].should  == 1.0
          536           result[6][1].should  == 2.0
          537           result[5][1].should  == 1.0
          538         end
          539 
          540       end
          541 
          542       describe 'with the first week of the second year belonging to the second year' do
          543 
          544         before(:all) do
          545           User.create!(:login => 'test 1', :created_at => DateTime.new(2009, 12, 21))
          546           User.create!(:login => 'test 2', :created_at => DateTime.new(2009, 12, 28))
          547           User.create!(:login => 'test 3', :created_at => DateTime.new(2010, 1, 3))
          548           User.create!(:login => 'test 4', :created_at => DateTime.new(2010, 1, 4))
          549           User.create!(:login => 'test 5', :created_at => DateTime.new(2010, 1, 11))
          550 
          551           Time.stub!(:now).and_return(DateTime.new(2010, 1, 25))
          552         end
          553 
          554         it 'should return correct data for aggregation :count' do
          555           @report = Saulabs::Reportable::Report.new(User, :registrations,
          556             :aggregation => :count,
          557             :grouping    => :week,
          558             :limit       => 10
          559           )
          560           result = @report.run.to_a
          561 
          562           result[9][1].should  == 0.0
          563           result[8][1].should  == 1.0
          564           result[7][1].should  == 1.0
          565           result[6][1].should  == 2.0
          566           result[5][1].should  == 1.0
          567         end
          568 
          569       end
          570 
          571     end
          572 
          573     after do
          574       Saulabs::Reportable::ReportCache.destroy_all
          575     end
          576 
          577     after(:all) do
          578       User.destroy_all
          579     end
          580 
          581   end
          582 
          583   describe '#read_data' do
          584 
          585     xit 'should invoke the aggregation method on the model' do
          586       @report = Saulabs::Reportable::Report.new(User, :registrations, :aggregation => :count)
          587       User.should_receive(:count).once.and_return([])
          588 
          589       @report.send(:read_data, Time.now, 5.days.from_now, { :grouping => @report.options[:grouping], :conditions => [] })
          590     end
          591 
          592     it 'should setup the conditions' do
          593       @report.should_receive(:setup_conditions).once.and_return([])
          594 
          595       @report.send(:read_data, Time.now, 5.days.from_now, { :grouping => @report.options[:grouping], :conditions => [] })
          596     end
          597 
          598   end
          599 
          600   describe '#setup_conditions' do
          601 
          602     before do
          603       @begin_at = Time.now
          604       @end_at = 5.days.from_now
          605       @created_at_column_clause = "#{ActiveRecord::Base.connection.quote_table_name('users')}.#{ActiveRecord::Base.connection.quote_column_name('created_at')}"
          606     end
          607 
          608     it 'should return conditions for date_column BETWEEN begin_at and end_at only when no custom conditions are specified and both begin and end date are specified' do
          609       @report.send(:setup_conditions, @begin_at, @end_at).should == ["#{@created_at_column_clause} BETWEEN ? AND ?", @begin_at, @end_at]
          610     end
          611 
          612     it 'should return conditions for date_column >= begin_at when no custom conditions and a begin_at are specified' do
          613       @report.send(:setup_conditions, @begin_at, nil).should == ["#{@created_at_column_clause} >= ?", @begin_at]
          614     end
          615 
          616     it 'should return conditions for date_column <= end_at when no custom conditions and a end_at are specified' do
          617       @report.send(:setup_conditions, nil, @end_at).should == ["#{@created_at_column_clause} <= ?", @end_at]
          618     end
          619 
          620     it 'should raise an argument error when neither begin_at or end_at are specified' do
          621       lambda {@report.send(:setup_conditions, nil, nil)}.should raise_error(ArgumentError)
          622     end
          623 
          624     it 'should return conditions for date_column BETWEEN begin_at and end_date only when an empty Hash of custom conditions is specified' do
          625       @report.send(:setup_conditions, @begin_at, @end_at, {}).should == ["#{@created_at_column_clause} BETWEEN ? AND ?", @begin_at, @end_at]
          626     end
          627 
          628     it 'should return conditions for date_column BETWEEN begin_at and end_date only when an empty Array of custom conditions is specified' do
          629       @report.send(:setup_conditions, @begin_at, @end_at, []).should == ["#{@created_at_column_clause} BETWEEN ? AND ?", @begin_at, @end_at]
          630     end
          631 
          632     it 'should correctly include custom conditions if they are specified as a Hash' do
          633       custom_conditions = { :first_name => 'first name', :last_name => 'last name' }
          634 
          635       conditions = @report.send(:setup_conditions, @begin_at, @end_at, custom_conditions)
          636       # cannot directly check for string equqlity here since hashes are not ordered and so there is no way to now in which order the conditions are added to the SQL clause
          637       conditions[0].should =~ (/#{ActiveRecord::Base.connection.quote_table_name('users')}.#{ActiveRecord::Base.connection.quote_column_name('first_name')} = #{ActiveRecord::Base.connection.quote('first name')}/)
          638       conditions[0].should =~ (/#{ActiveRecord::Base.connection.quote_table_name('users')}.#{ActiveRecord::Base.connection.quote_column_name('last_name')} = #{ActiveRecord::Base.connection.quote('last name')}/)
          639       conditions[0].should =~ (/#{@created_at_column_clause} BETWEEN \? AND \?/)
          640       conditions[1].should == @begin_at
          641       conditions[2].should == @end_at
          642     end
          643 
          644     it 'should correctly include custom conditions if they are specified as an Array' do
          645       custom_conditions = ['first_name = ? AND last_name = ?', 'first name', 'last name']
          646 
          647       @report.send(:setup_conditions, @begin_at, @end_at, custom_conditions).should == ["first_name = #{ActiveRecord::Base.connection.quote('first name')} AND last_name = #{ActiveRecord::Base.connection.quote('last name')} AND #{@created_at_column_clause} BETWEEN ? AND ?", @begin_at, @end_at]
          648     end
          649 
          650   end
          651 
          652   describe '#ensure_valid_options' do
          653 
          654     it 'should raise an error if malformed conditions are specified' do
          655       lambda { @report.send(:ensure_valid_options, { :conditions => 1 }) }.should raise_error(ArgumentError)
          656     end
          657 
          658     it 'should not raise an error if conditions are specified as an Array' do
          659       lambda { @report.send(:ensure_valid_options, { :conditions => ['first_name = ?', 'first name'] }) }.should_not raise_error(ArgumentError)
          660     end
          661 
          662     it 'should not raise an error if conditions are specified as a Hash' do
          663       lambda { @report.send(:ensure_valid_options, { :conditions => { :first_name => 'first name' } }) }.should_not raise_error(ArgumentError)
          664     end
          665 
          666     it 'should raise an error if an invalid grouping is specified' do
          667       lambda { @report.send(:ensure_valid_options, { :grouping => :decade }) }.should raise_error(ArgumentError)
          668     end
          669 
          670     it 'should raise an error if an end date is specified that is not a DateTime' do
          671       lambda { @report.send(:ensure_valid_options, { :end_date => 'today' }) }.should raise_error(ArgumentError)
          672     end
          673 
          674     it 'should raise an error if an end date is specified that is in the future' do
          675       lambda { @report.send(:ensure_valid_options, { :end_date => (DateTime.now + 1.month) }) }.should raise_error(ArgumentError)
          676     end
          677 
          678     it 'should raise an error if both an end date and :live_data = true are specified' do
          679       lambda { @report.send(:ensure_valid_options, { :end_date => DateTime.now, :live_data => true }) }.should raise_error(ArgumentError)
          680     end
          681 
          682     it 'should not raise an error if both an end date and :live_data = false are specified' do
          683       lambda { @report.send(:ensure_valid_options, { :end_date => DateTime.now, :live_data => false }) }.should_not raise_error
          684     end
          685 
          686     describe 'for context :initialize' do
          687 
          688       it 'should not raise an error if valid options are specified' do
          689         lambda { @report.send(:ensure_valid_options, {
          690             :limit        => 100,
          691             :aggregation  => :count,
          692             :grouping     => :day,
          693             :date_column  => :created_at,
          694             :value_column => :id,
          695             :conditions   => [],
          696             :live_data    => true
          697           })
          698         }.should_not raise_error(ArgumentError)
          699       end
          700 
          701       it 'should raise an error if an unsupported option is specified' do
          702         lambda { @report.send(:ensure_valid_options, { :invalid => :option }) }.should raise_error(ArgumentError)
          703       end
          704 
          705       it 'should raise an error if an invalid aggregation is specified' do
          706         lambda { @report.send(:ensure_valid_options, { :aggregation => :invalid }) }.should raise_error(ArgumentError)
          707       end
          708 
          709       it 'should raise an error if aggregation :sum is spesicied but no :value_column' do
          710         lambda { @report.send(:ensure_valid_options, { :aggregation => :sum }) }.should raise_error(ArgumentError)
          711       end
          712 
          713     end
          714 
          715     describe 'for context :run' do
          716 
          717       it 'should not raise an error if valid options are specified' do
          718         lambda { @report.send(:ensure_valid_options, { :limit => 100, :conditions => [], :grouping => :week, :live_data => true }, :run)
          719         }.should_not raise_error(ArgumentError)
          720       end
          721 
          722       it 'should raise an error if an unsupported option is specified' do
          723         lambda { @report.send(:ensure_valid_options, { :aggregation => :sum }, :run) }.should raise_error(ArgumentError)
          724       end
          725 
          726     end
          727 
          728   end
          729 
          730 end