survey-gizmo-ruby 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +18 -0
- data/Gemfile.lock +48 -0
- data/LICENSE.txt +20 -0
- data/README.md +66 -0
- data/Rakefile +43 -0
- data/VERSION +1 -0
- data/lib/survey-gizmo-ruby.rb +1 -0
- data/lib/survey_gizmo/api/option.rb +28 -0
- data/lib/survey_gizmo/api/page.rb +31 -0
- data/lib/survey_gizmo/api/question.rb +35 -0
- data/lib/survey_gizmo/api/survey.rb +20 -0
- data/lib/survey_gizmo/collection.rb +68 -0
- data/lib/survey_gizmo/resource.rb +200 -0
- data/lib/survey_gizmo/survey_gizmo.rb +30 -0
- data/spec/spec_helper.rb +17 -0
- data/spec/support/model_cleanup.rb +38 -0
- data/spec/support/spec_shared_api_object.rb +127 -0
- data/spec/support/test_resource_classes.rb +42 -0
- data/spec/survey-gizmo-ruby_spec.rb +244 -0
- data/spec/test_json/page.json +1 -0
- data/spec/test_json/question.json +1 -0
- data/spec/test_json/survey.json +1 -0
- metadata +149 -0
data/Gemfile
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
|
3
|
+
gem "activesupport", '~> 3.0.1'
|
4
|
+
gem 'i18n'
|
5
|
+
gem 'virtus', '~> 0.0.5'
|
6
|
+
gem 'httparty'
|
7
|
+
|
8
|
+
group :development do
|
9
|
+
gem "yard", "~> 0.6.0"
|
10
|
+
gem "bundler", "~> 1.0.0"
|
11
|
+
gem "jeweler", "~> 1.6.4"
|
12
|
+
end
|
13
|
+
|
14
|
+
group :test do
|
15
|
+
gem "webmock", :require => 'webmock/rspec'
|
16
|
+
gem "rspec", "~> 2.3.0"
|
17
|
+
gem 'net-http-spy', :require => nil
|
18
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
activesupport (3.0.10)
|
5
|
+
addressable (2.2.6)
|
6
|
+
crack (0.1.8)
|
7
|
+
diff-lcs (1.1.3)
|
8
|
+
git (1.2.5)
|
9
|
+
httparty (0.8.0)
|
10
|
+
multi_json
|
11
|
+
multi_xml
|
12
|
+
i18n (0.5.0)
|
13
|
+
jeweler (1.6.4)
|
14
|
+
bundler (~> 1.0)
|
15
|
+
git (>= 1.2.5)
|
16
|
+
rake
|
17
|
+
multi_json (1.0.3)
|
18
|
+
multi_xml (0.4.0)
|
19
|
+
net-http-spy (0.2.1)
|
20
|
+
rake (0.9.2)
|
21
|
+
rspec (2.3.0)
|
22
|
+
rspec-core (~> 2.3.0)
|
23
|
+
rspec-expectations (~> 2.3.0)
|
24
|
+
rspec-mocks (~> 2.3.0)
|
25
|
+
rspec-core (2.3.1)
|
26
|
+
rspec-expectations (2.3.0)
|
27
|
+
diff-lcs (~> 1.1.2)
|
28
|
+
rspec-mocks (2.3.0)
|
29
|
+
virtus (0.0.8)
|
30
|
+
webmock (1.7.6)
|
31
|
+
addressable (~> 2.2, > 2.2.5)
|
32
|
+
crack (>= 0.1.7)
|
33
|
+
yard (0.6.8)
|
34
|
+
|
35
|
+
PLATFORMS
|
36
|
+
ruby
|
37
|
+
|
38
|
+
DEPENDENCIES
|
39
|
+
activesupport (~> 3.0.1)
|
40
|
+
bundler (~> 1.0.0)
|
41
|
+
httparty
|
42
|
+
i18n
|
43
|
+
jeweler (~> 1.6.4)
|
44
|
+
net-http-spy
|
45
|
+
rspec (~> 2.3.0)
|
46
|
+
virtus (~> 0.0.5)
|
47
|
+
webmock
|
48
|
+
yard (~> 0.6.0)
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 Kabari Hendrick
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
# Survey Gizmo (ruby)
|
2
|
+
|
3
|
+
Integrate with the [Survey Gizmo API](http://developer.surveygizmo.com/resources/rest-api-documentation-version-1-01/) using an ActiveModel style interface. We currently support rest API **v1**.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
The gem hasn't been pushed to rubygems.org yet, so for now just install from the repo with rake.
|
8
|
+
|
9
|
+
## Basic Usage
|
10
|
+
|
11
|
+
require 'survey-gizmo-ruby'
|
12
|
+
|
13
|
+
# somewhere in your app define your survey gizmo login credentials.
|
14
|
+
SurveyGizmo.setup(:user => 'you@somewhere.com', :password => 'mypassword')
|
15
|
+
|
16
|
+
SurveyGizmo::API::Survey.first(:id => 12345)
|
17
|
+
|
18
|
+
SurveyGizmo::API::Question.create(:survey_id => 1234, :page_id => 1, :title => 'Do you like ruby?', :type => 'checkbox')
|
19
|
+
|
20
|
+
## Adding API Objects
|
21
|
+
|
22
|
+
Currently, the following API objects are included in the gem: `Survey`, `Question`, `Option`, `Page`. If you want to use something that isn't included you can easily write a class that handles it. Here's an example of the `SurveyGizmo::API::Survey` class:
|
23
|
+
|
24
|
+
class Survey
|
25
|
+
# the base where most of the methods for handling the API are stored
|
26
|
+
include SurveyGizmo::Resource
|
27
|
+
|
28
|
+
# the attribtues the object should respond to
|
29
|
+
attribute :id, Integer
|
30
|
+
attribute :title, String
|
31
|
+
attribute :status, String
|
32
|
+
attribute :type, String, :default => 'survey'
|
33
|
+
attribute :created_on, DateTime
|
34
|
+
|
35
|
+
# defing the paths used to retrieve/set info
|
36
|
+
route '/survey/:id', :via => [:get, :update, :delete]
|
37
|
+
route '/survey', :via => :create
|
38
|
+
|
39
|
+
# this must be defined with the params that would be included in any route
|
40
|
+
def to_param_options
|
41
|
+
{:id => self.id}
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
The [Virtus](https://github.com/solnic/virtus) gem is included to handle the attributes, so please check their documentation as well.
|
46
|
+
|
47
|
+
# Contributing to survey-gizmo-ruby
|
48
|
+
|
49
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
50
|
+
* Take a gander at the github issues beforehand
|
51
|
+
* Fork the project
|
52
|
+
* Start a feature/bugfix branch and hack away
|
53
|
+
* Make sure to add tests for it!!!!
|
54
|
+
* Submit a pull request
|
55
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
56
|
+
|
57
|
+
## Missing Features
|
58
|
+
|
59
|
+
There are several API objects that are available and not included in this gem. It is also missing OAuth authentication ability. Also, the error notification isn't intuitive. It'd be great if someone could help tackle those!
|
60
|
+
|
61
|
+
|
62
|
+
# Copyright
|
63
|
+
|
64
|
+
Copyright (c) 2011 RipTheJacker. See LICENSE.txt for
|
65
|
+
further details.
|
66
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
begin
|
6
|
+
Bundler.setup(:default, :development)
|
7
|
+
rescue Bundler::BundlerError => e
|
8
|
+
$stderr.puts e.message
|
9
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
10
|
+
exit e.status_code
|
11
|
+
end
|
12
|
+
require 'rake'
|
13
|
+
|
14
|
+
require 'jeweler'
|
15
|
+
Jeweler::Tasks.new do |gem|
|
16
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
17
|
+
gem.name = "survey-gizmo-ruby"
|
18
|
+
gem.homepage = "http://github.com/RipTheJacker/survey-gizmo-ruby"
|
19
|
+
gem.license = "MIT"
|
20
|
+
gem.summary = %Q{gem to consume the Survey Gizmo API}
|
21
|
+
gem.description = %Q{}
|
22
|
+
gem.email = "self@ripthejacker.com"
|
23
|
+
gem.authors = ["Kabari Hendrick"]
|
24
|
+
gem.files = FileList['lib/**/*.rb', 'Gemfile*', '[A-Z]*', 'Rakefile', 'spec/**/*'].to_a
|
25
|
+
# dependencies defined in Gemfile
|
26
|
+
end
|
27
|
+
Jeweler::RubygemsDotOrgTasks.new
|
28
|
+
|
29
|
+
require 'rspec/core'
|
30
|
+
require 'rspec/core/rake_task'
|
31
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
32
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
33
|
+
end
|
34
|
+
|
35
|
+
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
36
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
37
|
+
spec.rcov = true
|
38
|
+
end
|
39
|
+
|
40
|
+
task :default => :spec
|
41
|
+
|
42
|
+
require 'yard'
|
43
|
+
YARD::Rake::YardocTask.new
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.5.0
|
@@ -0,0 +1 @@
|
|
1
|
+
require "survey_gizmo/survey_gizmo"
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module SurveyGizmo; module API
|
2
|
+
class Option
|
3
|
+
include SurveyGizmo::Resource
|
4
|
+
|
5
|
+
attribute :id, Integer
|
6
|
+
attribute :title, String
|
7
|
+
attribute :value, String
|
8
|
+
attribute :survey_id, Integer
|
9
|
+
attribute :page_id, Integer
|
10
|
+
attribute :question_id, Integer
|
11
|
+
|
12
|
+
# routing
|
13
|
+
route '/survey/:survey_id/surveypage/:page_id/surveyquestion/:question_id/surveyoption', :via => :create
|
14
|
+
route '/survey/:survey_id/surveypage/:page_id/surveyquestion/:question_id/surveyoption/:id', :via => [:get, :update, :delete]
|
15
|
+
|
16
|
+
# survey gizmo sends a hash back for :title
|
17
|
+
# @private
|
18
|
+
def title_with_multilingual=(val)
|
19
|
+
self.title_without_multilingual = val.is_a?(Hash) ? val['English'] : val
|
20
|
+
end
|
21
|
+
|
22
|
+
alias_method_chain :title=, :multilingual
|
23
|
+
|
24
|
+
def to_param_options
|
25
|
+
{:id => self.id, :survey_id => self.survey_id, :page_id => self.page_id, :question_id => self.question_id}
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end; end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module SurveyGizmo; module API
|
2
|
+
class Page
|
3
|
+
include SurveyGizmo::Resource
|
4
|
+
|
5
|
+
attribute :id, Integer
|
6
|
+
attribute :title, String
|
7
|
+
attribute :description, String
|
8
|
+
attribute :properties, Hash
|
9
|
+
attribute :after, Integer
|
10
|
+
attribute :survey_id, Integer
|
11
|
+
|
12
|
+
|
13
|
+
# routing
|
14
|
+
route '/survey/:survey_id/surveypage', :via => :create
|
15
|
+
route '/survey/:survey_id/surveypage/:id', :via => [:get, :update, :delete]
|
16
|
+
|
17
|
+
collection :questions
|
18
|
+
|
19
|
+
# survey gizmo sends a hash back for :title
|
20
|
+
# @private
|
21
|
+
def title_with_multilingual=(val)
|
22
|
+
self.title_without_multilingual = val.is_a?(Hash) ? val['English'] : val
|
23
|
+
end
|
24
|
+
|
25
|
+
alias_method_chain :title=, :multilingual
|
26
|
+
|
27
|
+
def to_param_options
|
28
|
+
{:id => self.id, :survey_id => self.survey_id}
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end; end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module SurveyGizmo; module API
|
2
|
+
class Question
|
3
|
+
include SurveyGizmo::Resource
|
4
|
+
|
5
|
+
attribute :id, Integer
|
6
|
+
attribute :title, String
|
7
|
+
attribute :type, String
|
8
|
+
attribute :description, String
|
9
|
+
attribute :properties, Hash
|
10
|
+
attribute :after, Integer
|
11
|
+
attribute :survey_id, Integer
|
12
|
+
attribute :page_id, Integer
|
13
|
+
|
14
|
+
alias_attribute :_subtype, :type
|
15
|
+
|
16
|
+
# routing
|
17
|
+
route '/survey/:survey_id/surveyquestion/:id', :via => :get
|
18
|
+
route '/survey/:survey_id/surveypage/:page_id/surveyquestion', :via => :create
|
19
|
+
route '/survey/:survey_id/surveypage/:page_id/surveyquestion/:id', :via => [:update, :delete]
|
20
|
+
|
21
|
+
collection :options
|
22
|
+
|
23
|
+
# survey gizmo sends a hash back for :title
|
24
|
+
# @private
|
25
|
+
def title_with_multilingual=(val)
|
26
|
+
self.title_without_multilingual = val.is_a?(Hash) ? val['English'] : val
|
27
|
+
end
|
28
|
+
|
29
|
+
alias_method_chain :title=, :multilingual
|
30
|
+
|
31
|
+
def to_param_options
|
32
|
+
{:id => self.id, :survey_id => self.survey_id, :page_id => self.page_id}
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end; end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module SurveyGizmo; module API
|
2
|
+
class Survey
|
3
|
+
include SurveyGizmo::Resource
|
4
|
+
|
5
|
+
attribute :id, Integer
|
6
|
+
attribute :title, String
|
7
|
+
attribute :status, String
|
8
|
+
attribute :type, String, :default => 'survey'
|
9
|
+
attribute :created_on, DateTime
|
10
|
+
|
11
|
+
route '/survey/:id', :via => [:get, :update, :delete]
|
12
|
+
route '/survey', :via => :create
|
13
|
+
|
14
|
+
collection :pages
|
15
|
+
|
16
|
+
def to_param_options
|
17
|
+
{:id => self.id}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end; end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module SurveyGizmo
|
2
|
+
class Collection
|
3
|
+
include Enumerable
|
4
|
+
|
5
|
+
private
|
6
|
+
# @param [Class] resource
|
7
|
+
# @param [Symbol] name
|
8
|
+
# @param [Array] values
|
9
|
+
def initialize(resource, name, values)
|
10
|
+
@array = Array(values)
|
11
|
+
@collection = []
|
12
|
+
@loaded = false
|
13
|
+
@options = resource.collections[name]
|
14
|
+
end
|
15
|
+
|
16
|
+
public
|
17
|
+
|
18
|
+
def length
|
19
|
+
@array.length
|
20
|
+
end
|
21
|
+
|
22
|
+
def each
|
23
|
+
lazy_load
|
24
|
+
if block_given?
|
25
|
+
@collection.each{ |o| yield(o)}
|
26
|
+
else
|
27
|
+
@collection.each
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def method_missing(meth, *args, &blk)
|
32
|
+
@collection.send(meth, *args, &blk)
|
33
|
+
end
|
34
|
+
|
35
|
+
def model
|
36
|
+
return @model if defined?(@model)
|
37
|
+
return (@model = options[:target]) if options[:target].is_a?(Class)
|
38
|
+
name_string = options[:target].is_a?(Symbol) ? ActiveSupport::Inflector.classify(options[:target]) : options[:target]
|
39
|
+
@model = name_string[/::/] ? Object.const_get?(name_string) : Resource.descendants.detect{ |d| ActiveSupport::Inflector.demodulize(d.name) == name_string }
|
40
|
+
raise NameError, "#{name_string} is not a descendant of SurveyGizmo::Resource" unless @model
|
41
|
+
@model
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
protected
|
46
|
+
attr_accessor :options
|
47
|
+
|
48
|
+
def lazy_load
|
49
|
+
return if loaded?
|
50
|
+
@collection = @array.map{|hash| load_object(hash) }
|
51
|
+
mark_loaded
|
52
|
+
end
|
53
|
+
|
54
|
+
def load_object(obj_or_attributes)
|
55
|
+
return obj_or_attributes if loaded?
|
56
|
+
obj_or_attributes.is_a?(Hash) ? model.load(obj_or_attributes) : obj_or_attributes
|
57
|
+
end
|
58
|
+
|
59
|
+
def mark_loaded
|
60
|
+
@loaded = true
|
61
|
+
end
|
62
|
+
|
63
|
+
def loaded?
|
64
|
+
@loaded
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,200 @@
|
|
1
|
+
require "set"
|
2
|
+
|
3
|
+
module SurveyGizmo
|
4
|
+
module Resource
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
include Virtus
|
9
|
+
instance_variable_set('@paths', {})
|
10
|
+
instance_variable_set('@collections', {})
|
11
|
+
SurveyGizmo::Resource.descendants << self
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.descendants
|
15
|
+
@descendants ||= Set.new
|
16
|
+
end
|
17
|
+
|
18
|
+
module ClassMethods
|
19
|
+
|
20
|
+
# Get a list of resources
|
21
|
+
# @param [Hash] conditions
|
22
|
+
# @return [SurveGizmo::Collection, false]
|
23
|
+
def all(conditions = {})
|
24
|
+
response = SurveyGizmo.get(handle_route(:create, conditions))
|
25
|
+
if response.parsed_response['result_ok']
|
26
|
+
collection = SurveyGizmo::Collection.new(self, nil, response.parsed_response['data'])
|
27
|
+
collection.send(:options=, {:target => self, :parent => self})
|
28
|
+
collection
|
29
|
+
else
|
30
|
+
# do something
|
31
|
+
# e = response.parsed_response['message']
|
32
|
+
false
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# Get the first resource
|
37
|
+
# @param [Hash] conditions
|
38
|
+
# @return [Object, false]
|
39
|
+
def first(conditions)
|
40
|
+
response = SurveyGizmo.get(handle_route(:get, conditions))
|
41
|
+
if response.parsed_response['result_ok']
|
42
|
+
resource = new(conditions.merge(response.parsed_response['data']))
|
43
|
+
resource.__send__(:clean!)
|
44
|
+
resource
|
45
|
+
else
|
46
|
+
# do something
|
47
|
+
# e = response.parsed_response['message']
|
48
|
+
false
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# Create a new resource
|
53
|
+
# @param [Hash] attributes
|
54
|
+
# @return [Object]
|
55
|
+
def create(attributes = {})
|
56
|
+
resource = new(attributes)
|
57
|
+
resource.__send__(:_create)
|
58
|
+
resource
|
59
|
+
end
|
60
|
+
|
61
|
+
# Define the path where a resource is located
|
62
|
+
# @param [String] path the path in Survey Gizmo for the resource
|
63
|
+
# @param [Hash] options must include `:via` which is `:get`, `:create`, `:update`, `:delete`, or `:any`
|
64
|
+
def route(path, options)
|
65
|
+
methods = options[:via]
|
66
|
+
methods = [:get, :create, :update, :delete] if methods == :any
|
67
|
+
methods.is_a?(Array) ? methods.each{|m| @paths[m] = path } : (@paths[methods] = path)
|
68
|
+
nil
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
def load(attributes = {})
|
73
|
+
resource = new(attributes)
|
74
|
+
resource.__send__(:clean!)
|
75
|
+
resource
|
76
|
+
end
|
77
|
+
|
78
|
+
def collection(resource_name, model = nil)
|
79
|
+
@collections[resource_name] = {:parent => self, :target => (model ? model : resource_name)} # workaround for weird bug with passing a class to Collection
|
80
|
+
class_eval(<<-EOS)
|
81
|
+
def #{resource_name}
|
82
|
+
@#{resource_name} ||= []
|
83
|
+
end
|
84
|
+
|
85
|
+
def #{resource_name}=(array)
|
86
|
+
@#{resource_name} = SurveyGizmo::Collection.new(#{self}, :#{resource_name}, array)
|
87
|
+
end
|
88
|
+
EOS
|
89
|
+
end
|
90
|
+
|
91
|
+
def collections
|
92
|
+
@collections
|
93
|
+
end
|
94
|
+
|
95
|
+
def handle_route(key, *interp)
|
96
|
+
path = @paths[key]
|
97
|
+
raise "No routes defined for `#{key}` in #{self.name}" unless path
|
98
|
+
options = interp.last.is_a?(Hash) ? interp.pop : path.scan(/:(\w+)/).inject({}){|hash, k| hash.merge(k.to_sym => interp.shift) }
|
99
|
+
path.gsub(/:(\w+)/){|m| options[$1.to_sym] }
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def update(attributes = {})
|
104
|
+
self.attributes = attributes
|
105
|
+
self.save
|
106
|
+
end
|
107
|
+
|
108
|
+
def save
|
109
|
+
response = SurveyGizmo.post(handle_route(:update), :query => self.attributes_without_blanks)
|
110
|
+
_result = response.parsed_response['result_ok']
|
111
|
+
saved! if _result
|
112
|
+
_result
|
113
|
+
end
|
114
|
+
|
115
|
+
# fetch resource from SurveyGizmo and reload the attributes
|
116
|
+
def reload
|
117
|
+
response = SurveyGizmo.get(handle_route(:get))
|
118
|
+
if response.parsed_response['result_ok']
|
119
|
+
self.attributes = response.parsed_response['data']
|
120
|
+
clean!
|
121
|
+
self
|
122
|
+
else
|
123
|
+
# do something
|
124
|
+
# e = response.parsed_response['message']
|
125
|
+
false
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def destroy
|
130
|
+
return false if new?
|
131
|
+
response = SurveyGizmo.delete(handle_route(:delete))
|
132
|
+
_result = response.parsed_response['result_ok']
|
133
|
+
destroyed! if _result
|
134
|
+
_result
|
135
|
+
end
|
136
|
+
|
137
|
+
def new?
|
138
|
+
@_state.nil?
|
139
|
+
end
|
140
|
+
|
141
|
+
# @todo This seemed like a good way to prevent accidently trying to perform an action
|
142
|
+
# on a record at a point when it would fail. Not sure if it's really necessary though.
|
143
|
+
[:clean, # stored and not dirty
|
144
|
+
:saved, # stored and not modified
|
145
|
+
:destroyed, # duh!
|
146
|
+
:zombie # needs to be stored
|
147
|
+
].each do |state|
|
148
|
+
define_method("#{state}!") do
|
149
|
+
@_state = state
|
150
|
+
end
|
151
|
+
|
152
|
+
define_method("#{state}?") do
|
153
|
+
@_state == state
|
154
|
+
end
|
155
|
+
|
156
|
+
private "#{state}!"
|
157
|
+
end
|
158
|
+
|
159
|
+
# Sets the hash that will be used to interpolate values in routes. It needs to be defined per model.
|
160
|
+
# @return [Hash] a hash of the values needed in routing. ie. {:id => self.id}
|
161
|
+
def to_param_options
|
162
|
+
raise "Define #to_param_options in #{self.class.name}"
|
163
|
+
end
|
164
|
+
|
165
|
+
def inspect
|
166
|
+
attrs = self.class.attributes.map do |attrib|
|
167
|
+
value = attrib.get!(self).inspect
|
168
|
+
|
169
|
+
"#{attrib.instance_variable_name}=#{value}"
|
170
|
+
end
|
171
|
+
|
172
|
+
"#<#{self.class.name}:#{self.object_id} #{attrs.join(' ')}>"
|
173
|
+
end
|
174
|
+
|
175
|
+
protected
|
176
|
+
|
177
|
+
def handle_route(key)
|
178
|
+
self.class.handle_route(key, to_param_options)
|
179
|
+
end
|
180
|
+
|
181
|
+
# @private
|
182
|
+
def _create(attributes = {})
|
183
|
+
response = SurveyGizmo.put(handle_route(:create), :query => self.attributes_without_blanks)
|
184
|
+
if response.parsed_response['result_ok']
|
185
|
+
self.attributes = response.parsed_response['data']
|
186
|
+
saved!
|
187
|
+
else
|
188
|
+
# do something
|
189
|
+
# e = response.parsed_response['message']
|
190
|
+
false
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
# @private
|
195
|
+
def attributes_without_blanks
|
196
|
+
self.attributes.reject{|k,v| v.blank? }
|
197
|
+
end
|
198
|
+
|
199
|
+
end
|
200
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require "active_support/core_ext/string"
|
2
|
+
require "active_support/core_ext/module"
|
3
|
+
require "active_support/core_ext/hash"
|
4
|
+
require "active_support/core_ext/object/blank"
|
5
|
+
require "active_support/concern"
|
6
|
+
require "virtus"
|
7
|
+
require "httparty"
|
8
|
+
|
9
|
+
require "survey_gizmo/resource"
|
10
|
+
require "survey_gizmo/collection"
|
11
|
+
|
12
|
+
require "survey_gizmo/api/survey"
|
13
|
+
require "survey_gizmo/api/question"
|
14
|
+
require "survey_gizmo/api/option"
|
15
|
+
require "survey_gizmo/api/page"
|
16
|
+
|
17
|
+
module SurveyGizmo
|
18
|
+
include HTTParty
|
19
|
+
|
20
|
+
format :json
|
21
|
+
base_uri 'https://restapi.surveygizmo.com/v1'
|
22
|
+
@@options = {}
|
23
|
+
mattr_accessor :options
|
24
|
+
|
25
|
+
def self.setup(opts = {})
|
26
|
+
self.options = opts
|
27
|
+
default_params({"user:pass" => opts.values_at(:user, :password).join(':')})
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
3
|
+
require "bundler/setup"
|
4
|
+
Bundler.require(:test)
|
5
|
+
require 'survey-gizmo-ruby'
|
6
|
+
require "active_support/json"
|
7
|
+
require "active_support/ordered_hash"
|
8
|
+
|
9
|
+
# Requires supporting files with custom matchers and macros, etc,
|
10
|
+
# in ./support/ and its subdirectories.
|
11
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
12
|
+
|
13
|
+
RSpec.configure do |config|
|
14
|
+
config.after(:all) do
|
15
|
+
SurveyGizmoSpec.cleanup_models
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module SurveyGizmoSpec
|
2
|
+
# global model cleanup. Mostly stolen from DataMapper.
|
3
|
+
def self.cleanup_models
|
4
|
+
descendants = SurveyGizmo::Resource.descendants.to_a
|
5
|
+
|
6
|
+
while model = descendants.shift
|
7
|
+
model_name = model.name.to_s.strip
|
8
|
+
|
9
|
+
unless model_name.empty? || model_name[0] == ?#
|
10
|
+
parts = model_name.split('::')
|
11
|
+
constant_name = parts.pop.to_sym
|
12
|
+
base = parts.empty? ? Object : SurveyGizmoSpec.full_const_get(parts.join('::'))
|
13
|
+
|
14
|
+
base.class_eval { remove_const(constant_name) if const_defined?(constant_name) }
|
15
|
+
end
|
16
|
+
|
17
|
+
model.instance_methods(false).each { |method| model.send(:undef_method, method) }
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
SurveyGizmo::Resource.descendants.clear
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
class Object
|
27
|
+
def full_const_get(name)
|
28
|
+
list = name.split("::")
|
29
|
+
list.shift if list.first.blank?
|
30
|
+
obj = self
|
31
|
+
list.each do |x|
|
32
|
+
# This is required because const_get tries to look for constants in the
|
33
|
+
# ancestor chain, but we only want constants that are HERE
|
34
|
+
obj = obj.const_defined?(x) ? obj.const_get(x) : obj.const_missing(x)
|
35
|
+
end
|
36
|
+
obj
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
shared_examples_for 'an API object' do
|
2
|
+
before(:each) do
|
3
|
+
SurveyGizmo.setup(:user => 'test@test.com', :password => 'password')
|
4
|
+
end
|
5
|
+
|
6
|
+
context "create" do
|
7
|
+
it "should make a request" do
|
8
|
+
stub_api_call(:put)
|
9
|
+
described_class.create(create_attributes)
|
10
|
+
a_request(:put, /#{@base}#{uri_paths[:create]}/).should have_been_made
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should return a new instance" do
|
14
|
+
stub_api_call(:put)
|
15
|
+
obj = described_class.create(create_attributes)
|
16
|
+
obj.should be_instance_of(described_class)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should set the attributes" do
|
20
|
+
stub_request(:put, /#{@base}/).to_return(json_response(true, create_attributes))
|
21
|
+
obj = described_class.create(create_attributes)
|
22
|
+
obj.attributes.reject{|k,v| v.blank? }.should == create_attributes
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context "get" do
|
27
|
+
it "should make a request" do
|
28
|
+
stub_request(:get, /#{@base}/).to_return(json_response(true, get_attributes))
|
29
|
+
described_class.first(first_params)
|
30
|
+
a_request(:get, /#{@base}#{uri_paths[:get]}/).should have_been_made
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should set the attributes" do
|
34
|
+
stub_request(:get, /#{@base}/).to_return(json_response(true, get_attributes))
|
35
|
+
obj = described_class.first(first_params)
|
36
|
+
obj.attributes.reject{|k,v| v.blank? }.should == get_attributes
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should return false if the request fails" do
|
40
|
+
stub_request(:get, /#{@base}/).to_return(json_response(false, "something is wrong"))
|
41
|
+
described_class.first(first_params).should == false
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context "update" do
|
46
|
+
before(:each) do
|
47
|
+
@obj = described_class.new(get_attributes)
|
48
|
+
@obj.__send__(:clean!)
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should make a request" do
|
52
|
+
stub_api_call(:post)
|
53
|
+
@obj.update
|
54
|
+
a_request(:post, /#{@base}#{uri_paths[:update]}/).should have_been_made
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'should change object state to saved' do
|
58
|
+
stub_api_call(:post)
|
59
|
+
@obj.update(update_attributes)
|
60
|
+
@obj.should be_saved
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should not be marked saved if the request fails" do
|
64
|
+
stub_api_call(:post, false)
|
65
|
+
@obj.update
|
66
|
+
@obj.should_not be_saved
|
67
|
+
end
|
68
|
+
|
69
|
+
xit "cannot be updated if new" do
|
70
|
+
@obj.instance_variable_set('@_state', nil)
|
71
|
+
@obj.update(update_attributes).should be_false
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
context "destroy" do
|
77
|
+
before(:each) do
|
78
|
+
@obj = described_class.new(get_attributes)
|
79
|
+
@obj.__send__(:clean!)
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should make a request" do
|
83
|
+
stub_api_call(:delete)
|
84
|
+
@obj.destroy
|
85
|
+
a_request(:delete, /#{@base}#{uri_paths[:delete]}/).should have_been_made
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'should change object state to destroyed' do
|
89
|
+
stub_api_call(:delete)
|
90
|
+
@obj.destroy
|
91
|
+
@obj.should be_destroyed
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should not be marked destroyed if the request fails" do
|
95
|
+
stub_api_call(:delete, false)
|
96
|
+
@obj.destroy
|
97
|
+
@obj.should_not be_destroyed
|
98
|
+
end
|
99
|
+
|
100
|
+
it "cannot be destroyed if new" do
|
101
|
+
@obj.instance_variable_set('@_state', nil)
|
102
|
+
@obj.destroy.should be_false
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
context '#all' do
|
107
|
+
it "should make a get request" do
|
108
|
+
stub_request(:get, /#{@base}/).to_return(json_response(true, []))
|
109
|
+
described_class.all(get_attributes)
|
110
|
+
a_request(:get, /#{@base}#{uri_paths[:create]}/).should have_been_made
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should create a collection using the class" do
|
114
|
+
@array = [
|
115
|
+
{:id => 1, :title => 'resource 1'},
|
116
|
+
{:id => 2, :title => 'resource 2'},
|
117
|
+
{:id => 3, :title => 'resource 3'}
|
118
|
+
]
|
119
|
+
|
120
|
+
stub_request(:get, /#{@base}/).to_return(json_response(true, @array))
|
121
|
+
collection = described_class.all(get_attributes)
|
122
|
+
collection.should be_instance_of(SurveyGizmo::Collection)
|
123
|
+
collection.first.should be_instance_of(described_class)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module SurveyGizmoSpec
|
2
|
+
class ResourceTest
|
3
|
+
include SurveyGizmo::Resource
|
4
|
+
|
5
|
+
attribute :id, Integer
|
6
|
+
attribute :title, String
|
7
|
+
attribute :test_id, Integer
|
8
|
+
|
9
|
+
# routes
|
10
|
+
route '/test/:id', :via => :get
|
11
|
+
route '/test/:test_id/resource', :via => :create
|
12
|
+
route '/test/:test_id/resource/:id', :via => [:update, :delete]
|
13
|
+
|
14
|
+
def to_param_options
|
15
|
+
{:id => self.id, :test_id => self.test_id}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class CollectionTest
|
20
|
+
include SurveyGizmo::Resource
|
21
|
+
|
22
|
+
attribute :id, Integer
|
23
|
+
attribute :title, String
|
24
|
+
|
25
|
+
# routes
|
26
|
+
route '/test/:id', :via => :get
|
27
|
+
route '/test/collection', :via => :create
|
28
|
+
route '/test/collection/:id', :via => [:update, :delete]
|
29
|
+
|
30
|
+
def to_param_options
|
31
|
+
{:id => self.id, :test_id => self.test_id}
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class GenericResource
|
36
|
+
include SurveyGizmo::Resource
|
37
|
+
|
38
|
+
attribute :id, Integer
|
39
|
+
attribute :title, String
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,244 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe "SurveyGizmo" do
|
4
|
+
before(:each) do
|
5
|
+
@base = 'https://restapi.surveygizmo.com/v1'
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should have a base uri" do
|
9
|
+
SurveyGizmo.base_uri.should == 'https://restapi.surveygizmo.com/v1'
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should allow basic authentication configuration" do
|
13
|
+
SurveyGizmo.setup(:user => 'test@test.com', :password => 'password')
|
14
|
+
SurveyGizmo.default_options[:default_params].should == {'user:pass' => 'test@test.com:password'}
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should raise an error if auth isn't configured"
|
18
|
+
|
19
|
+
describe SurveyGizmo::Resource do
|
20
|
+
before(:each) do
|
21
|
+
SurveyGizmo.setup(:user => 'test@test.com', :password => 'password')
|
22
|
+
end
|
23
|
+
|
24
|
+
let(:described_class) { SurveyGizmoSpec::ResourceTest }
|
25
|
+
|
26
|
+
let(:create_attributes){ {:title => 'Spec', :test_id => 5} }
|
27
|
+
let(:get_attributes) { create_attributes.merge(:id => 1) }
|
28
|
+
let(:update_attributes){ {:title => 'Updated'} }
|
29
|
+
let(:first_params){ {:id => 1} }
|
30
|
+
let(:uri_paths){
|
31
|
+
{
|
32
|
+
:get => '/test/1',
|
33
|
+
:create => '/test/5/resource',
|
34
|
+
:update => '/test/5/resource/1',
|
35
|
+
:delete => '/test/5/resource/1'
|
36
|
+
}
|
37
|
+
}
|
38
|
+
|
39
|
+
it "#new?" do
|
40
|
+
described_class.new.should be_new
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
it '#reload' do
|
45
|
+
stub_request(:get, /#{@base}/).to_return(json_response(true, get_attributes))
|
46
|
+
obj = described_class.new(create_attributes)
|
47
|
+
obj.attributes.reject{|k,v| v.blank? }.should == create_attributes
|
48
|
+
obj.reload
|
49
|
+
obj.attributes.reject{|k,v| v.blank? }.should == get_attributes
|
50
|
+
end
|
51
|
+
|
52
|
+
it '#valid?'
|
53
|
+
it "should be in zombie state if requests fail"
|
54
|
+
|
55
|
+
it "should track descendants" do
|
56
|
+
SurveyGizmo::Resource.descendants.should include(SurveyGizmoSpec::ResourceTest)
|
57
|
+
end
|
58
|
+
|
59
|
+
it_should_behave_like 'an API object'
|
60
|
+
end
|
61
|
+
|
62
|
+
describe SurveyGizmo::API::Survey do
|
63
|
+
let(:create_attributes){ {:title => 'Spec', :type => 'survey', :status => 'In Design'} }
|
64
|
+
let(:get_attributes) { create_attributes.merge(:id => 1234) }
|
65
|
+
let(:update_attributes){ {:title => 'Updated'} }
|
66
|
+
let(:first_params){ {:id => 1234} }
|
67
|
+
let(:uri_paths){
|
68
|
+
h = { :create => '/survey' }
|
69
|
+
h.default = '/survey/1234'
|
70
|
+
h
|
71
|
+
}
|
72
|
+
|
73
|
+
it_should_behave_like 'an API object'
|
74
|
+
end
|
75
|
+
|
76
|
+
describe SurveyGizmo::API::Question do
|
77
|
+
let(:create_attributes){ {:survey_id => 1234, :page_id => 1, :title => 'Spec Question', :type => 'radio', :properties => {"required" => true, "option_sort" => false} } }
|
78
|
+
let(:get_attributes) {
|
79
|
+
create_attributes.merge(:id => 1)
|
80
|
+
}
|
81
|
+
let(:update_attributes){ {:survey_id => 1234, :page_id => 1, :title => 'Updated'} }
|
82
|
+
let(:first_params){ {:id => 1, :survey_id => 1234} }
|
83
|
+
let(:uri_paths){
|
84
|
+
{ :get => '/survey/1234/surveyquestion/1',
|
85
|
+
:create => '/survey/1234/surveypage/1/surveyquestion',
|
86
|
+
:update => '/survey/1234/surveypage/1/surveyquestion/1',
|
87
|
+
:delete => '/survey/1234/surveypage/1/surveyquestion/1'
|
88
|
+
}
|
89
|
+
}
|
90
|
+
|
91
|
+
it_should_behave_like 'an API object'
|
92
|
+
|
93
|
+
it "should handle the title hash returned from the API" do
|
94
|
+
@question = described_class.new('title' => {'English' => 'Some title'})
|
95
|
+
@question.title.should == 'Some title'
|
96
|
+
end
|
97
|
+
|
98
|
+
it "should handle the _subtype key" do
|
99
|
+
@question = described_class.new(:_subtype => 'radio')
|
100
|
+
@question.type.should == 'radio'
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
describe SurveyGizmo::API::Option do
|
105
|
+
let(:create_attributes){ {:survey_id => 1234, :page_id => 1, :question_id => 1, :title => 'Spec Question', :value => 'Spec Answer'} }
|
106
|
+
let(:get_attributes) {
|
107
|
+
create_attributes.merge(:id => 1)
|
108
|
+
}
|
109
|
+
let(:update_attributes){ {:survey_id => 1234, :page_id => 1, :question_id => 1, :title => 'Updated'} }
|
110
|
+
let(:first_params){ {:id => 1, :survey_id => 1234, :page_id => 1, :question_id => 1} }
|
111
|
+
let(:uri_paths){
|
112
|
+
h = { :create => '/survey/1234/surveypage/1/surveyquestion/1/surveyoption' }
|
113
|
+
h.default = '/survey/1234/surveypage/1/surveyquestion/1/surveyoption/1'
|
114
|
+
h
|
115
|
+
}
|
116
|
+
|
117
|
+
it_should_behave_like 'an API object'
|
118
|
+
|
119
|
+
end
|
120
|
+
|
121
|
+
describe SurveyGizmo::API::Page do
|
122
|
+
let(:create_attributes){ {:survey_id => 1234, :title => 'Spec Page'} }
|
123
|
+
let(:get_attributes) {
|
124
|
+
create_attributes.merge(:id => 1)
|
125
|
+
}
|
126
|
+
let(:update_attributes){ {:survey_id => 1234, :title => 'Updated'} }
|
127
|
+
let(:first_params){ {:id => 1, :survey_id => 1234 } }
|
128
|
+
let(:uri_paths){
|
129
|
+
h = { :create => '/survey/1234/surveypage' }
|
130
|
+
h.default = '/survey/1234/surveypage/1'
|
131
|
+
h
|
132
|
+
}
|
133
|
+
|
134
|
+
it_should_behave_like 'an API object'
|
135
|
+
|
136
|
+
end
|
137
|
+
|
138
|
+
|
139
|
+
describe "Collection" do
|
140
|
+
before(:each) do
|
141
|
+
@array = [
|
142
|
+
{:id => 1, :title => 'Test 1'},
|
143
|
+
{:id => 2, :title => 'Test 2'},
|
144
|
+
{:id => 3, :title => 'Test 3'},
|
145
|
+
{:id => 4, :title => 'Test 4'}
|
146
|
+
]
|
147
|
+
|
148
|
+
SurveyGizmo::Collection.send :public, *SurveyGizmo::Collection.private_instance_methods
|
149
|
+
end
|
150
|
+
|
151
|
+
let(:described_class) { SurveyGizmoSpec::CollectionTest }
|
152
|
+
|
153
|
+
context "class" do
|
154
|
+
before(:each) do
|
155
|
+
described_class.collection :generic_resources
|
156
|
+
end
|
157
|
+
|
158
|
+
subject { SurveyGizmo::Collection.new(described_class, :generic_resources, @array) }
|
159
|
+
|
160
|
+
it { should_not be_loaded }
|
161
|
+
|
162
|
+
it "should set the options in the collections property" do
|
163
|
+
described_class.collections.should == {:generic_resources => {:parent => described_class, :target => :generic_resources}}
|
164
|
+
end
|
165
|
+
|
166
|
+
it "should load objects using the given class" do
|
167
|
+
subject.first.should be_instance_of(SurveyGizmoSpec::GenericResource)
|
168
|
+
end
|
169
|
+
|
170
|
+
it "should be loaded before iteration" do
|
171
|
+
subject.should_not be_loaded
|
172
|
+
subject.each
|
173
|
+
subject.should be_loaded
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
context '#collection' do
|
178
|
+
before(:each) do
|
179
|
+
described_class.collection(:resources, 'ResourceTest')
|
180
|
+
end
|
181
|
+
|
182
|
+
it { lambda{ described_class.collection :resources, 'ResourceTest'}.should_not raise_error }
|
183
|
+
|
184
|
+
it "should have an accessor for the collection" do
|
185
|
+
described_class.public_instance_methods.should include(:resources)
|
186
|
+
described_class.public_instance_methods.should include(:resources=)
|
187
|
+
end
|
188
|
+
|
189
|
+
it "should set an empty collection" do
|
190
|
+
described_class.collection(:resources, 'ResourceTest')
|
191
|
+
obj = described_class.new()
|
192
|
+
obj.resources.should be_empty
|
193
|
+
end
|
194
|
+
|
195
|
+
it "should set a collection" do
|
196
|
+
described_class.collection(:resources, 'ResourceTest')
|
197
|
+
obj = described_class.new()
|
198
|
+
obj.resources = @array
|
199
|
+
obj.resources.should be_instance_of(SurveyGizmo::Collection)
|
200
|
+
obj.resources.length.should == @array.length
|
201
|
+
end
|
202
|
+
|
203
|
+
it "should set a collection from a hash" do
|
204
|
+
obj = described_class.new(:id => 1, :resources => @array)
|
205
|
+
obj.resources.should be_instance_of(SurveyGizmo::Collection)
|
206
|
+
obj.resources.length.should == @array.length
|
207
|
+
end
|
208
|
+
|
209
|
+
it "can handle multiple collections" do
|
210
|
+
described_class.collection(:generic_resources)
|
211
|
+
described_class.public_instance_methods.should include(:resources)
|
212
|
+
described_class.public_instance_methods.should include(:generic_resources)
|
213
|
+
end
|
214
|
+
|
215
|
+
it "can handle nested collections" do
|
216
|
+
SurveyGizmoSpec::ResourceTest.collection :generic_resources
|
217
|
+
@array2 = [
|
218
|
+
{:id => 1, :title => 'Generic Test 5'},
|
219
|
+
{:id => 2, :title => 'Generic Test 6'},
|
220
|
+
{:id => 3, :title => 'Generic Test 7'}
|
221
|
+
]
|
222
|
+
|
223
|
+
@array << {:id => 99, :generic_resources => @array2}
|
224
|
+
obj = described_class.new(:id => 1, :resources => @array)
|
225
|
+
obj.resources.first.should be_instance_of(SurveyGizmoSpec::ResourceTest)
|
226
|
+
obj.resources.last.generic_resources.first.should be_instance_of(SurveyGizmoSpec::GenericResource)
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
def stub_api_call(method, result = true)
|
232
|
+
stub_request(method, /#{@base}/).to_return(json_response(result, {}))
|
233
|
+
end
|
234
|
+
|
235
|
+
def request_params(opts = {})
|
236
|
+
{"user:pass" => 'test@test.com:password'}.merge(opts)
|
237
|
+
end
|
238
|
+
|
239
|
+
def json_response(result, data)
|
240
|
+
body = {:result_ok => result}
|
241
|
+
result ? body.merge!(:data => data) : body.merge!(:message => data)
|
242
|
+
{:headers => {'Content-Type' => 'application/json'}, :body => body.to_json}
|
243
|
+
end
|
244
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
{\"result_ok\":true,\"data\":{\"id\":1,\"_type\":\"SurveyPage\",\"title\":{\"English\":\"Page One\"},\"properties\":{\"hidden\":false},\"description\":[],\"questions\":[{\"id\":2,\"_type\":\"SurveyQuestion\",\"_subtype\":\"radio\",\"title\":{\"English\":\"Do you like steak?\"},\"shortname\":null,\"varname\":null,\"description\":[],\"has_showhide_deps\":null,\"properties\":{\"option_sort\":false,\"required\":true,\"hidden\":false,\"orientation\":\"VERT\",\"labels_right\":true,\"map_key\":\"radio\"},\"options\":[{\"id\":10001,\"_type\":\"SurveyOption\",\"title\":{\"English\":\"I like it\"},\"value\":\"I like it\",\"properties\":null},{\"id\":10002,\"_type\":\"SurveyOption\",\"title\":{\"English\":\"I love it\"},\"value\":\"I love it\",\"properties\":null},{\"id\":10003,\"_type\":\"SurveyOption\",\"title\":{\"English\":\"I want some more of it\"},\"value\":\"I want some more of it\",\"properties\":null}],\"sub_question_skus\":null},{\"id\":3,\"_type\":\"SurveyQuestion\",\"_subtype\":\"checkbox\",\"title\":{\"English\":\"What does Dr Pepper taste like?\"},\"shortname\":null,\"varname\":null,\"description\":[],\"has_showhide_deps\":null,\"properties\":{\"option_sort\":false,\"required\":false,\"hidden\":false,\"element_style\":\"OS\",\"orientation\":\"VERT\",\"minimum_response\":0,\"labels_right\":true,\"map_key\":\"checkbox\"},\"options\":[{\"id\":10004,\"_type\":\"SurveyOption\",\"title\":{\"English\":\"Dr. Pepper\"},\"value\":\"Dr. Pepper\",\"properties\":null},{\"id\":10005,\"_type\":\"SurveyOption\",\"title\":{\"English\":\"Chicken\"},\"value\":\"Chicken\",\"properties\":null},{\"id\":10006,\"_type\":\"SurveyOption\",\"title\":{\"English\":\"Ramen Noodles\"},\"value\":\"Ramen Noodles\",\"properties\":null}],\"sub_question_skus\":null}]}}
|
@@ -0,0 +1 @@
|
|
1
|
+
{\"result_ok\":true,\"data\":{\"id\":2,\"_type\":\"SurveyQuestion\",\"_subtype\":\"radio\",\"title\":{\"English\":\"Do you like steak?\"},\"shortname\":null,\"varname\":null,\"description\":[],\"has_showhide_deps\":null,\"properties\":{\"option_sort\":false,\"required\":true,\"hidden\":false,\"orientation\":\"VERT\",\"labels_right\":true,\"map_key\":\"radio\"},\"options\":[{\"id\":10001,\"_type\":\"SurveyOption\",\"title\":{\"English\":\"I like it\"},\"value\":\"I like it\",\"properties\":null},{\"id\":10002,\"_type\":\"SurveyOption\",\"title\":{\"English\":\"I love it\"},\"value\":\"I love it\",\"properties\":null},{\"id\":10003,\"_type\":\"SurveyOption\",\"title\":{\"English\":\"I want some more of it\"},\"value\":\"I want some more of it\",\"properties\":null}],\"sub_question_skus\":null}}
|
@@ -0,0 +1 @@
|
|
1
|
+
{\"result_ok\":true,\"data\":{\"id\":\"1234\",\"team\":\"0\",\"_type\":\"Survey\",\"_subtype\":\"Standard Survey\",\"status\":\"In Design\",\"created_on\":\"2011-08-23 17:43:39\",\"modified_on\":\"2011-09-15 18:18:39\",\"languages\":[\"English\"],\"title\":\"Test Survey\",\"internal_title\":\"Test Survey\",\"title_ml\":{\"English\":\"Test Survey\"},\"theme\":\"11147\",\"statistics\":null,\"links\":{\"edit\":\"https:\\/\\/appv3.sgizmo.com\\/login\\/v1?authenticate=2593d488a24e1bb4a1267a44ad2cc3f607a23460&account_user_id=123456&r=%2Fprojects%2Feditor%3Fid%3D620263&signature=ba540c\",\"publish\":\"https:\\/\\/appv3.sgizmo.com\\/login\\/v1?authenticate=2593d488a24e1bb4a1267a44ad2cc3f607a23460&account_user_id=123456&r=%2Fprojects%2Fpromote%3Fid%3D620263&signature=5954e7\"},\"pages\":[{\"id\":1,\"_type\":\"SurveyPage\",\"title\":{\"English\":\"Page One\"},\"properties\":{\"hidden\":false},\"description\":[],\"questions\":[{\"id\":2,\"_type\":\"SurveyQuestion\",\"_subtype\":\"radio\",\"title\":{\"English\":\"Do you like steak?\"},\"shortname\":null,\"varname\":null,\"description\":[],\"has_showhide_deps\":null,\"properties\":{\"option_sort\":false,\"required\":true,\"hidden\":false,\"orientation\":\"VERT\",\"labels_right\":true,\"map_key\":\"radio\"},\"options\":[{\"id\":10001,\"_type\":\"SurveyOption\",\"title\":{\"English\":\"I like it\"},\"value\":\"I like it\",\"properties\":null},{\"id\":10002,\"_type\":\"SurveyOption\",\"title\":{\"English\":\"I love it\"},\"value\":\"I love it\",\"properties\":null},{\"id\":10003,\"_type\":\"SurveyOption\",\"title\":{\"English\":\"I want some more of it\"},\"value\":\"I want some more of it\",\"properties\":null}],\"sub_question_skus\":null},{\"id\":3,\"_type\":\"SurveyQuestion\",\"_subtype\":\"checkbox\",\"title\":{\"English\":\"What does Dr Pepper taste like?\"},\"shortname\":null,\"varname\":null,\"description\":[],\"has_showhide_deps\":null,\"properties\":{\"option_sort\":false,\"required\":false,\"hidden\":false,\"element_style\":\"OS\",\"orientation\":\"VERT\",\"minimum_response\":0,\"labels_right\":true,\"map_key\":\"checkbox\"},\"options\":[{\"id\":10004,\"_type\":\"SurveyOption\",\"title\":{\"English\":\"Dr. Pepper\"},\"value\":\"Dr. Pepper\",\"properties\":null},{\"id\":10005,\"_type\":\"SurveyOption\",\"title\":{\"English\":\"Chicken\"},\"value\":\"Chicken\",\"properties\":null},{\"id\":10006,\"_type\":\"SurveyOption\",\"title\":{\"English\":\"Ramen Noodles\"},\"value\":\"Ramen Noodles\",\"properties\":null}],\"sub_question_skus\":null}]},{\"id\":2,\"_type\":\"SurveyPage\",\"title\":{\"English\":\"Thank You!\"},\"properties\":{\"hidden\":false},\"description\":[],\"questions\":[{\"id\":1,\"_type\":\"SurveyDecorative\",\"_subtype\":\"instructions\",\"title\":{\"English\":\"Thank you for taking our survey. Your response is very important to us.\"},\"shortname\":null,\"varname\":null,\"description\":[],\"has_showhide_deps\":null,\"properties\":{\"hidden\":false},\"options\":[],\"sub_question_skus\":null}]}]}}
|
metadata
ADDED
@@ -0,0 +1,149 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: survey-gizmo-ruby
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.5.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Kabari Hendrick
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-09-30 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: activesupport
|
16
|
+
requirement: &70260063096500 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 3.0.1
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70260063096500
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: i18n
|
27
|
+
requirement: &70260063389380 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70260063389380
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: virtus
|
38
|
+
requirement: &70260063597440 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ~>
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 0.0.5
|
44
|
+
type: :runtime
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70260063597440
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: httparty
|
49
|
+
requirement: &70260063748800 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :runtime
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70260063748800
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: yard
|
60
|
+
requirement: &70260064153320 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ~>
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: 0.6.0
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *70260064153320
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: bundler
|
71
|
+
requirement: &70260065755920 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ~>
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: 1.0.0
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: *70260065755920
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: jeweler
|
82
|
+
requirement: &70260067262120 !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ~>
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: 1.6.4
|
88
|
+
type: :development
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: *70260067262120
|
91
|
+
description: ''
|
92
|
+
email: self@ripthejacker.com
|
93
|
+
executables: []
|
94
|
+
extensions: []
|
95
|
+
extra_rdoc_files:
|
96
|
+
- LICENSE.txt
|
97
|
+
- README.md
|
98
|
+
files:
|
99
|
+
- Gemfile
|
100
|
+
- Gemfile.lock
|
101
|
+
- LICENSE.txt
|
102
|
+
- README.md
|
103
|
+
- Rakefile
|
104
|
+
- VERSION
|
105
|
+
- lib/survey-gizmo-ruby.rb
|
106
|
+
- lib/survey_gizmo/api/option.rb
|
107
|
+
- lib/survey_gizmo/api/page.rb
|
108
|
+
- lib/survey_gizmo/api/question.rb
|
109
|
+
- lib/survey_gizmo/api/survey.rb
|
110
|
+
- lib/survey_gizmo/collection.rb
|
111
|
+
- lib/survey_gizmo/resource.rb
|
112
|
+
- lib/survey_gizmo/survey_gizmo.rb
|
113
|
+
- spec/spec_helper.rb
|
114
|
+
- spec/support/model_cleanup.rb
|
115
|
+
- spec/support/spec_shared_api_object.rb
|
116
|
+
- spec/support/test_resource_classes.rb
|
117
|
+
- spec/survey-gizmo-ruby_spec.rb
|
118
|
+
- spec/test_json/page.json
|
119
|
+
- spec/test_json/question.json
|
120
|
+
- spec/test_json/survey.json
|
121
|
+
homepage: http://github.com/RipTheJacker/survey-gizmo-ruby
|
122
|
+
licenses:
|
123
|
+
- MIT
|
124
|
+
post_install_message:
|
125
|
+
rdoc_options: []
|
126
|
+
require_paths:
|
127
|
+
- lib
|
128
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
130
|
+
requirements:
|
131
|
+
- - ! '>='
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
segments:
|
135
|
+
- 0
|
136
|
+
hash: -2566715168940454907
|
137
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
138
|
+
none: false
|
139
|
+
requirements:
|
140
|
+
- - ! '>='
|
141
|
+
- !ruby/object:Gem::Version
|
142
|
+
version: '0'
|
143
|
+
requirements: []
|
144
|
+
rubyforge_project:
|
145
|
+
rubygems_version: 1.8.8
|
146
|
+
signing_key:
|
147
|
+
specification_version: 3
|
148
|
+
summary: gem to consume the Survey Gizmo API
|
149
|
+
test_files: []
|