<commit_before># frozen_string_literal: true

require "spec_helper"

describe Results::Csv::Generator, :reset_factory_sequences do
  let(:responses) { Response.with_associations.order(:created_at) }
  let(:generated_csv) { Results::Csv::Generator2.new(responses).to_s }
  let(:ordered_responses) { Response.with_associations.order(:created_at) }

  around do |example|
    # Use a weird timezone so we know times are handled properly.
    @old_tz = Time.zone
    Time.zone = ActiveSupport::TimeZone["Saskatchewan"]
    example.run
    Time.zone = @old_tz
  end

  context "with no data" do
    it "should generate empty string" do
      expect(generated_csv).to eq ""
    end
  end

  context "with lots of question types and a non-repeat group" do
    let(:form1) do
      create(:form, question_types: ["text",                       # 1
                                     "geo_multilevel_select_one",  # 2
                                     "long_text",                  # 3
                                     "integer",                    # 4
                                     "decimal",                    # 5
                                     "location",                   # 6
                                     "select_one",                 # 7
                                     %w[select_one select_one],    # 8, 9
                                     "select_multiple",            # 10
                                     "datetime",                   # 11
                                     "date",                       # 12
                                     "time"])                      # 13
    end
    let(:form2) do
      create(:form, question_types: %w[text long_text geo_select_one]).tap do |f|
        # Share the mutli_level geo question with form1
        f.add_questions_to_top_level(form1.questions[1])
      end
    end

    before do
      # Need to freeze the time so the times in the expectation file match.
      # The times shown in the resulting CSV should be in the current zone, not UTC.
      # So e.g. 6:30am instead of 12:30pm.
      Timecop.freeze(Time.zone.parse("2015-11-20 12:30 UTC")) do
        create(:response,
          form: form1,
          answer_values: ["foo✓", %w[Canada Calgary],
                          "alpha", 100, -123.50,
                          "15.937378 44.36453", "Cat", %w[Dog Cat], %w[Dog Cat],
                          "2015-10-12 18:15:12 UTC", "2014-11-09", "23:15"])

        # We put this one out of order to ensure sorting works.
        Timecop.freeze(-10.minutes) do
          create(:response,
            form: form1,
            answer_values: ["alpha", %w[Ghana Tamale], "bravo", 80, 1.23, nil, nil,
                            ["Dog", nil], %w[Cat], "2015-01-12 09:15:12 UTC", "2014-02-03", "3:43"])
        end

        # Response with multilevel geo partial answer with node (Canada) with no coordinates
        Timecop.freeze(10.minutes) do
          create(:response,
            form: form1,
            answer_values: ["foo", %w[Canada], "bar", 100, -123.50,
                            "15.937378 44.36453", "Cat", %w[Dog Cat], %w[Dog Cat],
                            "2015-10-12 18:15 UTC", "2014-11-09", "23:15:19"])
        end

        Timecop.freeze(15.minutes) do
          # Response with multilevel geo partial answer with node (Ghana) with coordinates
          # and geo answer altitude & accuracy
          create(:response,
            form: form1,
            answer_values: ["foo", %w[Ghana], "bar", 100, -123.50,
                            "15.937378 44.36453 123.45 20.4", "Cat", %w[Dog Cat], %w[Dog Cat],
                            "2015-10-12 18:15 UTC", "2014-11-09", "23:15:19"])
        end

        Timecop.freeze(20.minutes) do
          # Response from second form
          create(:response,
            form: form2,
            answer_values: ["foo", "bar", "Funton", %w[Ghana Accra]])
        end
      end
    end

    it "should generate correct CSV" do
      expect(generated_csv).to eq prepare_response_csv_expectation("basic.csv")
    end
  end

  context "with repeat groups" do
    let(:repeat_form) do
      create(:form,
        question_types:
          ["integer",
           {repeating: {items: %w[text integer select_multiple], name: "Fruit"}},
           "integer",
           {repeating: {items: %w[text geo_multilevel_select_one integer], name: "Vegetable"}}])
    end

    before do
      Timecop.freeze(Time.zone.parse("2015-11-20 12:30 UTC")) do
        create(:response, form: repeat_form, answer_values: [
          1,
          [:repeating,
           ["Apple", 1, %w[Cat Dog]],
           ["Banana", 2, %w[Cat]]],
          2,
          [:repeating,
           ["Asparagus", %w[Ghana Accra], 3]]
        ])

        Timecop.freeze(10.minutes) do
          create(:response, form: repeat_form, answer_values: [
            3,
            [:repeating,
             ["Xigua", 10, %w[Dog]],
             ["Yuzu", 9, %w[Cat Dog]],
             ["Ugli", 8, %w[Cat]]],
            4,
            [:repeating,
             ["Zucchini", %w[Canada Calgary], 7],
             ["Yam", %w[Canada Ottawa], 6]]
          ])
        end
      end
    end

    it "should generate a row per repeat item, plus one row per response" do
      expect(generated_csv).to eq prepare_response_csv_expectation("with_repeat_groups.csv")
    end
  end

  def prepare_response_csv_expectation(filename)
    prepare_expectation("response_csv/#{filename}",
      id: responses.map(&:id), shortcode: responses.map(&:shortcode))
  end
end
<commit_msg>7338: Fixed zero case and refactored spec<commit_after># frozen_string_literal: true

require "spec_helper"

