act_blue_reporter 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +25 -0
- data/.ruby-version +1 -0
- data/.travis.yml +14 -0
- data/Gemfile +4 -0
- data/Guardfile +11 -0
- data/LICENSE.txt +22 -0
- data/README.md +37 -0
- data/Rakefile +12 -0
- data/act_blue_reporter.gemspec +33 -0
- data/lib/act_blue_reporter/base.rb +8 -0
- data/lib/act_blue_reporter/campaign.rb +49 -0
- data/lib/act_blue_reporter/connect.rb +57 -0
- data/lib/act_blue_reporter/contribution_report.rb +30 -0
- data/lib/act_blue_reporter/exceptions.rb +16 -0
- data/lib/act_blue_reporter/version.rb +3 -0
- data/lib/act_blue_reporter.rb +10 -0
- data/spec/campaign_spec.rb +78 -0
- data/spec/connect_spec.rb +21 -0
- data/spec/contribution_report_spec.rb +31 -0
- data/spec/spec_data.rb +198 -0
- data/spec/spec_helper.rb +75 -0
- metadata +212 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 03bdbd7f49fc11b96a8ffbdf59f75c9b277a0f76
|
4
|
+
data.tar.gz: 57608ae1fb9e8429d9a0746daea595aafd923d1f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e07ff66199a5e10f5524c3c1deac8b8b09ed88633010ffbd811e6d29f499a66fb1c40b88248a3ba53db501553cc6862f43dca84f6b2cb75e0b7f83ddeea429a2
|
7
|
+
data.tar.gz: 08ea144d231393c60194bf1bf899b709a0bf3e86962da16f143dd588576dc6124e36610980924d97797e39f12b4c840c5603fe80e6c9cd079f51861265bd15d9
|
data/.gitignore
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
*.bundle
|
19
|
+
*.so
|
20
|
+
*.o
|
21
|
+
*.a
|
22
|
+
mkmf.log
|
23
|
+
.project
|
24
|
+
.DS_Store
|
25
|
+
.idea
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.1.2
|
data/.travis.yml
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
language: ruby
|
2
|
+
cache: bundler
|
3
|
+
rvm:
|
4
|
+
- 2.1.2
|
5
|
+
script: bundle exec rake
|
6
|
+
notifications:
|
7
|
+
email:
|
8
|
+
recipients:
|
9
|
+
- cdale77@gmail.com
|
10
|
+
on_failure: change
|
11
|
+
on_success: never
|
12
|
+
env:
|
13
|
+
global:
|
14
|
+
secure: STGu7bKcpOa1PiEuSsiiq+3X7n7qzBnKdrSqZGT8EGu3T+ZwMsba/XwffD2ABa3xHkeSm/08Jwg29mLBiN1BQALsQZ7T88pe0AvzEUAW5KG1Q7Ns4TnHmMMJYGAibq29CrDZttJmQzM3Ancu5k3gN/fO3cjk6qJsRiqpyTFd6ho=
|
data/Gemfile
ADDED
data/Guardfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Brad Johnson
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
[![Code Climate](https://codeclimate.com/github/cdale77/act_blue_reporter/badges/gpa.svg)](https://codeclimate.com/github/cdale77/act_blue_reporter)
|
2
|
+
[![Test Coverage](https://codeclimate.com/github/cdale77/act_blue_reporter/badges/coverage.svg)](https://codeclimate.com/github/cdale77/act_blue_reporter)
|
3
|
+
[![Build Status](https://travis-ci.org/cdale77/act_blue_reporter.svg?branch=master)](https://travis-ci.org/cdale77/act_blue_reporter)
|
4
|
+
|
5
|
+
# ActBlueReporter
|
6
|
+
|
7
|
+
This is a Ruby gem designed to simplify getting contribution information from
|
8
|
+
ActBlue. It is designed to work across multiple ActBlue campaigns.
|
9
|
+
|
10
|
+
It is not a full-fledged wrapper for the ActBlue API; it doesn't do much more
|
11
|
+
than retrieve data.
|
12
|
+
|
13
|
+
## Installation
|
14
|
+
|
15
|
+
Add this line to your application's Gemfile:
|
16
|
+
|
17
|
+
gem 'act_blue_reporter'
|
18
|
+
|
19
|
+
And then execute:
|
20
|
+
|
21
|
+
$ bundle
|
22
|
+
|
23
|
+
Or install it yourself as:
|
24
|
+
|
25
|
+
$ gem install act_blue_reporter
|
26
|
+
|
27
|
+
## Usage
|
28
|
+
|
29
|
+
TODO: Write usage instructions here
|
30
|
+
|
31
|
+
## Contributing
|
32
|
+
|
33
|
+
1. Fork it ( https://github.com/cdale77/act_blue_reporter/fork )
|
34
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
35
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
36
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
37
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require 'rspec/core/rake_task'
|
3
|
+
require 'bundler/gem_tasks'
|
4
|
+
|
5
|
+
# Default directory to look in is `/specs`
|
6
|
+
# Run with `rake spec`
|
7
|
+
RSpec::Core::RakeTask.new(:spec) do |task|
|
8
|
+
task.rspec_opts = ["--color", "--format documentation"]
|
9
|
+
end
|
10
|
+
|
11
|
+
task default: :spec
|
12
|
+
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "act_blue_reporter/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "act_blue_reporter"
|
8
|
+
spec.version = ActBlueReporter::VERSION
|
9
|
+
spec.authors = ["Brad Johnson"]
|
10
|
+
spec.email = ["cdale77@gmail.com"]
|
11
|
+
spec.summary = "A Ruby "
|
12
|
+
spec.description = "A Ruby gem to facilitate gathering contribution \
|
13
|
+
information from multiple ActBlue campaigns. "
|
14
|
+
spec.homepage = "https://github.com/cdale77/act_blue_reporter"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0")
|
18
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
19
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
20
|
+
spec.require_paths = ["lib"]
|
21
|
+
|
22
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
23
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
24
|
+
spec.add_development_dependency "rspec", "~> 3.1"
|
25
|
+
spec.add_development_dependency "pry", "~> 0.10"
|
26
|
+
spec.add_development_dependency "pry-remote", "~> 0.1"
|
27
|
+
spec.add_development_dependency "pry-nav", "~> 0.2"
|
28
|
+
spec.add_development_dependency "codeclimate-test-reporter", "~> 0.4"
|
29
|
+
spec.add_development_dependency "webmock", "~> 1.18"
|
30
|
+
|
31
|
+
spec.add_runtime_dependency "httparty", "~> 0.13"
|
32
|
+
spec.add_runtime_dependency "activesupport", "~> 4.0"
|
33
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
module ActBlueReporter
|
2
|
+
# This is the base class for all ActBlue classes. The purpose of this library
|
3
|
+
# is to provide a simple Ruby interface for retrieving contribution
|
4
|
+
# information from ActBlue via API. https://secure.actblue.com/api
|
5
|
+
class Base
|
6
|
+
include ActBlueReporter::Exceptions
|
7
|
+
end
|
8
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require "active_support/core_ext/time/calculations"
|
2
|
+
require "active_support/core_ext/integer/time"
|
3
|
+
|
4
|
+
module ActBlueReporter
|
5
|
+
|
6
|
+
class Campaign < ActBlueReporter::Connect
|
7
|
+
# This class models a campaign or committee at ActBlue and provides
|
8
|
+
# some basic functionality. ActBlue calls these "entities".
|
9
|
+
|
10
|
+
def initialize(act_blue_login, act_blue_password, act_blue_entity_id)
|
11
|
+
@auth = { username: act_blue_login, password: act_blue_password }
|
12
|
+
@act_blue_entity_id = act_blue_entity_id
|
13
|
+
end
|
14
|
+
|
15
|
+
def details
|
16
|
+
request_uri = "/entities/#{@act_blue_entity_id}"
|
17
|
+
response = make_request(request_uri, @auth)
|
18
|
+
payload = response["entity"]
|
19
|
+
raise ActBlueReporter::Exceptions::PayloadError unless payload
|
20
|
+
return payload
|
21
|
+
end
|
22
|
+
|
23
|
+
def all_contributions
|
24
|
+
request_uri = "/contributions?destination=#{@act_blue_entity_id}"
|
25
|
+
response = make_request(request_uri, @auth)
|
26
|
+
payload = response["contributions"]
|
27
|
+
raise ActBlueReporter::Exceptions::PayloadError unless payload
|
28
|
+
return payload
|
29
|
+
end
|
30
|
+
|
31
|
+
def contributions_in_time_range(start_time, end_time)
|
32
|
+
response = make_request( "/contributions?destination=#{@entity.to_s}&" \
|
33
|
+
"payment_timestamp=#{start_time.to_s}/" \
|
34
|
+
"#{end_time.to_s}",
|
35
|
+
@auth)
|
36
|
+
payload = response["contributions"]
|
37
|
+
raise ActBlueReporter::Exceptions::PayloadError unless payload
|
38
|
+
return payload
|
39
|
+
end
|
40
|
+
|
41
|
+
def contributions_in_last_24_hrs
|
42
|
+
start_time = (Time.now.at_beginning_of_day - 24.hours).iso8601
|
43
|
+
end_time = Time.now.at_beginning_of_day.iso8601
|
44
|
+
payload = contributions_in_time_range(start_time, end_time)
|
45
|
+
raise ActBlueReporter::Exceptions::PayloadError unless payload
|
46
|
+
return payload
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require "httparty"
|
2
|
+
|
3
|
+
module ActBlueReporter
|
4
|
+
|
5
|
+
class Connect < ActBlueReporter::Base
|
6
|
+
|
7
|
+
# This class provides the basic request method used to communicate with
|
8
|
+
# ActBlue.
|
9
|
+
|
10
|
+
include HTTParty
|
11
|
+
|
12
|
+
ACTBLUE_URI = "https://secure.actblue.com/api/2009-08"
|
13
|
+
HEADER = { "Accept" => "application/xml" }
|
14
|
+
|
15
|
+
private
|
16
|
+
def make_request(request_uri, authentication)
|
17
|
+
|
18
|
+
response = request_wrapper(request_uri, authentication)
|
19
|
+
|
20
|
+
# raise an error if anything is wrong with the response
|
21
|
+
check_response(response)
|
22
|
+
|
23
|
+
# return the parsed data as a hash.
|
24
|
+
return response.parsed_response
|
25
|
+
end
|
26
|
+
|
27
|
+
def request_wrapper(request_uri, authentication)
|
28
|
+
Timeout.timeout(5) do
|
29
|
+
HTTParty.get("#{ACTBLUE_URI}#{request_uri}",
|
30
|
+
basic_auth: authentication,
|
31
|
+
headers: HEADER)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def check_response(response)
|
36
|
+
# response can be nil if the act blue entity id is blank
|
37
|
+
unless response
|
38
|
+
raise_error("No response. Check the ActBlue entity ID.")
|
39
|
+
end
|
40
|
+
|
41
|
+
# raise an error if parsed_response is nil
|
42
|
+
unless response.parsed_response
|
43
|
+
raise_error("Did not get any data from ActBlue.")
|
44
|
+
end
|
45
|
+
|
46
|
+
# raise an error if the success code is false
|
47
|
+
unless response.success?
|
48
|
+
raise_error("HTTP response code: #{response.response.code}")
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
def raise_error(message)
|
54
|
+
raise ActBlueReporter::Exceptions::ConnectionError.new(msg: message)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module ActBlueReporter
|
2
|
+
class ContributionReport < ActBlueReporter::Base
|
3
|
+
|
4
|
+
# This class takes a report from the Campaign class and formats
|
5
|
+
# it for convenience. In particular the structure of the response
|
6
|
+
# from ActBlue is different in the case of one or > 1 contributions.
|
7
|
+
|
8
|
+
attr_reader :payload
|
9
|
+
|
10
|
+
def initialize(payload)
|
11
|
+
@payload = payload
|
12
|
+
end
|
13
|
+
|
14
|
+
def report
|
15
|
+
# The hash from ActBlue is structured differently in the case of
|
16
|
+
# 1 or 1+ responses. This code returns a predictable structure
|
17
|
+
if count == 0
|
18
|
+
[]
|
19
|
+
elsif count == 1
|
20
|
+
[] << @payload["contribution"]
|
21
|
+
else
|
22
|
+
@payload["contribution"]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def count
|
27
|
+
@payload["count"] || 0
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module ActBlueReporter
|
2
|
+
module Exceptions
|
3
|
+
# Custom exceptions
|
4
|
+
class ConnectionError < StandardError
|
5
|
+
def initialize(msg = "Error while connecting to ActBlue.")
|
6
|
+
super
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class PayloadError < StandardError
|
11
|
+
def initialize(msg = "Did not receive the requested data from ActBlue")
|
12
|
+
super
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require "act_blue_reporter/version"
|
2
|
+
require_relative "act_blue_reporter/exceptions"
|
3
|
+
require_relative "act_blue_reporter/base"
|
4
|
+
require_relative "act_blue_reporter/connect"
|
5
|
+
require_relative "act_blue_reporter/campaign"
|
6
|
+
require_relative "act_blue_reporter/contribution_report"
|
7
|
+
|
8
|
+
module ActBlueReporter
|
9
|
+
|
10
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe ActBlueReporter::Campaign do
|
4
|
+
|
5
|
+
let!(:campaign) { ActBlueReporter::Campaign.new("", "", "") }
|
6
|
+
let!(:failing_campaign) { ActBlueReporter::Campaign.new("", "", "0") }
|
7
|
+
|
8
|
+
describe '#initialize' do
|
9
|
+
it 'should create an object' do
|
10
|
+
expect(campaign).to be_an_instance_of ActBlueReporter::Campaign
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '#details' do
|
15
|
+
describe 'success' do
|
16
|
+
it 'should return a Hash' do
|
17
|
+
expect(campaign.details).to be_an_instance_of Hash
|
18
|
+
end
|
19
|
+
it 'should return a response with the correct info' do
|
20
|
+
expect(campaign.details["id"]).to eql "00000"
|
21
|
+
expect(campaign.details["displayname"]).to eql "Test Committee"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
describe 'failure' do
|
25
|
+
it 'should raise an error' do
|
26
|
+
expect { failing_campaign.details }.to raise_error
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '#all_contributions' do
|
32
|
+
describe 'success' do
|
33
|
+
it 'should return a Hash' do
|
34
|
+
expect(campaign.all_contributions).to be_an_instance_of Hash
|
35
|
+
end
|
36
|
+
end
|
37
|
+
it 'should return a response with the correct info' do
|
38
|
+
expect(campaign.all_contributions["count"]).to eq "3"
|
39
|
+
end
|
40
|
+
describe 'failure' do
|
41
|
+
it 'should raise an error' do
|
42
|
+
expect { failing_campaign.all_contributions }.to raise_error
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe '#contributions_in_time_range' do
|
48
|
+
describe 'success' do
|
49
|
+
start_time = "2014-08-23T00:00:00-07:00"
|
50
|
+
end_time = "2014-08-24T00:00:00-07:00"
|
51
|
+
describe 'success' do
|
52
|
+
it 'should return a Hash' do
|
53
|
+
expect(campaign.contributions_in_time_range(start_time, end_time)).to \
|
54
|
+
be_an_instance_of Hash
|
55
|
+
end
|
56
|
+
it 'should return a response with the correct info' do
|
57
|
+
expect(campaign.contributions_in_time_range(start_time, end_time)["count"]).to \
|
58
|
+
eq "3"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
describe 'failure' do
|
63
|
+
it 'should raise an error' do
|
64
|
+
expect do
|
65
|
+
failing_campaign.contributions_in_time_range(start_time, end_time)
|
66
|
+
end.to raise_error
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe '#contributions_in_last_24_hrs' do
|
72
|
+
describe 'success' do
|
73
|
+
it 'should return a Hash' do
|
74
|
+
expect(campaign.contributions_in_last_24_hrs).to be_an_instance_of Hash
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe ActBlueReporter do
|
4
|
+
|
5
|
+
describe ActBlueReporter::Connect do
|
6
|
+
|
7
|
+
let(:act_blue_connect) { ActBlueReporter::Connect.new }
|
8
|
+
|
9
|
+
describe 'class constants' do
|
10
|
+
it 'should have a constant for the ActBlue URI' do
|
11
|
+
expect(ActBlueReporter::Connect::ACTBLUE_URI).to eql \
|
12
|
+
"https://secure.actblue.com/api/2009-08"
|
13
|
+
end
|
14
|
+
it 'should have a constant for the headers' do
|
15
|
+
expect(ActBlueReporter::Connect::HEADER).to be_an_instance_of Hash
|
16
|
+
expect(ActBlueReporter::Connect::HEADER["Accept"]).to eql \
|
17
|
+
"application/xml"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe ActBlueReporter::ContributionReport do
|
4
|
+
|
5
|
+
let!(:campaign) { ActBlueReporter::Campaign.new("", "", "") }
|
6
|
+
let!(:payload) { campaign.contributions_in_last_24_hrs }
|
7
|
+
let!(:report) { ActBlueReporter::ContributionReport.new(payload) }
|
8
|
+
|
9
|
+
describe '#initialize' do
|
10
|
+
it 'should create an object' do
|
11
|
+
expect(report).to be_an_instance_of ActBlueReporter::ContributionReport
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe '#payload' do
|
16
|
+
it 'should return the original payload' do
|
17
|
+
expect(report.payload). to eq payload
|
18
|
+
end
|
19
|
+
end
|
20
|
+
describe '#report' do
|
21
|
+
it 'should return an array of contributions' do
|
22
|
+
expect(report.report).to be_an_instance_of Array
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe '#count' do
|
27
|
+
it 'should return the number of contributions' do
|
28
|
+
expect(report.count).to eq payload["count"]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/spec/spec_data.rb
ADDED
@@ -0,0 +1,198 @@
|
|
1
|
+
module SpecData
|
2
|
+
def self.act_blue_entity_response_xml
|
3
|
+
"<entity id='00000'
|
4
|
+
href='https://secure.actblue.com/api/2009-08/entities/28576'>
|
5
|
+
<displayname>Test Committee</displayname>
|
6
|
+
<legalname>Test Committee</legalname>
|
7
|
+
<prefacewitharticle>false</prefacewitharticle>
|
8
|
+
<sortname>test committee</sortname>
|
9
|
+
<kind>org</kind>
|
10
|
+
<govid>A00000000</govid>
|
11
|
+
<contributionlimit>5000.00</contributionlimit>
|
12
|
+
<links>
|
13
|
+
<link>https://secure.actblue.com/entity/fundraisers/00000</link>
|
14
|
+
<donate>https://secure.actblue.com/contribute/entity/00000</donate>
|
15
|
+
<website>http://example.com</website>
|
16
|
+
</links>
|
17
|
+
<listentries>
|
18
|
+
<listentry page='example_event' entity='00000' position='1'>
|
19
|
+
<page name='example'
|
20
|
+
href='https://secure.actblue.com/api/2009-08/pages/example'>
|
21
|
+
<user user-key='XXXXXXXXXXXX'>
|
22
|
+
<email>example@example.com</email>
|
23
|
+
</user>
|
24
|
+
<title>Example</title>
|
25
|
+
<author></author>
|
26
|
+
</page>
|
27
|
+
<blurb></blurb>
|
28
|
+
</listentry>
|
29
|
+
</listentries>
|
30
|
+
<scoreboards>
|
31
|
+
<scoreboard dimensions='entity'>
|
32
|
+
<fact entity='00000'>
|
33
|
+
<count>123</count>
|
34
|
+
<total>31467.00</total>
|
35
|
+
</fact>
|
36
|
+
</scoreboard>
|
37
|
+
<scoreboard dimensions='entity page'>
|
38
|
+
<fact entity='00000' page='example2'>
|
39
|
+
<page name='example2'
|
40
|
+
href='https://secure.actblue.com/api/2009-08/pages/example2'>
|
41
|
+
<user user-key='XXXXXXXXXXX'>
|
42
|
+
<email>somebody@example.com</email>
|
43
|
+
</user>
|
44
|
+
<title>Contribute now</title>
|
45
|
+
<author>Example Committee</author>
|
46
|
+
</page>
|
47
|
+
<count>215</count>
|
48
|
+
<total>12184.00</total>
|
49
|
+
</fact>
|
50
|
+
</scoreboard>
|
51
|
+
<scoreboard dimensions='candidacy entity'>
|
52
|
+
</scoreboard>
|
53
|
+
</scoreboards>
|
54
|
+
</entity>"
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.act_blue_contributions_response_xml
|
58
|
+
|
59
|
+
"<?xml version='1.0' encoding='UTF-8'?>
|
60
|
+
<contributions count='3'>
|
61
|
+
<contribution order-number='AB00000000'>
|
62
|
+
<source>
|
63
|
+
<firstname>Jeff</firstname>
|
64
|
+
<lastname>Jones</lastname>
|
65
|
+
<addr1>1834 Richmond Ave</addr1>
|
66
|
+
<addr2/>
|
67
|
+
<city>San Jose</city>
|
68
|
+
<state>CA</state>
|
69
|
+
<zip>95128</zip>
|
70
|
+
<country>United States</country>
|
71
|
+
<employer>Self-employed</employer>
|
72
|
+
<occupation>Attorney at law</occupation>
|
73
|
+
<empaddr1/>
|
74
|
+
<empaddr2/>
|
75
|
+
<empcity/>
|
76
|
+
<empstate/>
|
77
|
+
<empzip/>
|
78
|
+
<empcountry/>
|
79
|
+
<email-preferred>false</email-preferred>
|
80
|
+
<phone>408-555-5555</phone>
|
81
|
+
<email>me@example.com.com</email>
|
82
|
+
</source>
|
83
|
+
<recurringtimes>3</recurringtimes>
|
84
|
+
<refcode/>
|
85
|
+
<referrer></referrer>
|
86
|
+
<successuri></successuri>
|
87
|
+
<lineitems>
|
88
|
+
<lineitem effective-at='2012-04-03T04:19:00-04:00'>
|
89
|
+
<amount>10.00</amount>
|
90
|
+
<sequence>4</sequence>
|
91
|
+
<entity id='00000'>
|
92
|
+
<legalname>Test Campaign</legalname>
|
93
|
+
<displayname>Test Campaign</displayname>
|
94
|
+
</entity>
|
95
|
+
</lineitem>
|
96
|
+
<lineitem effective-at='2012-03-03T04:22:53-05:00'>
|
97
|
+
<amount>10.00</amount>
|
98
|
+
<sequence>3</sequence>
|
99
|
+
<entity id='00000'>
|
100
|
+
<legalname>Test Campaign</legalname>
|
101
|
+
<displayname>Test Campaign</displayname>
|
102
|
+
</entity>
|
103
|
+
</lineitem>
|
104
|
+
<lineitem effective-at='2012-05-03T04:17:22-04:00'>
|
105
|
+
<amount>10.00</amount>
|
106
|
+
<sequence>5</sequence>
|
107
|
+
<entity id='00000'>
|
108
|
+
<legalname>Test Campaign</legalname>
|
109
|
+
<displayname>Test Campaign</displayname>
|
110
|
+
</entity>
|
111
|
+
</lineitem>
|
112
|
+
</lineitems>
|
113
|
+
</contribution>
|
114
|
+
<contribution order-number='AB00000000'>
|
115
|
+
<source>
|
116
|
+
<firstname>Captain</firstname>
|
117
|
+
<lastname>Crunch</lastname>
|
118
|
+
<addr1>180 East Ave</addr1>
|
119
|
+
<addr2/>
|
120
|
+
<city>Cupertino</city>
|
121
|
+
<state>CA</state>
|
122
|
+
<zip>95014</zip>
|
123
|
+
<country>United States</country>
|
124
|
+
<employer>Stanford</employer>
|
125
|
+
<occupation>Student</occupation>
|
126
|
+
<empaddr1/>
|
127
|
+
<empaddr2/>
|
128
|
+
<empcity/>
|
129
|
+
<empstate/>
|
130
|
+
<empzip/>
|
131
|
+
<empcountry/>
|
132
|
+
<email-preferred>false</email-preferred>
|
133
|
+
<phone>408-555-5555</phone>
|
134
|
+
<email>crunch@example.com</email>
|
135
|
+
</source>
|
136
|
+
<recurringtimes>2</recurringtimes>
|
137
|
+
<refcode/>
|
138
|
+
<referrer></referrer>
|
139
|
+
<successuri></successuri>
|
140
|
+
<lineitems>
|
141
|
+
<lineitem effective-at='2012-04-05T04:15:41-04:00'>
|
142
|
+
<amount>10.00</amount>
|
143
|
+
<sequence>4</sequence>
|
144
|
+
<entity id='00000'>
|
145
|
+
<legalname>Test Campaign</legalname>
|
146
|
+
<displayname></displayname>
|
147
|
+
</entity>
|
148
|
+
</lineitem>
|
149
|
+
<lineitem effective-at='2012-02-05T04:22:20-05:00'>
|
150
|
+
<amount>10.00</amount>
|
151
|
+
<sequence>2</sequence>
|
152
|
+
<entity id='00000'>
|
153
|
+
<legalname>Test Campaign</legalname>
|
154
|
+
<displayname>Test Campaign</displayname>
|
155
|
+
</entity>
|
156
|
+
</lineitem>
|
157
|
+
</lineitems>
|
158
|
+
</contribution>
|
159
|
+
<contribution order-number='AB0000000'>
|
160
|
+
<source>
|
161
|
+
<firstname>Susan</firstname>
|
162
|
+
<lastname>Smit</lastname>
|
163
|
+
<addr1>6 Expressway, #125</addr1>
|
164
|
+
<addr2/>
|
165
|
+
<city>San Jose</city>
|
166
|
+
<state>CA</state>
|
167
|
+
<zip>95120</zip>
|
168
|
+
<country>United States</country>
|
169
|
+
<employer>Law Office</employer>
|
170
|
+
<occupation>Attorney</occupation>
|
171
|
+
<empaddr1/>
|
172
|
+
<empaddr2/>
|
173
|
+
<empcity/>
|
174
|
+
<empstate/>
|
175
|
+
<empzip/>
|
176
|
+
<empcountry/>
|
177
|
+
<email-preferred>false</email-preferred>
|
178
|
+
<phone></phone>
|
179
|
+
<email>example@example.com</email>
|
180
|
+
</source>
|
181
|
+
<recurringtimes>1</recurringtimes>
|
182
|
+
<refcode/>
|
183
|
+
<referrer></referrer>
|
184
|
+
<successuri></successuri>
|
185
|
+
<lineitems>
|
186
|
+
<lineitem effective-at='2012-01-09T18:12:07-05:00'>
|
187
|
+
<amount>500.00</amount>
|
188
|
+
<sequence>1</sequence>
|
189
|
+
<entity id='00000'>
|
190
|
+
<legalname>Test Campaign</legalname>
|
191
|
+
<displayname>Test Campaign</displayname>
|
192
|
+
</entity>
|
193
|
+
</lineitem>
|
194
|
+
</lineitems>
|
195
|
+
</contribution>
|
196
|
+
</contributions>"
|
197
|
+
end
|
198
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
require "codeclimate-test-reporter"
|
2
|
+
CodeClimate::TestReporter.start
|
3
|
+
require "active_support/core_ext/time/calculations"
|
4
|
+
require "pry"
|
5
|
+
require "act_blue_reporter"
|
6
|
+
require "spec_data"
|
7
|
+
require "webmock/rspec"
|
8
|
+
WebMock.disable_net_connect!(allow_localhost: true, allow: "codeclimate.com")
|
9
|
+
|
10
|
+
RSpec.configure do |config|
|
11
|
+
#include the custom data file
|
12
|
+
config.include SpecData
|
13
|
+
|
14
|
+
# stub out HTTP requests
|
15
|
+
config.before(:each) do
|
16
|
+
|
17
|
+
# successful entities request
|
18
|
+
stub_request(:get,
|
19
|
+
"https://secure.actblue.com/api/2009-08/entities/").
|
20
|
+
with(headers: { "Accept" => "application/xml" }).
|
21
|
+
to_return(status: 200,
|
22
|
+
body: "#{SpecData.act_blue_entity_response_xml}",
|
23
|
+
headers: {
|
24
|
+
"Date" => "Sun, 24 Aug 2014 20:02:46 GMT",
|
25
|
+
"Server" => "Apache",
|
26
|
+
"Content-Type" => "application/xml; charset=utf-8",
|
27
|
+
"Status" => "200 OK"
|
28
|
+
}
|
29
|
+
)
|
30
|
+
|
31
|
+
# failing entities request
|
32
|
+
stub_request(:get,
|
33
|
+
"https://secure.actblue.com/api/2009-08/entities/0").
|
34
|
+
with(headers: { "Accept" => "application/xml" }).
|
35
|
+
to_return(status: 404,
|
36
|
+
body: "",
|
37
|
+
headers: {
|
38
|
+
"Date" => "Sun, 24 Aug 2014 20:02:46 GMT",
|
39
|
+
"Server" => "Apache",
|
40
|
+
"Content-Type" => "application/xml; charset=utf-8",
|
41
|
+
"Status" => "404 Not Found"
|
42
|
+
}
|
43
|
+
)
|
44
|
+
|
45
|
+
# all contributions request
|
46
|
+
stub_request(:get,
|
47
|
+
"https://secure.actblue.com/api/2009-08/contributions?destination=").
|
48
|
+
with(headers: {'Accept'=>'application/xml'}).
|
49
|
+
to_return(status: 200,
|
50
|
+
body: "#{SpecData.act_blue_contributions_response_xml}",
|
51
|
+
headers: {
|
52
|
+
"Date" => "Sun, 24 Aug 2014 20:02:46 GMT",
|
53
|
+
"Server" => "Apache",
|
54
|
+
"Content-Type" => "application/xml; charset=utf-8",
|
55
|
+
"Status" => "200 OK"
|
56
|
+
}
|
57
|
+
)
|
58
|
+
|
59
|
+
# contributions in time range requests
|
60
|
+
stub_request(:get,
|
61
|
+
/https:\/\/secure.actblue.com\/api\/2009-08\/contributions\?destination=&payment_timestamp=.*/).
|
62
|
+
with(headers: {'Accept'=>'application/xml'}).
|
63
|
+
to_return(status: 200,
|
64
|
+
body: "#{SpecData.act_blue_contributions_response_xml}",
|
65
|
+
headers: {
|
66
|
+
"Date" => "Sun, 24 Aug 2014 20:02:46 GMT",
|
67
|
+
"Server" => "Apache",
|
68
|
+
"Content-Type" => "application/xml; charset=utf-8",
|
69
|
+
"Status" => "200 OK"
|
70
|
+
}
|
71
|
+
)
|
72
|
+
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|
metadata
ADDED
@@ -0,0 +1,212 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: act_blue_reporter
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Brad Johnson
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-09-20 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.6'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.6'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.1'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.1'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pry
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.10'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.10'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: pry-remote
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0.1'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0.1'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: pry-nav
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0.2'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0.2'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: codeclimate-test-reporter
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0.4'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0.4'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: webmock
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '1.18'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '1.18'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: httparty
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0.13'
|
132
|
+
type: :runtime
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0.13'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: activesupport
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '4.0'
|
146
|
+
type: :runtime
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '4.0'
|
153
|
+
description: 'A Ruby gem to facilitate gathering contribution information
|
154
|
+
from multiple ActBlue campaigns. '
|
155
|
+
email:
|
156
|
+
- cdale77@gmail.com
|
157
|
+
executables: []
|
158
|
+
extensions: []
|
159
|
+
extra_rdoc_files: []
|
160
|
+
files:
|
161
|
+
- ".gitignore"
|
162
|
+
- ".ruby-version"
|
163
|
+
- ".travis.yml"
|
164
|
+
- Gemfile
|
165
|
+
- Guardfile
|
166
|
+
- LICENSE.txt
|
167
|
+
- README.md
|
168
|
+
- Rakefile
|
169
|
+
- act_blue_reporter.gemspec
|
170
|
+
- lib/act_blue_reporter.rb
|
171
|
+
- lib/act_blue_reporter/base.rb
|
172
|
+
- lib/act_blue_reporter/campaign.rb
|
173
|
+
- lib/act_blue_reporter/connect.rb
|
174
|
+
- lib/act_blue_reporter/contribution_report.rb
|
175
|
+
- lib/act_blue_reporter/exceptions.rb
|
176
|
+
- lib/act_blue_reporter/version.rb
|
177
|
+
- spec/campaign_spec.rb
|
178
|
+
- spec/connect_spec.rb
|
179
|
+
- spec/contribution_report_spec.rb
|
180
|
+
- spec/spec_data.rb
|
181
|
+
- spec/spec_helper.rb
|
182
|
+
homepage: https://github.com/cdale77/act_blue_reporter
|
183
|
+
licenses:
|
184
|
+
- MIT
|
185
|
+
metadata: {}
|
186
|
+
post_install_message:
|
187
|
+
rdoc_options: []
|
188
|
+
require_paths:
|
189
|
+
- lib
|
190
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
191
|
+
requirements:
|
192
|
+
- - ">="
|
193
|
+
- !ruby/object:Gem::Version
|
194
|
+
version: '0'
|
195
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
196
|
+
requirements:
|
197
|
+
- - ">="
|
198
|
+
- !ruby/object:Gem::Version
|
199
|
+
version: '0'
|
200
|
+
requirements: []
|
201
|
+
rubyforge_project:
|
202
|
+
rubygems_version: 2.2.2
|
203
|
+
signing_key:
|
204
|
+
specification_version: 4
|
205
|
+
summary: A Ruby
|
206
|
+
test_files:
|
207
|
+
- spec/campaign_spec.rb
|
208
|
+
- spec/connect_spec.rb
|
209
|
+
- spec/contribution_report_spec.rb
|
210
|
+
- spec/spec_data.rb
|
211
|
+
- spec/spec_helper.rb
|
212
|
+
has_rdoc:
|