felis 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/.travis.yml +1 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +73 -0
- data/Rakefile +4 -0
- data/felis.gemspec +29 -0
- data/lib/felis.rb +10 -0
- data/lib/felis/api.rb +89 -0
- data/lib/felis/emma_error.rb +4 -0
- data/lib/felis/version.rb +3 -0
- data/spec/cassettes/add_member.yml +37 -0
- data/spec/cassettes/delete_member.yml +36 -0
- data/spec/cassettes/get_members.yml +41 -0
- data/spec/cassettes/invalid_delete_request.yml +36 -0
- data/spec/cassettes/invalid_get_request.yml +36 -0
- data/spec/cassettes/invalid_post_request.yml +36 -0
- data/spec/cassettes/invalid_put_request.yml +37 -0
- data/spec/cassettes/retrieve_member_for_put_request.yml +41 -0
- data/spec/cassettes/update_member.yml +36 -0
- data/spec/felis/felis_spec.rb +195 -0
- data/spec/spec_helper.rb +21 -0
- metadata +193 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
language: ruby
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Dennis Monsewicz
|
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,73 @@
|
|
1
|
+
# Felis
|
2
|
+
Felis is an API wrapper for [Emma's API](http://api.myemma.com/index.html)
|
3
|
+
|
4
|
+
[](https://travis-ci.org/dennismonsewicz/felis)
|
5
|
+
|
6
|
+
## Requirements
|
7
|
+
[MyEmma](http://myemma.com/) account and API credentials (private & public key)
|
8
|
+
|
9
|
+
## Usage
|
10
|
+
|
11
|
+
## Instantiation
|
12
|
+
```ruby
|
13
|
+
require 'felis'
|
14
|
+
felis = Felis::API.new(account_id: 'ACCOUNT_ID', public_key: 'PUBLIC_KEY', private_key: 'PRIVATE_KEY')
|
15
|
+
```
|
16
|
+
|
17
|
+
You can also set environment variables and Felis will use them when you create an instance
|
18
|
+
```ruby
|
19
|
+
ENV['EMMA_ACCOUNT_ID'] = 'account_id'
|
20
|
+
ENV['EMMA_PUBLIC_KEY'] = 'public_key'
|
21
|
+
ENV['EMMA_PRIVATE_KEY'] = 'private_key'
|
22
|
+
felis = Felis::API.new
|
23
|
+
```
|
24
|
+
|
25
|
+
## GET Request
|
26
|
+
```ruby
|
27
|
+
# Returns array of members
|
28
|
+
request = felis.get '/members'
|
29
|
+
puts request.inspect
|
30
|
+
```
|
31
|
+
|
32
|
+
## POST Request
|
33
|
+
```ruby
|
34
|
+
# Will return a reference object of the newly added member
|
35
|
+
request = felis.post '/members/add', {"email" => "test@example.com", fields: {first_name: "Jack", last_name: "Jill"}}
|
36
|
+
puts request.inspect
|
37
|
+
```
|
38
|
+
|
39
|
+
## PUT Request
|
40
|
+
```ruby
|
41
|
+
# Returns true on success
|
42
|
+
request = felis.put '/members/123', { fields: { first_name: "Jane" } }
|
43
|
+
puts request.inspect
|
44
|
+
```
|
45
|
+
|
46
|
+
## DELETE Request
|
47
|
+
```ruby
|
48
|
+
# Returns true on success
|
49
|
+
request = felis.delete '/members/123'
|
50
|
+
puts request.inspect
|
51
|
+
```
|
52
|
+
|
53
|
+
## Installation
|
54
|
+
|
55
|
+
Add this line to your application's Gemfile:
|
56
|
+
|
57
|
+
gem 'felis'
|
58
|
+
|
59
|
+
And then execute:
|
60
|
+
|
61
|
+
$ bundle
|
62
|
+
|
63
|
+
Or install it yourself as:
|
64
|
+
|
65
|
+
$ gem install felis
|
66
|
+
|
67
|
+
## Contributing
|
68
|
+
|
69
|
+
1. Fork it
|
70
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
71
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
72
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
73
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/felis.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'felis/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "felis"
|
8
|
+
spec.version = Felis::VERSION
|
9
|
+
spec.authors = ["Dennis Monsewicz"]
|
10
|
+
spec.email = ["dennismonsewicz@gmail.com"]
|
11
|
+
spec.description = %q{A wrapper for Emma API}
|
12
|
+
spec.summary = %q{A wrapper for Emma API}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency "httparty"
|
22
|
+
spec.add_dependency "multi_json"
|
23
|
+
|
24
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
25
|
+
spec.add_development_dependency "rake"
|
26
|
+
spec.add_development_dependency "rspec"
|
27
|
+
spec.add_development_dependency "vcr"
|
28
|
+
spec.add_development_dependency "webmock", "< 1.16"
|
29
|
+
end
|
data/lib/felis.rb
ADDED
data/lib/felis/api.rb
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
module Felis
|
2
|
+
class API
|
3
|
+
include HTTParty
|
4
|
+
|
5
|
+
default_timeout 30
|
6
|
+
|
7
|
+
attr_accessor :account_id, :private_key, :public_key, :base_uri, :debug, :timeout
|
8
|
+
|
9
|
+
def initialize(options = {})
|
10
|
+
@base_uri = options.fetch(:base_uri, "https://api.e2ma.net")
|
11
|
+
@account_id = options.fetch(:account_id, ENV['EMMA_ACCOUNT_ID'] || nil)
|
12
|
+
@private_key = options.fetch(:private_key, ENV['EMMA_PRIVATE_KEY'] || nil)
|
13
|
+
@public_key = options.fetch(:public_key, ENV['EMMA_PUBLIC_KEY'] || nil)
|
14
|
+
@debug = options.fetch(:debug, false)
|
15
|
+
@timeout = options.fetch(:timeout, 30)
|
16
|
+
|
17
|
+
@defaults = { basic_auth: { username: @public_key, password: @private_key } }
|
18
|
+
|
19
|
+
setup_base_uri
|
20
|
+
end
|
21
|
+
|
22
|
+
# HTTP GET Request
|
23
|
+
def get(path, query = {})
|
24
|
+
request(:get, path, query)
|
25
|
+
end
|
26
|
+
|
27
|
+
# HTTP POST Request
|
28
|
+
def post(path, params = {})
|
29
|
+
request(:post, path, params)
|
30
|
+
end
|
31
|
+
|
32
|
+
# HTTP PUT Request
|
33
|
+
def put(path, params = {})
|
34
|
+
request(:put, path, params)
|
35
|
+
end
|
36
|
+
|
37
|
+
# HTTP DELETE Request
|
38
|
+
def delete(path, query = {})
|
39
|
+
request(:delete, path, query)
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def request(method, path, params = {})
|
45
|
+
self.class.debug_output($stderr) if @debug
|
46
|
+
uri = "#{self.class.base_uri}#{path}"
|
47
|
+
|
48
|
+
setup_http_body(method, params)
|
49
|
+
|
50
|
+
begin
|
51
|
+
response = self.class.send(method.to_sym, uri, @defaults)
|
52
|
+
|
53
|
+
@parsed_response = nil
|
54
|
+
|
55
|
+
if response.body
|
56
|
+
@parsed_response = MultiJson.load(response.body)
|
57
|
+
|
58
|
+
if should_raise_error?
|
59
|
+
error = EmmaError.new(@parsed_response["error"])
|
60
|
+
raise error
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
@parsed_response
|
65
|
+
rescue MultiJson::LoadError => e
|
66
|
+
error = EmmaError.new(e)
|
67
|
+
raise error
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def setup_http_body(method, params)
|
72
|
+
@defaults.reject! { |k, v| [:query, :body].include? k }
|
73
|
+
|
74
|
+
unless params.empty?
|
75
|
+
@defaults.merge!({query: params}).tap { |h| h.delete(:body) } if [:get, :delete].include? method.to_sym
|
76
|
+
@defaults.merge!({body: MultiJson.dump(params)}).tap { |h| h.delete(:query) } if [:put, :post].include? method.to_sym
|
77
|
+
end
|
78
|
+
@defaults.merge!({timeout: @timeout})
|
79
|
+
end
|
80
|
+
|
81
|
+
def setup_base_uri
|
82
|
+
self.class.base_uri "#{@base_uri}/#{@account_id}"
|
83
|
+
end
|
84
|
+
|
85
|
+
def should_raise_error?
|
86
|
+
@parsed_response.is_a?(Hash) && @parsed_response['error']
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: post
|
5
|
+
uri: https://YOUR_PUBLIC_KEY:YOUR_PRIVATE_KEY@api.e2ma.net/YOUR_ACCOUNT_ID/members/add
|
6
|
+
body:
|
7
|
+
encoding: UTF-8
|
8
|
+
string: ! '{"email":"test.me@test.com","fields":{"first_name":"Tester","last_name":"McTesterson"}}'
|
9
|
+
headers: {}
|
10
|
+
response:
|
11
|
+
status:
|
12
|
+
code: 200
|
13
|
+
message: OK
|
14
|
+
headers:
|
15
|
+
Date:
|
16
|
+
- Tue, 07 Jan 2014 20:56:51 GMT
|
17
|
+
Server:
|
18
|
+
- Apache/2.2.14 (Ubuntu)
|
19
|
+
X-Varnish:
|
20
|
+
- '1006640612'
|
21
|
+
Age:
|
22
|
+
- '0'
|
23
|
+
Connection:
|
24
|
+
- keep-alive
|
25
|
+
Via:
|
26
|
+
- 1.1 varnish
|
27
|
+
Content-Length:
|
28
|
+
- '65'
|
29
|
+
Content-Type:
|
30
|
+
- application/json; charset=utf8
|
31
|
+
body:
|
32
|
+
encoding: US-ASCII
|
33
|
+
string: ! "{\n \"status\": \"a\", \n \"added\": false, \n \"member_id\":
|
34
|
+
485383562\n}"
|
35
|
+
http_version:
|
36
|
+
recorded_at: Tue, 07 Jan 2014 20:56:51 GMT
|
37
|
+
recorded_with: VCR 2.8.0
|
@@ -0,0 +1,36 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: delete
|
5
|
+
uri: https://YOUR_PUBLIC_KEY:YOUR_PRIVATE_KEY@api.e2ma.net/YOUR_ACCOUNT_ID/members/485383562
|
6
|
+
body:
|
7
|
+
encoding: US-ASCII
|
8
|
+
string: ''
|
9
|
+
headers: {}
|
10
|
+
response:
|
11
|
+
status:
|
12
|
+
code: 200
|
13
|
+
message: OK
|
14
|
+
headers:
|
15
|
+
Date:
|
16
|
+
- Tue, 07 Jan 2014 20:56:53 GMT
|
17
|
+
Server:
|
18
|
+
- Apache/2.2.14 (Ubuntu)
|
19
|
+
X-Varnish:
|
20
|
+
- '1006640713'
|
21
|
+
Age:
|
22
|
+
- '0'
|
23
|
+
Connection:
|
24
|
+
- keep-alive
|
25
|
+
Via:
|
26
|
+
- 1.1 varnish
|
27
|
+
Content-Length:
|
28
|
+
- '4'
|
29
|
+
Content-Type:
|
30
|
+
- application/json; charset=utf8
|
31
|
+
body:
|
32
|
+
encoding: US-ASCII
|
33
|
+
string: 'true'
|
34
|
+
http_version:
|
35
|
+
recorded_at: Tue, 07 Jan 2014 20:56:52 GMT
|
36
|
+
recorded_with: VCR 2.8.0
|
@@ -0,0 +1,41 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: get
|
5
|
+
uri: https://YOUR_PUBLIC_KEY:YOUR_PRIVATE_KEY@api.e2ma.net/YOUR_ACCOUNT_ID/members
|
6
|
+
body:
|
7
|
+
encoding: US-ASCII
|
8
|
+
string: ''
|
9
|
+
headers: {}
|
10
|
+
response:
|
11
|
+
status:
|
12
|
+
code: 200
|
13
|
+
message: OK
|
14
|
+
headers:
|
15
|
+
Date:
|
16
|
+
- Tue, 07 Jan 2014 20:56:51 GMT
|
17
|
+
Server:
|
18
|
+
- Apache/2.2.14 (Ubuntu)
|
19
|
+
X-Varnish:
|
20
|
+
- '1006640557'
|
21
|
+
Age:
|
22
|
+
- '0'
|
23
|
+
Connection:
|
24
|
+
- keep-alive
|
25
|
+
Via:
|
26
|
+
- 1.1 varnish
|
27
|
+
Content-Length:
|
28
|
+
- '5'
|
29
|
+
Content-Type:
|
30
|
+
- application/json; charset=utf8
|
31
|
+
body:
|
32
|
+
encoding: US-ASCII
|
33
|
+
string: ! '[
|
34
|
+
|
35
|
+
|
36
|
+
]
|
37
|
+
|
38
|
+
'
|
39
|
+
http_version:
|
40
|
+
recorded_at: Tue, 07 Jan 2014 20:56:50 GMT
|
41
|
+
recorded_with: VCR 2.8.0
|
@@ -0,0 +1,36 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: delete
|
5
|
+
uri: https://YOUR_PUBLIC_KEY:YOUR_PRIVATE_KEY@api.e2ma.net/YOUR_ACCOUNT_ID/members/123
|
6
|
+
body:
|
7
|
+
encoding: UTF-8
|
8
|
+
string: ! '{"fields":{"first_name":"Jane"}}'
|
9
|
+
headers: {}
|
10
|
+
response:
|
11
|
+
status:
|
12
|
+
code: 404
|
13
|
+
message: Not Found
|
14
|
+
headers:
|
15
|
+
Date:
|
16
|
+
- Tue, 07 Jan 2014 20:56:55 GMT
|
17
|
+
Server:
|
18
|
+
- Apache/2.2.14 (Ubuntu)
|
19
|
+
X-Varnish:
|
20
|
+
- '1006640814'
|
21
|
+
Age:
|
22
|
+
- '0'
|
23
|
+
Connection:
|
24
|
+
- keep-alive
|
25
|
+
Via:
|
26
|
+
- 1.1 varnish
|
27
|
+
Content-Length:
|
28
|
+
- '29'
|
29
|
+
Content-Type:
|
30
|
+
- application/json
|
31
|
+
body:
|
32
|
+
encoding: US-ASCII
|
33
|
+
string: ! '{"error": "Entity not found"}'
|
34
|
+
http_version:
|
35
|
+
recorded_at: Tue, 07 Jan 2014 20:56:54 GMT
|
36
|
+
recorded_with: VCR 2.8.0
|
@@ -0,0 +1,36 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: get
|
5
|
+
uri: https://YOUR_PUBLIC_KEY:YOUR_PRIVATE_KEY@api.e2ma.net/YOUR_ACCOUNT_ID/members/123
|
6
|
+
body:
|
7
|
+
encoding: US-ASCII
|
8
|
+
string: ''
|
9
|
+
headers: {}
|
10
|
+
response:
|
11
|
+
status:
|
12
|
+
code: 404
|
13
|
+
message: Not Found
|
14
|
+
headers:
|
15
|
+
Date:
|
16
|
+
- Tue, 07 Jan 2014 20:56:54 GMT
|
17
|
+
Server:
|
18
|
+
- Apache/2.2.14 (Ubuntu)
|
19
|
+
X-Varnish:
|
20
|
+
- '1006640736'
|
21
|
+
Age:
|
22
|
+
- '0'
|
23
|
+
Connection:
|
24
|
+
- keep-alive
|
25
|
+
Via:
|
26
|
+
- 1.1 varnish
|
27
|
+
Content-Length:
|
28
|
+
- '29'
|
29
|
+
Content-Type:
|
30
|
+
- application/json
|
31
|
+
body:
|
32
|
+
encoding: US-ASCII
|
33
|
+
string: ! '{"error": "Entity not found"}'
|
34
|
+
http_version:
|
35
|
+
recorded_at: Tue, 07 Jan 2014 20:56:53 GMT
|
36
|
+
recorded_with: VCR 2.8.0
|
@@ -0,0 +1,36 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: post
|
5
|
+
uri: https://YOUR_PUBLIC_KEY:YOUR_PRIVATE_KEY@api.e2ma.net/YOUR_ACCOUNT_ID/members/add
|
6
|
+
body:
|
7
|
+
encoding: UTF-8
|
8
|
+
string: ! '{"fields":{"first_name":"Jane"}}'
|
9
|
+
headers: {}
|
10
|
+
response:
|
11
|
+
status:
|
12
|
+
code: 400
|
13
|
+
message: Bad Request
|
14
|
+
headers:
|
15
|
+
Date:
|
16
|
+
- Tue, 07 Jan 2014 20:56:54 GMT
|
17
|
+
Server:
|
18
|
+
- Apache/2.2.14 (Ubuntu)
|
19
|
+
X-Varnish:
|
20
|
+
- '1006640756'
|
21
|
+
Age:
|
22
|
+
- '0'
|
23
|
+
Connection:
|
24
|
+
- keep-alive, close
|
25
|
+
Via:
|
26
|
+
- 1.1 varnish
|
27
|
+
Content-Length:
|
28
|
+
- '62'
|
29
|
+
Content-Type:
|
30
|
+
- application/json
|
31
|
+
body:
|
32
|
+
encoding: US-ASCII
|
33
|
+
string: ! '{"error": "You must provide an email address for this member"}'
|
34
|
+
http_version:
|
35
|
+
recorded_at: Tue, 07 Jan 2014 20:56:53 GMT
|
36
|
+
recorded_with: VCR 2.8.0
|
@@ -0,0 +1,37 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: put
|
5
|
+
uri: https://YOUR_PUBLIC_KEY:YOUR_PRIVATE_KEY@api.e2ma.net/YOUR_ACCOUNT_ID/members/delete
|
6
|
+
body:
|
7
|
+
encoding: UTF-8
|
8
|
+
string: ! '{"fields":{"first_name":"Jane"}}'
|
9
|
+
headers: {}
|
10
|
+
response:
|
11
|
+
status:
|
12
|
+
code: 400
|
13
|
+
message: Bad Request
|
14
|
+
headers:
|
15
|
+
Date:
|
16
|
+
- Tue, 07 Jan 2014 20:56:55 GMT
|
17
|
+
Server:
|
18
|
+
- Apache/2.2.14 (Ubuntu)
|
19
|
+
X-Varnish:
|
20
|
+
- '1006640783'
|
21
|
+
Age:
|
22
|
+
- '0'
|
23
|
+
Connection:
|
24
|
+
- keep-alive, close
|
25
|
+
Via:
|
26
|
+
- 1.1 varnish
|
27
|
+
Content-Length:
|
28
|
+
- '77'
|
29
|
+
Content-Type:
|
30
|
+
- application/json
|
31
|
+
body:
|
32
|
+
encoding: US-ASCII
|
33
|
+
string: ! '{"error": "You must provide a list of member ids in order to use
|
34
|
+
this call."}'
|
35
|
+
http_version:
|
36
|
+
recorded_at: Tue, 07 Jan 2014 20:56:54 GMT
|
37
|
+
recorded_with: VCR 2.8.0
|
@@ -0,0 +1,41 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: get
|
5
|
+
uri: https://YOUR_PUBLIC_KEY:YOUR_PRIVATE_KEY@api.e2ma.net/YOUR_ACCOUNT_ID/members/email/test.me@test.com
|
6
|
+
body:
|
7
|
+
encoding: US-ASCII
|
8
|
+
string: ''
|
9
|
+
headers: {}
|
10
|
+
response:
|
11
|
+
status:
|
12
|
+
code: 200
|
13
|
+
message: OK
|
14
|
+
headers:
|
15
|
+
Date:
|
16
|
+
- Tue, 07 Jan 2014 20:56:52 GMT
|
17
|
+
Server:
|
18
|
+
- Apache/2.2.14 (Ubuntu)
|
19
|
+
X-Varnish:
|
20
|
+
- '1006640654'
|
21
|
+
Age:
|
22
|
+
- '0'
|
23
|
+
Connection:
|
24
|
+
- keep-alive
|
25
|
+
Via:
|
26
|
+
- 1.1 varnish
|
27
|
+
Content-Length:
|
28
|
+
- '442'
|
29
|
+
Content-Type:
|
30
|
+
- application/json; charset=utf8
|
31
|
+
body:
|
32
|
+
encoding: US-ASCII
|
33
|
+
string: ! "{\n \"status\": \"active\", \n \"confirmed_opt_in\": null, \n \"account_id\":
|
34
|
+
\"YOUR_ACCOUNT_ID\", \n \"fields\": {\n \"first_name\": \"Tester\", \n \"last_name\":
|
35
|
+
\"McTesterson\"\n }, \n \"member_id\": 485383562, \n \"last_modified_at\":
|
36
|
+
\"@D:2014-01-07T14:56:52\", \n \"member_status_id\": \"a\", \n \"plaintext_preferred\":
|
37
|
+
false, \n \"email_error\": null, \n \"member_since\": \"@D:2014-01-07T12:53:35\",
|
38
|
+
\n \"bounce_count\": 0, \n \"deleted_at\": null, \n \"email\": \"test.me@test.com\"\n}"
|
39
|
+
http_version:
|
40
|
+
recorded_at: Tue, 07 Jan 2014 20:56:51 GMT
|
41
|
+
recorded_with: VCR 2.8.0
|
@@ -0,0 +1,36 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: put
|
5
|
+
uri: https://YOUR_PUBLIC_KEY:YOUR_PRIVATE_KEY@api.e2ma.net/YOUR_ACCOUNT_ID/members/485383562
|
6
|
+
body:
|
7
|
+
encoding: UTF-8
|
8
|
+
string: ! '{"fields":{"first_name":"Jack","last_name":"Jill"}}'
|
9
|
+
headers: {}
|
10
|
+
response:
|
11
|
+
status:
|
12
|
+
code: 200
|
13
|
+
message: OK
|
14
|
+
headers:
|
15
|
+
Date:
|
16
|
+
- Tue, 07 Jan 2014 20:56:53 GMT
|
17
|
+
Server:
|
18
|
+
- Apache/2.2.14 (Ubuntu)
|
19
|
+
X-Varnish:
|
20
|
+
- '1006640681'
|
21
|
+
Age:
|
22
|
+
- '0'
|
23
|
+
Connection:
|
24
|
+
- keep-alive
|
25
|
+
Via:
|
26
|
+
- 1.1 varnish
|
27
|
+
Content-Length:
|
28
|
+
- '4'
|
29
|
+
Content-Type:
|
30
|
+
- application/json; charset=utf8
|
31
|
+
body:
|
32
|
+
encoding: US-ASCII
|
33
|
+
string: 'true'
|
34
|
+
http_version:
|
35
|
+
recorded_at: Tue, 07 Jan 2014 20:56:52 GMT
|
36
|
+
recorded_with: VCR 2.8.0
|
@@ -0,0 +1,195 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Felis do
|
4
|
+
|
5
|
+
let(:account_id) { "YOUR_ACCOUNT_ID" }
|
6
|
+
let(:private_key) { "YOUR_PRIVATE_KEY" }
|
7
|
+
let(:public_key) { "YOUR_PUBLIC_KEY" }
|
8
|
+
let(:felis_with_creds) { Felis::API.new(account_id: account_id, private_key: private_key, public_key: public_key) }
|
9
|
+
|
10
|
+
describe "attributes" do
|
11
|
+
|
12
|
+
let(:felis) { Felis::API.new }
|
13
|
+
|
14
|
+
context "when no base_uri is set by default" do
|
15
|
+
it "sets the base_uri in constructor" do
|
16
|
+
felis.base_uri.should eq "https://api.e2ma.net"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context "when no account_id is passed to constructor" do
|
21
|
+
context "when ENV contains Emma Account Id" do
|
22
|
+
it "sets the account_id in constructor" do
|
23
|
+
ENV["EMMA_ACCOUNT_ID"] = account_id
|
24
|
+
@felis = Felis::API.new
|
25
|
+
@felis.account_id.should eq ENV["EMMA_ACCOUNT_ID"]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context "when ENV does not contain Emma Account Id" do
|
30
|
+
it "sets the account_id to nil" do
|
31
|
+
ENV['EMMA_ACCOUNT_ID'] = nil
|
32
|
+
felis.account_id.should be_nil
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context "when account_id is passed to constructor" do
|
38
|
+
it "account_id is not nil" do
|
39
|
+
@felis = Felis::API.new(account_id: account_id)
|
40
|
+
@felis.account_id.should_not be_nil
|
41
|
+
@felis.account_id.should eq account_id
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context "when no private key is passed to constructor" do
|
46
|
+
context "when ENV contains Emma Private Key" do
|
47
|
+
it "sets the private_key in constructor" do
|
48
|
+
ENV["EMMA_PRIVATE_KEY"] = private_key
|
49
|
+
@felis = Felis::API.new
|
50
|
+
felis.private_key.should eq ENV['EMMA_PRIVATE_KEY']
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context "when ENV does not contain Emma Private Key" do
|
55
|
+
it "sets the private_key to nil" do
|
56
|
+
ENV['EMMA_PRIVATE_KEY'] = nil
|
57
|
+
felis.private_key.should be_nil
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context "when private_key is passed to constructor" do
|
63
|
+
it "private_key is not nil" do
|
64
|
+
@felis = Felis::API.new(private_key: private_key)
|
65
|
+
@felis.private_key.should_not be_nil
|
66
|
+
@felis.private_key.should eq private_key
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context "when no public key is passed to constructor" do
|
71
|
+
context "when ENV contains Emma Public Key" do
|
72
|
+
it "sets the public_key in constructor" do
|
73
|
+
ENV["EMMA_PUBLIC_KEY"] = public_key
|
74
|
+
@felis = Felis::API.new
|
75
|
+
felis.public_key.should eq ENV['EMMA_PUBLIC_KEY']
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context "when public_key is passed to constructor" do
|
80
|
+
it "public_key is not nil" do
|
81
|
+
@felis = Felis::API.new(public_key: public_key)
|
82
|
+
@felis.public_key.should_not be_nil
|
83
|
+
@felis.public_key.should eq public_key
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
context "when ENV does not contain Emma Public Key" do
|
88
|
+
it "sets the public_key to nil" do
|
89
|
+
ENV['EMMA_PUBLIC_KEY'] = nil
|
90
|
+
felis.public_key.should be_nil
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
context "when no debug option is passed to constructor" do
|
96
|
+
it "sets debug mode to false" do
|
97
|
+
felis.debug.should be_false
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe "build api url" do
|
103
|
+
|
104
|
+
let(:base_uri) { "https://api.e2ma.net" }
|
105
|
+
|
106
|
+
context "with new instance" do
|
107
|
+
it "will setup the base_uri with the account_id" do
|
108
|
+
felis_with_creds.class.base_uri.should eq "#{base_uri}/#{account_id}"
|
109
|
+
end
|
110
|
+
|
111
|
+
it "will setup the basic auth variables for HTTP requests" do
|
112
|
+
defaults = felis_with_creds.instance_variable_get(:"@defaults")
|
113
|
+
defaults[:basic_auth][:username].should_not be_nil
|
114
|
+
defaults[:basic_auth][:username].should eq public_key
|
115
|
+
|
116
|
+
defaults[:basic_auth][:password].should_not be_nil
|
117
|
+
defaults[:basic_auth][:password].should eq private_key
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
describe "API calls" do
|
123
|
+
|
124
|
+
context "HTTP valid GET request" do
|
125
|
+
it "will parse the response" do
|
126
|
+
VCR.use_cassette 'get_members' do
|
127
|
+
request = call(:get, '/members')
|
128
|
+
request.should eq []
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
context "HTTP POST request" do
|
134
|
+
it "will parse the respone" do
|
135
|
+
VCR.use_cassette 'add_member' do
|
136
|
+
request = call(:post, '/members/add', { email: "test.me@test.com", fields: {first_name: "Tester", last_name: "McTesterson"} })
|
137
|
+
request.should have_key("member_id")
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
context "HTTP PUT request" do
|
143
|
+
it "will parse the response" do
|
144
|
+
VCR.use_cassette 'retrieve_member_for_put_request' do
|
145
|
+
member = call(:get, '/members/email/test.me@test.com')
|
146
|
+
|
147
|
+
VCR.use_cassette 'update_member' do
|
148
|
+
request = call(:put, "/members/#{member['member_id']}", { fields: { first_name: "Jack", last_name: "Jill" }})
|
149
|
+
request.should be_true
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
context "HTTP DELETE request" do
|
156
|
+
it "will parse the response" do
|
157
|
+
VCR.use_cassette 'retrieve_member_for_put_request' do
|
158
|
+
member = call(:get, '/members/email/test.me@test.com')
|
159
|
+
|
160
|
+
VCR.use_cassette 'delete_member' do
|
161
|
+
request = call(:delete, "/members/#{member['member_id']}")
|
162
|
+
request.should be_true
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
context "invalid HTTP requests" do
|
169
|
+
it "will raise an error" do
|
170
|
+
VCR.use_cassette 'invalid_get_request' do
|
171
|
+
expect { call(:get, '/members/123') }.to raise_error(Felis::EmmaError)
|
172
|
+
end
|
173
|
+
|
174
|
+
VCR.use_cassette 'invalid_post_request' do
|
175
|
+
expect { call(:post, '/members/add', { fields: { first_name: "Jane" } }) }.to raise_error(Felis::EmmaError)
|
176
|
+
end
|
177
|
+
|
178
|
+
VCR.use_cassette 'invalid_put_request' do
|
179
|
+
expect { call(:put, '/members/delete') }.to raise_error(Felis::EmmaError)
|
180
|
+
end
|
181
|
+
|
182
|
+
VCR.use_cassette 'invalid_delete_request' do
|
183
|
+
expect { call(:delete, '/members/123') }.to raise_error(Felis::EmmaError)
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
end
|
189
|
+
|
190
|
+
private
|
191
|
+
def call(method, path, params = {})
|
192
|
+
felis_with_creds.send(method, path, params)
|
193
|
+
end
|
194
|
+
|
195
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
|
6
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
7
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
8
|
+
require 'felis'
|
9
|
+
require 'vcr'
|
10
|
+
require 'webmock'
|
11
|
+
|
12
|
+
VCR.configure do |c|
|
13
|
+
c.cassette_library_dir = 'spec/cassettes'
|
14
|
+
c.hook_into :webmock
|
15
|
+
c.default_cassette_options = { record: :new_episodes }
|
16
|
+
c.configure_rspec_metadata!
|
17
|
+
end
|
18
|
+
|
19
|
+
RSpec.configure do |config|
|
20
|
+
config.color_enabled = true
|
21
|
+
end
|
metadata
ADDED
@@ -0,0 +1,193 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: felis
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Dennis Monsewicz
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2014-01-08 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: httparty
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: multi_json
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: bundler
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '1.3'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.3'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rake
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: rspec
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: vcr
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: webmock
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - <
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '1.16'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - <
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '1.16'
|
126
|
+
description: A wrapper for Emma API
|
127
|
+
email:
|
128
|
+
- dennismonsewicz@gmail.com
|
129
|
+
executables: []
|
130
|
+
extensions: []
|
131
|
+
extra_rdoc_files: []
|
132
|
+
files:
|
133
|
+
- .gitignore
|
134
|
+
- .rspec
|
135
|
+
- .travis.yml
|
136
|
+
- Gemfile
|
137
|
+
- LICENSE.txt
|
138
|
+
- README.md
|
139
|
+
- Rakefile
|
140
|
+
- felis.gemspec
|
141
|
+
- lib/felis.rb
|
142
|
+
- lib/felis/api.rb
|
143
|
+
- lib/felis/emma_error.rb
|
144
|
+
- lib/felis/version.rb
|
145
|
+
- spec/cassettes/add_member.yml
|
146
|
+
- spec/cassettes/delete_member.yml
|
147
|
+
- spec/cassettes/get_members.yml
|
148
|
+
- spec/cassettes/invalid_delete_request.yml
|
149
|
+
- spec/cassettes/invalid_get_request.yml
|
150
|
+
- spec/cassettes/invalid_post_request.yml
|
151
|
+
- spec/cassettes/invalid_put_request.yml
|
152
|
+
- spec/cassettes/retrieve_member_for_put_request.yml
|
153
|
+
- spec/cassettes/update_member.yml
|
154
|
+
- spec/felis/felis_spec.rb
|
155
|
+
- spec/spec_helper.rb
|
156
|
+
homepage: ''
|
157
|
+
licenses:
|
158
|
+
- MIT
|
159
|
+
post_install_message:
|
160
|
+
rdoc_options: []
|
161
|
+
require_paths:
|
162
|
+
- lib
|
163
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
164
|
+
none: false
|
165
|
+
requirements:
|
166
|
+
- - ! '>='
|
167
|
+
- !ruby/object:Gem::Version
|
168
|
+
version: '0'
|
169
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
170
|
+
none: false
|
171
|
+
requirements:
|
172
|
+
- - ! '>='
|
173
|
+
- !ruby/object:Gem::Version
|
174
|
+
version: '0'
|
175
|
+
requirements: []
|
176
|
+
rubyforge_project:
|
177
|
+
rubygems_version: 1.8.25
|
178
|
+
signing_key:
|
179
|
+
specification_version: 3
|
180
|
+
summary: A wrapper for Emma API
|
181
|
+
test_files:
|
182
|
+
- spec/cassettes/add_member.yml
|
183
|
+
- spec/cassettes/delete_member.yml
|
184
|
+
- spec/cassettes/get_members.yml
|
185
|
+
- spec/cassettes/invalid_delete_request.yml
|
186
|
+
- spec/cassettes/invalid_get_request.yml
|
187
|
+
- spec/cassettes/invalid_post_request.yml
|
188
|
+
- spec/cassettes/invalid_put_request.yml
|
189
|
+
- spec/cassettes/retrieve_member_for_put_request.yml
|
190
|
+
- spec/cassettes/update_member.yml
|
191
|
+
- spec/felis/felis_spec.rb
|
192
|
+
- spec/spec_helper.rb
|
193
|
+
has_rdoc:
|