Commit 67fbf37f19aa9fe470fc286fe048517e2d26ab44
1 parent
bed4d517
Exists in
master
and in
1 other branch
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.)
Showing
2 changed files
with
75 additions
and
1 deletions
Show diff stats
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 | ... | ... |