salsa_labs 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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 789c61d06d857f8f1de240ce34828659bc89f63f
4
+ data.tar.gz: 51a6cf8d8845b2105ca3afaaa5dcab4bf37b8856
5
+ SHA512:
6
+ metadata.gz: 7f4b97d640ef36363b0a47054e2b0e05beab55f345300d59ac92983521531312f00154a117fcc4942cc1e38518319e57fa98826c3ddd8a756cf8734290dbcc30
7
+ data.tar.gz: ea1f1ea916fef505b78ee05d846109e7df28a76ce62e9a10685566dec3b2df4276402f295c2bf98191524027a4dc1ab4ec2d688abac9d0584200bf649cddcf77
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in bateman.gemspec
4
+ gemspec
5
+
data/Gemfile.lock ADDED
@@ -0,0 +1,58 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ salsa_labs (0.0.1)
5
+ faraday
6
+ httparty
7
+ nokogiri
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ addressable (2.3.5)
13
+ crack (0.4.1)
14
+ safe_yaml (~> 0.9.0)
15
+ diff-lcs (1.2.5)
16
+ docile (1.1.1)
17
+ fakeweb (1.3.0)
18
+ faraday (0.8.8)
19
+ multipart-post (~> 1.2.0)
20
+ httparty (0.12.0)
21
+ json (~> 1.8)
22
+ multi_xml (>= 0.5.2)
23
+ json (1.8.1)
24
+ mini_portile (0.5.2)
25
+ multi_json (1.8.2)
26
+ multi_xml (0.5.5)
27
+ multipart-post (1.2.0)
28
+ nokogiri (1.6.1)
29
+ mini_portile (~> 0.5.0)
30
+ rspec (2.14.1)
31
+ rspec-core (~> 2.14.0)
32
+ rspec-expectations (~> 2.14.0)
33
+ rspec-mocks (~> 2.14.0)
34
+ rspec-core (2.14.7)
35
+ rspec-expectations (2.14.4)
36
+ diff-lcs (>= 1.1.3, < 2.0)
37
+ rspec-mocks (2.14.4)
38
+ safe_yaml (0.9.7)
39
+ simplecov (0.8.2)
40
+ docile (~> 1.1.0)
41
+ multi_json
42
+ simplecov-html (~> 0.8.0)
43
+ simplecov-html (0.8.0)
44
+ vcr (2.8.0)
45
+ webmock (1.16.1)
46
+ addressable (>= 2.2.7)
47
+ crack (>= 0.3.2)
48
+
49
+ PLATFORMS
50
+ ruby
51
+
52
+ DEPENDENCIES
53
+ fakeweb
54
+ rspec
55
+ salsa_labs!
56
+ simplecov
57
+ vcr
58
+ webmock
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Velocity
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,84 @@
1
+ # SalsaLabs bindings for Ruby
2
+
3
+ [![Gem
4
+ Version](https://badge.fury.io/rb/salsa_labs.png)](http://badge.fury.io/rb/salsa_labs)
5
+ [![Build Status](https://travis-ci.org/fivetooldev/salsa_labs.png?branch=master)](https://travis-ci.org/fivetooldev/salsa_labs)
6
+ [![Dependency Status](https://gemnasium.com/fivetooldev/salsa_labs.png)](https://gemnasium.com/fivetooldev/salsa_labs)
7
+ [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/fivetooldev/salsa_labs)
8
+
9
+ ``salsa_labs`` can fetch data from the [Salsa Labs](http://salsalabs.com) API.
10
+
11
+ ## Installation
12
+
13
+ Add this line to your application's Gemfile:
14
+
15
+ gem 'salsa_labs'
16
+
17
+ And then execute:
18
+
19
+ $ bundle
20
+
21
+ Or install it yourself as:
22
+
23
+ $ gem install salsa_labs
24
+
25
+ ## Usage
26
+
27
+ By default, you can store your API credentials as the environment variables ``SALSA_LABS_API_EMAIL`` and ``SALSA_LABS_API_PASSWORD`` to avoid the need to re-enter your password multiple times. Otherwise you will need to pass your credentials into the ``SalsaLabs::ApiClient`` or appropriate fetching method as you call it.
28
+
29
+ ``SalsaLabs::ApiClient`` is a general-purpose object for performing GET requests from the Salsa API.
30
+
31
+ ```ruby
32
+ # Create a client
33
+ client = SalsaLabs::ApiClient.new({email: 'barry@example.com', password: 'myPassword'})
34
+
35
+ # Perform arbitrary requests from Salsa API. If not already authenticated, client will do so automatically.
36
+ client.fetch('getObjects.sjs', {object: 'Supporter'})
37
+ # => Returns XML output of all supporters returned by API.
38
+
39
+ # Pass filter criteria to #fetch to retrieve a more focused result set.
40
+ # Filtering can be necessary if your result set exceeds allowed API limits.
41
+ # This query pulls all supporters with an address in Washington, D.C.
42
+ client.fetch('getObjects.sjs', {object: 'Supporter', State: 'DC'})
43
+ ```
44
+
45
+ You can get a list of API calls and information about Salsa database objects here:
46
+ [https://help.salsalabs.com/entries/23537918-Getting-data-from-Salsa](https://help.salsalabs.com/entries/23537918-Getting-data-from-Salsa)
47
+
48
+ Currently specific functionality exists to work with Action campaigns, but more objects will be added later.
49
+
50
+ ```ruby
51
+ # Fetch all actions from Salsa. First argument is filter criteria, second argument is credentials if you are not storing them as environment variables.
52
+ actions = SalsaLabs::Action.fetch({}, {})
53
+ # => Array of SalsaLabs::Action objects.
54
+
55
+ # Examine the Action.
56
+ actions.first.attributes
57
+ # => {'title' => 'My Action Title', 'organization_key' => '90210', action_key => '1234'}
58
+ ```
59
+
60
+ ``SalsaLabs::Action#attributes`` returns a hash corresponding to all the attributes returned by the API, so it should accommodate custom fields and/or new fields added later by SalsaLabs. All attribute names are downcased.
61
+
62
+ ## Dependencies
63
+
64
+ Ruby 1.9 is required.
65
+
66
+ ## Credits
67
+
68
+ The ``salsa_labs`` gem was created and is maintained by [Allison Sheren](http://github.com/asheren) and [Geoff Harcourt](http://github.com/geoffharcourt).
69
+
70
+ Development is generously sponsored by [Velocity](http://wearevelocity.com), in support of their work with progressive organizations.
71
+
72
+ ## Contributing
73
+
74
+ 1. Fork it
75
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
76
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
77
+ 4. Push to the branch (`git push origin my-new-feature`)
78
+ 5. Create new Pull Request
79
+
80
+ ## License
81
+
82
+ The ``salsa_labs`` gem is Copyright 2013-2014 Velocity. It is free software, and
83
+ may be redistributed under the terms of the MIT license, specified in the
84
+ LICENSE file.
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,85 @@
1
+ module SalsaLabs
2
+ ##
3
+ # Used to request information from Salsa Labs. Handles cookie-based
4
+ # authentication, and raises an exception when the API returns an error.
5
+ ##
6
+ class ApiClient
7
+
8
+ attr_reader :authentication_cookie
9
+
10
+ def initialize(credentials = {})
11
+ @email = credentials[:email] || ENV['SALSA_LABS_API_EMAIL']
12
+ @password = credentials[:password] || ENV['SALSA_LABS_API_PASSWORD']
13
+
14
+ @authenticated = false
15
+ end
16
+
17
+ def authenticate
18
+ return true if authenticated?
19
+
20
+ response = authenticate!
21
+
22
+ @authentication_cookie = response.env[:response_headers]["set-cookie"]
23
+ @authenticated = Nokogiri::XML(response.body).css('error').empty?
24
+ end
25
+
26
+ def authenticated?
27
+ @authenticated
28
+ end
29
+
30
+ def fetch(endpoint, params)
31
+ authenticate unless authenticated?
32
+
33
+ perform_get_request(endpoint, params).body
34
+ end
35
+
36
+ private
37
+
38
+ attr_reader :authenticated,
39
+ :email,
40
+ :password
41
+
42
+ def authenticate!
43
+ perform_get_request(
44
+ '/api/authenticate.sjs',
45
+ authentication_parameters
46
+ )
47
+ end
48
+
49
+ def authentication_parameters
50
+ {email: email, password: password}
51
+ end
52
+
53
+ def connection
54
+ @connection ||= Faraday.
55
+ new(url: 'https://hq-salsa.wiredforchange.com') do |faraday|
56
+
57
+ faraday.use Faraday::Request::UrlEncoded
58
+ faraday.adapter Faraday.default_adapter
59
+ end
60
+ end
61
+
62
+ def perform_get_request(endpoint, params)
63
+ response = connection.get do |request|
64
+ request.headers['cookie'] = authentication_cookie.to_s
65
+ request.url(endpoint, params)
66
+ end
67
+
68
+ raise_if_error!(response)
69
+
70
+ response
71
+ end
72
+
73
+ def raise_if_error!(response)
74
+ # Raise SalsaLabs::Error if response.body contains error (need to do this
75
+ # because API always gives 200 but then gives an error in the XML).
76
+ errors = Nokogiri::XML(response.body).css('error')
77
+
78
+ if errors.any?
79
+ raise SalsaLabs::Error.new(response),
80
+ "There is an error: #{errors.first.text}"
81
+ end
82
+ end
83
+ end
84
+
85
+ end
@@ -0,0 +1,35 @@
1
+ module SalsaLabs
2
+ ##
3
+ # Action represents a single instance of an advocacy campaign ("Action") in
4
+ # the Salsa Labs / DemocracyInAction CRM.
5
+ ##
6
+ class Action < SalsaObject
7
+
8
+ attr_reader :attributes
9
+
10
+ def initialize(attributes)
11
+ @attributes = attributes
12
+ end
13
+
14
+ def action_key
15
+ (attributes['action_key'] || 0).to_i
16
+ end
17
+
18
+ def description
19
+ attributes['description']
20
+ end
21
+
22
+ def reference_name
23
+ attributes['reference_name']
24
+ end
25
+
26
+ def title
27
+ attributes['title']
28
+ end
29
+
30
+ def self.fetch(credentials = {})
31
+ ActionsFetcher.new(credentials).fetch
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,61 @@
1
+ module SalsaLabs
2
+ ##
3
+ # Service object to pull back a collection of actions from the Salsa Labs API.
4
+ ##
5
+ class ActionsFetcher
6
+
7
+ def initialize(filter_parameters = {}, credentials = {})
8
+ @filter_parameters = filter_parameters
9
+ @client = SalsaLabs::ApiClient.new(credentials)
10
+ end
11
+
12
+ def fetch
13
+ item_nodes.map do |node|
14
+ SalsaLabs::Action.new(SalsaLabsApiObjectNode.new(node).attributes)
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ attr_reader :client, :filter_parameters
21
+
22
+ def api_call
23
+ client.fetch('/api/getObjects.sjs', api_parameters)
24
+ end
25
+
26
+ def api_parameters
27
+ filter_parameters.merge(object: 'Action')
28
+ end
29
+
30
+ def item_nodes
31
+ Nokogiri::XML(api_call).css('item')
32
+ end
33
+
34
+ ##
35
+ # Object used to translate API's XML node into a hash of attributes for
36
+ # SalsaLabs::Action creation.
37
+ ##
38
+ class SalsaLabsApiObjectNode
39
+
40
+ def initialize(xml_element)
41
+ @node = xml_element
42
+ end
43
+
44
+ def attributes
45
+ children.inject({}) do |memo, attribute|
46
+ memo[attribute.name.downcase] = attribute.text
47
+ attribute
48
+ end
49
+ end
50
+
51
+ private
52
+
53
+ attr_reader :node
54
+
55
+ def children
56
+ node.children
57
+ end
58
+
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,19 @@
1
+ module SalsaLabs
2
+ ##
3
+ # Base class used for subclasses that can be represented by Salsa Labs
4
+ # concepts that can be returned by getObject or getObjects.
5
+ ##
6
+ class SalsaObject
7
+
8
+ attr_reader :attributes
9
+
10
+ def initialize(params)
11
+ @attributes = params
12
+ end
13
+
14
+ def organization_key
15
+ (attributes['organization_key'] || 0).to_i
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,3 @@
1
+ module SalsaLabs
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,30 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'salsa_labs/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "salsa_labs"
8
+ gem.version = SalsaLabs::VERSION
9
+ gem.authors = ['Geoff Harcourt', 'Allison Sheren']
10
+ gem.email = ['asheren@gmail.com']
11
+ gem.description = %q{A Ruby binding for the Salsa Labs (http://salsalabs.com) API.}
12
+ gem.summary = %q{Salsa Labs' API contains information about supporters, donations, and actions. This gem faciliates pulling that information into a Ruby application.}
13
+ gem.homepage = "http://github.com/geoffharcourt/ruby-salsa_labs"
14
+ gem.files = `git ls-files`.split($/)
15
+ gem.test_files = gem.files.grep(%r{^(spec)/})
16
+ gem.require_paths = ['lib']
17
+ gem.licenses = ['LICENSE']
18
+
19
+ gem.add_runtime_dependency 'dotenv'
20
+ gem.add_runtime_dependency 'faraday'
21
+ gem.add_runtime_dependency 'httparty'
22
+ gem.add_runtime_dependency 'nokogiri'
23
+
24
+ gem.add_development_dependency 'fakeweb'
25
+ gem.add_development_dependency 'rspec'
26
+ gem.add_development_dependency 'simplecov'
27
+ gem.add_development_dependency 'vcr'
28
+ gem.add_development_dependency 'webmock'
29
+
30
+ end
data/salsa_labs.rb ADDED
@@ -0,0 +1,18 @@
1
+ require 'faraday'
2
+ require 'nokogiri'
3
+
4
+ require 'salsa_labs/version'
5
+ require 'salsa_labs/api_client'
6
+ require 'salsa_labs/salsa_object'
7
+ require 'salsa_labs/action'
8
+ require 'salsa_labs/actions_fetcher'
9
+
10
+ module SalsaLabs
11
+
12
+ ##
13
+ # Exception class for API-related errors.
14
+ ##
15
+ class Error < StandardError
16
+ end
17
+
18
+ end
@@ -0,0 +1,50 @@
1
+ <?xml version="1.0"?>
2
+ <data organization_KEY="6120">
3
+ <Action>
4
+ <item>
5
+ <action_KEY>6656</action_KEY>
6
+ <organization_KEY>6120</organization_KEY>
7
+ <chapter_KEY/>
8
+ <Last_Modified>Tue Dec 17 2013 11:08:58 GMT-0500 (EST)</Last_Modified>
9
+ <Date_Created>Wed Sep 26 2012 14:30:02 GMT-0400 (EDT)</Date_Created>
10
+ <Reference_Name>My TItle</Reference_Name>
11
+ <Title>My Action Title</Title>
12
+ <Description>&lt;p&gt;&amp;#160;&lt;/p&gt;</Description>
13
+ <Allow_Comments_BOOLVALUE>false</Allow_Comments_BOOLVALUE>
14
+ <Allow_Comments>false</Allow_Comments>
15
+ <Comment_Question/>
16
+ <Max_Number_Of_Emails/>
17
+ <Max_Number_Of_Faxes/>
18
+ <Signatures/>
19
+ <Signature_Goal/>
20
+ <Deadline/>
21
+ <Signature_Minimum_for_Display/>
22
+ <Allow_Anonymous_BOOLVALUE>false</Allow_Anonymous_BOOLVALUE>
23
+ <Allow_Anonymous>false</Allow_Anonymous>
24
+ <Footer>&lt;p&gt;&amp;#160;&lt;/p&gt;</Footer>
25
+ <Request>First_Name,Last_Name,Street,Street_2,City,State,Zip,Email</Request>
26
+ <Required>First_Name,Last_Name,Street,City,State,Zip,Email</Required>
27
+ <Thank_You_Text/>
28
+ <redirect_path/>
29
+ <alternate_action_path/>
30
+ <email_trigger_KEYS/>
31
+ <add_to_groups_KEYS/>
32
+ <optionally_add_to_groups_KEYS/>
33
+ <Restriction_Type/>
34
+ <Restricted_Regions/>
35
+ <Restricted_Districts/>
36
+ <Restricted_Text/>
37
+ <No_Target_Text/>
38
+ <template_KEY/>
39
+ <Style>Targeted</Style>
40
+ <style_path/>
41
+ <Status/>
42
+ <linkRequest/>
43
+ <linkRequired/>
44
+ <key>6656</key>
45
+ <object>action</object>
46
+ </item>
47
+ <count>1</count>
48
+ </Action>
49
+ </data>
50
+
@@ -0,0 +1,67 @@
1
+ require "spec_helper"
2
+
3
+ describe SalsaLabs::Action do
4
+
5
+ let(:attributes) do
6
+ {
7
+ 'action_key' => '1234',
8
+ 'description' => 'Lengthy Description',
9
+ 'organization_key' => '90210',
10
+ 'reference_name' => 'A Good Reference',
11
+ 'title' => 'A Distinguished Title'
12
+ }
13
+ end
14
+
15
+ let(:action) { SalsaLabs::Action.new(attributes) }
16
+
17
+ describe "#action_key" do
18
+ it "returns the action_key attribute as an integer" do
19
+ expect(action.action_key).to eq(1234)
20
+ end
21
+ end
22
+
23
+ describe "#attributes" do
24
+ it "returns the attributes hash passed in to initialize" do
25
+ expect(action.attributes).to eq(attributes)
26
+ end
27
+ end
28
+
29
+ describe "#description" do
30
+ it "returns the description attribute" do
31
+ expect(action.description).to eq('Lengthy Description')
32
+ end
33
+ end
34
+
35
+ describe "#organization_key" do
36
+ it "returns the organization_key attribute as an integer" do
37
+ expect(action.organization_key).to eq(90210)
38
+ end
39
+ end
40
+
41
+ describe "#reference_name" do
42
+ it "returns the reference_name attribute" do
43
+ expect(action.reference_name).to eq('A Good Reference')
44
+ end
45
+ end
46
+
47
+ describe "#title" do
48
+ it "returns the title as an attribute" do
49
+ expect(action.title).to eq('A Distinguished Title')
50
+ end
51
+ end
52
+
53
+ describe ".fetch" do
54
+ let(:actions_fetcher) { double('ActionsFetcher', fetch: []) }
55
+
56
+ before(:each) do
57
+ SalsaLabs::ActionsFetcher.stub(new: actions_fetcher)
58
+ end
59
+
60
+ it "calls .fetch on an SalsaLabs::ActionsFetcher object" do
61
+ SalsaLabs::Action.fetch
62
+
63
+ expect(actions_fetcher).to have_received(:fetch)
64
+ end
65
+ end
66
+
67
+ end
@@ -0,0 +1,32 @@
1
+ require "spec_helper"
2
+
3
+ describe SalsaLabs::ActionsFetcher do
4
+
5
+ let(:client) do
6
+ double(
7
+ 'API client',
8
+ fetch: File.read('spec/fixtures/getObjects.sjs_action.xml')
9
+ )
10
+ end
11
+
12
+ describe "#fetch" do
13
+ before(:each) do
14
+ allow(SalsaLabs::ApiClient).to receive(:new) { client }
15
+ end
16
+
17
+ it "calls the getObjects API endpoint" do
18
+ SalsaLabs::ActionsFetcher.new.fetch
19
+
20
+ expect(client).to have_received(:fetch).
21
+ with('/api/getObjects.sjs', {object: 'Action'})
22
+ end
23
+
24
+ it "returns an array of SalsaLabs::Action objects" do
25
+ results = SalsaLabs::ActionsFetcher.new.fetch
26
+
27
+ expect(results).to be_a(Array)
28
+ expect(results.first).to be_a(SalsaLabs::Action)
29
+ end
30
+ end
31
+
32
+ end
@@ -0,0 +1,79 @@
1
+ require 'spec_helper'
2
+ require 'vcr'
3
+
4
+ describe SalsaLabs::ApiClient do
5
+
6
+ let(:api_client) do
7
+ SalsaLabs::ApiClient.new({
8
+ email: 'allison@example.com', password: 'password'
9
+ })
10
+ end
11
+
12
+ describe "#authenticate" do
13
+ it "stores the cookie from Salsa Labs" do
14
+ VCR.use_cassette 'successful_authentication',
15
+ match_requests_on: [:path] do
16
+
17
+ api_client.authenticate
18
+
19
+ expect(api_client.authentication_cookie).to eq(
20
+ 'JSESSIONID=67EBA60BFE7BCF73E2BA0B8E6F9592D0-n2; Path=/; Secure; '\
21
+ 'HttpOnly, hqtab_2=""; Expires=Thu, 01-Jan-1970 00:00:10 GMT, '\
22
+ 'READONLY_Short_Name=""; Expires=Thu, 01-Jan-1970 00:00:10 GMT, '\
23
+ 'SRV=vweb213; path=/'
24
+ )
25
+ end
26
+ end
27
+
28
+ context "with proper credentials" do
29
+ it "sets authenticated to be true" do
30
+ VCR.use_cassette 'successful_authentication',
31
+ match_requests_on: [:path] do
32
+
33
+ api_client.authenticate
34
+
35
+ expect(api_client.authenticated?).to be_true
36
+ end
37
+ end
38
+
39
+ end
40
+
41
+ context "with improper credentials" do
42
+ it "raises an exception" do
43
+ VCR.use_cassette 'unsuccessful_authentication',
44
+ match_requests_on: [:path] do
45
+
46
+ expect{
47
+ api_client.authenticate
48
+ }.to raise_error(SalsaLabs::Error)
49
+ end
50
+ end
51
+ end
52
+ end
53
+
54
+ describe "#authenticated?" do
55
+ it "returns the value of the instance variable @authenticated" do
56
+ api_client.instance_variable_set(:@authenticated, 123)
57
+
58
+ expect(api_client.authenticated?).to eq(123)
59
+ end
60
+ end
61
+
62
+ describe "#fetch" do
63
+ it "returns the body of the response from Salsa Labs for that API call" do
64
+ VCR.use_cassette 'get_objects/action',
65
+ match_requests_on: [:path] do
66
+
67
+ data = api_client.fetch('/api/getObjects.sjs', object: 'Action')
68
+
69
+ expect(data.gsub(/\n|\s{2,}/, "")).
70
+ to eq(salsa_get_objects_for_action_xml_response)
71
+ end
72
+ end
73
+ end
74
+
75
+ def salsa_get_objects_for_action_xml_response
76
+ File.read('spec/fixtures/getObjects.sjs_action.xml').gsub(/\n|\s{2,}/, '')
77
+ end
78
+
79
+ end
@@ -0,0 +1,26 @@
1
+ require "spec_helper"
2
+
3
+ describe SalsaLabs::SalsaObject do
4
+
5
+ let(:attributes) do
6
+ {
7
+ "description" => "A depiction of a description",
8
+ "organization_key" => "456"
9
+ }
10
+ end
11
+
12
+ let(:salsa_object) { SalsaLabs::SalsaObject.new(attributes) }
13
+
14
+ describe "#attributes" do
15
+ it "returns the hash used to constuct the object" do
16
+ expect(salsa_object.attributes).to eq(attributes)
17
+ end
18
+ end
19
+
20
+ describe "#organization_key" do
21
+ it "returns the organization_key attribute as an integer" do
22
+ expect(salsa_object.organization_key).to eq(456)
23
+ end
24
+ end
25
+
26
+ end
@@ -0,0 +1,20 @@
1
+ require 'simplecov'
2
+ SimpleCov.start
3
+
4
+ require 'salsa_labs'
5
+
6
+ require 'rspec/autorun'
7
+ require 'vcr'
8
+ require 'webmock'
9
+
10
+ WebMock.disable_net_connect!
11
+
12
+ RSpec.configure do |config|
13
+ config.treat_symbols_as_metadata_keys_with_true_values = true
14
+ end
15
+
16
+ VCR.configure do |c|
17
+ c.cassette_library_dir = 'spec/vcr_cassettes'
18
+ c.hook_into :faraday
19
+ c.hook_into :webmock
20
+ end
@@ -0,0 +1,45 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://hq-salsa.wiredforchange.com/api/authenticate.sjs?email=allison@example.com&password=password
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ User-Agent:
11
+ - Faraday v0.8.8
12
+ cookie:
13
+ - ''
14
+ response:
15
+ status:
16
+ code: 200
17
+ message:
18
+ headers:
19
+ server:
20
+ - nginx/1.0.0
21
+ date:
22
+ - Sat, 28 Dec 2013 02:55:27 GMT
23
+ content-type:
24
+ - text/xml;charset=UTF-8
25
+ transfer-encoding:
26
+ - chunked
27
+ connection:
28
+ - keep-alive
29
+ keep-alive:
30
+ - timeout=20
31
+ set-cookie:
32
+ - JSESSIONID=67EBA60BFE7BCF73E2BA0B8E6F9592D0-n2; Path=/; Secure; HttpOnly,
33
+ hqtab_2=""; Expires=Thu, 01-Jan-1970 00:00:10 GMT, READONLY_Short_Name="";
34
+ Expires=Thu, 01-Jan-1970 00:00:10 GMT, SRV=vweb213; path=/
35
+ requesturi:
36
+ - "/api/authenticate.sjs?email=allison@example.com&password=password"
37
+ cache-control:
38
+ - private
39
+ body:
40
+ encoding: UTF-8
41
+ string: "<?xml version=\"1.0\"?>\n\t\t\t<data organization_KEY=\"6120\">\n\t\t\t<message>Successful
42
+ Login</message>\n\t\t\t</data>"
43
+ http_version:
44
+ recorded_at: Sat, 28 Dec 2013 02:55:27 GMT
45
+ recorded_with: VCR 2.8.0
@@ -0,0 +1,45 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://hq-salsa.wiredforchange.com/api/authenticate.sjs?email=allison%40example.com&password=password
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ User-Agent:
11
+ - Faraday v0.8.8
12
+ cookie:
13
+ - ''
14
+ response:
15
+ status:
16
+ code: 200
17
+ message:
18
+ headers:
19
+ server:
20
+ - nginx/1.0.0
21
+ date:
22
+ - Sat, 28 Dec 2013 02:56:00 GMT
23
+ content-type:
24
+ - text/xml;charset=UTF-8
25
+ transfer-encoding:
26
+ - chunked
27
+ connection:
28
+ - keep-alive
29
+ keep-alive:
30
+ - timeout=20
31
+ set-cookie:
32
+ - JSESSIONID=646F52AB13B1FCD5AA7B94A935B6E479-n3; Path=/; Secure; HttpOnly,
33
+ hqtab_2=""; Expires=Thu, 01-Jan-1970 00:00:10 GMT, READONLY_Short_Name="";
34
+ Expires=Thu, 01-Jan-1970 00:00:10 GMT, SRV=vweb208; path=/
35
+ requesturi:
36
+ - "/api/authenticate.sjs?email=allison%40example.com&password=password"
37
+ cache-control:
38
+ - private
39
+ body:
40
+ encoding: UTF-8
41
+ string: "<?xml version=\"1.0\"?>\n\t\t\t<data>\n\t\t\t<error>Invalid login,
42
+ please try again.</error>\n\t\t\t</data>"
43
+ http_version:
44
+ recorded_at: Sat, 28 Dec 2013 02:56:00 GMT
45
+ recorded_with: VCR 2.8.0
metadata ADDED
@@ -0,0 +1,200 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: salsa_labs
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Geoff Harcourt
8
+ - Allison Sheren
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-12-28 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: dotenv
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: '0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: faraday
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: httparty
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :runtime
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: nokogiri
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: fakeweb
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ - !ruby/object:Gem::Dependency
85
+ name: rspec
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ - !ruby/object:Gem::Dependency
99
+ name: simplecov
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ type: :development
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ - !ruby/object:Gem::Dependency
113
+ name: vcr
114
+ requirement: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ type: :development
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ - !ruby/object:Gem::Dependency
127
+ name: webmock
128
+ requirement: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - ">="
131
+ - !ruby/object:Gem::Version
132
+ version: '0'
133
+ type: :development
134
+ prerelease: false
135
+ version_requirements: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - ">="
138
+ - !ruby/object:Gem::Version
139
+ version: '0'
140
+ description: A Ruby binding for the Salsa Labs (http://salsalabs.com) API.
141
+ email:
142
+ - asheren@gmail.com
143
+ executables: []
144
+ extensions: []
145
+ extra_rdoc_files: []
146
+ files:
147
+ - Gemfile
148
+ - Gemfile.lock
149
+ - LICENSE
150
+ - README.md
151
+ - Rakefile
152
+ - lib/salsa_labs/API_Client.rb
153
+ - lib/salsa_labs/action.rb
154
+ - lib/salsa_labs/actions_fetcher.rb
155
+ - lib/salsa_labs/salsa_object.rb
156
+ - lib/salsa_labs/version.rb
157
+ - salsa_labs.gemspec
158
+ - salsa_labs.rb
159
+ - spec/fixtures/getObjects.sjs_action.xml
160
+ - spec/salsa_labs/action_spec.rb
161
+ - spec/salsa_labs/actions_fetcher_spec.rb
162
+ - spec/salsa_labs/api_client_spec.rb
163
+ - spec/salsa_labs/salsa_object_spec.rb
164
+ - spec/spec_helper.rb
165
+ - spec/vcr_cassettes/successful_authentication.yml
166
+ - spec/vcr_cassettes/unsuccessful_authentication.yml
167
+ homepage: http://github.com/geoffharcourt/ruby-salsa_labs
168
+ licenses:
169
+ - LICENSE
170
+ metadata: {}
171
+ post_install_message:
172
+ rdoc_options: []
173
+ require_paths:
174
+ - lib
175
+ required_ruby_version: !ruby/object:Gem::Requirement
176
+ requirements:
177
+ - - ">="
178
+ - !ruby/object:Gem::Version
179
+ version: '0'
180
+ required_rubygems_version: !ruby/object:Gem::Requirement
181
+ requirements:
182
+ - - ">="
183
+ - !ruby/object:Gem::Version
184
+ version: '0'
185
+ requirements: []
186
+ rubyforge_project:
187
+ rubygems_version: 2.2.0
188
+ signing_key:
189
+ specification_version: 4
190
+ summary: Salsa Labs' API contains information about supporters, donations, and actions.
191
+ This gem faciliates pulling that information into a Ruby application.
192
+ test_files:
193
+ - spec/fixtures/getObjects.sjs_action.xml
194
+ - spec/salsa_labs/action_spec.rb
195
+ - spec/salsa_labs/actions_fetcher_spec.rb
196
+ - spec/salsa_labs/api_client_spec.rb
197
+ - spec/salsa_labs/salsa_object_spec.rb
198
+ - spec/spec_helper.rb
199
+ - spec/vcr_cassettes/successful_authentication.yml
200
+ - spec/vcr_cassettes/unsuccessful_authentication.yml