describe Results::Csv::Generator, :reset_factory_sequences do
  let(:responses) { Response.with_associations.order(:created_at) }
  let(:ordered_responses) { Response.with_associations.order(:created_at) }
  subject(:output) { Results::Csv::Generator2.new(responses).to_s }

  around do |example|
    # Use a weird timezone so we know times are handled properly.
    in_timezone("Saskatchewan") { example.run }
  end

  context "with no data" do
    it "produces correct csv" do
      is_expected.to eq "ResponseID,Form,Submitter,DateSubmitted,ResponseShortcode,"\
        "GroupNum1,ItemNum1,GroupName,GroupLevel\r\n"
    end
  end

  context "with lots of question types and a non-repeat group" do
    let(:form1) do
      create(:form, question_types: ["text",                       # 1
                                     "geo_multilevel_select_one",  # 2
                                     "long_text",                  # 3
                                     "integer",                    # 4
                                     "decimal",                    # 5
                                     "location",                   # 6
                                     "select_one",                 # 7
                                     %w[select_one select_one],    # 8, 9
                                     "select_multiple",            # 10
                                     "datetime",                   # 11
                                     "date",                       # 12
                                     "time"])                      # 13
    end
    let(:form2) do
      create(:form, question_types: %w[text long_text geo_select_one]).tap do |f|
        # Share the mutli_level geo question with form1
        f.add_questions_to_top_level(form1.questions[1])
      end
    end

    before do
      # Need to freeze the time so the times in the expectation file match.
      # The times shown in the resulting CSV should be in the current zone, not UTC.
      # So e.g. 6:30am instead of 12:30pm.
      Timecop.freeze(Time.zone.parse("2015-11-20 12:30 UTC")) do
        create(:response,
          form: form1,
          answer_values: ["foo✓", %w[Canada Calgary],
                          "alpha", 100, -123.50,
                          "15.937378 44.36453", "Cat", %w[Dog Cat], %w[Dog Cat],
                          "2015-10-12 18:15:12 UTC", "2014-11-09", "23:15"])

        # We put this one out of order to ensure sorting works.
        Timecop.freeze(-10.minutes) do
          create(:response,
            form: form1,
            answer_values: ["alpha", %w[Ghana Tamale], "bravo", 80, 1.23, nil, nil,
                            ["Dog", nil], %w[Cat], "2015-01-12 09:15:12 UTC", "2014-02-03", "3:43"])
        end

        # Response with multilevel geo partial answer with node (Canada) with no coordinates
        Timecop.freeze(10.minutes) do
          create(:response,
            form: form1,
            answer_values: ["foo", %w[Canada], "bar", 100, -123.50,
                            "15.937378 44.36453", "Cat", %w[Dog Cat], %w[Dog Cat],
                            "2015-10-12 18:15 UTC", "2014-11-09", "23:15:19"])
        end

        Timecop.freeze(15.minutes) do
          # Response with multilevel geo partial answer with node (Ghana) with coordinates
          # and geo answer altitude & accuracy
          create(:response,
            form: form1,
            answer_values: ["foo", %w[Ghana], "bar", 100, -123.50,
                            "15.937378 44.36453 123.45 20.4", "Cat", %w[Dog Cat], %w[Dog Cat],
                            "2015-10-12 18:15 UTC", "2014-11-09", "23:15:19"])
        end

        Timecop.freeze(20.minutes) do
          # Response from second form
          create(:response,
            form: form2,
            answer_values: ["foo", "bar", "Funton", %w[Ghana Accra]])
        end
      end
    end

    it "produces correct csv" do
      is_expected.to eq prepare_response_csv_expectation("basic.csv")
    end
  end

  context "with repeat groups" do
    let(:repeat_form) do
      create(:form,
        question_types:
          ["integer",                                  # 1
           {repeating: {name: "Fruit", items: [
             "text",                                   # 2
             "integer",                                # 3
             "select_multiple"                         # 4
           ]}},
           "integer",                                  # 5
           {repeating: {name: "Vegetable", items: [
             "text",                                   # 6
             "geo_multilevel_select_one",              # 7
             "integer"                                 # 8
           ]}}])
    end

    before do
      Timecop.freeze(Time.zone.parse("2015-11-20 12:30 UTC")) do
        create(:response, form: repeat_form, answer_values: [
          1,
          [:repeating,
           ["Apple", 1, %w[Cat Dog]],
           ["Banana", 2, %w[Cat]]],
          2,
          [:repeating,
           ["Asparagus", %w[Ghana Accra], 3]]
        ])

        Timecop.freeze(10.minutes) do
          create(:response, form: repeat_form, answer_values: [
            3,
            [:repeating,
             ["Xigua", 10, %w[Dog]],
             ["Yuzu", 9, %w[Cat Dog]],
             ["Ugli", 8, %w[Cat]]],
            4,
            [:repeating,
             ["Zucchini", %w[Canada Calgary], 7],
             ["Yam", %w[Canada Ottawa], 6]]
          ])
        end
      end
    end

    it "produces correct csv" do
      is_expected.to eq prepare_response_csv_expectation("with_repeat_groups.csv")
    end
  end

  def prepare_response_csv_expectation(filename)
    prepare_expectation("response_csv/#{filename}",
      id: responses.map(&:id), shortcode: responses.map(&:shortcode))
  end
end

{'fraction_non_alphanumeric': 0.11726412637791858, 'fraction_numerical': 0.04756531551080635, 'mean_word_length': 1.477316706084713, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 27, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5313041', 'n_tokens_mistral': 3788, 'n_tokens_neox': 3246, 'n_words': 852}