From a84fa66031298b3b675fe4d2abd6fd713678bb42 Mon Sep 17 00:00:00 2001 From: "G. Torres" Date: Wed, 23 Oct 2024 06:52:34 -0400 Subject: [PATCH 01/11] Updates functionality to generate csv for all stories --- app/controllers/stories_controller.rb | 15 +++++++++++++-- app/views/projects/_import_export.html.erb | 8 +++++++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/app/controllers/stories_controller.rb b/app/controllers/stories_controller.rb index 768aa26d..42f703c7 100644 --- a/app/controllers/stories_controller.rb +++ b/app/controllers/stories_controller.rb @@ -90,7 +90,12 @@ def export csv = if params[:export_with_comments] == "1" CSV.generate(headers: true) do |csv| csv << CSV_HEADERS + ["comment"] - @project.stories.includes(:comments).approved.by_position.each do |story| + stories = if params.include?(:export_all) && params[:export_all] == "1" + @project.stories.includes(:comments) + else + @project.stories.includes(:comments).approved + end + stories.by_position.each do |story| comments = [] story.comments.each do |comment| comments << "#{display_name(comment.user)}: #{comment.body}" @@ -101,7 +106,13 @@ def export else CSV.generate(headers: true) do |csv| csv << CSV_HEADERS - @project.stories.approved.by_position.each do |story| + stories = if params.include?(:export_all) && params[:export_all] == "1" + @project.stories + else + @project.stories.approved + end + + stories.by_position.each do |story| csv << story.attributes.slice(*CSV_HEADERS) end end diff --git a/app/views/projects/_import_export.html.erb b/app/views/projects/_import_export.html.erb index d3549268..dac9bcb4 100644 --- a/app/views/projects/_import_export.html.erb +++ b/app/views/projects/_import_export.html.erb @@ -33,7 +33,13 @@
<%= form_with url: export_project_stories_path(@project), method: :get do |f| %> <%= f.submit "Export", class: "button green", data: { disable_with: false } %> -
+ <% if current_user.admin? %> +
+ <%= f.label :export_all do %> + <%= f.check_box :export_all %> + Export all stories + <% end %> + <% end %> <%= f.label :export_with_comments do %> <%= f.check_box :export_with_comments %> Export with comments From e661ac8c39a32826864c4423e0633372e800e7c9 Mon Sep 17 00:00:00 2001 From: "G. Torres" Date: Wed, 23 Oct 2024 06:53:34 -0400 Subject: [PATCH 02/11] Adds spec to test that admins can export all stories in CSV file --- spec/controllers/stories_controller_spec.rb | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/spec/controllers/stories_controller_spec.rb b/spec/controllers/stories_controller_spec.rb index c9e677dc..0d72e0d4 100644 --- a/spec/controllers/stories_controller_spec.rb +++ b/spec/controllers/stories_controller_spec.rb @@ -187,6 +187,27 @@ expect(csv_data).to eq(expected_csv_content) end + context "when an admin" do + it "exports a CSV file with all stories" do + user = FactoryBot.create(:user) + user.admin = true + + story2 = FactoryBot.create(:story, project: project, status: :rejected) + story3 = FactoryBot.create(:story, project: project, status: :pending) + get :export, params: {project_id: project.id, export_all: "1"} + expect(response).to have_http_status(:ok) + + csv_data = CSV.parse(response.body) + expected_csv_content = [ + ["id", "title", "description", "position"], + [story.id.to_s, story.title, story.description, story.position.to_s], + [story2.id.to_s, story2.title, story2.description, story2.position.to_s], + [story3.id.to_s, story3.title, story3.description, story3.position.to_s] + ] + expect(csv_data).to eq(expected_csv_content) + end + end + context "with comments" do it "exports a CSV file with only approved stories" do user = FactoryBot.create(:user) From 08632120c2c37d25055a38d4ea58131189cc4b09 Mon Sep 17 00:00:00 2001 From: "G. Torres" Date: Fri, 25 Oct 2024 20:25:14 -0400 Subject: [PATCH 03/11] Moving the csv generation into their own respective methods to fix code climate issue --- app/controllers/stories_controller.rb | 60 +++++++++++++++------------ 1 file changed, 34 insertions(+), 26 deletions(-) diff --git a/app/controllers/stories_controller.rb b/app/controllers/stories_controller.rb index 42f703c7..7db6aad9 100644 --- a/app/controllers/stories_controller.rb +++ b/app/controllers/stories_controller.rb @@ -88,37 +88,45 @@ def import def export csv = if params[:export_with_comments] == "1" - CSV.generate(headers: true) do |csv| - csv << CSV_HEADERS + ["comment"] - stories = if params.include?(:export_all) && params[:export_all] == "1" - @project.stories.includes(:comments) - else - @project.stories.includes(:comments).approved - end - stories.by_position.each do |story| - comments = [] - story.comments.each do |comment| - comments << "#{display_name(comment.user)}: #{comment.body}" - end - csv << [story.id, story.title, story.description, story.position] + comments - end - end + generate_csv_with_comments else - CSV.generate(headers: true) do |csv| - csv << CSV_HEADERS - stories = if params.include?(:export_all) && params[:export_all] == "1" - @project.stories - else - @project.stories.approved - end + generate_csv_without_comments + end + filename = "#{@project.title.gsub(/[^\w]/, "_")}-#{Time.now.to_formatted_s(:short).tr(" ", "_")}.csv" + send_data csv, filename: filename + end - stories.by_position.each do |story| - csv << story.attributes.slice(*CSV_HEADERS) + def generate_csv_with_comments + CSV.generate(headers: true) do |csv| + csv << CSV_HEADERS + ["comment"] + stories = if params.include?(:export_all) && params[:export_all] == "1" + @project.stories.includes(:comments) + else + @project.stories.includes(:comments).approved + end + stories.by_position.each do |story| + comments = [] + story.comments.each do |comment| + comments << "#{display_name(comment.user)}: #{comment.body}" end + csv << [story.id, story.title, story.description, story.position] + comments + end + end + end + + def generate_csv_without_comments + CSV.generate(headers: true) do |csv| + csv << CSV_HEADERS + stories = if params.include?(:export_all) && params[:export_all] == "1" + @project.stories + else + @project.stories.approved + end + + stories.by_position.each do |story| + csv << story.attributes.slice(*CSV_HEADERS) end end - filename = "#{@project.title.gsub(/[^\w]/, "_")}-#{Time.now.to_formatted_s(:short).tr(" ", "_")}.csv" - send_data csv, filename: filename end def render_markdown From 8b295e674daff3f8204eb26a6f06f4920a022887 Mon Sep 17 00:00:00 2001 From: "G. Torres" Date: Wed, 30 Oct 2024 14:35:03 -0400 Subject: [PATCH 04/11] Refactored csv generation into a method --- app/controllers/stories_controller.rb | 47 ++++++++++----------------- 1 file changed, 18 insertions(+), 29 deletions(-) diff --git a/app/controllers/stories_controller.rb b/app/controllers/stories_controller.rb index 7db6aad9..57b78b05 100644 --- a/app/controllers/stories_controller.rb +++ b/app/controllers/stories_controller.rb @@ -87,44 +87,33 @@ def import end def export - csv = if params[:export_with_comments] == "1" - generate_csv_with_comments - else - generate_csv_without_comments - end + csv = generate_csv(params[:export_with_comments], params[:export_all]) filename = "#{@project.title.gsub(/[^\w]/, "_")}-#{Time.now.to_formatted_s(:short).tr(" ", "_")}.csv" send_data csv, filename: filename end - def generate_csv_with_comments - CSV.generate(headers: true) do |csv| - csv << CSV_HEADERS + ["comment"] - stories = if params.include?(:export_all) && params[:export_all] == "1" - @project.stories.includes(:comments) - else - @project.stories.includes(:comments).approved - end - stories.by_position.each do |story| - comments = [] - story.comments.each do |comment| - comments << "#{display_name(comment.user)}: #{comment.body}" - end - csv << [story.id, story.title, story.description, story.position] + comments - end + def generate_csv(with_comments, export_all) + stories = if with_comments == "1" && export_all == "1" + @project.stories.includes(:comments) + elsif with_comments == "1" + @project.stories.includes(:comments).approved + elsif export_all == "1" + @project.stories + else + @project.stories.approved end - end - def generate_csv_without_comments CSV.generate(headers: true) do |csv| - csv << CSV_HEADERS - stories = if params.include?(:export_all) && params[:export_all] == "1" - @project.stories - else - @project.stories.approved - end + csv << ((with_comments == "1") ? (CSV_HEADERS + ["comment"]) : CSV_HEADERS) stories.by_position.each do |story| - csv << story.attributes.slice(*CSV_HEADERS) + if with_comments == "1" + comments = [] + story.comments.each do |comment| + comments << "#{display_name(comment.user)}: #{comment.body}" + end + end + csv << ((with_comments == "1") ? ([story.id, story.title, story.description, story.position] + comments) : story.attributes.slice(*CSV_HEADERS)) end end end From 2d268d8bb786d98d0bf0100c4f8345208aa3092f Mon Sep 17 00:00:00 2001 From: "G. Torres" Date: Wed, 30 Oct 2024 16:13:28 -0400 Subject: [PATCH 05/11] Refactoring generate_csv method --- app/controllers/stories_controller.rb | 29 +++++++++++++-------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/app/controllers/stories_controller.rb b/app/controllers/stories_controller.rb index 57b78b05..b0f308e9 100644 --- a/app/controllers/stories_controller.rb +++ b/app/controllers/stories_controller.rb @@ -87,33 +87,32 @@ def import end def export - csv = generate_csv(params[:export_with_comments], params[:export_all]) + csv = if params[:export_with_comments] == "1" && params[:export_all] == "1" + generate_csv(@project.stories.includes(:comments), with_comments: true, export_all: true) + elsif params[:export_with_comments] == "1" + generate_csv(@project.stories.includes(:comments).approved, with_comments: true, export_all: false) + elsif params[:export_all] == "1" + generate_csv(@project.stories, with_comments: false, export_all: true) + else + generate_csv(@project.stories.approved, with_comments: false, export_all: false) + end + filename = "#{@project.title.gsub(/[^\w]/, "_")}-#{Time.now.to_formatted_s(:short).tr(" ", "_")}.csv" send_data csv, filename: filename end - def generate_csv(with_comments, export_all) - stories = if with_comments == "1" && export_all == "1" - @project.stories.includes(:comments) - elsif with_comments == "1" - @project.stories.includes(:comments).approved - elsif export_all == "1" - @project.stories - else - @project.stories.approved - end - + def generate_csv(stories, with_comments: false, export_all: false) CSV.generate(headers: true) do |csv| - csv << ((with_comments == "1") ? (CSV_HEADERS + ["comment"]) : CSV_HEADERS) + csv << (with_comments ? (CSV_HEADERS + ["comment"]) : CSV_HEADERS) stories.by_position.each do |story| - if with_comments == "1" + if with_comments comments = [] story.comments.each do |comment| comments << "#{display_name(comment.user)}: #{comment.body}" end end - csv << ((with_comments == "1") ? ([story.id, story.title, story.description, story.position] + comments) : story.attributes.slice(*CSV_HEADERS)) + csv << (with_comments ? ([story.id, story.title, story.description, story.position] + comments) : story.attributes.slice(*CSV_HEADERS)) end end end From 126d8c10d56234ae9da0acd008e6cc8b5ad6b82a Mon Sep 17 00:00:00 2001 From: "G. Torres" Date: Wed, 30 Oct 2024 16:37:51 -0400 Subject: [PATCH 06/11] Removes tertiary statements I added --- app/controllers/stories_controller.rb | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/app/controllers/stories_controller.rb b/app/controllers/stories_controller.rb index b0f308e9..024e5bd3 100644 --- a/app/controllers/stories_controller.rb +++ b/app/controllers/stories_controller.rb @@ -103,7 +103,13 @@ def export def generate_csv(stories, with_comments: false, export_all: false) CSV.generate(headers: true) do |csv| - csv << (with_comments ? (CSV_HEADERS + ["comment"]) : CSV_HEADERS) + headers = if with_comments + CSV_HEADERS + ["comment"] + else + CSV_HEADERS + end + + csv << headers stories.by_position.each do |story| if with_comments @@ -111,8 +117,11 @@ def generate_csv(stories, with_comments: false, export_all: false) story.comments.each do |comment| comments << "#{display_name(comment.user)}: #{comment.body}" end + + csv << [story.id, story.title, story.description, story.position] + comments + else + csv << story.attributes.slice(*CSV_HEADERS) end - csv << (with_comments ? ([story.id, story.title, story.description, story.position] + comments) : story.attributes.slice(*CSV_HEADERS)) end end end From 6c5f0db3013adf79ed51b7d1040a5a1647ffa025 Mon Sep 17 00:00:00 2001 From: "G. Torres" Date: Wed, 30 Oct 2024 17:08:37 -0400 Subject: [PATCH 07/11] Replaces .each call to map --- app/controllers/stories_controller.rb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/controllers/stories_controller.rb b/app/controllers/stories_controller.rb index 024e5bd3..4027d76a 100644 --- a/app/controllers/stories_controller.rb +++ b/app/controllers/stories_controller.rb @@ -113,9 +113,8 @@ def generate_csv(stories, with_comments: false, export_all: false) stories.by_position.each do |story| if with_comments - comments = [] - story.comments.each do |comment| - comments << "#{display_name(comment.user)}: #{comment.body}" + comments = story.comments.map do |comment| + "#{display_name(comment.user)}: #{comment.body}" end csv << [story.id, story.title, story.description, story.position] + comments From 10cfcff9a3424c78febe6ce661f67f1fc6feda2a Mon Sep 17 00:00:00 2001 From: "G. Torres" Date: Wed, 6 Nov 2024 17:03:21 -0500 Subject: [PATCH 08/11] Refactor creation of header to get rid of complexity --- app/controllers/stories_controller.rb | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/app/controllers/stories_controller.rb b/app/controllers/stories_controller.rb index 4027d76a..f086eb32 100644 --- a/app/controllers/stories_controller.rb +++ b/app/controllers/stories_controller.rb @@ -103,11 +103,7 @@ def export def generate_csv(stories, with_comments: false, export_all: false) CSV.generate(headers: true) do |csv| - headers = if with_comments - CSV_HEADERS + ["comment"] - else - CSV_HEADERS - end + headers = with_comments ? CSV_HEADERS + ["comment"] : CSV_HEADERS csv << headers From e67e7c3b88dd16cad368fb082993588c43a1f4dc Mon Sep 17 00:00:00 2001 From: "G. Torres" Date: Wed, 6 Nov 2024 17:11:35 -0500 Subject: [PATCH 09/11] Removes tertiary statement that changed the headers depending on whether or not there are comments --- app/controllers/stories_controller.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/stories_controller.rb b/app/controllers/stories_controller.rb index f086eb32..655356c7 100644 --- a/app/controllers/stories_controller.rb +++ b/app/controllers/stories_controller.rb @@ -103,8 +103,8 @@ def export def generate_csv(stories, with_comments: false, export_all: false) CSV.generate(headers: true) do |csv| - headers = with_comments ? CSV_HEADERS + ["comment"] : CSV_HEADERS - + headers = CSV_HEADERS.dup + headers << "comment" if with_comments csv << headers stories.by_position.each do |story| From bfc2027d73a7ef5d8430159f2bf6b1df602be896 Mon Sep 17 00:00:00 2001 From: "G. Torres" Date: Thu, 7 Nov 2024 11:00:30 -0500 Subject: [PATCH 10/11] Uses .tap to get rid of cognitive complexity --- app/controllers/stories_controller.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/controllers/stories_controller.rb b/app/controllers/stories_controller.rb index 655356c7..efe969d4 100644 --- a/app/controllers/stories_controller.rb +++ b/app/controllers/stories_controller.rb @@ -103,9 +103,7 @@ def export def generate_csv(stories, with_comments: false, export_all: false) CSV.generate(headers: true) do |csv| - headers = CSV_HEADERS.dup - headers << "comment" if with_comments - csv << headers + csv << CSV_HEADERS.dup.tap { |headers| headers << "comment" if with_comments } stories.by_position.each do |story| if with_comments From a34187371b55bdee567bf917a9e5d50b9aabfaca Mon Sep 17 00:00:00 2001 From: "G. Torres" Date: Thu, 7 Nov 2024 12:07:34 -0500 Subject: [PATCH 11/11] Reduces complexity in the method by making headers easier to understand and removing the other if statement --- app/controllers/stories_controller.rb | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/app/controllers/stories_controller.rb b/app/controllers/stories_controller.rb index efe969d4..a7fcbb18 100644 --- a/app/controllers/stories_controller.rb +++ b/app/controllers/stories_controller.rb @@ -103,18 +103,20 @@ def export def generate_csv(stories, with_comments: false, export_all: false) CSV.generate(headers: true) do |csv| - csv << CSV_HEADERS.dup.tap { |headers| headers << "comment" if with_comments } + headers = CSV_HEADERS.dup + headers << "comment" if with_comments + csv << headers stories.by_position.each do |story| + comments = [] + if with_comments comments = story.comments.map do |comment| "#{display_name(comment.user)}: #{comment.body}" end - - csv << [story.id, story.title, story.description, story.position] + comments - else - csv << story.attributes.slice(*CSV_HEADERS) end + + csv << [story.id, story.title, story.description, story.position] + comments end end end