signable 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 +7 -0
- data/.gitignore +17 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +22 -0
- data/README.md +68 -0
- data/Rakefile +1 -0
- data/lib/signable.rb +42 -0
- data/lib/signable/base.rb +7 -0
- data/lib/signable/concerns/column.rb +26 -0
- data/lib/signable/concerns/embed.rb +22 -0
- data/lib/signable/concerns/model.rb +68 -0
- data/lib/signable/concerns/prefix.rb +24 -0
- data/lib/signable/concerns/query.rb +68 -0
- data/lib/signable/configuration.rb +5 -0
- data/lib/signable/contact.rb +8 -0
- data/lib/signable/document.rb +16 -0
- data/lib/signable/envelope.rb +22 -0
- data/lib/signable/list.rb +27 -0
- data/lib/signable/merge_field.rb +16 -0
- data/lib/signable/model/column.rb +12 -0
- data/lib/signable/model/embed.rb +12 -0
- data/lib/signable/party.rb +11 -0
- data/lib/signable/query/client.rb +51 -0
- data/lib/signable/query/response.rb +15 -0
- data/lib/signable/template.rb +21 -0
- data/lib/signable/version.rb +3 -0
- data/signable.gemspec +28 -0
- data/spec/signable/base_spec.rb +8 -0
- data/spec/signable/list_spec.rb +40 -0
- data/spec/signable/model/column_spec.rb +20 -0
- data/spec/signable/model/embed_spec.rb +15 -0
- data/spec/signable/query/response_spec.rb +34 -0
- data/spec/spec_helper.rb +8 -0
- data/spec/support/concerns/column.rb +40 -0
- data/spec/support/concerns/embed.rb +24 -0
- data/spec/support/concerns/model.rb +80 -0
- data/spec/support/concerns/prefix.rb +43 -0
- data/spec/support/concerns/query.rb +70 -0
- metadata +163 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: fc1e8af822245449ffd3e162892afdbf6669f316
|
4
|
+
data.tar.gz: f476428be5b19933f2ae20b85491ba4b61af9be7
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1d986bc4150d38e57747fd1a57d17cb6d28344c1d34a2c251dc58c56e1bd7d855346909ef45743f563a2f484e6ba1ab7883c66ee717914bf8dbb734007289e8a
|
7
|
+
data.tar.gz: 6e2b2dc96dc6fa180e313927a405bae29e101133a3fbb88365acedf688638007a3e3e82ab270160b22b5839b8a23a04a109688094c9caad0e2747138238526d2
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Anthony Laibe
|
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,68 @@
|
|
1
|
+
# Signable
|
2
|
+
|
3
|
+
The signable client provides a simple Ruby interface to the Signable API.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'signable'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install signable
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
### Configuration
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
Signable.configure do |config|
|
25
|
+
config.base_url = ENV.fetch('SIGNABLE_BASE_URL')
|
26
|
+
config.api_key = ENV.fetch('SIGNABLE_API_KEY')
|
27
|
+
end
|
28
|
+
```
|
29
|
+
|
30
|
+
### Retrieve a template
|
31
|
+
|
32
|
+
```ruby
|
33
|
+
Signable::Template.find 'fingerprint'
|
34
|
+
```
|
35
|
+
|
36
|
+
### Build a document
|
37
|
+
|
38
|
+
```ruby
|
39
|
+
Signable::Document.new(template_fingerprint: fingerprint, title: title)
|
40
|
+
```
|
41
|
+
|
42
|
+
A document may also contain merge_fields (see signable documentation)
|
43
|
+
|
44
|
+
### Build a party
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
Signable::Party.new(id: id, name: 'name', email: 'email')
|
48
|
+
```
|
49
|
+
|
50
|
+
Party id can be retrieved from the template
|
51
|
+
|
52
|
+
### Create an envelope
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
envelope = Signable::Envelope.new title: 'title', redirect_url: 'https://www.autoenrolment.co.uk'
|
56
|
+
envelope.documents = documents
|
57
|
+
envelope.parties = parties
|
58
|
+
|
59
|
+
envelope.save
|
60
|
+
```
|
61
|
+
|
62
|
+
## Contributing
|
63
|
+
|
64
|
+
1. Fork it ( http://github.com/<my-github-username>/signable/fork )
|
65
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
66
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
67
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
68
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/lib/signable.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
module Signable
|
2
|
+
class << self
|
3
|
+
attr_accessor :configuration
|
4
|
+
|
5
|
+
def configuration
|
6
|
+
@configuration ||= Configuration.new
|
7
|
+
end
|
8
|
+
|
9
|
+
def configure
|
10
|
+
yield(configuration)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
require "active_support/all"
|
16
|
+
require "httparty"
|
17
|
+
|
18
|
+
require "signable/version"
|
19
|
+
|
20
|
+
require "signable/configuration"
|
21
|
+
|
22
|
+
require "signable/concerns/prefix"
|
23
|
+
require "signable/model/column"
|
24
|
+
require "signable/model/embed"
|
25
|
+
|
26
|
+
require "signable/list"
|
27
|
+
|
28
|
+
require "signable/concerns/query"
|
29
|
+
require "signable/concerns/embed"
|
30
|
+
require "signable/concerns/column"
|
31
|
+
require "signable/concerns/model"
|
32
|
+
require "signable/base"
|
33
|
+
|
34
|
+
require "signable/query/response"
|
35
|
+
require "signable/query/client"
|
36
|
+
|
37
|
+
require "signable/contact"
|
38
|
+
require "signable/envelope"
|
39
|
+
require "signable/template"
|
40
|
+
require "signable/party"
|
41
|
+
require "signable/merge_field"
|
42
|
+
require "signable/document"
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Signable
|
2
|
+
module Concerns
|
3
|
+
module Column
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
def required_column
|
7
|
+
self.class.columns.select(&:required?)
|
8
|
+
end
|
9
|
+
|
10
|
+
def find_column(name)
|
11
|
+
self.class.columns.find { |column| column.match?(name) }
|
12
|
+
end
|
13
|
+
|
14
|
+
module ClassMethods
|
15
|
+
def column(name, options = {})
|
16
|
+
columns << Signable::Model::Column.new(name, options.merge(prefix: prefix))
|
17
|
+
end
|
18
|
+
|
19
|
+
def columns
|
20
|
+
@columns ||= []
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Signable
|
2
|
+
module Concerns
|
3
|
+
module Embed
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
def find_embed(name)
|
7
|
+
self.class.embeds.find { |embed| embed.match?(name) }
|
8
|
+
end
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
def embed(name, options = {})
|
12
|
+
embeds << Signable::Model::Embed.new(name, options.merge({ prefix: prefix }))
|
13
|
+
end
|
14
|
+
|
15
|
+
def embeds
|
16
|
+
@embeds ||= []
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module Signable
|
2
|
+
module Concerns
|
3
|
+
module Model
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
include Signable::Concerns::Embed
|
6
|
+
include Signable::Concerns::Column
|
7
|
+
|
8
|
+
def initialize(attributes = {})
|
9
|
+
@attributes = HashWithIndifferentAccess.new
|
10
|
+
self.attributes = attributes
|
11
|
+
end
|
12
|
+
|
13
|
+
def attributes=(attributes = {})
|
14
|
+
attributes.each do |key, value|
|
15
|
+
if column = find_column(key)
|
16
|
+
@attributes[column.name] = value
|
17
|
+
elsif embed = find_embed(key)
|
18
|
+
values = value.map { |hash| embed.embed_class.new(hash) }
|
19
|
+
@attributes[embed.name] = values
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def form_data
|
25
|
+
hash = HashWithIndifferentAccess.new
|
26
|
+
|
27
|
+
@attributes.each do |key, value|
|
28
|
+
next if key == :id
|
29
|
+
|
30
|
+
if (column = self.find_column(key))
|
31
|
+
hash[column.name_with_prefix] = value
|
32
|
+
elsif (embed = self.find_embed(key))
|
33
|
+
hash[embed.name_with_prefix] = value.map(&:form_data)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
hash
|
38
|
+
end
|
39
|
+
|
40
|
+
def method_missing(method, *args, &block)
|
41
|
+
get_method = method.to_s.gsub('=', '')
|
42
|
+
object = find_column(get_method) || find_embed(get_method)
|
43
|
+
if object
|
44
|
+
if get_method.to_sym == method
|
45
|
+
@attributes[object.name]
|
46
|
+
else
|
47
|
+
@attributes[object.name] = args.first
|
48
|
+
end
|
49
|
+
else
|
50
|
+
super
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def valid?
|
55
|
+
required_column.all? do |column|
|
56
|
+
@attributes[column.name].present?
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
module ClassMethods
|
61
|
+
def prefix
|
62
|
+
name.demodulize.underscore
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Signable
|
2
|
+
module Concerns
|
3
|
+
module Prefix
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
def match?(name)
|
7
|
+
[name_without_prefix, name_with_prefix].include? name.to_s
|
8
|
+
end
|
9
|
+
|
10
|
+
def name_with_prefix
|
11
|
+
"#{prefix}_#{name}"
|
12
|
+
end
|
13
|
+
|
14
|
+
def name_without_prefix
|
15
|
+
name.to_s.gsub("#{prefix}_", "")
|
16
|
+
end
|
17
|
+
|
18
|
+
def prefix
|
19
|
+
options[:prefix]
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module Signable
|
2
|
+
module Concerns
|
3
|
+
module Query
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
def save
|
7
|
+
return false unless valid?
|
8
|
+
persisted? ? update : create
|
9
|
+
end
|
10
|
+
|
11
|
+
def delete
|
12
|
+
self.class.client.delete self.class.entry_point, id
|
13
|
+
end
|
14
|
+
|
15
|
+
def persisted?
|
16
|
+
id.present? rescue false
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def update
|
22
|
+
response = self.class.client.update self.class.entry_point, id, self
|
23
|
+
response.ok?
|
24
|
+
end
|
25
|
+
|
26
|
+
def create
|
27
|
+
response = self.class.client.create self.class.entry_point, self
|
28
|
+
if response.ok?
|
29
|
+
self.attributes = response.object
|
30
|
+
true
|
31
|
+
else
|
32
|
+
false
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
module ClassMethods
|
37
|
+
def all(offset = 0, limit = 10)
|
38
|
+
response = client.all(entry_point, offset, limit)
|
39
|
+
|
40
|
+
if response.ok?
|
41
|
+
List.new(self, response.object)
|
42
|
+
else
|
43
|
+
[]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def find(id)
|
48
|
+
response = client.find(entry_point, id)
|
49
|
+
|
50
|
+
if response.ok?
|
51
|
+
self.new response.object
|
52
|
+
else
|
53
|
+
nil
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def entry_point
|
58
|
+
prefix.pluralize
|
59
|
+
end
|
60
|
+
|
61
|
+
def client
|
62
|
+
@client ||= Signable::Query::Client.new
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Signable
|
2
|
+
class Document
|
3
|
+
include Signable::Concerns::Model
|
4
|
+
|
5
|
+
column :template_fingerprint, presence: true
|
6
|
+
column :title, presence: true
|
7
|
+
column :pdf_url
|
8
|
+
column :pages
|
9
|
+
embed :merge_fields
|
10
|
+
|
11
|
+
def page
|
12
|
+
pages.first
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Signable
|
2
|
+
class Envelope < Signable::Base
|
3
|
+
|
4
|
+
column :title, presence: true
|
5
|
+
column :fingerprint
|
6
|
+
column :status
|
7
|
+
column :signed_pdf
|
8
|
+
column :signing_embed
|
9
|
+
column :redirect_url
|
10
|
+
embed :documents
|
11
|
+
embed :parties
|
12
|
+
|
13
|
+
def update
|
14
|
+
raise "not available"
|
15
|
+
end
|
16
|
+
|
17
|
+
def delete
|
18
|
+
raise "not available"
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Signable
|
2
|
+
class List < Struct.new(:data_type, :hash)
|
3
|
+
|
4
|
+
def offset
|
5
|
+
hash['offset']
|
6
|
+
end
|
7
|
+
|
8
|
+
def limit
|
9
|
+
hash['limit']
|
10
|
+
end
|
11
|
+
|
12
|
+
def total
|
13
|
+
hash["total_#{data_name}"]
|
14
|
+
end
|
15
|
+
|
16
|
+
def data
|
17
|
+
@data ||= hash[data_name].map { |attributes| data_type.new attributes }
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def data_name
|
23
|
+
data_type.name.demodulize.underscore.pluralize
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Signable
|
2
|
+
class MergeField
|
3
|
+
include Signable::Concerns::Model
|
4
|
+
|
5
|
+
# Must be before the columns call because the column class method use
|
6
|
+
# the prefix method
|
7
|
+
def self.prefix
|
8
|
+
'field'
|
9
|
+
end
|
10
|
+
|
11
|
+
column :id
|
12
|
+
column :merge
|
13
|
+
column :value
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Signable
|
2
|
+
module Query
|
3
|
+
class Client
|
4
|
+
include HTTParty
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
self.class.base_uri "https://#{Signable.configuration.base_url}/v1"
|
8
|
+
self.class.basic_auth Signable.configuration.api_key, ''
|
9
|
+
self.class.default_options[:verify] = false
|
10
|
+
end
|
11
|
+
|
12
|
+
def all(entry_point, offset, limit)
|
13
|
+
response = self.class.get "/#{entry_point}", query: { offset: offset, limit: limit }
|
14
|
+
Response.new response
|
15
|
+
end
|
16
|
+
|
17
|
+
def find(entry_point, id)
|
18
|
+
response = self.class.get "/#{entry_point}/#{id}"
|
19
|
+
Response.new response
|
20
|
+
end
|
21
|
+
|
22
|
+
def update(entry_point, id, object)
|
23
|
+
response = self.class.put "/#{entry_point}/#{id}", body: jsonify(object.form_data)
|
24
|
+
Response.new response
|
25
|
+
end
|
26
|
+
|
27
|
+
def create(entry_point, object)
|
28
|
+
response = self.class.post "/#{entry_point}", body: jsonify(object.form_data)
|
29
|
+
Response.new response
|
30
|
+
end
|
31
|
+
|
32
|
+
def delete(entry_poind, id)
|
33
|
+
response = self.class.delete "/#{entry_point}/#{id}"
|
34
|
+
Response.new response
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def jsonify(hash)
|
40
|
+
hash.each do |key, value|
|
41
|
+
if value.is_a? Array
|
42
|
+
hash[key] = value.to_json
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
hash
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Signable
|
2
|
+
class Template < Signable::Base
|
3
|
+
|
4
|
+
column :id
|
5
|
+
column :fingerprint
|
6
|
+
column :title
|
7
|
+
embed :parties
|
8
|
+
|
9
|
+
def save
|
10
|
+
raise "not available"
|
11
|
+
end
|
12
|
+
|
13
|
+
def update
|
14
|
+
raise "not available"
|
15
|
+
end
|
16
|
+
|
17
|
+
def delete
|
18
|
+
raise "not available"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/signable.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'signable/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "signable"
|
8
|
+
spec.version = Signable::VERSION
|
9
|
+
spec.authors = ["Anthony Laibe"]
|
10
|
+
spec.email = ["anthony@laibe.cc"]
|
11
|
+
spec.summary = %q{The signable client provides a simple Ruby interface to the Signable API.}
|
12
|
+
spec.description = %q{The signable client provides a simple Ruby interface to the Signable API.}
|
13
|
+
spec.homepage = "https://github.com/smartpension/signable"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
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_development_dependency "bundler", "~> 1.5"
|
22
|
+
spec.add_development_dependency "rake", "~> 10.4"
|
23
|
+
spec.add_development_dependency "rspec", "~> 3.2"
|
24
|
+
|
25
|
+
spec.add_dependency "activesupport", "~> 4.2"
|
26
|
+
spec.add_dependency "httparty", "~> 0.13"
|
27
|
+
|
28
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
DataType = Struct.new(:hash)
|
4
|
+
|
5
|
+
describe Signable::List do
|
6
|
+
|
7
|
+
let(:hash) {{ 'offset' => 5, 'limit' => 12, 'total_data_types' => 2, 'data_types' => [{},{}] }}
|
8
|
+
let(:list) { Signable::List.new(DataType, hash) }
|
9
|
+
|
10
|
+
describe "#offset" do
|
11
|
+
subject { list.offset }
|
12
|
+
|
13
|
+
it { should be 5 }
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "#limit" do
|
17
|
+
subject { list.limit }
|
18
|
+
|
19
|
+
it { should be 12 }
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "#total" do
|
23
|
+
subject { list.total }
|
24
|
+
|
25
|
+
it { should be 2 }
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "#data" do
|
29
|
+
context "length" do
|
30
|
+
subject { list.data.length }
|
31
|
+
it { should be 2 }
|
32
|
+
end
|
33
|
+
|
34
|
+
context "class name" do
|
35
|
+
subject { list.data.first.class.name }
|
36
|
+
it { should be_eql 'DataType' }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Signable::Model::Column do
|
4
|
+
|
5
|
+
it_behaves_like 'Prefix'
|
6
|
+
|
7
|
+
describe "#required?" do
|
8
|
+
subject { column.required? }
|
9
|
+
context "when presence is true" do
|
10
|
+
let(:column) { Signable::Model::Column.new('name', presence: true) }
|
11
|
+
it { should be true }
|
12
|
+
end
|
13
|
+
|
14
|
+
context "when presence is false" do
|
15
|
+
let(:column) { Signable::Model::Column.new('name', presence: false) }
|
16
|
+
it { should be false }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Signable::Model::Embed do
|
4
|
+
|
5
|
+
it_behaves_like 'Prefix'
|
6
|
+
|
7
|
+
describe "#embed_class" do
|
8
|
+
let(:column) { Signable::Model::Embed.new('contacts') }
|
9
|
+
|
10
|
+
subject { column.embed_class }
|
11
|
+
|
12
|
+
it { should be Signable::Contact }
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Signable::Query::Response do
|
4
|
+
|
5
|
+
describe "#ok?" do
|
6
|
+
let(:response) { Signable::Query::Response.new http_response }
|
7
|
+
subject { response.ok? }
|
8
|
+
|
9
|
+
context "when code is 200" do
|
10
|
+
let(:http_response) { double 'http_response', code: 200 }
|
11
|
+
it { should be true }
|
12
|
+
end
|
13
|
+
|
14
|
+
context "when code is 202" do
|
15
|
+
let(:http_response) { double 'http_response', code: 202 }
|
16
|
+
it { should be true }
|
17
|
+
end
|
18
|
+
|
19
|
+
context "when code is !200" do
|
20
|
+
let(:http_response) { double 'http_response', code: 205 }
|
21
|
+
it { should be false }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "#object" do
|
26
|
+
let(:http_response) { double 'http_response', body: { bar: 'foo' }.to_json }
|
27
|
+
|
28
|
+
it "parse body response" do
|
29
|
+
response = Signable::Query::Response.new http_response
|
30
|
+
expect(response.object).to be_eql({ 'bar' => 'foo' })
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
shared_examples 'Column' do
|
2
|
+
|
3
|
+
before do
|
4
|
+
described_class.instance_variable_set(:@columns, [])
|
5
|
+
end
|
6
|
+
|
7
|
+
describe "#required_column" do
|
8
|
+
it "return required column only" do
|
9
|
+
described_class.column :required, presence: true
|
10
|
+
described_class.column :non_required
|
11
|
+
|
12
|
+
object = described_class.new
|
13
|
+
expect(object.required_column.length).to be 1
|
14
|
+
expect(object.required_column.first.name).to be :required
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "#find_column" do
|
19
|
+
it "return first column which match the name" do
|
20
|
+
described_class.column :match
|
21
|
+
described_class.column :non_match
|
22
|
+
|
23
|
+
object = described_class.new
|
24
|
+
expect(object.find_column('match').name).to be :match
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe ".column" do
|
29
|
+
it "add a new column to the list of columns" do
|
30
|
+
described_class.column :foo
|
31
|
+
expect(described_class.columns.last.name).to be :foo
|
32
|
+
end
|
33
|
+
|
34
|
+
it "automatically add the prefix" do
|
35
|
+
described_class.column :foo
|
36
|
+
|
37
|
+
expect(described_class.columns.last.prefix).to be_eql described_class.name.demodulize.underscore
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
shared_examples 'Embed' do
|
2
|
+
describe "#find_embed" do
|
3
|
+
it "return first embed which match the name" do
|
4
|
+
described_class.embed :match
|
5
|
+
described_class.embed :non_match
|
6
|
+
|
7
|
+
object = described_class.new
|
8
|
+
expect(object.find_embed('match').name).to be :match
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe ".embed" do
|
13
|
+
it "add a new embed to the list of embeds" do
|
14
|
+
described_class.embed :foo
|
15
|
+
expect(described_class.embeds.last.name).to be :foo
|
16
|
+
end
|
17
|
+
|
18
|
+
it "automatically add the prefix" do
|
19
|
+
described_class.embed :foo
|
20
|
+
|
21
|
+
expect(described_class.embeds.last.prefix).to be_eql described_class.name.demodulize.underscore
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
Signable::Embedded = Struct.new(:arg) do
|
2
|
+
|
3
|
+
def form_data
|
4
|
+
"embedded"
|
5
|
+
end
|
6
|
+
|
7
|
+
end
|
8
|
+
|
9
|
+
shared_examples 'Model' do
|
10
|
+
|
11
|
+
it_behaves_like 'Column'
|
12
|
+
it_behaves_like 'Embed'
|
13
|
+
|
14
|
+
before do
|
15
|
+
described_class.instance_variable_set(:@columns, [])
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "#attributes" do
|
19
|
+
it "set attributes specified by column" do
|
20
|
+
described_class.column :foo
|
21
|
+
object = described_class.new foo: 'bar'
|
22
|
+
expect(object.foo).to be_eql 'bar'
|
23
|
+
end
|
24
|
+
|
25
|
+
it "set object specified by embed" do
|
26
|
+
described_class.embed :embeddeds
|
27
|
+
object = described_class.new embeddeds: ['bar']
|
28
|
+
expect(object.embeddeds.first.arg).to be_eql 'bar'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe '#form_data' do
|
33
|
+
subject { described.form_data }
|
34
|
+
|
35
|
+
context 'when attribute is a column' do
|
36
|
+
let(:described) { described_class.new foo: 'bar' }
|
37
|
+
|
38
|
+
before do
|
39
|
+
described_class.column :foo
|
40
|
+
end
|
41
|
+
|
42
|
+
it { should be_eql({ "base_foo" => "bar" }) }
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'when attribute is an embed' do
|
46
|
+
let(:described) { described_class.new embeddeds: ['bar'] }
|
47
|
+
|
48
|
+
before do
|
49
|
+
described_class.embed :embeddeds
|
50
|
+
end
|
51
|
+
|
52
|
+
it { should be_eql({ "base_embeddeds" => ["embedded"] }) }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "#valid?" do
|
57
|
+
subject { described.valid? }
|
58
|
+
|
59
|
+
before do
|
60
|
+
described_class.column :required, presence: true
|
61
|
+
end
|
62
|
+
|
63
|
+
context "when all required fields are present" do
|
64
|
+
let (:described) { described_class.new required: 'test' }
|
65
|
+
|
66
|
+
it { should be true }
|
67
|
+
end
|
68
|
+
|
69
|
+
context "when all required fields are not present" do
|
70
|
+
let (:described) { described_class.new }
|
71
|
+
it { should be false }
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe ".prefix" do
|
76
|
+
subject { described_class.prefix }
|
77
|
+
|
78
|
+
it { should be_eql described_class.name.demodulize.underscore }
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
shared_examples 'Prefix' do
|
2
|
+
|
3
|
+
let(:described) { described_class.new 'test', { prefix: 'prefix' } }
|
4
|
+
|
5
|
+
describe "#match?" do
|
6
|
+
subject { described.match?(name) }
|
7
|
+
context "when name match name with prefix" do
|
8
|
+
let(:name) { 'prefix_test'}
|
9
|
+
it { should be true }
|
10
|
+
end
|
11
|
+
|
12
|
+
context "when name match name without prefix" do
|
13
|
+
let(:name) { 'test'}
|
14
|
+
it { should be true }
|
15
|
+
end
|
16
|
+
|
17
|
+
context "when name do not match" do
|
18
|
+
let(:name) { 'something'}
|
19
|
+
it { should be false }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "#name_with_prefix" do
|
24
|
+
subject { described.name_with_prefix }
|
25
|
+
|
26
|
+
it { should be_eql 'prefix_test' }
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "#prefix" do
|
30
|
+
subject { described.prefix }
|
31
|
+
|
32
|
+
it { should be_eql 'prefix' }
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "#name_without_prefix" do
|
36
|
+
let(:described) { described_class.new 'prefix_test', { prefix: 'prefix' } }
|
37
|
+
|
38
|
+
subject { described.name_without_prefix }
|
39
|
+
|
40
|
+
it { should be_eql 'test' }
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
shared_examples 'Query' do
|
2
|
+
|
3
|
+
before do
|
4
|
+
described_class.instance_variable_set(:@columns, [])
|
5
|
+
described_class.column :id
|
6
|
+
end
|
7
|
+
|
8
|
+
let(:response) { double 'response', ok?: false }
|
9
|
+
|
10
|
+
describe "#save" do
|
11
|
+
context "when persisted" do
|
12
|
+
let(:described) { described_class.new id: 1 }
|
13
|
+
|
14
|
+
it "call client update" do
|
15
|
+
expect(described_class.client).to receive(:update).with(described_class.entry_point, 1, described).and_return response
|
16
|
+
described.save
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context "#when not persisted" do
|
21
|
+
let(:described) { described_class.new }
|
22
|
+
|
23
|
+
it "call client create" do
|
24
|
+
expect(described_class.client).to receive(:create).with(described_class.entry_point, described).and_return response
|
25
|
+
described.save
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "#delete" do
|
31
|
+
let(:described) { described_class.new id: 1 }
|
32
|
+
|
33
|
+
it "call client delete" do
|
34
|
+
expect(described_class.client).to receive(:delete).with(described_class.entry_point, described.id).and_return response
|
35
|
+
described.delete
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "#persisted?" do
|
40
|
+
let(:described) { described_class.new }
|
41
|
+
|
42
|
+
subject { described.persisted?}
|
43
|
+
|
44
|
+
context "when id is nil" do
|
45
|
+
it { should be false }
|
46
|
+
end
|
47
|
+
|
48
|
+
context "when id is present" do
|
49
|
+
before do
|
50
|
+
described.id = 1
|
51
|
+
end
|
52
|
+
it { should be true }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe ".all" do
|
57
|
+
it "call client all with default value for offet and limit" do
|
58
|
+
expect(described_class.client).to receive(:all).with(described_class.entry_point, 0, 10).and_return response
|
59
|
+
described_class.all
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe ".find" do
|
64
|
+
it "call client find" do
|
65
|
+
expect(described_class.client).to receive(:find).with(described_class.entry_point, 1).and_return response
|
66
|
+
described_class.find 1
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
metadata
ADDED
@@ -0,0 +1,163 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: signable
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Anthony Laibe
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-03-30 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.5'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.5'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.4'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.4'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.2'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.2'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: activesupport
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '4.2'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '4.2'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: httparty
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0.13'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0.13'
|
83
|
+
description: The signable client provides a simple Ruby interface to the Signable
|
84
|
+
API.
|
85
|
+
email:
|
86
|
+
- anthony@laibe.cc
|
87
|
+
executables: []
|
88
|
+
extensions: []
|
89
|
+
extra_rdoc_files: []
|
90
|
+
files:
|
91
|
+
- ".gitignore"
|
92
|
+
- Gemfile
|
93
|
+
- LICENSE.txt
|
94
|
+
- README.md
|
95
|
+
- Rakefile
|
96
|
+
- lib/signable.rb
|
97
|
+
- lib/signable/base.rb
|
98
|
+
- lib/signable/concerns/column.rb
|
99
|
+
- lib/signable/concerns/embed.rb
|
100
|
+
- lib/signable/concerns/model.rb
|
101
|
+
- lib/signable/concerns/prefix.rb
|
102
|
+
- lib/signable/concerns/query.rb
|
103
|
+
- lib/signable/configuration.rb
|
104
|
+
- lib/signable/contact.rb
|
105
|
+
- lib/signable/document.rb
|
106
|
+
- lib/signable/envelope.rb
|
107
|
+
- lib/signable/list.rb
|
108
|
+
- lib/signable/merge_field.rb
|
109
|
+
- lib/signable/model/column.rb
|
110
|
+
- lib/signable/model/embed.rb
|
111
|
+
- lib/signable/party.rb
|
112
|
+
- lib/signable/query/client.rb
|
113
|
+
- lib/signable/query/response.rb
|
114
|
+
- lib/signable/template.rb
|
115
|
+
- lib/signable/version.rb
|
116
|
+
- signable.gemspec
|
117
|
+
- spec/signable/base_spec.rb
|
118
|
+
- spec/signable/list_spec.rb
|
119
|
+
- spec/signable/model/column_spec.rb
|
120
|
+
- spec/signable/model/embed_spec.rb
|
121
|
+
- spec/signable/query/response_spec.rb
|
122
|
+
- spec/spec_helper.rb
|
123
|
+
- spec/support/concerns/column.rb
|
124
|
+
- spec/support/concerns/embed.rb
|
125
|
+
- spec/support/concerns/model.rb
|
126
|
+
- spec/support/concerns/prefix.rb
|
127
|
+
- spec/support/concerns/query.rb
|
128
|
+
homepage: https://github.com/smartpension/signable
|
129
|
+
licenses:
|
130
|
+
- MIT
|
131
|
+
metadata: {}
|
132
|
+
post_install_message:
|
133
|
+
rdoc_options: []
|
134
|
+
require_paths:
|
135
|
+
- lib
|
136
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
137
|
+
requirements:
|
138
|
+
- - ">="
|
139
|
+
- !ruby/object:Gem::Version
|
140
|
+
version: '0'
|
141
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
requirements: []
|
147
|
+
rubyforge_project:
|
148
|
+
rubygems_version: 2.2.2
|
149
|
+
signing_key:
|
150
|
+
specification_version: 4
|
151
|
+
summary: The signable client provides a simple Ruby interface to the Signable API.
|
152
|
+
test_files:
|
153
|
+
- spec/signable/base_spec.rb
|
154
|
+
- spec/signable/list_spec.rb
|
155
|
+
- spec/signable/model/column_spec.rb
|
156
|
+
- spec/signable/model/embed_spec.rb
|
157
|
+
- spec/signable/query/response_spec.rb
|
158
|
+
- spec/spec_helper.rb
|
159
|
+
- spec/support/concerns/column.rb
|
160
|
+
- spec/support/concerns/embed.rb
|
161
|
+
- spec/support/concerns/model.rb
|
162
|
+
- spec/support/concerns/prefix.rb
|
163
|
+
- spec/support/concerns/query.rb
|