clever_reach 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 +15 -0
- data/.gitignore +5 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/LICENSE +19 -0
- data/README.md +27 -0
- data/Rakefile +1 -0
- data/clever_reach.gemspec +27 -0
- data/lib/clever_reach.rb +16 -0
- data/lib/clever_reach/base.rb +36 -0
- data/lib/clever_reach/configuration.rb +21 -0
- data/lib/clever_reach/errors.rb +113 -0
- data/lib/clever_reach/response_decorator.rb +44 -0
- data/lib/clever_reach/version.rb +3 -0
- data/spec/clever_reach/base_spec.rb +73 -0
- data/spec/clever_reach/configuration_spec.rb +45 -0
- data/spec/clever_reach/errors_spec.rb +117 -0
- data/spec/clever_reach/response_decorator_spec.rb +77 -0
- data/spec/clever_reach_spec.rb +29 -0
- data/spec/spec_helper.rb +29 -0
- metadata +112 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
ZGVkNzU2NTg3NTEyZWUwMDdmMGMzMjFhMGQ0NDZhY2YyMDk2ZTI2OQ==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
ZWQ0ZmQ0OTllNzA3YzljYWE1ZGI4MjRhMTM2ZGZjMDEyZmZmOGY5Yg==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
Mjg0MGU2MjNjODRhYWE1OTY3NGZhYjFkOWNkYzcyMjE3MDNmMjU4ZWMwYmZm
|
10
|
+
Zjk5OTU1NGU1OWNmMmE5ZDg0OGM2NWRlZGQ0OTRlMGZlNGYzMDE2NGIwMzE0
|
11
|
+
OWU3ZmEyNDJlZWMwOGRhODNjNTdlMGI4YjA1OWEyNGRhZjRjZDA=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
NTE1Yzg1ZWVkNzRkNDVhYzkyNTYzNDFjNjVlNDJiNTU4NGI3ZjZhNzI0NWUz
|
14
|
+
NjdkMDk5MTIyOTcxNGE3YTExNWQyOGVjYzYzYzAyZDdiYWZjYWIzZDJhNjY2
|
15
|
+
ZmJmNDBkNmZmNDRhMDM3MjA4NzA3ODIzOTY4NzY1NTE1OTM5MzE=
|
data/.rspec
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2012, 2013 Stephan Schubert <stephan@frozencherry.de>
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# clever_reach
|
2
|
+
|
3
|
+
Ruby bindings for CleverReach's API
|
4
|
+
|
5
|
+
[](https://codeclimate.com/github/jazen/clever_reach)
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
In your Gemfile:
|
10
|
+
|
11
|
+
``` ruby
|
12
|
+
gem 'clever_reach'
|
13
|
+
```
|
14
|
+
|
15
|
+
## Introduction
|
16
|
+
|
17
|
+
``` ruby
|
18
|
+
require 'clever_reach'
|
19
|
+
|
20
|
+
CleverReach.configure do |config|
|
21
|
+
config.api_key = "12345" # Replace with your API key
|
22
|
+
end
|
23
|
+
|
24
|
+
api = CleverReach::Base.new
|
25
|
+
resp = api.client_get_details
|
26
|
+
resp.to_hash # => { :id => '12345', :first_name => 'Stephan', ... }
|
27
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "clever_reach/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "clever_reach"
|
7
|
+
s.version = CleverReach::VERSION
|
8
|
+
s.authors = ["Stephan Schubert"]
|
9
|
+
s.email = ["stephan@frozencherry.de"]
|
10
|
+
s.homepage = "https://github.com/jazen/clever_reach"
|
11
|
+
s.summary = "Ruby bindings for CleverReach's API"
|
12
|
+
s.description = "Ruby bindings for CleverReach's API"
|
13
|
+
s.licenses = %w(MIT)
|
14
|
+
|
15
|
+
s.rubyforge_project = "clever_reach"
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
|
22
|
+
# specify any dependencies here; for example:
|
23
|
+
s.add_development_dependency 'rspec'
|
24
|
+
s.add_development_dependency 'savon_spec'
|
25
|
+
|
26
|
+
s.add_runtime_dependency 'savon', '~> 1.0'
|
27
|
+
end
|
data/lib/clever_reach.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require "clever_reach/version"
|
2
|
+
|
3
|
+
module CleverReach
|
4
|
+
autoload :Base, 'clever_reach/base'
|
5
|
+
autoload :Configuration, 'clever_reach/configuration'
|
6
|
+
autoload :Errors, 'clever_reach/errors'
|
7
|
+
autoload :ResponseDecorator, 'clever_reach/response_decorator'
|
8
|
+
|
9
|
+
def self.config
|
10
|
+
Configuration.instance
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.configure
|
14
|
+
yield config
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'savon'
|
2
|
+
|
3
|
+
module CleverReach
|
4
|
+
class Base
|
5
|
+
attr_reader :api_key
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@api_key = CleverReach.config.api_key
|
9
|
+
end
|
10
|
+
|
11
|
+
def client
|
12
|
+
@client ||= Savon.client(CleverReach.config.wsdl_url)
|
13
|
+
end
|
14
|
+
|
15
|
+
def method_missing(name, *args)
|
16
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
17
|
+
response = request(name, options)
|
18
|
+
|
19
|
+
ResponseDecorator.new(response).tap do |r|
|
20
|
+
raise Errors.lookup(r.status_code) unless r.valid?
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
private # ----------------------------------------------
|
25
|
+
|
26
|
+
def request(method_name, body)
|
27
|
+
# The 'apiKey' MUST come first in the *ordered* hash.
|
28
|
+
body = { 'apiKey' => @api_key }.merge(body)
|
29
|
+
|
30
|
+
client.request(method_name) do
|
31
|
+
soap.body = body
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
|
3
|
+
module CleverReach
|
4
|
+
class Configuration
|
5
|
+
include Singleton
|
6
|
+
|
7
|
+
@@defaults = {
|
8
|
+
wsdl_url: 'http://api.cleverreach.com/soap/interface_v5.1.php?wsdl'
|
9
|
+
}
|
10
|
+
|
11
|
+
attr_accessor :wsdl_url, :api_key, :list_id
|
12
|
+
|
13
|
+
def self.defaults
|
14
|
+
@@defaults
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize
|
18
|
+
@@defaults.each { |k,v| send("#{k}=", v) }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
module CleverReach
|
2
|
+
module Errors
|
3
|
+
# http://support.cleverreach.de/entries/20674817-fehlercode-api
|
4
|
+
|
5
|
+
class BaseError < StandardError
|
6
|
+
end
|
7
|
+
|
8
|
+
class InvalidAPIKey < BaseError
|
9
|
+
def initialize
|
10
|
+
super('invalid API key')
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class NeedSessionBeforeUsage < BaseError
|
15
|
+
def initialize
|
16
|
+
super('need session before usage')
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class PermissionDenied < BaseError
|
21
|
+
def initialize
|
22
|
+
super('permission denied')
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class DataNotFound < BaseError
|
27
|
+
def initialize
|
28
|
+
super('data not found')
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class EmailInvalid < BaseError
|
33
|
+
def initialize
|
34
|
+
super('email invalid')
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class EmailBlacklisted < BaseError
|
39
|
+
def initialize
|
40
|
+
super('email blacklisted')
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
class DuplicateData < BaseError
|
45
|
+
def initialize
|
46
|
+
super('duplicate data')
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
class SubscriberAlreadyActive < BaseError
|
51
|
+
def initialize
|
52
|
+
super('subscriber already active')
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
class InsertingOrderFailed < BaseError
|
57
|
+
def initialize
|
58
|
+
super('inserting order failed')
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
class BatchTooBig < BaseError
|
63
|
+
def initialize
|
64
|
+
super('batch too big (max 50)')
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
class SubscriberAlreadyInactive < BaseError
|
69
|
+
def initialize
|
70
|
+
super('subscriber already inactive')
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
class GivenEmailIsTooShort < BaseError
|
75
|
+
def initialize
|
76
|
+
super('given email is too short')
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
class NoFormsAvailable < BaseError
|
81
|
+
def initialize
|
82
|
+
super('no forms available')
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
class ErrorSavingFilter < BaseError
|
87
|
+
def initialize
|
88
|
+
super('error saving filter')
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
ErrorMap = {
|
93
|
+
1 => InvalidAPIKey,
|
94
|
+
5 => NeedSessionBeforeUsage,
|
95
|
+
10 => PermissionDenied,
|
96
|
+
20 => DataNotFound,
|
97
|
+
30 => EmailInvalid,
|
98
|
+
40 => EmailBlacklisted,
|
99
|
+
50 => DuplicateData,
|
100
|
+
60 => SubscriberAlreadyActive,
|
101
|
+
70 => InsertingOrderFailed,
|
102
|
+
80 => BatchTooBig,
|
103
|
+
90 => SubscriberAlreadyInactive,
|
104
|
+
100 => GivenEmailIsTooShort,
|
105
|
+
110 => NoFormsAvailable,
|
106
|
+
120 => ErrorSavingFilter,
|
107
|
+
}
|
108
|
+
|
109
|
+
def self.lookup(code)
|
110
|
+
ErrorMap[code]
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module CleverReach
|
2
|
+
class ResponseDecorator < SimpleDelegator
|
3
|
+
|
4
|
+
def initialize(response)
|
5
|
+
super
|
6
|
+
@response = response
|
7
|
+
end
|
8
|
+
|
9
|
+
def valid?
|
10
|
+
# Let's be flexible when checking for the status.
|
11
|
+
answer_hash[:status] =~ /success/i
|
12
|
+
end
|
13
|
+
|
14
|
+
def status_code
|
15
|
+
answer_hash[:statuscode].to_i
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_hash
|
19
|
+
data = answer_hash[:data]
|
20
|
+
clean! data.dup
|
21
|
+
end
|
22
|
+
|
23
|
+
private # ----------------------------------------------
|
24
|
+
|
25
|
+
def response_hash_key
|
26
|
+
@response.body.keys.find { |k| k.to_s =~ /_response$/ }
|
27
|
+
end
|
28
|
+
|
29
|
+
def answer_hash
|
30
|
+
@response.body[response_hash_key][:return]
|
31
|
+
end
|
32
|
+
|
33
|
+
def clean!(hash)
|
34
|
+
hash.reject! do |k,v|
|
35
|
+
if v.is_a? Hash
|
36
|
+
clean!(v); false
|
37
|
+
else
|
38
|
+
k.to_s =~ /^@/
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe CleverReach::Base do
|
4
|
+
|
5
|
+
let(:wsdl_url) { "http://api.test.com/wsdl" }
|
6
|
+
let(:api_key) { "12345" }
|
7
|
+
let(:client) { subject.client }
|
8
|
+
|
9
|
+
before :all do
|
10
|
+
CleverReach.configure do |config|
|
11
|
+
config.wsdl_url = wsdl_url
|
12
|
+
config.api_key = api_key
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "#new" do # -------------------------------------
|
17
|
+
|
18
|
+
it "should use the configured API key" do
|
19
|
+
subject.api_key.should == api_key
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "#client" do # ----------------------------------
|
25
|
+
|
26
|
+
it "should return configured Savon::Client" do
|
27
|
+
client.should be_instance_of(Savon::Client)
|
28
|
+
client.wsdl.document.should == wsdl_url
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should re-use the client" do
|
32
|
+
client.should == client
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "Response w/ errors" do # -----------------------
|
38
|
+
|
39
|
+
let(:body_with_errors) do
|
40
|
+
{ :foo_response => { :return => { :status => 'ERROR', :statuscode => '30' } } }
|
41
|
+
end
|
42
|
+
|
43
|
+
let(:response) { stub(body: body_with_errors) }
|
44
|
+
|
45
|
+
before :each do
|
46
|
+
subject.should_receive(:request).with(:foo, anything).and_return(response)
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should raise the appropiate error" do
|
50
|
+
lambda { subject.foo }.should raise_error(CleverReach::Errors::EmailInvalid)
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
# TODO Can't figure out how to stub/mock requests for Savon.
|
56
|
+
# I'v opened a new issue on github asking for some documentation.
|
57
|
+
#
|
58
|
+
# https://github.com/rubiii/savon/issues/307
|
59
|
+
#
|
60
|
+
# it "blah" do
|
61
|
+
# savon.expects(:client_get_details).with('apiKey' => api_key).returns({})
|
62
|
+
# subject.client_get_details
|
63
|
+
# end
|
64
|
+
|
65
|
+
# describe "A request" do # --------------------------------
|
66
|
+
|
67
|
+
# it "should return a ResponseDecorator" do
|
68
|
+
# subject.foobar.should be_instance_of(ResponseDecorator)
|
69
|
+
# end
|
70
|
+
|
71
|
+
# end
|
72
|
+
|
73
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe CleverReach::Configuration do
|
4
|
+
|
5
|
+
let(:klass) { CleverReach::Configuration }
|
6
|
+
let(:subject) { CleverReach.config }
|
7
|
+
|
8
|
+
it "should be a singleton" do
|
9
|
+
klass.included_modules.should include(Singleton)
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "Default configuration" do
|
13
|
+
|
14
|
+
let(:defaults) do
|
15
|
+
{
|
16
|
+
wsdl_url: 'http://api.cleverreach.com/soap/interface_v5.1.php?wsdl'
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should have some default settings" do
|
21
|
+
klass.defaults.should == defaults
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should use the default settings automatically" do
|
25
|
+
keys = subject.instance_variables.map { |name| name.to_s.sub('@', '').to_sym }
|
26
|
+
keys.should include(*defaults.keys)
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "Specifying a list id" do
|
32
|
+
|
33
|
+
before :each do
|
34
|
+
CleverReach.configure do |config|
|
35
|
+
config.list_id = '123'
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should be readable" do
|
40
|
+
subject.list_id.should == '123'
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe CleverReach::Errors do
|
4
|
+
|
5
|
+
describe CleverReach::Errors::BaseError do # -------------
|
6
|
+
|
7
|
+
let(:subject) { CleverReach::Errors::BaseError.new }
|
8
|
+
|
9
|
+
it "should be subclass of StandardError" do
|
10
|
+
subject.should be_kind_of(StandardError)
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "Custom errors" do # ----------------------------
|
16
|
+
|
17
|
+
let(:error_scope) { CleverReach::Errors }
|
18
|
+
let(:error_class) { error_scope::BaseError }
|
19
|
+
|
20
|
+
it "should define an error for 'invalid API Key'" do
|
21
|
+
error = error_scope::InvalidAPIKey.new
|
22
|
+
error.should be_kind_of(error_class)
|
23
|
+
error.message.should == 'invalid API key'
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should define an error for 'need session before usage'" do
|
27
|
+
error = error_scope::NeedSessionBeforeUsage.new
|
28
|
+
error.should be_kind_of(error_class)
|
29
|
+
error.message.should == 'need session before usage'
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should define an error for 'permission denied'" do
|
33
|
+
error = error_scope::PermissionDenied.new
|
34
|
+
error.should be_kind_of(error_class)
|
35
|
+
error.message.should == 'permission denied'
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should define an error for 'data not found'" do
|
39
|
+
error = error_scope::DataNotFound.new
|
40
|
+
error.should be_kind_of(error_class)
|
41
|
+
error.message.should == 'data not found'
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should define an error for 'email invalid'" do
|
45
|
+
error = error_scope::EmailInvalid.new
|
46
|
+
error.should be_kind_of(error_class)
|
47
|
+
error.message.should == 'email invalid'
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should define an error for 'email blacklisted'" do
|
51
|
+
error = error_scope::EmailBlacklisted.new
|
52
|
+
error.should be_kind_of(error_class)
|
53
|
+
error.message.should == 'email blacklisted'
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should define an error for 'duplicate data'" do
|
57
|
+
error = error_scope::DuplicateData.new
|
58
|
+
error.should be_kind_of(error_class)
|
59
|
+
error.message.should == 'duplicate data'
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should define an error for 'subscriber already active'" do
|
63
|
+
error = error_scope::SubscriberAlreadyActive.new
|
64
|
+
error.should be_kind_of(error_class)
|
65
|
+
error.message.should == 'subscriber already active'
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should define an error for 'inserting order failed'" do
|
69
|
+
error = error_scope::InsertingOrderFailed.new
|
70
|
+
error.should be_kind_of(error_class)
|
71
|
+
error.message.should == 'inserting order failed'
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should define an error for 'batch to big (max 50)'" do
|
75
|
+
error = error_scope::BatchTooBig.new
|
76
|
+
error.should be_kind_of(error_class)
|
77
|
+
error.message.should == 'batch too big (max 50)'
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should define an error for 'subscriber already inactive'" do
|
81
|
+
error = error_scope::SubscriberAlreadyInactive.new
|
82
|
+
error.should be_kind_of(error_class)
|
83
|
+
error.message.should == 'subscriber already inactive'
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should define an error for 'given email is too short'" do
|
87
|
+
error = error_scope::GivenEmailIsTooShort.new
|
88
|
+
error.should be_kind_of(error_class)
|
89
|
+
error.message.should == 'given email is too short'
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should define an error for 'no forms available'" do
|
93
|
+
error = error_scope::NoFormsAvailable.new
|
94
|
+
error.should be_kind_of(error_class)
|
95
|
+
error.message.should == 'no forms available'
|
96
|
+
end
|
97
|
+
|
98
|
+
it "should define an error for 'error saving filter'" do
|
99
|
+
error = error_scope::ErrorSavingFilter.new
|
100
|
+
error.should be_kind_of(error_class)
|
101
|
+
error.message.should == 'error saving filter'
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
describe ".lookup" do # ----------------------------------
|
107
|
+
|
108
|
+
CleverReach::Errors::ErrorMap.each do |code, klass|
|
109
|
+
it "should map error code #{code} to an error class '#{klass.name}'" do
|
110
|
+
subject.lookup(code).should == klass
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
|
117
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe CleverReach::ResponseDecorator do
|
4
|
+
|
5
|
+
let(:body) do
|
6
|
+
{ :client_get_details_response => {
|
7
|
+
:return => {
|
8
|
+
:status => "SUCCESS",
|
9
|
+
:message => { :"@xsi:type" => "xsd:string" },
|
10
|
+
:statuscode => "0",
|
11
|
+
:data => {
|
12
|
+
:id => "12345",
|
13
|
+
:firstname => "Stephan",
|
14
|
+
:name => "Schubert",
|
15
|
+
:company => "avianta UG",
|
16
|
+
:email => "stephan@frozencherry.de",
|
17
|
+
:login_domain => "12345.cleverreach.com",
|
18
|
+
:item => { :foo => "1", :"@xsi:type" => "foo" },
|
19
|
+
:"@xsi:type" => "tns:clientData"
|
20
|
+
},
|
21
|
+
:"@xsi:type" => "tns:returnClient" },
|
22
|
+
:"@xmlns:ns1"=>"CRS"
|
23
|
+
}
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
let(:response) { stub(body: body) }
|
28
|
+
let(:subject) { CleverReach::ResponseDecorator.new(response) }
|
29
|
+
|
30
|
+
describe "Method Delegation" do # ------------------------
|
31
|
+
let(:response) { stub(body: body, foo: 1) }
|
32
|
+
|
33
|
+
it "should check the underlying object" do
|
34
|
+
subject.foo.should == 1
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "#to_hash" do # ----------------------------------
|
39
|
+
|
40
|
+
it "should return a cleaned hash with just the valuable data" do
|
41
|
+
subject.to_hash.should == {
|
42
|
+
id: "12345",
|
43
|
+
firstname: "Stephan",
|
44
|
+
name: "Schubert",
|
45
|
+
company: "avianta UG",
|
46
|
+
email: "stephan@frozencherry.de",
|
47
|
+
login_domain: "12345.cleverreach.com",
|
48
|
+
item: { foo: "1" }
|
49
|
+
}
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "Response w/o errors" do # ----------------------
|
55
|
+
it { should be_valid }
|
56
|
+
|
57
|
+
it "should have status code 0" do
|
58
|
+
subject.status_code.should be_zero
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "Response w/ errors" do # -----------------------
|
63
|
+
let(:body) do
|
64
|
+
{ :some_method_response => {
|
65
|
+
:return => { :status => 'ERROR', :statuscode => '40' }
|
66
|
+
}
|
67
|
+
}
|
68
|
+
end
|
69
|
+
|
70
|
+
it { should_not be_valid }
|
71
|
+
|
72
|
+
it "should have a non-zero status code" do
|
73
|
+
subject.status_code.should_not be_zero
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe CleverReach do
|
4
|
+
|
5
|
+
let(:klass) { CleverReach }
|
6
|
+
|
7
|
+
it "should have a VERSION" do
|
8
|
+
klass::VERSION.should_not be_nil
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "Configuration" do # ----------------------------
|
12
|
+
|
13
|
+
it "should have a configuration instance" do
|
14
|
+
klass.config.should be_instance_of(klass::Configuration)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should support configuration with a block" do
|
18
|
+
klass::Configuration.class_eval { attr_accessor :foo }
|
19
|
+
|
20
|
+
klass.configure do |config|
|
21
|
+
config.foo = :bar
|
22
|
+
end
|
23
|
+
|
24
|
+
klass.config.foo.should == :bar
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# Setup rubygems/bundler
|
2
|
+
require 'rubygems'
|
3
|
+
require 'bundler/setup'
|
4
|
+
|
5
|
+
require 'savon'
|
6
|
+
require 'savon_spec'
|
7
|
+
|
8
|
+
# The gem itself
|
9
|
+
require 'clever_reach'
|
10
|
+
|
11
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
12
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
13
|
+
# Require this file using `require "spec_helper"` to ensure that it is only
|
14
|
+
# loaded once.
|
15
|
+
#
|
16
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
17
|
+
RSpec.configure do |config|
|
18
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
19
|
+
config.run_all_when_everything_filtered = true
|
20
|
+
config.filter_run :focus
|
21
|
+
|
22
|
+
config.include Savon::Spec::Macros
|
23
|
+
|
24
|
+
# Run specs in random order to surface order dependencies. If you find an
|
25
|
+
# order dependency and want to debug it, you can fix the order by providing
|
26
|
+
# the seed, which is printed after each run.
|
27
|
+
# --seed 1234
|
28
|
+
config.order = 'random'
|
29
|
+
end
|
metadata
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: clever_reach
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Stephan Schubert
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-11-16 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rspec
|
15
|
+
version_requirements: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ! '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
requirement: !ruby/object:Gem::Requirement
|
22
|
+
requirements:
|
23
|
+
- - ! '>='
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: '0'
|
26
|
+
prerelease: false
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: savon_spec
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ! '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ! '>='
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
prerelease: false
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: savon
|
43
|
+
version_requirements: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.0'
|
48
|
+
type: :runtime
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '1.0'
|
54
|
+
prerelease: false
|
55
|
+
description: Ruby bindings for CleverReach's API
|
56
|
+
email:
|
57
|
+
- stephan@frozencherry.de
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- .gitignore
|
63
|
+
- .rspec
|
64
|
+
- Gemfile
|
65
|
+
- LICENSE
|
66
|
+
- README.md
|
67
|
+
- Rakefile
|
68
|
+
- clever_reach.gemspec
|
69
|
+
- lib/clever_reach.rb
|
70
|
+
- lib/clever_reach/base.rb
|
71
|
+
- lib/clever_reach/configuration.rb
|
72
|
+
- lib/clever_reach/errors.rb
|
73
|
+
- lib/clever_reach/response_decorator.rb
|
74
|
+
- lib/clever_reach/version.rb
|
75
|
+
- spec/clever_reach/base_spec.rb
|
76
|
+
- spec/clever_reach/configuration_spec.rb
|
77
|
+
- spec/clever_reach/errors_spec.rb
|
78
|
+
- spec/clever_reach/response_decorator_spec.rb
|
79
|
+
- spec/clever_reach_spec.rb
|
80
|
+
- spec/spec_helper.rb
|
81
|
+
homepage: https://github.com/jazen/clever_reach
|
82
|
+
licenses:
|
83
|
+
- MIT
|
84
|
+
metadata: {}
|
85
|
+
post_install_message:
|
86
|
+
rdoc_options: []
|
87
|
+
require_paths:
|
88
|
+
- lib
|
89
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
95
|
+
requirements:
|
96
|
+
- - ! '>='
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
99
|
+
requirements: []
|
100
|
+
rubyforge_project: clever_reach
|
101
|
+
rubygems_version: 2.1.11
|
102
|
+
signing_key:
|
103
|
+
specification_version: 4
|
104
|
+
summary: Ruby bindings for CleverReach's API
|
105
|
+
test_files:
|
106
|
+
- spec/clever_reach/base_spec.rb
|
107
|
+
- spec/clever_reach/configuration_spec.rb
|
108
|
+
- spec/clever_reach/errors_spec.rb
|
109
|
+
- spec/clever_reach/response_decorator_spec.rb
|
110
|
+
- spec/clever_reach_spec.rb
|
111
|
+
- spec/spec_helper.rb
|
112
|
+
has_rdoc:
|