|
1 | 1 | require "rails_helper" |
2 | 2 |
|
3 | 3 | RSpec.describe CsvGenerator do |
4 | | - let(:form_document) { build(:v2_form_document, form_id: 42, available_languages:) } |
5 | | - let(:submission) { build(:submission, form_document:, created_at: timestamp, reference: submission_reference, mode:, submission_locale:) } |
6 | | - let(:page) { build :page } |
7 | | - let(:text_question) { build :text, :with_answer, question_text: "What is the meaning of life?" } |
8 | | - let(:name_question) { build :first_middle_last_name_question, question_text: "What is your name?" } |
9 | | - let(:file_question) { build :file, :with_uploaded_file, question_text: "Upload a file", original_filename: "test.txt" } |
10 | | - let(:first_step) { build :step, question: text_question } |
11 | | - let(:second_step) { build :step, question: name_question } |
12 | | - let(:third_step) { build :step, question: file_question } |
13 | | - let(:all_steps) { [first_step, second_step, third_step] } |
14 | | - let(:journey) { instance_double(Flow::Journey, all_steps:, completed_file_upload_questions: [file_question]) } |
| 4 | + let(:form_document) { build(:v2_form_document, form_id: 42, available_languages:, steps: [text_step, name_step, file_upload_step], start_page: text_step[:id]) } |
| 5 | + let(:submission) { create(:submission, form_document:, created_at: timestamp, reference: submission_reference, mode:, submission_locale:, answers:) } |
| 6 | + let(:text_step) { build :v2_question_page_step, :with_text_settings, question_text: "What is the meaning of life?", next_step_id: name_step[:id] } |
| 7 | + let(:name_step) { build :v2_question_page_step, :with_name_settings, question_text: "What is your name?", next_step_id: file_upload_step[:id] } |
| 8 | + let(:file_upload_step) { build :v2_question_page_step, :with_file_upload_settings, question_text: "Upload a file" } |
| 9 | + let(:text_answer) { "blue" } |
| 10 | + let(:first_name_answer) { "Alice" } |
| 11 | + let(:last_name_answer) { "Smith" } |
| 12 | + let(:file_upload_answer) { "file.txt" } |
| 13 | + let(:answers) do |
| 14 | + { |
| 15 | + text_step[:id] => { "text" => text_answer }, |
| 16 | + name_step[:id] => { "first_name" => first_name_answer, "last_name" => last_name_answer }, |
| 17 | + file_upload_step[:id] => { "original_filename" => file_upload_answer }, |
| 18 | + } |
| 19 | + end |
| 20 | + |
15 | 21 | let(:mode) { "form" } |
16 | 22 | let(:submission_reference) { Faker::Alphanumeric.alphanumeric(number: 8).upcase } |
17 | 23 | let(:submission_locale) { :en } |
|
20 | 26 | Time.use_zone("London") { Time.zone.local(2022, 9, 14, 8, 0o0, 0o0) } |
21 | 27 | end |
22 | 28 |
|
23 | | - before do |
24 | | - allow(Flow::Journey).to receive(:new).and_return(journey) |
25 | | - end |
26 | | - |
27 | 29 | describe "#generate_submission" do |
28 | 30 | subject(:csv) { described_class.generate_submission(submission:, is_s3_submission:) } |
29 | 31 |
|
|
38 | 40 | expect(CSV.parse(csv)).to eq( |
39 | 41 | [ |
40 | 42 | ["Reference", "Submitted at", "What is the meaning of life?", "What is your name? - First name", "What is your name? - Last name", "Upload a file"], |
41 | | - [submission_reference, "2022-09-14T08:00:00+01:00", text_question.text, name_question.first_name, name_question.last_name, "test_#{submission_reference}.txt"], |
| 43 | + [submission_reference, "2022-09-14T08:00:00+01:00", text_answer, first_name_answer, last_name_answer, "file_#{submission_reference}.txt"], |
42 | 44 | ], |
43 | 45 | ) |
44 | 46 | end |
45 | 47 |
|
46 | 48 | context "when a question is optional and answer is not provided" do |
47 | | - let(:text_question) { build :text, question_text: "What is the meaning of life?", is_optional: true, text: nil } |
| 49 | + let(:text_answer) { "" } |
48 | 50 |
|
49 | 51 | it "generates a CSV including blank column for unanswered optional question" do |
50 | 52 | expect(CSV.parse(csv)).to eq( |
51 | 53 | [ |
52 | 54 | ["Reference", "Submitted at", "What is the meaning of life?", "What is your name? - First name", "What is your name? - Last name", "Upload a file"], |
53 | | - [submission_reference, "2022-09-14T08:00:00+01:00", "", name_question.first_name, name_question.last_name, "test_#{submission_reference}.txt"], |
| 55 | + [submission_reference, "2022-09-14T08:00:00+01:00", "", first_name_answer, last_name_answer, "file_#{submission_reference}.txt"], |
54 | 56 | ], |
55 | 57 | ) |
56 | 58 | end |
57 | 59 | end |
58 | 60 |
|
59 | 61 | context "when there are repeated steps" do |
60 | | - let(:name_question_repeated) { build :first_middle_last_name_question, question_text: "What is your name?" } |
61 | | - let(:second_step) { build :repeatable_step, questions: [name_question, name_question_repeated] } |
| 62 | + let(:name_step) { build :v2_question_page_step, :with_name_settings, question_text: "What is your name?", next_step_id: file_upload_step[:id], is_repeatable: true } |
| 63 | + let(:another_first_name_answer) { "John" } |
| 64 | + let(:another_last_name_answer) { "Smith" } |
| 65 | + let(:answers) do |
| 66 | + { |
| 67 | + text_step[:id] => { "text" => text_answer }, |
| 68 | + name_step[:id] => [ |
| 69 | + { "first_name" => first_name_answer, "last_name" => last_name_answer }, |
| 70 | + { "first_name" => another_first_name_answer, "last_name" => another_last_name_answer }, |
| 71 | + ], |
| 72 | + file_upload_step[:id] => { "original_filename" => file_upload_answer }, |
| 73 | + } |
| 74 | + end |
62 | 75 |
|
63 | 76 | it "generates a CSV with headers containing suffixes for the repeated steps" do |
64 | 77 | expect(CSV.parse(csv)).to eq( |
|
76 | 89 | [ |
77 | 90 | submission_reference, |
78 | 91 | "2022-09-14T08:00:00+01:00", |
79 | | - text_question.text, |
80 | | - name_question.first_name, |
81 | | - name_question.last_name, |
82 | | - name_question_repeated.first_name, |
83 | | - name_question_repeated.last_name, |
84 | | - "test_#{submission_reference}.txt", |
| 92 | + text_answer, |
| 93 | + first_name_answer, |
| 94 | + last_name_answer, |
| 95 | + another_first_name_answer, |
| 96 | + another_last_name_answer, |
| 97 | + "file_#{submission_reference}.txt", |
85 | 98 | ], |
86 | 99 | ], |
87 | 100 | ) |
|
95 | 108 | expect(CSV.parse(csv)).to eq( |
96 | 109 | [ |
97 | 110 | ["Reference", "Submitted at", "What is the meaning of life?", "What is your name? - First name", "What is your name? - Last name", "Upload a file", "Language"], |
98 | | - [submission_reference, "2022-09-14T08:00:00+01:00", text_question.text, name_question.first_name, name_question.last_name, "test_#{submission_reference}.txt", "en"], |
| 111 | + [submission_reference, "2022-09-14T08:00:00+01:00", text_answer, first_name_answer, last_name_answer, "file_#{submission_reference}.txt", "en"], |
99 | 112 | ], |
100 | 113 | ) |
101 | 114 | end |
|
109 | 122 | expect(CSV.parse(csv)).to eq( |
110 | 123 | [ |
111 | 124 | ["Reference", "Submitted at", "What is the meaning of life?", "What is your name? - First name", "What is your name? - Last name", "Upload a file"], |
112 | | - [submission_reference, "2022-09-14T08:00:00+01:00", text_question.text, name_question.first_name, name_question.last_name, file_question.original_filename], |
| 125 | + [submission_reference, "2022-09-14T08:00:00+01:00", text_answer, first_name_answer, last_name_answer, file_upload_answer], |
113 | 126 | ], |
114 | 127 | ) |
115 | 128 | end |
116 | 129 | end |
117 | 130 | end |
118 | 131 |
|
119 | 132 | describe "#generate_batched_submissions" do |
120 | | - subject(:csv) { described_class.generate_batched_submissions(submissions:, is_s3_submission:) } |
| 133 | + subject(:csv_list) { described_class.generate_batched_submissions(submissions_query:, is_s3_submission:) } |
121 | 134 |
|
122 | | - let(:submission_2) { build(:submission, form_document:, created_at: timestamp + 1.hour, reference: submission_reference_2, mode:, submission_locale: :cy) } |
123 | 135 | let(:submission_reference_2) { Faker::Alphanumeric.alphanumeric(number: 8).upcase } |
124 | | - let(:submissions) { [submission, submission_2] } |
125 | 136 | let(:is_s3_submission) { false } |
| 137 | + let(:submissions_query) { Submission.all } |
126 | 138 |
|
127 | | - it "generates a CSV with multiple rows for the submissions" do |
128 | | - expect(CSV.parse(csv)).to eq( |
129 | | - [ |
130 | | - ["Reference", "Submitted at", "What is the meaning of life?", "What is your name? - First name", "What is your name? - Last name", "Upload a file"], |
131 | | - [submission_reference, "2022-09-14T08:00:00+01:00", text_question.text, name_question.first_name, name_question.last_name, "test_#{submission_reference}.txt"], |
132 | | - [submission_reference_2, "2022-09-14T09:00:00+01:00", text_question.text, name_question.first_name, name_question.last_name, "test_#{submission_reference_2}.txt"], |
133 | | - ], |
134 | | - ) |
135 | | - end |
| 139 | + context "when all submissions result in the same CSV headers" do |
| 140 | + before do |
| 141 | + submission |
| 142 | + create(:submission, form_document:, created_at: timestamp + 1.hour, reference: submission_reference_2, mode:, submission_locale: :cy, answers:) |
| 143 | + end |
136 | 144 |
|
137 | | - context "when the form has multiple available languages" do |
138 | | - let(:available_languages) { %w[en cy] } |
| 145 | + it "returns an array with a single CSV string" do |
| 146 | + expect(csv_list).to be_a(Array) |
| 147 | + expect(csv_list.size).to eq(1) |
| 148 | + expect(csv_list.first).to be_a(String) |
| 149 | + end |
139 | 150 |
|
140 | | - it "generates a CSV with a language column" do |
141 | | - expect(CSV.parse(csv)).to eq( |
| 151 | + it "generates a CSV with multiple rows for the submissions" do |
| 152 | + csv = CSV.parse(csv_list.first) |
| 153 | + expect(csv.size).to eq(3) # header row + 2 submissions |
| 154 | + expect(csv).to eq( |
142 | 155 | [ |
143 | | - ["Reference", "Submitted at", "What is the meaning of life?", "What is your name? - First name", "What is your name? - Last name", "Upload a file", "Language"], |
144 | | - [submission_reference, "2022-09-14T08:00:00+01:00", text_question.text, name_question.first_name, name_question.last_name, "test_#{submission_reference}.txt", "en"], |
145 | | - [submission_reference_2, "2022-09-14T09:00:00+01:00", text_question.text, name_question.first_name, name_question.last_name, "test_#{submission_reference_2}.txt", "cy"], |
| 156 | + ["Reference", "Submitted at", "What is the meaning of life?", "What is your name? - First name", "What is your name? - Last name", "Upload a file"], |
| 157 | + [submission_reference, "2022-09-14T08:00:00+01:00", text_answer, first_name_answer, last_name_answer, "file_#{submission_reference}.txt"], |
| 158 | + [submission_reference_2, "2022-09-14T09:00:00+01:00", text_answer, first_name_answer, last_name_answer, "file_#{submission_reference_2}.txt"], |
146 | 159 | ], |
147 | 160 | ) |
148 | 161 | end |
| 162 | + |
| 163 | + context "when the form has multiple available languages" do |
| 164 | + let(:available_languages) { %w[en cy] } |
| 165 | + |
| 166 | + it "generates a CSV with a language column" do |
| 167 | + expect(CSV.parse(csv_list.first)).to eq( |
| 168 | + [ |
| 169 | + ["Reference", "Submitted at", "What is the meaning of life?", "What is your name? - First name", "What is your name? - Last name", "Upload a file", "Language"], |
| 170 | + [submission_reference, "2022-09-14T08:00:00+01:00", text_answer, first_name_answer, last_name_answer, "file_#{submission_reference}.txt", "en"], |
| 171 | + [submission_reference_2, "2022-09-14T09:00:00+01:00", text_answer, first_name_answer, last_name_answer, "file_#{submission_reference_2}.txt", "cy"], |
| 172 | + ], |
| 173 | + ) |
| 174 | + end |
| 175 | + end |
| 176 | + |
| 177 | + context "when the CSV is being sent to an S3 bucket" do |
| 178 | + let(:is_s3_submission) { true } |
| 179 | + |
| 180 | + it "generates a CSV without including the submission reference in the filename for the file upload question" do |
| 181 | + expect(CSV.parse(csv_list.first)).to eq( |
| 182 | + [ |
| 183 | + ["Reference", "Submitted at", "What is the meaning of life?", "What is your name? - First name", "What is your name? - Last name", "Upload a file"], |
| 184 | + [submission_reference, "2022-09-14T08:00:00+01:00", text_answer, first_name_answer, last_name_answer, file_upload_answer], |
| 185 | + [submission_reference_2, "2022-09-14T09:00:00+01:00", text_answer, first_name_answer, last_name_answer, file_upload_answer], |
| 186 | + ], |
| 187 | + ) |
| 188 | + end |
| 189 | + end |
149 | 190 | end |
150 | 191 |
|
151 | | - context "when the CSV is being sent to an S3 bucket" do |
152 | | - let(:is_s3_submission) { true } |
| 192 | + context "when all submissions result in different CSV headers" do |
| 193 | + let(:form_document) do |
| 194 | + build( |
| 195 | + :v2_form_document, |
| 196 | + steps: [text_step, name_step, file_upload_step], |
| 197 | + start_page: text_step[:id], |
| 198 | + updated_at: Time.utc(2022, 9, 14, 7, 0, 0).iso8601(3), |
| 199 | + ) |
| 200 | + end |
153 | 201 |
|
154 | | - it "generates a CSV without including the submission reference in the filename for the file upload question" do |
155 | | - expect(CSV.parse(csv)).to eq( |
156 | | - [ |
157 | | - ["Reference", "Submitted at", "What is the meaning of life?", "What is your name? - First name", "What is your name? - Last name", "Upload a file"], |
158 | | - [submission_reference, "2022-09-14T08:00:00+01:00", text_question.text, name_question.first_name, name_question.last_name, file_question.original_filename], |
159 | | - [submission_reference_2, "2022-09-14T09:00:00+01:00", text_question.text, name_question.first_name, name_question.last_name, file_question.original_filename], |
160 | | - ], |
| 202 | + let(:form_document_same_steps) do |
| 203 | + build( |
| 204 | + :v2_form_document, |
| 205 | + steps: [text_step, name_step, file_upload_step], |
| 206 | + start_page: text_step[:id], |
| 207 | + updated_at: Time.utc(2022, 9, 15, 7, 0, 0).iso8601(3), |
161 | 208 | ) |
162 | 209 | end |
| 210 | + |
| 211 | + let(:form_document_different_steps) do |
| 212 | + build( |
| 213 | + :v2_form_document, |
| 214 | + steps: [name_step, file_upload_step], |
| 215 | + start_page: name_step[:id], |
| 216 | + updated_at: Time.utc(2022, 9, 16, 7, 0, 0).iso8601(3), |
| 217 | + ) |
| 218 | + end |
| 219 | + |
| 220 | + before do |
| 221 | + create_list(:submission, 2, form_document:, answers:) |
| 222 | + create_list(:submission, 3, form_document: form_document_same_steps, answers:) |
| 223 | + create_list(:submission, 4, form_document: form_document_different_steps, answers:) |
| 224 | + end |
| 225 | + |
| 226 | + it "creates a CSV for each incompatible set of form versions" do |
| 227 | + expect(csv_list.count).to eq(2) |
| 228 | + expect(CSV.parse(csv_list[0]).count).to eq(6) |
| 229 | + expect(CSV.parse(csv_list[1]).count).to eq(5) |
| 230 | + end |
163 | 231 | end |
164 | 232 | end |
165 | 233 | end |
0 commit comments