vcs_client 0.4.6
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/.gitignore +24 -0
- data/.rvmrc +1 -0
- data/Gemfile +14 -0
- data/Gemfile.lock +61 -0
- data/LICENSE +20 -0
- data/README.rdoc +17 -0
- data/Rakefile +143 -0
- data/VERSION +1 -0
- data/features/step_definitions/vcs_client_steps.rb +36 -0
- data/features/support/env.rb +6 -0
- data/features/vcs_client.feature +17 -0
- data/lib/objects/action.rb +7 -0
- data/lib/objects/address.rb +20 -0
- data/lib/objects/basement.rb +15 -0
- data/lib/objects/person.rb +96 -0
- data/lib/objects/phone.rb +7 -0
- data/lib/objects/reference.rb +8 -0
- data/lib/vcs_client.rb +79 -0
- data/spec/action_spec.rb +15 -0
- data/spec/address_spec.rb +21 -0
- data/spec/basement_spec.rb +16 -0
- data/spec/fixtures/checkin_response.json +7 -0
- data/spec/fixtures/one_person.json +43 -0
- data/spec/fixtures/two_people.json +83 -0
- data/spec/person_spec.rb +92 -0
- data/spec/phone_spec.rb +16 -0
- data/spec/reference_spec.rb +14 -0
- data/spec/spec_helper.rb +24 -0
- data/spec/support/fixtures.rb +19 -0
- data/spec/support/mocha.rb +13 -0
- data/spec/vcs_client_spec.rb +83 -0
- data/vcs_client.gemspec +87 -0
- metadata +128 -0
data/.gitignore
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm --create use default@vcs_client > /dev/null
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
activesupport (2.3.8)
|
5
|
+
addressable (2.1.2)
|
6
|
+
bourne (1.0)
|
7
|
+
mocha (= 0.9.8)
|
8
|
+
builder (2.1.2)
|
9
|
+
columnize (0.3.1)
|
10
|
+
crack (0.1.7)
|
11
|
+
cucumber (0.8.3)
|
12
|
+
builder (~> 2.1.2)
|
13
|
+
diff-lcs (~> 1.1.2)
|
14
|
+
gherkin (~> 2.0.2)
|
15
|
+
json_pure (~> 1.4.3)
|
16
|
+
term-ansicolor (~> 1.0.4)
|
17
|
+
diff-lcs (1.1.2)
|
18
|
+
gemcutter (0.5.0)
|
19
|
+
json_pure
|
20
|
+
gherkin (2.0.2)
|
21
|
+
trollop (~> 1.16.2)
|
22
|
+
git (1.2.5)
|
23
|
+
httparty (0.6.0)
|
24
|
+
crack (= 0.1.7)
|
25
|
+
jeweler (1.4.0)
|
26
|
+
gemcutter (>= 0.1.0)
|
27
|
+
git (>= 1.2.5)
|
28
|
+
rubyforge (>= 2.0.0)
|
29
|
+
json_pure (1.4.3)
|
30
|
+
linecache (0.43)
|
31
|
+
mocha (0.9.8)
|
32
|
+
rake
|
33
|
+
rake (0.8.7)
|
34
|
+
rspec (1.3.0)
|
35
|
+
ruby-debug (0.10.3)
|
36
|
+
columnize (>= 0.1)
|
37
|
+
ruby-debug-base (~> 0.10.3.0)
|
38
|
+
ruby-debug-base (0.10.3)
|
39
|
+
linecache (>= 0.3)
|
40
|
+
rubyforge (2.0.4)
|
41
|
+
json_pure (>= 1.1.7)
|
42
|
+
shoulda (2.11.1)
|
43
|
+
term-ansicolor (1.0.5)
|
44
|
+
trollop (1.16.2)
|
45
|
+
webmock (1.3.0)
|
46
|
+
addressable (>= 2.1.1)
|
47
|
+
crack (>= 0.1.7)
|
48
|
+
|
49
|
+
PLATFORMS
|
50
|
+
ruby
|
51
|
+
|
52
|
+
DEPENDENCIES
|
53
|
+
activesupport
|
54
|
+
bourne (= 1.0)
|
55
|
+
cucumber
|
56
|
+
httparty (= 0.6.0)
|
57
|
+
jeweler
|
58
|
+
rspec (= 1.3.0)
|
59
|
+
ruby-debug
|
60
|
+
shoulda (= 2.11.1)
|
61
|
+
webmock
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 gill
|
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.rdoc
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
= vcs_client
|
2
|
+
|
3
|
+
Description goes here.
|
4
|
+
|
5
|
+
== Note on Patches/Pull Requests
|
6
|
+
|
7
|
+
* Fork the project.
|
8
|
+
* Make your feature addition or bug fix.
|
9
|
+
* Add tests for it. This is important so I don't break it in a
|
10
|
+
future version unintentionally.
|
11
|
+
* Commit, do not mess with rakefile, version, or history.
|
12
|
+
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
13
|
+
* Send me a pull request. Bonus points for topic branches.
|
14
|
+
|
15
|
+
== Copyright
|
16
|
+
|
17
|
+
Copyright (c) 2010 gill. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,143 @@
|
|
1
|
+
APP_NAME = 'vcs_client'
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'rake'
|
5
|
+
|
6
|
+
begin
|
7
|
+
require 'jeweler'
|
8
|
+
Jeweler::Tasks.new do |gem|
|
9
|
+
gem.name = "vcs_client"
|
10
|
+
gem.summary = %Q{This gem wraps the Voter Checkout Service API}
|
11
|
+
gem.description = %Q{This gem provides all the plumbing to interact with the Voter Checkout Service}
|
12
|
+
gem.email = "gilltots@gmail.com"
|
13
|
+
gem.homepage = "http://github.com/gilltots/vcs_client"
|
14
|
+
gem.authors = ["gill"]
|
15
|
+
gem.add_development_dependency "shoulda", ">= 0"
|
16
|
+
gem.add_dependency "httparty", ">= 0.5.2"
|
17
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
18
|
+
end
|
19
|
+
Jeweler::GemcutterTasks.new
|
20
|
+
rescue LoadError
|
21
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
22
|
+
end
|
23
|
+
|
24
|
+
task :default => :spec
|
25
|
+
|
26
|
+
task :test => :check_dependencies
|
27
|
+
|
28
|
+
require 'spec/rake/spectask'
|
29
|
+
|
30
|
+
desc "Run all examples"
|
31
|
+
Spec::Rake::SpecTask.new('spec') do |t|
|
32
|
+
t.spec_files = FileList['spec/**/*.rb']
|
33
|
+
# t.spec_opts = ['--debugger']
|
34
|
+
end
|
35
|
+
|
36
|
+
desc "Cruise Control task"
|
37
|
+
task :cruise do
|
38
|
+
gem 'activesupport', '2.3.8'
|
39
|
+
require 'metric_fu'
|
40
|
+
MetricFu::Configuration.run do |config|
|
41
|
+
# Define which metrics you want to use
|
42
|
+
config.metrics = [:rcov]
|
43
|
+
config.graphs = [:rcov]
|
44
|
+
config.rcov = {
|
45
|
+
:environment => 'test',
|
46
|
+
:test_files => ['spec/**/*_spec.rb'],
|
47
|
+
:rcov_opts => ["-Ilib:spec --aggregate rcov_data/rcov.data --sort coverage --no-html --profile --no-color --text-coverage --exclude /gems/,/Library/,/rubygems/,spec,/usr/,script,features/ "]}
|
48
|
+
end
|
49
|
+
|
50
|
+
path = File.expand_path(File.join(File.dirname(__FILE__)))
|
51
|
+
`mkdir -p #{path}/rcov_data/`
|
52
|
+
`rm #{path}/rcov_data/rcov.data` rescue nil
|
53
|
+
`rm #{path}/rerun.txt` rescue nil
|
54
|
+
# Even though metrics:all runs the specs under rcov, it doesn't report any failures, which is NOT what we want!
|
55
|
+
CruiseControl::invoke_rake_task 'spec'
|
56
|
+
CruiseControl::invoke_rake_task 'features'
|
57
|
+
CruiseControl::invoke_rake_task 'metrics:all'
|
58
|
+
# CruiseControl::invoke_rake_task 'verify_rcov'
|
59
|
+
end
|
60
|
+
|
61
|
+
task :local_metrics do
|
62
|
+
require 'metric_fu'
|
63
|
+
MetricFu::Configuration.run do |config|
|
64
|
+
# Define which metrics you want to use
|
65
|
+
config.metrics = [:rcov]
|
66
|
+
config.graphs = [:rcov]
|
67
|
+
config.rcov = {
|
68
|
+
:test_files => ['spec/**/*_spec.rb'],
|
69
|
+
:rcov_opts => [
|
70
|
+
"--sort coverage",
|
71
|
+
"--no-html",
|
72
|
+
"--text-coverage",
|
73
|
+
"--no-color",
|
74
|
+
"--profile",
|
75
|
+
"--exclude /gems/,Library/,spec/"
|
76
|
+
]
|
77
|
+
}
|
78
|
+
end
|
79
|
+
|
80
|
+
Rake::Task['metrics:all'].invoke
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
def get_coverage(file_location)
|
85
|
+
total_coverage = 0
|
86
|
+
File.open(file_location).each_line do |line|
|
87
|
+
if line =~ /Total Coverage: (\d+\.\d+)%\s/
|
88
|
+
total_coverage = $1.to_f
|
89
|
+
break
|
90
|
+
end
|
91
|
+
end
|
92
|
+
return total_coverage
|
93
|
+
end
|
94
|
+
|
95
|
+
task :verify_rcov do
|
96
|
+
project_root = "/home/deploy/.cruise/projects/#{APP_NAME}"
|
97
|
+
html_location = "output/rcov.html"
|
98
|
+
out = ENV['CC_BUILD_ARTIFACTS']
|
99
|
+
|
100
|
+
# Grab the last rcov level from a successful build (unsuccessful may not have created the file)
|
101
|
+
last_build = Dir.new(project_root).entries.select{|f| f =~ /success/}.sort{|a, b| File.mtime(File.join(project_root, a)) <=> File.mtime(File.join(project_root, b))}.last
|
102
|
+
|
103
|
+
threshold = last_build.nil? ? 0 : get_coverage(File.join(project_root, last_build, html_location))
|
104
|
+
total_coverage = get_coverage(File.join(out, html_location))
|
105
|
+
|
106
|
+
puts "Coverage: #{total_coverage}% (threshold: #{threshold}% from #{last_build})"
|
107
|
+
raise "Coverage must be at least #{threshold}% (from #{last_build}) but was #{total_coverage}%" if total_coverage < threshold
|
108
|
+
|
109
|
+
end
|
110
|
+
|
111
|
+
require 'rake/rdoctask'
|
112
|
+
Rake::RDocTask.new do |rdoc|
|
113
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
114
|
+
|
115
|
+
rdoc.rdoc_dir = 'rdoc'
|
116
|
+
rdoc.title = "vcs_client #{version}"
|
117
|
+
rdoc.rdoc_files.include('README*')
|
118
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
119
|
+
end
|
120
|
+
|
121
|
+
begin
|
122
|
+
require 'rcov/rcovtask'
|
123
|
+
Spec::Rake::SpecTask.new('rcov') do |t|
|
124
|
+
t.spec_files = FileList['spec/**/*.rb']
|
125
|
+
t.rcov = true
|
126
|
+
t.rcov_opts = ['--exclude', 'spec,/gems/']
|
127
|
+
end
|
128
|
+
rescue LoadError
|
129
|
+
task :rcov do
|
130
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
begin
|
135
|
+
require 'cucumber/rake/task'
|
136
|
+
Cucumber::Rake::Task.new(:features)
|
137
|
+
|
138
|
+
task :features => :check_dependencies
|
139
|
+
rescue LoadError
|
140
|
+
task :features do
|
141
|
+
abort "Cucumber is not available. In order to run features, you must: sudo gem install cucumber"
|
142
|
+
end
|
143
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.4.6
|
@@ -0,0 +1,36 @@
|
|
1
|
+
Given /^the vcs uri is set to "([^"]*)"$/ do |uri|
|
2
|
+
@uri = uri
|
3
|
+
VcsClient.vcs_uri = @uri
|
4
|
+
end
|
5
|
+
|
6
|
+
When /^I ask for a random voter from the "([^"]*)" campaign$/ do |campaign_id|
|
7
|
+
@client_id = rand(500)
|
8
|
+
@volunteer_id = rand(500)
|
9
|
+
@campaign_id = campaign_id
|
10
|
+
@voters = VcsClient.checkout(@campaign_id, @client_id, @volunteer_id)
|
11
|
+
end
|
12
|
+
|
13
|
+
Then /^I should get a valid collection of people$/ do
|
14
|
+
@voters.should be_kind_of(Array)
|
15
|
+
@voters.each do |person|
|
16
|
+
person.should be_kind_of(VcsClient::Person)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
When /^I ask for a random voter from the "([^"]*)" campaign at "([^"]*)" and "([^"]*)" withing "([^"]*)" miles$/ do |campaign_id, latitude, longitude, radius|
|
21
|
+
@client_id = rand(500)
|
22
|
+
@volunteer_id = rand(500)
|
23
|
+
@campaign_id = campaign_id
|
24
|
+
@voters = VcsClient.checkout(@campaign_id, @client_id, @volunteer_id, latitude, longitude, radius)
|
25
|
+
end
|
26
|
+
|
27
|
+
When /^I check the voters in$/ do
|
28
|
+
@voters.each do |person|
|
29
|
+
person.checkin(:disposition => "1", :response => "Something Happened")
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
Then /^I should have zero checkouts$/ do
|
34
|
+
response = HTTParty.get("#{@uri}/campaign/#{@campaign_id}/client/#{@client_id}/volunteer/#{@volunteer_id}/checkout", :format => :json)
|
35
|
+
response["campaign_#{@campaign_id}"].should == 0
|
36
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
Feature: Vcs client
|
2
|
+
|
3
|
+
Background:
|
4
|
+
Given the vcs uri is set to "http://vcsqa.dnc.org:8080"
|
5
|
+
|
6
|
+
Scenario: Getting a random voter
|
7
|
+
When I ask for a random voter from the "perf" campaign
|
8
|
+
Then I should get a valid collection of people
|
9
|
+
|
10
|
+
Scenario: Getting a random voter in a specific location
|
11
|
+
When I ask for a random voter from the "perf" campaign at "38.85" and "-77.04" withing "5" miles
|
12
|
+
Then I should get a valid collection of people
|
13
|
+
|
14
|
+
Scenario: Checking in a checked out voter
|
15
|
+
When I ask for a random voter from the "perf" campaign
|
16
|
+
And I check the voters in
|
17
|
+
Then I should have zero checkouts
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module VcsClient
|
2
|
+
|
3
|
+
class Address < Basement
|
4
|
+
attr_accessor :zip4, :latitude, :longitude, :zip, :city, :state, :address, :id, :type
|
5
|
+
|
6
|
+
# TODO: Once the Schema is updated for the spelling correction these aliases can be removed
|
7
|
+
alias :zipp4 :zip4
|
8
|
+
alias :zipp4= :zip4=
|
9
|
+
|
10
|
+
def latitude=(latitude)
|
11
|
+
@latitude = latitude.to_f
|
12
|
+
end
|
13
|
+
|
14
|
+
def longitude=(longitude)
|
15
|
+
@longitude = longitude.to_f
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'date'
|
2
|
+
|
3
|
+
module VcsClient
|
4
|
+
|
5
|
+
class Person < Basement
|
6
|
+
|
7
|
+
attr_accessor :precinct, :cong_dist, :first_name, :last_name, :middle_name, :sex, :date_of_birth, :univ, :party, :actions, :address, :phone, :references
|
8
|
+
|
9
|
+
def address=(_address)
|
10
|
+
@address = VcsClient::Address.new(_address) if _address
|
11
|
+
end
|
12
|
+
|
13
|
+
def phone=(_phone)
|
14
|
+
@phone = VcsClient::Phone.new(_phone) if _phone
|
15
|
+
end
|
16
|
+
|
17
|
+
def token
|
18
|
+
if self.actions && self.actions.key?("checkin")
|
19
|
+
self.actions["checkin"].url.split('/').last
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def references=(references)
|
24
|
+
if references
|
25
|
+
@references = references.inject([]) do |collection, reference|
|
26
|
+
collection << VcsClient::Reference.new(reference)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def age
|
32
|
+
if date_of_birth
|
33
|
+
date = Date.today
|
34
|
+
day_diff = date.day - date_of_birth.day
|
35
|
+
month_diff = date.month - date_of_birth.month - (day_diff < 0 ? 1 : 0)
|
36
|
+
date.year - date_of_birth.year - (month_diff < 0 ? 1 : 0)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def name
|
41
|
+
if @name.nil?
|
42
|
+
@name = [self.first_name, self.middle_name, self.last_name].compact.join(' ')
|
43
|
+
end
|
44
|
+
@name
|
45
|
+
end
|
46
|
+
|
47
|
+
def date_of_birth=(_date_of_birth)
|
48
|
+
@date_of_birth = case _date_of_birth
|
49
|
+
when /^\d{4}-\d{1,2}-\d{1,2}$/
|
50
|
+
Date.parse(_date_of_birth)
|
51
|
+
when /^\d{4}$/
|
52
|
+
Date.parse("#{_date_of_birth}-01-01")
|
53
|
+
else
|
54
|
+
nil
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# this dynamically creates a method on this object, named after the action name ('checkin')
|
59
|
+
# e.g. if the json has
|
60
|
+
# "actions": {
|
61
|
+
# "checkin": {
|
62
|
+
# "method": "PUT",
|
63
|
+
# "url": "/campaign/1234/client/1/volunteer/4321/checkout/4bfd8e5e8a9b8e7987000014"
|
64
|
+
# }
|
65
|
+
# },
|
66
|
+
#
|
67
|
+
# this adds a method called "checkin" to this object, that takes a single parameter for 'disposition' and
|
68
|
+
# performs a PUT to /campaign/1234/client/1/volunteer/4321/checkout/4bfd8e5e8a9b8e7987000014
|
69
|
+
#
|
70
|
+
# it also adds an Action object to the person, so calling this_person.actions will return a hash of all actions, where the keys
|
71
|
+
# are the action names and the values are Action objects with url and method
|
72
|
+
#
|
73
|
+
def actions=(actions)
|
74
|
+
@actions = actions.inject({}) do |collection, action|
|
75
|
+
name = action[0]
|
76
|
+
options = action[1]
|
77
|
+
define_meta_action(name, options)
|
78
|
+
collection.merge!(name => VcsClient::Action.new({:name => name}.merge(options)))
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
private
|
83
|
+
|
84
|
+
def define_meta_action(name, options)
|
85
|
+
# The following defines a metaclass method on the instance
|
86
|
+
method = <<-METHOD
|
87
|
+
def self.#{name}(args = {})
|
88
|
+
VcsClient.send(:#{options["method"].downcase}, '#{options["url"]}', :body => args, :format => :html)
|
89
|
+
end
|
90
|
+
METHOD
|
91
|
+
send(:eval, method)
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
data/lib/vcs_client.rb
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
require 'objects/basement'
|
3
|
+
require 'objects/action'
|
4
|
+
require 'objects/address'
|
5
|
+
require 'objects/phone'
|
6
|
+
require 'objects/reference'
|
7
|
+
require 'objects/person'
|
8
|
+
|
9
|
+
module VcsClient
|
10
|
+
|
11
|
+
include HTTParty
|
12
|
+
|
13
|
+
format :json
|
14
|
+
|
15
|
+
def self.vcs_uri=(uri)
|
16
|
+
base_uri uri
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.checkout(campaign_id, client_id, volunteer_id, lat = nil, long = nil, miles = nil)
|
20
|
+
query_type = 'random'
|
21
|
+
body = {'queryType' => query_type}
|
22
|
+
if (!lat.nil? && !long.nil?)
|
23
|
+
query_type = 'location'
|
24
|
+
if miles.nil?
|
25
|
+
raise VcsClient::NoRadius.new("When searching by location a radius is necessary")
|
26
|
+
end
|
27
|
+
|
28
|
+
body = {'queryType' => query_type, 'latitude' => lat, 'longitude' => long, 'miles' => miles}
|
29
|
+
end
|
30
|
+
result = post("/campaign/#{campaign_id}/client/#{client_id}/volunteer/#{volunteer_id}/checkout", :body => body)
|
31
|
+
filter_for_errors(result)
|
32
|
+
result["people"].inject([]) do |collection, person|
|
33
|
+
collection << Person.new(person)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.checkin(campaign_id, client_id, vol_id, token, disposition)
|
38
|
+
result = put("/campaign/#{campaign_id}/client/#{client_id}/volunteer/#{vol_id}/checkout/#{token}", :body => {'disposition' => disposition}, :format => "html")
|
39
|
+
filter_for_checkin_errors(result)
|
40
|
+
Crack::JSON.parse(result)
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def self.filter_for_errors(hash)
|
46
|
+
if hash.nil? || hash["people"].blank?
|
47
|
+
raise VcsClient::CheckoutFailed.new(hash)
|
48
|
+
end
|
49
|
+
hash
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.filter_for_checkin_errors(result)
|
53
|
+
if result == "Could not find an available Person"
|
54
|
+
raise VcsClient::CheckinFailed.new(result)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
class VcsError < StandardError
|
59
|
+
attr_accessor :response
|
60
|
+
|
61
|
+
def initialize(val)
|
62
|
+
@response = val
|
63
|
+
end
|
64
|
+
|
65
|
+
def to_s
|
66
|
+
"#{self.class.to_s}: #{self.response}"
|
67
|
+
end
|
68
|
+
|
69
|
+
def inspect
|
70
|
+
self.to_s
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
class CheckinFailed < VcsError; end
|
76
|
+
class CheckoutFailed < VcsError; end
|
77
|
+
class NoRadius < VcsError; end
|
78
|
+
|
79
|
+
end
|
data/spec/action_spec.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__),'spec_helper')
|
2
|
+
|
3
|
+
describe VcsClient::Action do
|
4
|
+
|
5
|
+
describe 'creating from attrs' do
|
6
|
+
subject do
|
7
|
+
VcsClient::Action.new({'name' => 'checkin', 'method' => 'PUT', 'url' => '/some/thing'})
|
8
|
+
end
|
9
|
+
|
10
|
+
its(:name) { should == 'checkin' }
|
11
|
+
its(:method) { should == 'PUT' }
|
12
|
+
its(:url) { should == '/some/thing' }
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__),'spec_helper')
|
2
|
+
|
3
|
+
describe VcsClient::Address do
|
4
|
+
|
5
|
+
describe 'creating from attrs' do
|
6
|
+
subject do
|
7
|
+
VcsClient::Address.new(Crack::JSON.parse(one_person_fixture)['people'].first['address'])
|
8
|
+
end
|
9
|
+
|
10
|
+
its(:address) { should == '1234 ADDRESS ST' }
|
11
|
+
its(:city) { should == 'CITY' }
|
12
|
+
its(:zip) { should == '00000' }
|
13
|
+
its(:id) { should == 123456789 }
|
14
|
+
its(:type) { should == 'r' }
|
15
|
+
its(:zip4) { should == '0000' }
|
16
|
+
its(:state) { should == 'TN' }
|
17
|
+
its(:latitude) { should == 0.0 }
|
18
|
+
its(:longitude) { should == -0.0 }
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__),'spec_helper')
|
2
|
+
|
3
|
+
describe VcsClient::Basement do
|
4
|
+
|
5
|
+
describe 'creating from attrs' do
|
6
|
+
|
7
|
+
subject do
|
8
|
+
VcsClient::Basement.new({:lat => 123, :long => 456})
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should not set anything, but also not bomb' do
|
12
|
+
(subject.methods - Object.methods).should be_empty
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
{
|
2
|
+
"people": [
|
3
|
+
{
|
4
|
+
"cong_dist": 1,
|
5
|
+
"party": "I",
|
6
|
+
"precinct": null,
|
7
|
+
"univ": 2,
|
8
|
+
"actions": {
|
9
|
+
"checkin": {
|
10
|
+
"method": "PUT",
|
11
|
+
"url": "/campaign/abcd/client/1234/volunteer/5678/checkout/abcdefg12345678"
|
12
|
+
}
|
13
|
+
},
|
14
|
+
"address": {
|
15
|
+
"zipp4": "0000",
|
16
|
+
"state": "TN",
|
17
|
+
"zip": "00000",
|
18
|
+
"city": "CITY",
|
19
|
+
"address": "1234 ADDRESS ST",
|
20
|
+
"id": 123456789,
|
21
|
+
"type": "r",
|
22
|
+
"latitude": "00.000000",
|
23
|
+
"longitude": "-00.000000"
|
24
|
+
},
|
25
|
+
"date_of_birth": "1980-3-20",
|
26
|
+
"first_name": "JOHN",
|
27
|
+
"last_name": "DOE",
|
28
|
+
"middle_name": "Q",
|
29
|
+
"phone": {
|
30
|
+
"type": "L",
|
31
|
+
"number": "5555555555"
|
32
|
+
},
|
33
|
+
"references": [
|
34
|
+
{
|
35
|
+
"src": "V",
|
36
|
+
"id": "AA0000000"
|
37
|
+
}
|
38
|
+
],
|
39
|
+
"sex": "M",
|
40
|
+
"id": "N-00000000-00AA-AAAA-0000-000000000000"
|
41
|
+
}
|
42
|
+
]
|
43
|
+
}
|
@@ -0,0 +1,83 @@
|
|
1
|
+
{
|
2
|
+
"people": [
|
3
|
+
{
|
4
|
+
"cong_dist": 1,
|
5
|
+
"party": "I",
|
6
|
+
"precinct": null,
|
7
|
+
"univ": 2,
|
8
|
+
"actions": {
|
9
|
+
"checkin": {
|
10
|
+
"method": "PUT",
|
11
|
+
"url": "/campaign/abcd/client/1234/volunteer/5678/checkout/abcdefg12345678"
|
12
|
+
}
|
13
|
+
},
|
14
|
+
"address": {
|
15
|
+
"zipp4": "0000",
|
16
|
+
"state": "TN",
|
17
|
+
"zip": "00000",
|
18
|
+
"city": "CITY",
|
19
|
+
"address": "1234 ADDRESS ST",
|
20
|
+
"id": 123456789,
|
21
|
+
"type": "r",
|
22
|
+
"latitude": "00.000000",
|
23
|
+
"longitude": "00.000000"
|
24
|
+
},
|
25
|
+
"date_of_birth": "1980-3-20",
|
26
|
+
"first_name": "JOHN",
|
27
|
+
"last_name": "DOE",
|
28
|
+
"middle_name": "Q",
|
29
|
+
"phone": {
|
30
|
+
"type": "L",
|
31
|
+
"number": "5555555555"
|
32
|
+
},
|
33
|
+
"references": [
|
34
|
+
{
|
35
|
+
"src": "V",
|
36
|
+
"id": "AA0000000"
|
37
|
+
}
|
38
|
+
],
|
39
|
+
"sex": "M",
|
40
|
+
"id": "N-00000000-00AA-AAAA-0000-000000000000"
|
41
|
+
},
|
42
|
+
{
|
43
|
+
"cong_dist": 1,
|
44
|
+
"party": "I",
|
45
|
+
"precinct": null,
|
46
|
+
"univ": 2,
|
47
|
+
"actions": {
|
48
|
+
"checkin": {
|
49
|
+
"method": "PUT",
|
50
|
+
"url": "/campaign/abcd/client/1234/volunteer/5678/checkout/aaaaa99999"
|
51
|
+
}
|
52
|
+
},
|
53
|
+
"address": {
|
54
|
+
"zipp4": "0000",
|
55
|
+
"state": "TN",
|
56
|
+
"zip": "00000",
|
57
|
+
"city": "CITY",
|
58
|
+
"address": "1234 ADDRESS ST",
|
59
|
+
"id": 123456789,
|
60
|
+
"type": "r",
|
61
|
+
"latitude": "00.000000",
|
62
|
+
"longitude": "00.000000"
|
63
|
+
},
|
64
|
+
"date_of_birth": "1981-2-17",
|
65
|
+
"first_name": "JANE",
|
66
|
+
"last_name": "DOE",
|
67
|
+
"middle_name": "P",
|
68
|
+
"phone": {
|
69
|
+
"type": "L",
|
70
|
+
"number": "5555555555"
|
71
|
+
},
|
72
|
+
"references": [
|
73
|
+
{
|
74
|
+
"src": "V",
|
75
|
+
"id": "BB0000000"
|
76
|
+
}
|
77
|
+
],
|
78
|
+
"sex": "F",
|
79
|
+
"id": "N-00000000-00BB-BBBB-0000-000000000000"
|
80
|
+
}
|
81
|
+
|
82
|
+
]
|
83
|
+
}
|
data/spec/person_spec.rb
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__),'spec_helper')
|
2
|
+
|
3
|
+
describe VcsClient::Person do
|
4
|
+
|
5
|
+
describe 'creating from attrs' do
|
6
|
+
|
7
|
+
subject do
|
8
|
+
VcsClient::Person.new(Crack::JSON.parse(one_person_fixture)['people'].first)
|
9
|
+
end
|
10
|
+
|
11
|
+
its(:precinct) { should be_nil }
|
12
|
+
its(:cong_dist) { should == 1 }
|
13
|
+
its(:first_name) { should == 'JOHN' }
|
14
|
+
its(:last_name) { should == 'DOE' }
|
15
|
+
its(:middle_name) { should == 'Q' }
|
16
|
+
its(:sex) { should == 'M' }
|
17
|
+
its(:univ) { should == 2 }
|
18
|
+
its(:party) { should == 'I' }
|
19
|
+
its(:date_of_birth) { should == Date.parse('1980-3-20') }
|
20
|
+
its(:address) { should be_instance_of(VcsClient::Address) }
|
21
|
+
its(:phone) { should be_instance_of(VcsClient::Phone) }
|
22
|
+
its(:token) { should == 'abcdefg12345678' }
|
23
|
+
|
24
|
+
it 'should return a nil token if no checkin action exists' do
|
25
|
+
VcsClient::Person.new.token.should be_nil
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should have an age accessor that uses the date_of_birth' do
|
29
|
+
Date.stubs(:today).returns(Date.parse('2010-3-20'))
|
30
|
+
subject.age.should == 30
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should have an array of 1 reference' do
|
34
|
+
subject.references.class.should == Array
|
35
|
+
subject.references.length.should == 1
|
36
|
+
subject.references.first.should be_instance_of(VcsClient::Reference)
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should have keyed hash for actions' do
|
40
|
+
subject.actions.class.should == Hash
|
41
|
+
subject.actions['checkin'].class.should == VcsClient::Action
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'should create a dynamic method called "checkin" that does a PUT' do
|
45
|
+
VcsClient.stubs(:put)
|
46
|
+
subject.checkin('')
|
47
|
+
VcsClient.should have_received(:put)
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
context 'nil responses' do
|
53
|
+
describe 'phone' do
|
54
|
+
subject { VcsClient::Person.new(:phone => nil, :address => nil, :date_of_birth => nil) }
|
55
|
+
its(:phone) { should be_nil }
|
56
|
+
its(:address) { should be_nil }
|
57
|
+
its(:date_of_birth) { should be_nil }
|
58
|
+
its(:age) { should be_nil }
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context 'nil references' do
|
63
|
+
it 'should not raise an error' do
|
64
|
+
expect {
|
65
|
+
VcsClient::Person.new(:references => nil)
|
66
|
+
}.to_not raise_error
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context 'only getting a year back for the date_of_birth' do
|
71
|
+
subject { VcsClient::Person.new(:date_of_birth => "1980") }
|
72
|
+
its(:date_of_birth) { should == Date.parse("1980-01-01") }
|
73
|
+
end
|
74
|
+
|
75
|
+
describe 'proper spacing for #name' do
|
76
|
+
it 'should properly display the full name when all 3 are given' do
|
77
|
+
person = VcsClient::Person.new(:first_name => "First", :middle_name => "Middle", :last_name => "Last")
|
78
|
+
person.name.should == "First Middle Last"
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'should properly display the full name when only first and last are given' do
|
82
|
+
person = VcsClient::Person.new(:first_name => "First", :last_name => "Last")
|
83
|
+
person.name.should == "First Last"
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'should properly display the full name when only first is given' do
|
87
|
+
person = VcsClient::Person.new(:first_name => "First")
|
88
|
+
person.name.should == "First"
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
data/spec/phone_spec.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__),'spec_helper')
|
2
|
+
|
3
|
+
describe VcsClient::Phone do
|
4
|
+
|
5
|
+
describe 'creating from attrs' do
|
6
|
+
|
7
|
+
subject do
|
8
|
+
VcsClient::Phone.new(Crack::JSON.parse(one_person_fixture)['people'].first['phone'])
|
9
|
+
end
|
10
|
+
|
11
|
+
its(:number) { should == '5555555555' }
|
12
|
+
its(:type) { should == 'L' }
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__),'spec_helper')
|
2
|
+
|
3
|
+
describe VcsClient::Reference do
|
4
|
+
|
5
|
+
describe 'creating from attrs' do
|
6
|
+
subject do
|
7
|
+
VcsClient::Reference.new({:src => 'source', :id => 456})
|
8
|
+
end
|
9
|
+
|
10
|
+
its(:src) { should == 'source' }
|
11
|
+
its(:id) { should == 456 }
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
require 'bundler'
|
4
|
+
Bundler.setup
|
5
|
+
|
6
|
+
require 'spec'
|
7
|
+
require 'shoulda'
|
8
|
+
require 'bourne'
|
9
|
+
require 'spec/autorun'
|
10
|
+
require 'ruby-debug'
|
11
|
+
require 'webmock/rspec'
|
12
|
+
|
13
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
14
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
15
|
+
|
16
|
+
Dir[File.expand_path(File.join(File.dirname(__FILE__),'support','**','*.rb'))].each {|f| require f}
|
17
|
+
|
18
|
+
require 'vcs_client'
|
19
|
+
|
20
|
+
Spec::Runner.configure do |config|
|
21
|
+
config.mock_with Mocha::API
|
22
|
+
config.include WebMock
|
23
|
+
config.include Fixtures
|
24
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Fixtures
|
2
|
+
def self.included(base)
|
3
|
+
Dir[File.expand_path(File.join(File.dirname(__FILE__),'../fixtures','**','*.*'))].each do |file|
|
4
|
+
file_name = file.split('/').last
|
5
|
+
method_name = file_name.split('.').first
|
6
|
+
method = <<-METHOD
|
7
|
+
def #{method_name}_fixture
|
8
|
+
unless @#{method_name}_fixture
|
9
|
+
fixture_file = File.new('#{file}', 'r')
|
10
|
+
@#{method_name}_fixture = fixture_file.read
|
11
|
+
fixture_file.close
|
12
|
+
end
|
13
|
+
@#{method_name}_fixture
|
14
|
+
end
|
15
|
+
METHOD
|
16
|
+
eval(method)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__),'spec_helper')
|
2
|
+
|
3
|
+
describe VcsClient do
|
4
|
+
|
5
|
+
describe 'setting the base_uri' do
|
6
|
+
before do
|
7
|
+
VcsClient.stubs(:base_uri)
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should set HTTParty's base_uri" do
|
11
|
+
VcsClient.vcs_uri = 'http://test.uri.com:8080'
|
12
|
+
VcsClient.should have_received(:base_uri).with('http://test.uri.com:8080')
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'with a fake VCS URI set' do
|
17
|
+
before do
|
18
|
+
VcsClient.vcs_uri = 'http://test.uri.com:8080'
|
19
|
+
end
|
20
|
+
|
21
|
+
describe 'checking out, stubbed' do
|
22
|
+
describe 'succesfully' do
|
23
|
+
it 'should work' do
|
24
|
+
stub_request(:post, /.+/).to_return(:body => two_people_fixture)
|
25
|
+
people = VcsClient.checkout('perf', rand(500), rand(500))
|
26
|
+
people.class.should == Array
|
27
|
+
people.length.should == 2
|
28
|
+
people.each do |person|
|
29
|
+
person.respond_to?(:checkin).should == true
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe 'successfully with lat/long info' do
|
35
|
+
it 'should also work' do
|
36
|
+
stub_request(:post, /.+/).to_return(:body => two_people_fixture)
|
37
|
+
people = VcsClient.checkout('perf', rand(500), rand(500), 38.883966, -77.008603, 5)
|
38
|
+
people.class.should == Array
|
39
|
+
people.length.should == 2
|
40
|
+
people.each do |person|
|
41
|
+
person.respond_to?(:checkin).should == true
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe 'if only lat and lon are given' do
|
47
|
+
it 'should raise an Exception for missing radius' do
|
48
|
+
expect {
|
49
|
+
VcsClient.checkout('perf', rand(500), rand(500), 0.0, -77.0)
|
50
|
+
}.to raise_error(VcsClient::NoRadius) { |exception| exception.inspect.should == 'VcsClient::NoRadius: When searching by location a radius is necessary' }
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe 'unsuccessfully' do
|
55
|
+
it 'should bomb' do
|
56
|
+
stub_request(:post, /.+/).to_return(:body => '{}')
|
57
|
+
expect {
|
58
|
+
VcsClient.checkout('perf',2,3)
|
59
|
+
}.to raise_error(VcsClient::CheckoutFailed){|ex| ex.inspect.should == 'VcsClient::CheckoutFailed: '}
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe 'checking in, stubbed' do
|
65
|
+
describe 'succesfully' do
|
66
|
+
it 'should work' do
|
67
|
+
stub_request(:put, /.+/).to_return(:body => checkin_response_fixture)
|
68
|
+
VcsClient.checkin(1,2,3,4,5)['response'].should == 'Checkin Successful'
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe 'unsuccessfully' do
|
73
|
+
it 'should bomb' do
|
74
|
+
stub_request(:put, /.+/).to_return(:body => 'Could not find an available Person')
|
75
|
+
expect {
|
76
|
+
VcsClient.checkin(1,2,3,4,5)
|
77
|
+
}.to raise_error(VcsClient::CheckinFailed){|ex| ex.inspect.should == 'VcsClient::CheckinFailed: Could not find an available Person' }
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
data/vcs_client.gemspec
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{vcs_client}
|
8
|
+
s.version = "0.4.6"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["gill"]
|
12
|
+
s.date = %q{2010-07-13}
|
13
|
+
s.description = %q{This gem provides all the plumbing to interact with the Voter Checkout Service}
|
14
|
+
s.email = %q{gilltots@gmail.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".gitignore",
|
21
|
+
".rvmrc",
|
22
|
+
"Gemfile",
|
23
|
+
"Gemfile.lock",
|
24
|
+
"LICENSE",
|
25
|
+
"README.rdoc",
|
26
|
+
"Rakefile",
|
27
|
+
"VERSION",
|
28
|
+
"features/step_definitions/vcs_client_steps.rb",
|
29
|
+
"features/support/env.rb",
|
30
|
+
"features/vcs_client.feature",
|
31
|
+
"lib/objects/action.rb",
|
32
|
+
"lib/objects/address.rb",
|
33
|
+
"lib/objects/basement.rb",
|
34
|
+
"lib/objects/person.rb",
|
35
|
+
"lib/objects/phone.rb",
|
36
|
+
"lib/objects/reference.rb",
|
37
|
+
"lib/vcs_client.rb",
|
38
|
+
"spec/action_spec.rb",
|
39
|
+
"spec/address_spec.rb",
|
40
|
+
"spec/basement_spec.rb",
|
41
|
+
"spec/fixtures/checkin_response.json",
|
42
|
+
"spec/fixtures/one_person.json",
|
43
|
+
"spec/fixtures/two_people.json",
|
44
|
+
"spec/person_spec.rb",
|
45
|
+
"spec/phone_spec.rb",
|
46
|
+
"spec/reference_spec.rb",
|
47
|
+
"spec/spec_helper.rb",
|
48
|
+
"spec/support/fixtures.rb",
|
49
|
+
"spec/support/mocha.rb",
|
50
|
+
"spec/vcs_client_spec.rb",
|
51
|
+
"vcs_client.gemspec"
|
52
|
+
]
|
53
|
+
s.homepage = %q{http://github.com/gilltots/vcs_client}
|
54
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
55
|
+
s.require_paths = ["lib"]
|
56
|
+
s.rubygems_version = %q{1.3.6}
|
57
|
+
s.summary = %q{This gem wraps the Voter Checkout Service API}
|
58
|
+
s.test_files = [
|
59
|
+
"spec/action_spec.rb",
|
60
|
+
"spec/address_spec.rb",
|
61
|
+
"spec/basement_spec.rb",
|
62
|
+
"spec/person_spec.rb",
|
63
|
+
"spec/phone_spec.rb",
|
64
|
+
"spec/reference_spec.rb",
|
65
|
+
"spec/spec_helper.rb",
|
66
|
+
"spec/support/fixtures.rb",
|
67
|
+
"spec/support/mocha.rb",
|
68
|
+
"spec/vcs_client_spec.rb"
|
69
|
+
]
|
70
|
+
|
71
|
+
if s.respond_to? :specification_version then
|
72
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
73
|
+
s.specification_version = 3
|
74
|
+
|
75
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
76
|
+
s.add_development_dependency(%q<shoulda>, [">= 0"])
|
77
|
+
s.add_runtime_dependency(%q<httparty>, [">= 0.5.2"])
|
78
|
+
else
|
79
|
+
s.add_dependency(%q<shoulda>, [">= 0"])
|
80
|
+
s.add_dependency(%q<httparty>, [">= 0.5.2"])
|
81
|
+
end
|
82
|
+
else
|
83
|
+
s.add_dependency(%q<shoulda>, [">= 0"])
|
84
|
+
s.add_dependency(%q<httparty>, [">= 0.5.2"])
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
metadata
ADDED
@@ -0,0 +1,128 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: vcs_client
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 4
|
8
|
+
- 6
|
9
|
+
version: 0.4.6
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- gill
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-07-13 00:00:00 -04:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: shoulda
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
version: "0"
|
30
|
+
type: :development
|
31
|
+
version_requirements: *id001
|
32
|
+
- !ruby/object:Gem::Dependency
|
33
|
+
name: httparty
|
34
|
+
prerelease: false
|
35
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
segments:
|
40
|
+
- 0
|
41
|
+
- 5
|
42
|
+
- 2
|
43
|
+
version: 0.5.2
|
44
|
+
type: :runtime
|
45
|
+
version_requirements: *id002
|
46
|
+
description: This gem provides all the plumbing to interact with the Voter Checkout Service
|
47
|
+
email: gilltots@gmail.com
|
48
|
+
executables: []
|
49
|
+
|
50
|
+
extensions: []
|
51
|
+
|
52
|
+
extra_rdoc_files:
|
53
|
+
- LICENSE
|
54
|
+
- README.rdoc
|
55
|
+
files:
|
56
|
+
- .gitignore
|
57
|
+
- .rvmrc
|
58
|
+
- Gemfile
|
59
|
+
- Gemfile.lock
|
60
|
+
- LICENSE
|
61
|
+
- README.rdoc
|
62
|
+
- Rakefile
|
63
|
+
- VERSION
|
64
|
+
- features/step_definitions/vcs_client_steps.rb
|
65
|
+
- features/support/env.rb
|
66
|
+
- features/vcs_client.feature
|
67
|
+
- lib/objects/action.rb
|
68
|
+
- lib/objects/address.rb
|
69
|
+
- lib/objects/basement.rb
|
70
|
+
- lib/objects/person.rb
|
71
|
+
- lib/objects/phone.rb
|
72
|
+
- lib/objects/reference.rb
|
73
|
+
- lib/vcs_client.rb
|
74
|
+
- spec/action_spec.rb
|
75
|
+
- spec/address_spec.rb
|
76
|
+
- spec/basement_spec.rb
|
77
|
+
- spec/fixtures/checkin_response.json
|
78
|
+
- spec/fixtures/one_person.json
|
79
|
+
- spec/fixtures/two_people.json
|
80
|
+
- spec/person_spec.rb
|
81
|
+
- spec/phone_spec.rb
|
82
|
+
- spec/reference_spec.rb
|
83
|
+
- spec/spec_helper.rb
|
84
|
+
- spec/support/fixtures.rb
|
85
|
+
- spec/support/mocha.rb
|
86
|
+
- spec/vcs_client_spec.rb
|
87
|
+
- vcs_client.gemspec
|
88
|
+
has_rdoc: true
|
89
|
+
homepage: http://github.com/gilltots/vcs_client
|
90
|
+
licenses: []
|
91
|
+
|
92
|
+
post_install_message:
|
93
|
+
rdoc_options:
|
94
|
+
- --charset=UTF-8
|
95
|
+
require_paths:
|
96
|
+
- lib
|
97
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - ">="
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
segments:
|
102
|
+
- 0
|
103
|
+
version: "0"
|
104
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
105
|
+
requirements:
|
106
|
+
- - ">="
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
segments:
|
109
|
+
- 0
|
110
|
+
version: "0"
|
111
|
+
requirements: []
|
112
|
+
|
113
|
+
rubyforge_project:
|
114
|
+
rubygems_version: 1.3.6
|
115
|
+
signing_key:
|
116
|
+
specification_version: 3
|
117
|
+
summary: This gem wraps the Voter Checkout Service API
|
118
|
+
test_files:
|
119
|
+
- spec/action_spec.rb
|
120
|
+
- spec/address_spec.rb
|
121
|
+
- spec/basement_spec.rb
|
122
|
+
- spec/person_spec.rb
|
123
|
+
- spec/phone_spec.rb
|
124
|
+
- spec/reference_spec.rb
|
125
|
+
- spec/spec_helper.rb
|
126
|
+
- spec/support/fixtures.rb
|
127
|
+
- spec/support/mocha.rb
|
128
|
+
- spec/vcs_client_spec.rb
|