formstack 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/formstack.rb +23 -0
- data/lib/formstack/client.rb +82 -0
- data/test/formstack_test.rb +69 -0
- data/test/helper.rb +43 -0
- metadata +147 -0
data/lib/formstack.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
require 'hashie'
|
3
|
+
|
4
|
+
directory = File.expand_path(File.dirname(__FILE__))
|
5
|
+
|
6
|
+
Hash.send :include, Hashie::HashExtensions
|
7
|
+
|
8
|
+
module Formstack
|
9
|
+
|
10
|
+
VERSION = "0.0.1".freeze
|
11
|
+
|
12
|
+
|
13
|
+
class FormstackError < StandardError
|
14
|
+
attr_reader :data
|
15
|
+
|
16
|
+
def initialize(data)
|
17
|
+
@data = data
|
18
|
+
super
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
require File.join(directory, 'formstack', 'client')
|
@@ -0,0 +1,82 @@
|
|
1
|
+
module Formstack
|
2
|
+
class Client
|
3
|
+
include HTTParty
|
4
|
+
base_uri "https://www.formstack.com/api/"
|
5
|
+
format :json
|
6
|
+
|
7
|
+
def initialize(key)
|
8
|
+
self.class.default_params(:api_key => key, :type => 'json')
|
9
|
+
end
|
10
|
+
|
11
|
+
def forms
|
12
|
+
self.class.get("/forms").forms.map{|f| handle_form(f)}
|
13
|
+
end
|
14
|
+
|
15
|
+
def form(form_id)
|
16
|
+
handle_form(self.class.get("/form", :query => {:id => form_id}))
|
17
|
+
end
|
18
|
+
|
19
|
+
def data(form_id, options={})
|
20
|
+
api_response = self.class.get("/data", :query => {:id => form_id}.merge(options))
|
21
|
+
api_response.submissions = api_response.submissions.map{|s| handle_submission(s) }
|
22
|
+
api_response
|
23
|
+
end
|
24
|
+
alias :submissions :data
|
25
|
+
|
26
|
+
def submission(submission_id, options={})
|
27
|
+
handle_submission(self.class.get("/submission", :query => {:id => submission_id}.merge(options)))
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
def submit(form_id, options={})
|
32
|
+
self.class.post("/submit", :body => {:id => form_id}.merge(prepare_params(form_id, options)))['id']
|
33
|
+
end
|
34
|
+
|
35
|
+
def edit(submission_id, options={})
|
36
|
+
self.class.post("/edit", :body => {:id => submission_id}.merge(prepare_params(submission_id, options)))['id']
|
37
|
+
end
|
38
|
+
|
39
|
+
def delete(submission_id)
|
40
|
+
self.class.post("/delete", :body => {:id => submission_id})['id']
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
def prepare_params(form_id, params={})
|
45
|
+
data = params.delete(:data)
|
46
|
+
form = form(form_id)
|
47
|
+
data.each do |field, value|
|
48
|
+
field_id = form.fields.any? {|f| f['name'] == field.to_s} ? form.fields.find {|f| f['name'] == field.to_s}['id'] : field
|
49
|
+
params["field_#{field_id}"] = value
|
50
|
+
end
|
51
|
+
params
|
52
|
+
end
|
53
|
+
|
54
|
+
def handle_form(form)
|
55
|
+
form.created = Time.parse(form.created) unless form.created.nil?
|
56
|
+
form
|
57
|
+
end
|
58
|
+
|
59
|
+
def handle_submission(submission)
|
60
|
+
data = submission.data
|
61
|
+
data.each do |datum|
|
62
|
+
submission[datum.field] = datum.value
|
63
|
+
end
|
64
|
+
submission.timestamp = Time.parse(submission.timestamp)
|
65
|
+
submission
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.get(*args); handle_response super end
|
69
|
+
def self.post(*args); handle_response super end
|
70
|
+
|
71
|
+
def self.handle_response(response)
|
72
|
+
case response.code
|
73
|
+
when 500...600; raise FormstackError.new(Hashie::Mash.new(response).error)
|
74
|
+
else; response
|
75
|
+
end
|
76
|
+
|
77
|
+
Hashie::Mash.new(response).response
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class FormstackTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
context "Formstack API" do
|
6
|
+
|
7
|
+
setup do
|
8
|
+
@client = Formstack::Client.new("OU812")
|
9
|
+
end
|
10
|
+
|
11
|
+
should "list forms for an account" do
|
12
|
+
stub_get("/forms?type=json&api_key=OU812", "forms.json")
|
13
|
+
forms = @client.forms
|
14
|
+
forms.size.should == 1
|
15
|
+
forms.first.name.should == 'Contact'
|
16
|
+
end
|
17
|
+
|
18
|
+
should "get details for a form" do
|
19
|
+
stub_get("/form?id=1234&type=json&api_key=OU812", "form.json")
|
20
|
+
form = @client.form(1234)
|
21
|
+
form.fields.size.should == 5
|
22
|
+
form.fields.first.section_heading.should == 'Contact Information'
|
23
|
+
end
|
24
|
+
|
25
|
+
should "get submitted data for a form" do
|
26
|
+
stub_get("/data?id=1234&page=1&type=json&api_key=OU812", "data.json")
|
27
|
+
submissions = @client.data(1234, :page => 1).submissions
|
28
|
+
submissions.size.should == 2
|
29
|
+
submissions.first['1111'].should == "John Smith"
|
30
|
+
submissions.first.timestamp.year.should == 2007
|
31
|
+
end
|
32
|
+
|
33
|
+
should "return a single submission collected for a form" do
|
34
|
+
stub_get("/submission?id=1001&type=json&api_key=OU812", "submission.json")
|
35
|
+
submission = @client.submission(1001)
|
36
|
+
submission['2222'].should == "Apple"
|
37
|
+
submission.timestamp.year.should == 2007
|
38
|
+
end
|
39
|
+
|
40
|
+
should "prepare data for form submission" do
|
41
|
+
stub_get("/form?id=1234&type=json&api_key=OU812", "form.json")
|
42
|
+
params = {:page => 3, :data => {:name => "Wynn Netherland", :phone => "940-867-5309", '123' => 'foo'}}
|
43
|
+
prepared = @client.prepare_params(1234, params)
|
44
|
+
prepared['field_7344054'].should == 'Wynn Netherland'
|
45
|
+
prepared['field_7344057'].should == '940-867-5309'
|
46
|
+
prepared['field_123'].should == 'foo'
|
47
|
+
end
|
48
|
+
|
49
|
+
should "submit data for a form" do
|
50
|
+
stub_post("/submit?type=json&api_key=OU812", "submit.json")
|
51
|
+
id = @client.submit(1234, :data => {:foo => 'bar'})
|
52
|
+
id.should == 10001
|
53
|
+
end
|
54
|
+
|
55
|
+
should "update submitted data for a form" do
|
56
|
+
stub_post("/edit?type=json&api_key=OU812", "submit.json")
|
57
|
+
id = @client.edit(1234, :data => {:foo => 'bar'})
|
58
|
+
id.should == 10001
|
59
|
+
end
|
60
|
+
|
61
|
+
should "delete submitted data for a form" do
|
62
|
+
stub_post("/delete?type=json&api_key=OU812", "submit.json")
|
63
|
+
id = @client.delete(1234)
|
64
|
+
id.should == 10001
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'test/unit'
|
3
|
+
require 'shoulda'
|
4
|
+
|
5
|
+
require 'redgreen'
|
6
|
+
require 'matchy'
|
7
|
+
require 'fakeweb'
|
8
|
+
|
9
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
10
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
11
|
+
require 'formstack'
|
12
|
+
|
13
|
+
|
14
|
+
# Set the default allow_net_connect option--usually you'll want this off.
|
15
|
+
# You don't usually want your test suite to make HTTP connections, do you?
|
16
|
+
FakeWeb.allow_net_connect = false
|
17
|
+
|
18
|
+
class Test::Unit::TestCase
|
19
|
+
end
|
20
|
+
|
21
|
+
def fixture_file(filename)
|
22
|
+
return '' if filename == ''
|
23
|
+
file_path = File.expand_path(File.dirname(__FILE__) + '/fixtures/' + filename)
|
24
|
+
File.read(file_path)
|
25
|
+
end
|
26
|
+
|
27
|
+
def formstack_url(url, options={})
|
28
|
+
url =~ /^http/ ? url : "https://www.formstack.com/api#{url}"
|
29
|
+
end
|
30
|
+
|
31
|
+
def stub_request(method, url, filename, status=nil)
|
32
|
+
options = {:body => ""}
|
33
|
+
options.merge!({:body => fixture_file(filename)}) if filename
|
34
|
+
options.merge!({:body => status.last}) if status
|
35
|
+
options.merge!({:status => status}) if status
|
36
|
+
|
37
|
+
FakeWeb.register_uri(method, formstack_url(url), options)
|
38
|
+
end
|
39
|
+
|
40
|
+
def stub_get(*args); stub_request(:get, *args) end
|
41
|
+
def stub_post(*args); stub_request(:post, *args) end
|
42
|
+
|
43
|
+
|
metadata
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: formstack
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
version: 0.0.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Wynn Netherland
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-05-23 00:00:00 -05:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
version_requirements: &id001 !ruby/object:Gem::Requirement
|
22
|
+
requirements:
|
23
|
+
- - ">="
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
segments:
|
26
|
+
- 0
|
27
|
+
- 1
|
28
|
+
- 3
|
29
|
+
version: 0.1.3
|
30
|
+
name: hashie
|
31
|
+
prerelease: false
|
32
|
+
requirement: *id001
|
33
|
+
type: :runtime
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
version_requirements: &id002 !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
segments:
|
40
|
+
- 0
|
41
|
+
- 1
|
42
|
+
- 0
|
43
|
+
version: 0.1.0
|
44
|
+
name: httparty
|
45
|
+
prerelease: false
|
46
|
+
requirement: *id002
|
47
|
+
type: :runtime
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
version_requirements: &id003 !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
segments:
|
54
|
+
- 2
|
55
|
+
- 10
|
56
|
+
- 1
|
57
|
+
version: 2.10.1
|
58
|
+
name: shoulda
|
59
|
+
prerelease: false
|
60
|
+
requirement: *id003
|
61
|
+
type: :development
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
version_requirements: &id004 !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - "="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
segments:
|
68
|
+
- 0
|
69
|
+
- 4
|
70
|
+
- 0
|
71
|
+
version: 0.4.0
|
72
|
+
name: matchy
|
73
|
+
prerelease: false
|
74
|
+
requirement: *id004
|
75
|
+
type: :development
|
76
|
+
- !ruby/object:Gem::Dependency
|
77
|
+
version_requirements: &id005 !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
segments:
|
82
|
+
- 1
|
83
|
+
- 2
|
84
|
+
- 5
|
85
|
+
version: 1.2.5
|
86
|
+
name: fakeweb
|
87
|
+
prerelease: false
|
88
|
+
requirement: *id005
|
89
|
+
type: :development
|
90
|
+
- !ruby/object:Gem::Dependency
|
91
|
+
version_requirements: &id006 !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - ">="
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
segments:
|
96
|
+
- 0
|
97
|
+
version: "0"
|
98
|
+
name: yard
|
99
|
+
prerelease: false
|
100
|
+
requirement: *id006
|
101
|
+
type: :development
|
102
|
+
description: Wrapper for the Formstack API
|
103
|
+
email: wynn.netherland@gmail.com
|
104
|
+
executables: []
|
105
|
+
|
106
|
+
extensions: []
|
107
|
+
|
108
|
+
extra_rdoc_files: []
|
109
|
+
|
110
|
+
files:
|
111
|
+
- lib/formstack/client.rb
|
112
|
+
- lib/formstack.rb
|
113
|
+
has_rdoc: true
|
114
|
+
homepage: http://github.com/pengwynn/formstack
|
115
|
+
licenses: []
|
116
|
+
|
117
|
+
post_install_message:
|
118
|
+
rdoc_options: []
|
119
|
+
|
120
|
+
require_paths:
|
121
|
+
- lib
|
122
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
123
|
+
requirements:
|
124
|
+
- - ">="
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
segments:
|
127
|
+
- 0
|
128
|
+
version: "0"
|
129
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
130
|
+
requirements:
|
131
|
+
- - ">="
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
segments:
|
134
|
+
- 1
|
135
|
+
- 3
|
136
|
+
- 6
|
137
|
+
version: 1.3.6
|
138
|
+
requirements: []
|
139
|
+
|
140
|
+
rubyforge_project:
|
141
|
+
rubygems_version: 1.3.6
|
142
|
+
signing_key:
|
143
|
+
specification_version: 3
|
144
|
+
summary: Wrapper for the Formstack API
|
145
|
+
test_files:
|
146
|
+
- test/helper.rb
|
147
|
+
- test/formstack_test.rb
|