Permalink
Browse files

json representation of repsonse sets. closes #287

  • Loading branch information...
1 parent e7a8fe5 commit 9b402ea499edff2a73e8f6167671d2a3466aa948 Mark Yoon committed Apr 4, 2012
@@ -0,0 +1,14 @@
+object @response_set
+attribute :api_id => :uuid
+attribute :created_at
+attribute :completed_at
+node(:survey_id){|rs| rs.survey.api_id }
+
+child :responses do
+ attribute :api_id => :uuid
+ attribute :created_at
+ attribute :updated_at => :modified_at
+ node(:answer_id){|r| r.answer.api_id }
+ node(:question_id){|r| r.question.api_id }
+ node(:value, :if => lambda{|r| r.answer.response_class != "answer"}){|r| r.as(r.answer.response_class) }
+end
@@ -40,50 +40,57 @@ Feature: Survey export
}
"""
-# Scenario: Exporting response sets
-# Given I parse
-# """
-# survey "Simple json response sets" do
-# section "Colors" do
-#
-# question_1 "What is your favorite color?", :pick => :one
-# answer "red"
-# answer "blue"
-# answer "green"
-# answer :other
-#
-# q_2b "What color don't you like?"
-# a_1 "color", :string
-# end
-# end
-# """
-# When I start the "Simple json" survey
-# And I choose "red"
-# And I fill in "color" with "orange"
-# And I press "Click here to finish"
-# Then there should be 1 response set with 2 responses with:
-# | answer |
-# | red |
-# | orange |
-# And the json for the last response set should be
-# """
-# {
-# "uuid":"*",
-# "survey_id":"*",
-# "created_at":"*",
-# "completed_at":"*",
-# "responses":[{
-# "uuid":"*",
-# "answer_id":"*",
-# "question_id":"*"
-# "created_at":"*",
-# "modified_at":"*"
-# },{
-# "uuid":"*",
-# "answer_id":"*",
-# "question_id":"*"
-# "created_at":"*",
-# "modified_at":"*"
-# }]
-# }
-# """
+ Scenario: Exporting response sets
+ Given I parse
+ """
+ survey "Simple json response sets" do
+ section "Colors" do
+
+ question_1 "What is your favorite color?", :pick => :one
+ answer "red"
+ answer "blue"
+ answer "green"
+ answer :other
+
+ q_2b "What color don't you like?"
+ a_1 "color", :string
+ end
+ section "Other" do
+ label "no"
+ end
+ end
+ """
+ When I start the "Simple json response sets" survey
+ And I choose "red"
+ And I press "Other"
+ And I wait 1 seconds
+ And I press "Colors"
+ And I fill in "color" with "orange"
+ And I press "Other"
+ And I press "Click here to finish"
+ Then there should be 1 response set with 2 responses with:
+ | answer |
+ | red |
+ And the json for the last response set for "Simple json response sets" should be
+ """
+ {
+ "uuid":"*",
+ "survey_id":"*",
+ "created_at":"*",
+ "completed_at":"*",
+ "responses":[{
+ "uuid":"*",
+ "answer_id":"*",
+ "question_id":"*",
+ "created_at":"*",
+ "modified_at":"*"
+ },{
+ "uuid":"*",
+ "answer_id":"*",
+ "question_id":"*",
+ "created_at":"*",
+ "modified_at":"*",
+ "value":"orange"
+ }]
+ }
+ """
@@ -91,7 +91,15 @@
Then /^the json for "([^"]*)" should be$/ do |title, string|
visit "/surveys/#{Survey.find_by_title(title).access_code}.json"
puts page.find('body').text
- Surveyor::Common.equal_json_excluding_uuids(page.find('body').text, string).should == true
+ Surveyor::Common.equal_json_excluding_wildcards(page.find('body').text, string).should == true
+end
+
+Then /^the json for the last response set for "([^"]*)" should be$/ do |title, string|
+ (survey = Survey.find_by_title(title)).should_not be_nil
+ (response_set = ResponseSet.last(:conditions => {:survey_id => survey.id})).should_not be_nil
+ visit "/surveys/#{survey.access_code}/#{response_set.access_code}.json"
+ puts page.find('body').text
+ Surveyor::Common.equal_json_excluding_wildcards(page.find('body').text, string).should == true
end
Then /the element "([^\"]*)" should be hidden$/ do |selector|
@@ -12,7 +12,7 @@ def migrations
unless options[:skip_migrations]
# because all migration timestamps end up the same, causing a collision when running rake db:migrate
# copied functionality from RAILS_GEM_PATH/lib/rails_generator/commands.rb
- %w(create_surveys create_survey_sections create_questions create_question_groups create_answers create_response_sets create_responses create_dependencies create_dependency_conditions create_validations create_validation_conditions add_display_order_to_surveys add_correct_answer_id_to_questions add_index_to_response_sets add_index_to_surveys add_unique_indicies add_section_id_to_responses add_default_value_to_answers add_api_ids add_display_type_to_answers add_api_id_to_question_groups).each_with_index do |model, i|
+ %w(create_surveys create_survey_sections create_questions create_question_groups create_answers create_response_sets create_responses create_dependencies create_dependency_conditions create_validations create_validation_conditions add_display_order_to_surveys add_correct_answer_id_to_questions add_index_to_response_sets add_index_to_surveys add_unique_indicies add_section_id_to_responses add_default_value_to_answers add_api_ids add_display_type_to_answers add_api_id_to_question_groups add_api_ids_to_response_sets_and_responses).each_with_index do |model, i|
unless (prev_migrations = Dir.glob("db/migrate/[0-9]*_*.rb").grep(/[0-9]+_#{model}.rb$/)).empty?
prev_migration_timestamp = prev_migrations[0].match(/([0-9]+)_#{model}.rb$/)[1]
end
@@ -0,0 +1,11 @@
+class AddApiIdsToResponseSetsAndResponses < ActiveRecord::Migration
+ def self.up
+ add_column :response_sets, :api_id, :string
+ add_column :responses, :api_id, :string
+ end
+
+ def self.down
+ remove_column :response_sets, :api_id
+ remove_column :responses, :api_id
+ end
+end
View
@@ -25,28 +25,24 @@ def to_normalized_string(text)
(cols.size > 5 ? cols[-5..-1] : cols).join("_")
end
- def equal_json_excluding_uuids(a,b)
+ def equal_json_excluding_wildcards(a,b)
return false if a.nil? or b.nil?
a = a.is_a?(String) ? JSON.load(a) : JSON.load(a.to_json)
b = b.is_a?(String) ? JSON.load(b) : JSON.load(b.to_json)
- deep_compare(a,b)
+ deep_compare_excluding_wildcards(a,b)
end
- def deep_compare(a,b)
+ def deep_compare_excluding_wildcards(a,b)
return false if a.class != b.class
if a.is_a?(Hash)
return false if a.size != b.size
a.each do |k,v|
- if k == "uuid"
- return false unless b.has_key?("uuid")
- else
- return false if deep_compare(v,b[k]) == false
- end
+ return false if deep_compare_excluding_wildcards(v,b[k]) == false
end
elsif a.is_a?(Array)
return false if a.size != b.size
- a.each_with_index{|e,i| return false if deep_compare(e,b[i]) == false }
+ a.each_with_index{|e,i| return false if deep_compare_excluding_wildcards(e,b[i]) == false }
else
- return a == b
+ return (a == "*") || (b == "*") || (a == b)
end
true
end
@@ -6,6 +6,10 @@ def self.included(base)
base.send :belongs_to, :response_set
base.send :belongs_to, :question
base.send :belongs_to, :answer
+
+ # Scopes
+ base.send :default_scope, :order => "created_at ASC"
+
@@validations_already_included ||= nil
unless @@validations_already_included
# Validations
@@ -30,6 +34,15 @@ def applicable_attributes(attrs)
end
# Instance Methods
+ def initialize(*args)
+ super(*args)
+ default_args
+ end
+
+ def default_args
+ self.api_id ||= Surveyor::Common.generate_api_id
+ end
+
def answer_id=(val)
write_attribute :answer_id, (val.is_a?(Array) ? val.detect{|x| !x.to_s.blank?} : val)
end
@@ -77,8 +77,9 @@ def initialize(*args)
def default_args
self.started_at ||= Time.now
self.access_code ||= random_unique_access_code
+ self.api_id ||= Surveyor::Common.generate_api_id
end
-
+
def random_unique_access_code
val = Surveyor::Common.make_tiny_code
while ResponseSet.find_by_access_code(val)
@@ -101,6 +102,13 @@ def to_csv(access_code = false, print_header = true)
end
result
end
+
+ def to_json
+ template_path = ActionController::Base.view_paths.find("show", ["surveyor"], false, {:handlers=>[:rabl], :locale=>[:en], :formats=>[:json]}, [], []).inspect
+ engine = Rabl::Engine.new(File.read(template_path))
+ engine.render(nil, {:object => self})
+ end
+
def complete!
self.completed_at = Time.now
end
@@ -39,6 +39,7 @@ def show
format.csv {
send_data(@response_set.to_csv, :type => 'text/csv; charset=utf-8; header=present',:filename => "#{@response_set.updated_at.strftime('%Y-%m-%d')}_#{@response_set.access_code}.csv")
}
+ format.json
end
else
flash[:notice] = t('surveyor.unable_to_find_your_responses')
@@ -76,8 +76,8 @@ def group
helper.response_for(nil, q1).should == nil
helper.response_for(rs, q1).should == r1
helper.response_for(rs, q1, a).should == r1
- helper.response_for(rs, q2).attributes.should == Response.new(:question => q2, :response_set => rs).attributes
- helper.response_for(rs, q2, b).attributes.should == Response.new(:question => q2, :response_set => rs).attributes
+ helper.response_for(rs, q2).attributes.reject{|k,v| k == "api_id"}.should == Response.new(:question => q2, :response_set => rs).attributes.reject{|k,v| k == "api_id"}
+ helper.response_for(rs, q2, b).attributes.reject{|k,v| k == "api_id"}.should == Response.new(:question => q2, :response_set => rs).attributes.reject{|k,v| k == "api_id"}
helper.response_for(rs, q3, c, "1").should == r3
end
View
@@ -21,19 +21,19 @@
it "should deep compare json objects" do
a = {"a" => "b"}.to_json
b = '{"a": "b"}'
- Surveyor::Common.equal_json_excluding_uuids(a,b).should be_true
+ Surveyor::Common.equal_json_excluding_wildcards(a,b).should be_true
a = {"y" => "x"}.to_json
b = {:y => "x"}
- Surveyor::Common.equal_json_excluding_uuids(a,b).should be_true
+ Surveyor::Common.equal_json_excluding_wildcards(a,b).should be_true
a = [{"y" => "x"}, {"j" => "b"}].to_json
b = '[{"y": "x"}]'
- Surveyor::Common.equal_json_excluding_uuids(a,b).should be_false
+ Surveyor::Common.equal_json_excluding_wildcards(a,b).should be_false
a = [{"y" => "x"}, {"uuid" => "*"}].to_json
b = '[{"y": "x"}, {"uuid": "12312312312123"}]'
- Surveyor::Common.equal_json_excluding_uuids(a,b).should be_true
+ Surveyor::Common.equal_json_excluding_wildcards(a,b).should be_true
a = %({"survey": {
"title":"Simple survey",
@@ -44,7 +44,18 @@
}
})
b = %({"survey": {"title": "Simple survey","uuid": "*","sections": [{"title": "Basic questions"}]}})
- Surveyor::Common.equal_json_excluding_uuids(a,b).should be_true
+ Surveyor::Common.equal_json_excluding_wildcards(a,b).should be_true
+
+ a = %({"survey": {
+ "title":"Simple survey",
+ "uuid":"72888670-9151-012e-9ec1-00254bc472f4",
+ "sections":[{
+ "title":"Different"
+ }]
+ }
+ })
+ b = %({"survey": {"title": "Simple survey","uuid": "*","sections": [{"title": "Basic questions"}]}})
+ Surveyor::Common.equal_json_excluding_wildcards(a,b).should be_false
end
describe '#generate_api_id' do
def generate
@@ -33,6 +33,12 @@
@response.answer = Factory(:answer, :response_class => "answer").tap { |a| a.id = 143 }
@response.correct?.should be_false
end
+
+ it "should be in order by created_at" do
+ @response.response_set.should_not be_nil
+ response2 = Factory(:response, :question => Factory(:question), :answer => Factory(:answer), :response_set => @response.response_set, :created_at => (@response.created_at + 1))
+ Response.all.should == [@response, response2]
+ end
describe "returns the response as the type requested" do
it "returns 'string'" do

0 comments on commit 9b402ea

Please sign in to comment.