ngp_van 0.1.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.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +1 -0
- data/README.md +117 -0
- data/lib/ngp_van.rb +47 -0
- data/lib/ngp_van/client.rb +41 -0
- data/lib/ngp_van/client/activist_codes.rb +15 -0
- data/lib/ngp_van/client/canvass_responses.rb +19 -0
- data/lib/ngp_van/client/codes.rb +31 -0
- data/lib/ngp_van/client/district_fields.rb +15 -0
- data/lib/ngp_van/client/event_types.rb +15 -0
- data/lib/ngp_van/client/events.rb +31 -0
- data/lib/ngp_van/client/locations.rb +27 -0
- data/lib/ngp_van/client/minivan_exports.rb +15 -0
- data/lib/ngp_van/client/notes.rb +19 -0
- data/lib/ngp_van/client/people.rb +31 -0
- data/lib/ngp_van/client/printed_lists.rb +15 -0
- data/lib/ngp_van/client/signups.rb +31 -0
- data/lib/ngp_van/client/survey_questions.rb +15 -0
- data/lib/ngp_van/client/users.rb +19 -0
- data/lib/ngp_van/configuration.rb +74 -0
- data/lib/ngp_van/connection.rb +32 -0
- data/lib/ngp_van/default.rb +41 -0
- data/lib/ngp_van/error.rb +124 -0
- data/lib/ngp_van/request.rb +39 -0
- data/lib/ngp_van/response.rb +15 -0
- data/lib/ngp_van/response/raise_error.rb +17 -0
- data/lib/ngp_van/version.rb +19 -0
- data/spec/ngp_van/client/activist_codes_spec.rb +88 -0
- data/spec/ngp_van/client/canvass_responses_spec.rb +126 -0
- data/spec/ngp_van/client/codes_spec.rb +197 -0
- data/spec/ngp_van/client/district_fields_spec.rb +79 -0
- data/spec/ngp_van/client/event_types_spec.rb +69 -0
- data/spec/ngp_van/client/events_spec.rb +205 -0
- data/spec/ngp_van/client/locations_spec.rb +172 -0
- data/spec/ngp_van/client/minivan_exports_spec.rb +82 -0
- data/spec/ngp_van/client/notes_spec.rb +107 -0
- data/spec/ngp_van/client/people_spec.rb +227 -0
- data/spec/ngp_van/client/printed_lists_spec.rb +91 -0
- data/spec/ngp_van/client/signups_spec.rb +209 -0
- data/spec/ngp_van/client/survey_questions_spec.rb +83 -0
- data/spec/ngp_van/client/users_spec.rb +122 -0
- data/spec/ngp_van/configuration_spec.rb +116 -0
- data/spec/ngp_van/request_spec.rb +137 -0
- data/spec/ngp_van_spec.rb +29 -0
- data/spec/spec_helper.rb +11 -0
- data/spec/support/fixtures/activist_code.json +10 -0
- data/spec/support/fixtures/activist_codes.json +36 -0
- data/spec/support/fixtures/canvass_response.json +25 -0
- data/spec/support/fixtures/canvass_responses_contact_types.json +10 -0
- data/spec/support/fixtures/canvass_responses_input_types.json +26 -0
- data/spec/support/fixtures/canvass_responses_result_codes.json +26 -0
- data/spec/support/fixtures/code.json +18 -0
- data/spec/support/fixtures/code_supported_entities.json +5 -0
- data/spec/support/fixtures/codes.json +55 -0
- data/spec/support/fixtures/create_code.json +16 -0
- data/spec/support/fixtures/create_event.json +62 -0
- data/spec/support/fixtures/create_event_shift.json +5 -0
- data/spec/support/fixtures/create_location.json +9 -0
- data/spec/support/fixtures/create_signup.json +32 -0
- data/spec/support/fixtures/create_user_district_field_values.json +7 -0
- data/spec/support/fixtures/district_field.json +28 -0
- data/spec/support/fixtures/district_fields.json +22 -0
- data/spec/support/fixtures/event.json +139 -0
- data/spec/support/fixtures/event_type.json +75 -0
- data/spec/support/fixtures/event_types.json +77 -0
- data/spec/support/fixtures/events.json +86 -0
- data/spec/support/fixtures/location.json +19 -0
- data/spec/support/fixtures/locations.json +25 -0
- data/spec/support/fixtures/match_candidate.json +61 -0
- data/spec/support/fixtures/match_response.json +4 -0
- data/spec/support/fixtures/minivan_export.json +66 -0
- data/spec/support/fixtures/minivan_exports.json +72 -0
- data/spec/support/fixtures/note_categories.json +17 -0
- data/spec/support/fixtures/note_category.json +8 -0
- data/spec/support/fixtures/note_category_types.json +6 -0
- data/spec/support/fixtures/person.json +61 -0
- data/spec/support/fixtures/printed_list.json +52 -0
- data/spec/support/fixtures/printed_lists.json +58 -0
- data/spec/support/fixtures/signup.json +55 -0
- data/spec/support/fixtures/signup_statuses.json +26 -0
- data/spec/support/fixtures/signups.json +112 -0
- data/spec/support/fixtures/survey_question.json +36 -0
- data/spec/support/fixtures/survey_questions.json +85 -0
- data/spec/support/fixtures/update_code.json +22 -0
- data/spec/support/fixtures/update_event.json +61 -0
- data/spec/support/fixtures/update_signup.json +35 -0
- data/spec/support/fixtures/update_user_district_field_values.json +6 -0
- data/spec/support/fixtures/user_district_field_values.json +7 -0
- data/spec/support/path_helpers.rb +9 -0
- data/spec/support/rspec.rb +51 -0
- data/spec/support/url_helpers.rb +5 -0
- data/spec/support/webmock.rb +5 -0
- metadata +269 -0
- metadata.gz.sig +0 -0
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module NgpVan
|
4
|
+
class Client
|
5
|
+
module PrintedLists
|
6
|
+
def printed_lists(params: {})
|
7
|
+
get(path: 'printedLists', params: params)
|
8
|
+
end
|
9
|
+
|
10
|
+
def printed_list(id:, params: {})
|
11
|
+
get(path: "printedLists/#{id}", params: params)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module NgpVan
|
4
|
+
class Client
|
5
|
+
module Signups
|
6
|
+
def signup_statuses(params: {})
|
7
|
+
get(path: 'signups/statuses', params: params)
|
8
|
+
end
|
9
|
+
|
10
|
+
def signup(id:, params: {})
|
11
|
+
get(path: "signups/#{id}", params: params)
|
12
|
+
end
|
13
|
+
|
14
|
+
def signups(params: {})
|
15
|
+
get(path: 'signups', params: params)
|
16
|
+
end
|
17
|
+
|
18
|
+
def create_signup(body: {})
|
19
|
+
post(path: 'signups', body: body)
|
20
|
+
end
|
21
|
+
|
22
|
+
def update_signup(id:, body: {})
|
23
|
+
put(path: "signups/#{id}", body: body)
|
24
|
+
end
|
25
|
+
|
26
|
+
def delete_signup(id:)
|
27
|
+
delete(path: "signups/#{id}")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module NgpVan
|
4
|
+
class Client
|
5
|
+
module SurveyQuestions
|
6
|
+
def survey_questions(params: {})
|
7
|
+
get(path: 'surveyQuestions', params: params)
|
8
|
+
end
|
9
|
+
|
10
|
+
def survey_question(id:, params: {})
|
11
|
+
get(path: "surveyQuestions/#{id}", params: params)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module NgpVan
|
4
|
+
class Client
|
5
|
+
module Users
|
6
|
+
def user_district_field_values(id:, params: {})
|
7
|
+
get(path: "users/#{id}/districtFieldValues", params: params)
|
8
|
+
end
|
9
|
+
|
10
|
+
def create_user_district_field_values(id:, body: {})
|
11
|
+
post(path: "users/#{id}/districtFieldValues", body: body)
|
12
|
+
end
|
13
|
+
|
14
|
+
def update_user_district_field_values(id:, body: {})
|
15
|
+
put(path: "users/#{id}/districtFieldValues", body: body)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'ngp_van/default'
|
4
|
+
require 'ngp_van/version'
|
5
|
+
|
6
|
+
module NgpVan
|
7
|
+
class Configuration
|
8
|
+
# The Application Name in the NGP VAN system. A short string that identifies
|
9
|
+
# your application (e.g., acmeCrmProduct)
|
10
|
+
#
|
11
|
+
# The `application_name` setting is used for authenticating requests.
|
12
|
+
#
|
13
|
+
# @return [String, nil]
|
14
|
+
attr_accessor :application_name
|
15
|
+
|
16
|
+
# The API Key acquired from NGP VAN. The API Key resembles the concatenation
|
17
|
+
# of a GUID, a | and a 0 or 1 (e.g.,
|
18
|
+
# bc7b6578-5619-4e8f-92ab-829208e1a511|1).
|
19
|
+
#
|
20
|
+
# The `api_key` setting is used for authenticating requests.
|
21
|
+
#
|
22
|
+
# @return [String, nil]
|
23
|
+
attr_accessor :api_key
|
24
|
+
|
25
|
+
# The API Endpoint url. Which endpoint you should use is determined by which
|
26
|
+
# VAN client with which you're working.
|
27
|
+
# @note See http://developers.ngpvan.com/van-api#van-endpoints
|
28
|
+
# @return [String]
|
29
|
+
attr_accessor :api_endpoint
|
30
|
+
|
31
|
+
# The User-Agent sent to the API endpoint. This defaults to the gem name,
|
32
|
+
# suffixed with the current version number.
|
33
|
+
# @return [String]
|
34
|
+
attr_accessor :user_agent
|
35
|
+
|
36
|
+
def initialize
|
37
|
+
setup
|
38
|
+
end
|
39
|
+
|
40
|
+
# Reset all configuration to default values.
|
41
|
+
# @return [NgpVan::Configuration]
|
42
|
+
def reset!
|
43
|
+
@application_name = NgpVan::Default.application_name
|
44
|
+
@api_key = NgpVan::Default.api_key
|
45
|
+
@api_endpoint = NgpVan::Default.api_endpoint
|
46
|
+
@user_agent = NgpVan::Default.user_agent
|
47
|
+
self
|
48
|
+
end
|
49
|
+
|
50
|
+
alias setup reset!
|
51
|
+
|
52
|
+
# Inspect the configuration object, masking private values.
|
53
|
+
# @return [String]
|
54
|
+
def inspect
|
55
|
+
inspected = super
|
56
|
+
|
57
|
+
if NgpVan.configuration.api_key
|
58
|
+
filter_value!(inspected, NgpVan.configuration.api_key)
|
59
|
+
end
|
60
|
+
|
61
|
+
if NgpVan.configuration.application_name
|
62
|
+
filter_value!(inspected, NgpVan.configuration.application_name)
|
63
|
+
end
|
64
|
+
|
65
|
+
inspected
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
def filter_value!(source, str)
|
71
|
+
source.gsub!(str, '[FILTERED]')
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'ngp_van/response/raise_error'
|
4
|
+
require 'faraday_middleware'
|
5
|
+
|
6
|
+
module NgpVan
|
7
|
+
module Connection
|
8
|
+
private
|
9
|
+
|
10
|
+
# rubocop:disable Metrics/MethodLength
|
11
|
+
def connection
|
12
|
+
options = {
|
13
|
+
url: NgpVan.configuration.api_endpoint,
|
14
|
+
headers: {
|
15
|
+
'Accept' => 'application/json; charset=utf-8',
|
16
|
+
'User-Agent' => NgpVan.configuration.user_agent
|
17
|
+
}
|
18
|
+
}
|
19
|
+
|
20
|
+
Faraday::Connection.new(options) do |connection|
|
21
|
+
connection.basic_auth(
|
22
|
+
NgpVan.configuration.application_name,
|
23
|
+
NgpVan.configuration.api_key
|
24
|
+
)
|
25
|
+
|
26
|
+
connection.request(:json)
|
27
|
+
connection.use NgpVan::Response::RaiseError
|
28
|
+
connection.adapter(Faraday.default_adapter)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'ngp_van/version'
|
4
|
+
|
5
|
+
module NgpVan
|
6
|
+
module Default
|
7
|
+
APPLICATION_NAME = nil
|
8
|
+
|
9
|
+
API_KEY = nil
|
10
|
+
|
11
|
+
API_ENDPOINT = 'https://api.securevan.com/v4/'
|
12
|
+
|
13
|
+
USER_AGENT = "NGP VAN Ruby Gem #{NgpVan::VERSION}"
|
14
|
+
|
15
|
+
class << self
|
16
|
+
# Default Application Name from {APPLICATION_NAME}
|
17
|
+
# @return [String]
|
18
|
+
def application_name
|
19
|
+
APPLICATION_NAME
|
20
|
+
end
|
21
|
+
|
22
|
+
# Default API Key from {API_KEY}
|
23
|
+
# @return [String]
|
24
|
+
def api_key
|
25
|
+
API_KEY
|
26
|
+
end
|
27
|
+
|
28
|
+
# Default API Endpoint from {API_ENDPOINT}
|
29
|
+
# @return [String]
|
30
|
+
def api_endpoint
|
31
|
+
API_ENDPOINT
|
32
|
+
end
|
33
|
+
|
34
|
+
# Default User Agent from {USER_AGENT}
|
35
|
+
# @return [String]
|
36
|
+
def user_agent
|
37
|
+
USER_AGENT
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module NgpVan
|
4
|
+
# Custom error class for rescuing from NgpVan errors.
|
5
|
+
class Error < StandardError
|
6
|
+
attr_reader :body, :response, :status
|
7
|
+
|
8
|
+
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize,
|
9
|
+
# rubocop:disable Style/CyclomaticComplexity
|
10
|
+
# Returns a NgpVan::Error subclass, depending on status and
|
11
|
+
# response message.
|
12
|
+
#
|
13
|
+
# @param [Hash] response HTTP response
|
14
|
+
# @return [NgpVan::Error]
|
15
|
+
def self.from_response(response)
|
16
|
+
status = response[:status].to_i
|
17
|
+
|
18
|
+
error_klass =
|
19
|
+
case status
|
20
|
+
when 400 then NgpVan::BadRequest
|
21
|
+
when 401 then NgpVan::Unauthorized
|
22
|
+
when 403 then NgpVan::Forbidden
|
23
|
+
when 405 then NgpVan::MethodNotAllowed
|
24
|
+
when 406 then NgpVan::NotAcceptable
|
25
|
+
when 408 then NgpVan::RequestTimeout
|
26
|
+
when 409 then NgpVan::Conflict
|
27
|
+
when 413 then NgpVan::RequestEntityTooLarge
|
28
|
+
when 415 then NgpVan::UnsupportedMediaType
|
29
|
+
when 422 then NgpVan::UnprocessableEntity
|
30
|
+
when 429 then NgpVan::TooManyRequests
|
31
|
+
when 404 then NgpVan::NotFound
|
32
|
+
when 400..499 then NgpVan::ClientError
|
33
|
+
when 500 then NgpVan::InternalServerError
|
34
|
+
when 501 then NgpVan::NotImplemented
|
35
|
+
when 502 then NgpVan::BadGateway
|
36
|
+
when 503 then NgpVan::ServiceUnavailable
|
37
|
+
when 504 then NgpVan::GatewayTimeout
|
38
|
+
when 500..599 then NgpVan::ServerError
|
39
|
+
end
|
40
|
+
|
41
|
+
error_klass.new(response) if error_klass
|
42
|
+
end
|
43
|
+
|
44
|
+
def initialize(response = nil)
|
45
|
+
@response = response
|
46
|
+
@body = ::JSON.parse(response[:body])
|
47
|
+
@status = response[:status]
|
48
|
+
|
49
|
+
super(build_error)
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def errors
|
55
|
+
body.delete('errors')
|
56
|
+
end
|
57
|
+
|
58
|
+
def build_error
|
59
|
+
return nil if response.nil?
|
60
|
+
|
61
|
+
{
|
62
|
+
status: status,
|
63
|
+
errors: errors
|
64
|
+
}
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# Errors in the 400-499 range
|
69
|
+
class ClientError < Error; end
|
70
|
+
|
71
|
+
# 400 Bad request
|
72
|
+
class BadRequest < ClientError; end
|
73
|
+
|
74
|
+
# 401 Unauthorized
|
75
|
+
class Unauthorized < ClientError; end
|
76
|
+
|
77
|
+
# 403 Forbidden
|
78
|
+
class Forbidden < ClientError; end
|
79
|
+
|
80
|
+
# 404 Not found
|
81
|
+
class NotFound < ClientError; end
|
82
|
+
|
83
|
+
# 405 Method not allowed
|
84
|
+
class MethodNotAllowed < ClientError; end
|
85
|
+
|
86
|
+
# 406 Not acceptable
|
87
|
+
class NotAcceptable < ClientError; end
|
88
|
+
|
89
|
+
# 408 Request timeout
|
90
|
+
class RequestTimeout < ClientError; end
|
91
|
+
|
92
|
+
# 409 Conflict
|
93
|
+
class Conflict < ClientError; end
|
94
|
+
|
95
|
+
# 413 Request entity too large
|
96
|
+
class RequestEntityTooLarge < ClientError; end
|
97
|
+
|
98
|
+
# 415 Unsupported media type
|
99
|
+
class UnsupportedMediaType < ClientError; end
|
100
|
+
|
101
|
+
# 422 Unprocessable entity
|
102
|
+
class UnprocessableEntity < ClientError; end
|
103
|
+
|
104
|
+
# 429 Too many requests
|
105
|
+
class TooManyRequests < ClientError; end
|
106
|
+
|
107
|
+
# Errors in the 500-599 range
|
108
|
+
class ServerError < Error; end
|
109
|
+
|
110
|
+
# 500 Internal server error
|
111
|
+
class InternalServerError < ServerError; end
|
112
|
+
|
113
|
+
# 501 Not implemented
|
114
|
+
class NotImplemented < ServerError; end
|
115
|
+
|
116
|
+
# 502 Bad gateway
|
117
|
+
class BadGateway < ServerError; end
|
118
|
+
|
119
|
+
# 503 Service unavailable
|
120
|
+
class ServiceUnavailable < ServerError; end
|
121
|
+
|
122
|
+
# 504 Gateway timeout
|
123
|
+
class GatewayTimeout < ServerError; end
|
124
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module NgpVan
|
6
|
+
module Request
|
7
|
+
# Perform an HTTP DELETE request
|
8
|
+
def delete(path:, params: {})
|
9
|
+
request(method: :delete, path: path, params: params)
|
10
|
+
end
|
11
|
+
|
12
|
+
# Perform an HTTP GET request
|
13
|
+
def get(path:, params: {})
|
14
|
+
request(method: :get, path: path, params: params)
|
15
|
+
end
|
16
|
+
|
17
|
+
# Perform an HTTP POST request
|
18
|
+
def post(path:, body: {})
|
19
|
+
request(method: :post, path: path, body: body)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Perform an HTTP PUT request
|
23
|
+
def put(path:, body: {})
|
24
|
+
request(method: :put, path: path, body: body)
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def request(method:, path:, params: {}, body: {})
|
30
|
+
response = connection.send(method) do |request|
|
31
|
+
request.path = URI.encode(path)
|
32
|
+
request.params = params
|
33
|
+
request.body = ::JSON.generate(body) unless body.empty?
|
34
|
+
end
|
35
|
+
|
36
|
+
Response.create(response.body)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module NgpVan
|
4
|
+
module Response
|
5
|
+
def self.create(body)
|
6
|
+
JSON.parse(body)
|
7
|
+
# The VAN API does not always return JSON. For example, when creating a new
|
8
|
+
# code, you post to /codes. The return is the integer ID of the newly
|
9
|
+
# created code, not a json representation of it. For cases like this, we
|
10
|
+
# will just return the body un-parsed.
|
11
|
+
rescue JSON::ParserError
|
12
|
+
body
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'ngp_van/error'
|
4
|
+
require 'faraday'
|
5
|
+
|
6
|
+
module NgpVan
|
7
|
+
module Response
|
8
|
+
class RaiseError < Faraday::Response::Middleware
|
9
|
+
private
|
10
|
+
|
11
|
+
def on_complete(response)
|
12
|
+
error = NgpVan::Error.from_response(response)
|
13
|
+
raise error if error
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module NgpVan
|
4
|
+
# Current major release.
|
5
|
+
# @return [Integer]
|
6
|
+
MAJOR = 0
|
7
|
+
|
8
|
+
# Current minor release.
|
9
|
+
# @return [Integer]
|
10
|
+
MINOR = 1
|
11
|
+
|
12
|
+
# Current patch level.
|
13
|
+
# @return [Integer]
|
14
|
+
PATCH = 1
|
15
|
+
|
16
|
+
# Full release version.
|
17
|
+
# @return [String]
|
18
|
+
VERSION = [MAJOR, MINOR, PATCH].join('.').freeze
|
19
|
+
end
|