Commit 67fbf37f19aa9fe470fc286fe048517e2d26ab44

Authored by Luke Baker
1 parent bed4d517

let FasterCSV do proper CSV escaping for strings

in ideas export CSV let FasterCSV handle the CSV escaping of strings
(strings with commas, quotes, newlines, etc.)
app/models/question.rb
... ... @@ -556,7 +556,7 @@ class Question < ActiveRecord::Base
556 556  
557 557 num_skips = self.skips.count(:conditions => {:prompt_id => left_prompts_ids + right_prompts_ids})
558 558  
559   - csv << [c.question_id, c.id, "'#{c.data.strip}'", c.wins, c.losses, num_skips, c.score, user_submitted , c.creator_id, c.created_at, c.updated_at, active, left_appearances, right_appearances]
  559 + csv << [c.question_id, c.id, c.data.strip, c.wins, c.losses, num_skips, c.score, user_submitted , c.creator_id, c.created_at, c.updated_at, active, left_appearances, right_appearances]
560 560  
561 561 end
562 562 when 'non_votes'
... ...
spec/models/question_spec.rb
... ... @@ -423,4 +423,78 @@ describe Question do
423 423 after(:all) { truncate_all }
424 424 end
425 425  
  426 + context "exporting data with odd characters" do
  427 + before(:all) do
  428 + @aoi_question = Factory.create(:question)
  429 + user = @aoi_question.site
  430 +
  431 + @aoi_question.it_should_autoactivate_ideas = true
  432 + @aoi_question.save!
  433 +
  434 + visitor = user.visitors.find_or_create_by_identifier('visitor identifier')
  435 +
  436 + user.create_choice(visitor.identifier, @aoi_question,
  437 + {:data => "foo\nbar", :local_identifier => "example creator"})
  438 + user.create_choice(visitor.identifier, @aoi_question,
  439 + {:data => "foo,bar", :local_identifier => "example creator"})
  440 + user.create_choice(visitor.identifier, @aoi_question,
  441 + {:data => "foo\"bar", :local_identifier => "example creator"})
  442 + user.create_choice(visitor.identifier, @aoi_question,
  443 + {:data => "foo'bar", :local_identifier => "example creator"})
  444 +
  445 + 40.times.each do |num|
  446 + @p = @aoi_question.picked_prompt
  447 +
  448 + @a = user.record_appearance(visitor, @p)
  449 +
  450 + vote_options = {:visitor_identifier => visitor.identifier,
  451 + :appearance_lookup => @a.lookup,
  452 + :prompt => @p,
  453 + :time_viewed => rand(1000),
  454 + :direction => (rand(2) == 0) ? "left" : "right"
  455 + }
  456 +
  457 + skip_options = {:visitor_identifier => visitor.identifier,
  458 + :appearance_lookup => @a.lookup,
  459 + :prompt => @p,
  460 + :time_viewed => rand(1000),
  461 + :skip_reason => "some reason"
  462 + }
  463 +
  464 + choice = rand(3)
  465 + case choice
  466 + when 0
  467 + user.record_vote(vote_options)
  468 + when 1
  469 + user.record_skip(skip_options)
  470 + when 2
  471 + #this is an orphaned appearance, so do nothing
  472 + end
  473 + end
  474 + end
  475 +
  476 + it "should export idea data to a csv file" do
  477 + filename = @aoi_question.export('ideas')
  478 +
  479 + filename.should_not be nil
  480 + filename.should match /.*ideamarketplace_#{@aoi_question.id}_ideas[.]csv$/
  481 + File.exists?(filename).should be_true
  482 + # Not specifying exact file syntax, it's likely to change frequently
  483 + #
  484 + rows = FasterCSV.read(filename)
  485 + rows.first.should include("Idea ID")
  486 + rows.first.should_not include("Skip ID")
  487 +
  488 + rows.shift
  489 + rows.each do |row|
  490 + row[2].should =~ /^foo.bar$/m
  491 + end
  492 +
  493 + #File.delete(filename).should_not be_nil
  494 +
  495 + end
  496 +
  497 + after(:all) { truncate_all }
  498 + end
  499 +
426 500 end
... ...