require 'rails_helper'

describe TargetFile::MyTarget do
  subject { create 'target_file/my_target' }

  describe "#execute_generation_process" do

    it "generates the file" do
      subject.execute_generation_process

      subject.reload.should_not have_log_entries /ERROR/
      subject.should be_completed

      File.basename(subject.original_file.path).should == "my_target-#{Date.current.to_s(:number)}.csv.gz"

      actual_string = read_zipfile(subject.original_file.path)

      actual_string.should eq <<-EXP.strip_heredoc
        My;Content;From;Dummy;App
      EXP

      subject.size.should be_within(2).of(46)
    end
  end

  describe ".generate!" do
    it "creates an instance and executes the generation process" do
      expect_any_instance_of( described_class ).to receive(:execute_generation_process)
      described_class.generate!
    end
  end

  describe ".builder_class" do
    it "returns the proper builder class" do
      described_class.builder_class.should eq TargetFile::MyTargetCsvBuilder
    end
  end

  describe ".create_from_source_file!" do
    let(:source_file) { create('source_file/my_source', original_file: fixture_file("source_files/my_source_1.csv") ).execute_loading_process }
    let(:time) { '2016-03-09T18:22:40Z'.to_time }
    before { Timecop.freeze time }
    after { Timecop.return }

    it "generates a target file with proper content and attributes" do
      allow_any_instance_of(described_class).to receive(:gzip_file?).and_return false
      target_file = described_class.create_from_source_file!(source_file)
      target_file.should be_completed
      target_file.start_time.should be_a Time
      target_file.end_time.should be_a Time
      target_file.original_file.path.should include "files/target_file/my_target/original_file"
      target_file.original_file.path.should end_with "/my_target-20160309.csv" # take target file name, not source file name
      target_file.size.should be_within(3).of(100)
      target_file.number_of_records.should eq 2

      actual_string = read_zipfile(target_file.original_file.path)
      actual_string.should eq <<-CSV.strip_heredoc
        my_date,my_var,My count,my_num,my_truth
        2015-05-09,abc D,19,4.8,true
        2015-11-09,def G,19,7.8,false
      CSV
    end

    it "works when source file is .gz and target file has gzip_file? => true" do
      allow_any_instance_of(described_class).to receive(:gzip_file?).and_return true
      target_path = source_file.original_file.path + ".gz"
      Dunlop::FileZip.gzip(source_file.original_file.path, target_path)
      gzip_source_file = create("source_file/my_source", original_file: File.open(target_path))
      gzip_source_file.execute_loading_process

      target_file = described_class.create_from_source_file!(gzip_source_file)
      target_file.number_of_records.should eq 2
      target_file.size.should be_within(3).of(100)
    end
  end

  describe "#builder" do
    subject { described_class.new.builder }
    it "works with not implemented defaults" do
      subject.should be_a TargetFile::MyTargetCsvBuilder
      subject.options.should eq Hash.new
    end

    it "can implement custop options" do
      allow_any_instance_of( described_class ).to receive(:builder_options).and_return(has_custom_options: 8)
      subject.options.should eq(has_custom_options: 8)
    end

    it "implements default data behaviour expecting a good iteration resource not being enumerable, but responding to id" do
      allow_any_instance_of( described_class ).to receive(:resource).and_return(double(id: 8))
      subject.data.should eq "8\n"
    end

    it "implements default data behaviour expecting a good iteration resource" do
      allow_any_instance_of( described_class ).to receive(:resource).and_return([double(id: 8), double(id: 9)])
      subject.data.should eq "8\n9\n"
    end
  end

  describe '#default_file' do
    it "returns the original_file" do
      subject.default_file.original_filename.should include 'target_file_factory'
    end
  end
end
