sk_sdk 0.0.7 → 0.0.8
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +18 -3
- data/Rakefile +13 -15
- data/VERSION +1 -1
- data/ci/Gemfile +11 -0
- data/lib/sk_sdk/README_Base.rdoc +64 -58
- data/lib/sk_sdk/base.rb +4 -4
- data/lib/sk_sdk/oauth.rb +1 -2
- data/lib/sk_sdk/omni_auth/README.rdoc +1 -1
- data/lib/sk_sdk/omni_auth/salesking.rb +2 -1
- data/lib/sk_sdk/sync.rb +170 -0
- data/sk_sdk.gemspec +20 -12
- data/spec/resources_spec_helper.rb +4 -2
- data/spec/sk_sdk/base_spec.rb +2 -2
- data/spec/sk_sdk/oauth_spec.rb +1 -1
- data/spec/sk_sdk/resources/clients_spec.rb +2 -2
- data/spec/sk_sdk/resources/credit_note_spec.rb +17 -11
- data/spec/sk_sdk/resources/invoice_spec.rb +17 -11
- data/spec/sk_sdk/resources/product_spec.rb +2 -2
- data/spec/sk_sdk/signed_request_spec.rb +6 -2
- data/spec/sk_sdk/sync_field_spec.rb +41 -0
- data/spec/sk_sdk/sync_spec.rb +126 -0
- data/spec/spec_helper.rb +2 -2
- metadata +49 -19
- data/lib/sk_sdk/ar_cli.rb +0 -33
- data/spec/sk_sdk/ar_cli_spec.rb +0 -41
- /data/lib/sk_sdk/{ar_cli/patches → ar_patches}/ar2/base.rb +0 -0
- /data/lib/sk_sdk/{ar_cli/patches → ar_patches}/ar2/validations.rb +0 -0
- /data/lib/sk_sdk/{ar_cli/patches → ar_patches}/ar3/base.rb +0 -0
- /data/lib/sk_sdk/{ar_cli/patches → ar_patches}/ar3/validations.rb +0 -0
data/README.rdoc
CHANGED
@@ -13,6 +13,7 @@ Dependencies (gem's):
|
|
13
13
|
* activesupport
|
14
14
|
* activeresource
|
15
15
|
* curb
|
16
|
+
* sk_api_schema
|
16
17
|
|
17
18
|
== Classes
|
18
19
|
|
@@ -22,22 +23,36 @@ All classes must be explicitly required so each can be used on their own.
|
|
22
23
|
require 'sk_sdk/oauth'
|
23
24
|
require 'sk_sdk/base'
|
24
25
|
|
25
|
-
=== API client
|
26
|
+
=== API client Base
|
26
27
|
|
27
28
|
Uses ActiveResource to CRUD SalesKing object's {see usage in README}[https://github.com/salesking/sk_sdk/blob/master/lib/sk_sdk/README_Base.rdoc]
|
28
29
|
|
29
30
|
=== oAuth
|
30
31
|
|
31
|
-
Handling oAuth related URL's and getting an access token
|
32
|
+
Handling oAuth related URL's and getting an access token.
|
33
|
+
There also is an omniAuth strategy in case you are using it.
|
32
34
|
|
33
35
|
=== SignedRequest
|
34
36
|
|
35
37
|
Helping in de/encoding of signed_request parameter available in canvas pages and
|
36
38
|
PubSub/Webhook callbacks.
|
37
39
|
|
40
|
+
=== Sync
|
41
|
+
|
42
|
+
Synchronize a local with an remote object. Tackles the problem of normalizing
|
43
|
+
objects to match internal data structures. Synchronization is done by a
|
44
|
+
field-mapping which also supports transition methods for each way.
|
45
|
+
|
38
46
|
== Usage
|
39
47
|
|
40
48
|
Read specs: https://github.com/salesking/sk_sdk/tree/master/spec/sk_sdk
|
41
49
|
|
50
|
+
== Tests
|
51
|
+
|
52
|
+
Before you run the tests use bundler to install all required gems:
|
53
|
+
# git clone
|
54
|
+
# cd into dir
|
55
|
+
BUNDLE_GEMFILE=ci/Gemfile bundle install
|
56
|
+
BUNDLE_GEMFILE=ci/Gemfile bundle exec rake spec
|
42
57
|
|
43
|
-
Copyright (c) 2011 Georg Leciejewski, released under the MIT license
|
58
|
+
Copyright (c) 2011 Georg Leciejewski, released under the MIT license
|
data/Rakefile
CHANGED
@@ -1,23 +1,23 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'rake'
|
3
|
-
require '
|
4
|
-
|
3
|
+
require 'rdoc/task'
|
4
|
+
require 'rspec'
|
5
|
+
require 'rspec/core/rake_task'
|
5
6
|
|
6
7
|
begin
|
7
8
|
require 'jeweler'
|
8
9
|
Jeweler::Tasks.new do |gem|
|
9
10
|
gem.name = "sk_sdk"
|
10
11
|
gem.summary = %Q{SalesKing SDK Ruby}
|
11
|
-
gem.description = %Q{Connect your business world with SalesKing. This gem gives ruby developers a jump-start for building SalesKing Business Apps.
|
12
|
+
gem.description = %Q{Connect your business world with SalesKing. This gem gives ruby developers a jump-start for building SalesKing Business Apps. It provides classes to handle oAuth, make RESTfull API requests and parses JSON Schema }
|
12
13
|
gem.email = "gl@salesking.eu"
|
13
14
|
gem.homepage = "http://github.com/salesking/sk_sdk"
|
14
15
|
gem.authors = ["Georg Leciejewski"]
|
15
16
|
gem.add_dependency 'curb'
|
16
17
|
gem.add_dependency 'activesupport'
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
gem.add_development_dependency "rspec", "< 2"
|
18
|
+
gem.add_dependency 'sk_api_schema'
|
19
|
+
gem.add_dependency 'activeresource'
|
20
|
+
gem.add_development_dependency "rspec"
|
21
21
|
gem.add_development_dependency "rcov"
|
22
22
|
end
|
23
23
|
Jeweler::GemcutterTasks.new
|
@@ -28,19 +28,17 @@ end
|
|
28
28
|
desc 'Default: run specs.'
|
29
29
|
task :default => :spec
|
30
30
|
|
31
|
-
spec_files = Rake::FileList["spec/**/*_spec.rb"]
|
32
|
-
|
33
31
|
desc "Run specs"
|
34
|
-
|
35
|
-
t.
|
36
|
-
|
32
|
+
RSpec::Core::RakeTask.new do |t|
|
33
|
+
t.pattern = "./spec/**/*_spec.rb" # don't need this, it's default.
|
34
|
+
# Put spec opts in a file named .rspec in root
|
37
35
|
end
|
38
36
|
|
39
37
|
desc "Generate code coverage"
|
40
|
-
|
41
|
-
t.
|
38
|
+
RSpec::Core::RakeTask.new(:coverage) do |t|
|
39
|
+
t.pattern = "./spec/**/*_spec.rb" # don't need this, it's default.
|
42
40
|
t.rcov = true
|
43
|
-
t.rcov_opts = ['--exclude', 'spec
|
41
|
+
t.rcov_opts = ['--exclude', 'spec']
|
44
42
|
end
|
45
43
|
|
46
44
|
desc 'Generate documentation.'
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.8
|
data/ci/Gemfile
ADDED
data/lib/sk_sdk/README_Base.rdoc
CHANGED
@@ -1,15 +1,13 @@
|
|
1
1
|
= SalesKing API Client
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
Getter/Setter methods(less restrict). The client also adds some patches to AR to
|
6
|
-
fix json parsing issues.
|
3
|
+
Easily access SalesKing resources in a RESTfull way with this ActiveResource
|
4
|
+
based SalesKing API client.
|
7
5
|
|
8
6
|
== Install
|
9
7
|
|
10
8
|
gem install sk_sdk
|
11
9
|
|
12
|
-
|
10
|
+
For bundler add this to the Gemfile
|
13
11
|
|
14
12
|
gem "sk_sdk"
|
15
13
|
# or directly require a used class
|
@@ -22,15 +20,19 @@ Dependencies (gem's):
|
|
22
20
|
|
23
21
|
== Authorization
|
24
22
|
|
25
|
-
This client should be used with an oAuth2 access_token
|
26
|
-
|
27
|
-
|
23
|
+
This client should be used with an oAuth2 access_token. But you can still use
|
24
|
+
HTTBasic Auth(username & password). For a quick start BasicAuth is definitely
|
25
|
+
easier, but it is less secure since you cannot track which client
|
28
26
|
is accessing your account and the client has the full rights of the user. So if
|
29
27
|
someone gets your credentials he can log into your SalesKing account and do
|
30
28
|
whatever you can!
|
31
29
|
|
30
|
+
For a production environment using HTTP BasicAuth you should create one user
|
31
|
+
per api client and restrict his rights with our role-system!
|
32
|
+
|
32
33
|
Getting an access_token or checking is validity is not the scope of this
|
33
|
-
library, it merely sets
|
34
|
+
library, it merely sets an AUTHORIZATION header if you added a token in the
|
35
|
+
connection settings.
|
34
36
|
AUTHORIZATION: Bearer YourAccessToken
|
35
37
|
See our {oAuth helper class}[https://github.com/salesking/sk_sdk/blob/master/lib/sk_sdk/oauth.rb]
|
36
38
|
and read our {oAuth docs}[http://dev.blog.salesking.eu/docs/authentication/].
|
@@ -40,81 +42,85 @@ and read our {oAuth docs}[http://dev.blog.salesking.eu/docs/authentication/].
|
|
40
42
|
SalesKing's api interface is RESTful(mostly) and returns & accepts JSON data.
|
41
43
|
All resources such as clients, invoices, products can be accessed via URL's
|
42
44
|
through standard HTTP methods GET, POST, PUT and DELETE.
|
43
|
-
see available objects and endpoints here:
|
44
|
-
https://github.com/salesking/sk_api_schema/tree/master/json
|
45
45
|
|
46
|
-
|
47
|
-
|
46
|
+
The available objects and their endpoints(links) are described in {our json-schema}[https://github.com/salesking/sk_api_schema/tree/master/json].
|
47
|
+
Take a look into the links-section of each schema to see available
|
48
|
+
endpoints/routes and their parameter f.ex. to apply search filtering
|
49
|
+
|
50
|
+
Your classes simply descend from SK::SDK::Base and need the connection settings.
|
51
|
+
You MUST provide the full URL using the right protocol in the connection and
|
52
|
+
remember our production system only supports HTTPS:
|
53
|
+
https + SUBDomain + salesking url + /api
|
54
|
+
|
55
|
+
Create a single class
|
48
56
|
|
49
57
|
require 'sk_sdk/base'
|
50
|
-
|
58
|
+
|
51
59
|
class Client < SK::SDK::Base;end
|
52
60
|
|
53
|
-
#
|
61
|
+
# connection using BasicAuth
|
62
|
+
Client.set_connection {:site => 'https://my_sub.salesking.eu/api',
|
63
|
+
:user => 'my-users@login-email.com',
|
64
|
+
:password => 'password' })
|
65
|
+
|
66
|
+
client = Client.new(:last_name => 'Ding', :organisation => "Carpenters Inc.")
|
67
|
+
client.first_name = "Bill"
|
68
|
+
client.save
|
69
|
+
|
70
|
+
|
71
|
+
Create multiple classes at once
|
72
|
+
|
73
|
+
require 'sk_sdk/base'
|
54
74
|
module; King; end
|
55
75
|
%w[Client Invoice Product LineItem].each do |model|
|
56
76
|
eval "class King::#{model} < SK::SDK::Base;end"
|
57
77
|
end
|
58
78
|
|
59
|
-
#
|
79
|
+
# connection using oAuth access token
|
60
80
|
SK::SDK::Base.set_connection {:site => 'https://my_sub.salesking.eu/api',
|
61
|
-
:
|
62
|
-
:password => 'password' })
|
63
|
-
#OR Use an oAuth access token
|
64
|
-
#SK::SDK::Base.set_connection {:site => 'https://my_sub.salesking.eu/api',
|
65
|
-
# :token => 'someAccessToken'})
|
66
|
-
|
67
|
-
# use it
|
68
|
-
client = Client.new(:last_name=> 'Meister')
|
69
|
-
client.first_name = "Bau"
|
70
|
-
client.save
|
71
|
-
credit_note = King::CreditNote.new
|
72
|
-
|
73
|
-
You MUST provide the full url using the right protocol when you set the
|
74
|
-
connection and remember our production system only supports HTTPS:
|
75
|
-
http/https + SUBDomain + salesking url + /api
|
76
|
-
|
77
|
-
The old ArCli.make method to create the classes, still exists but is deprecated:
|
81
|
+
:token => 'someAccessToken'})
|
78
82
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
83
|
+
invoice = Invoice.new
|
84
|
+
invoice.title = "Hosting 2011"
|
85
|
+
item = LineItem.new { :position=>1, :name => 'Daily Backup',
|
86
|
+
:quantity_unit=> 'Month', :quantity => 12,
|
87
|
+
:price_single => 10.00 }
|
88
|
+
invoice.line_items = [ item ]
|
89
|
+
invoice.status = 'open'
|
90
|
+
invoice.save
|
85
91
|
|
86
92
|
|
87
93
|
Want to know more about REST style webservices?
|
88
94
|
* http://en.wikipedia.org/wiki/Representational_State_Transfer
|
89
95
|
* http://www.google.com/search?q=REST+site%3Awww.infoq.com
|
90
96
|
|
91
|
-
|
92
|
-
|
93
|
-
Authentification can be done with oAuth2 but we still support HTTP BasicAuth
|
94
|
-
using your SalesKing login email and password. oAuth examples(support) will
|
95
|
-
follow.
|
96
|
-
|
97
|
-
For a production environment be advised to create a user, per api client, and
|
98
|
-
restrict his rights with our build in role-system!
|
97
|
+
== Hints on ActiveResource
|
99
98
|
|
99
|
+
* Most of the magic is coming from ActiveResource so you should read {its README and code}[https://github.com/rails/rails/tree/master/activeresource]
|
100
|
+
* This client does NOT rely on parsing the JSON Schema, since ActiveResource(AR) creates the Getter/Setter methods.
|
101
|
+
* We added some patches for AR to fix JSON parsing issues, due to our nesting.
|
102
|
+
* non-restful routes can be accessed by custom methods {see examples in AR}[https://github.com/rails/rails/blob/master/activeresource/lib/active_resource/custom_methods.rb]
|
103
|
+
Invoice.find('uuid').post(:print, :template_id => 'pdf-template-uuid')
|
100
104
|
|
101
|
-
|
105
|
+
== Tutorials & Tools
|
102
106
|
|
103
|
-
Since browsers do not support PUT/DELETE methods you can use CURL
|
104
|
-
command-line http client
|
105
|
-
http-basic-auth
|
107
|
+
Since browsers do not support PUT/DELETE methods you can use CURL(a linux
|
108
|
+
command-line http client) for testing. And of course any http library supporting
|
109
|
+
http-basic-auth.
|
106
110
|
|
107
|
-
* Getting started
|
108
|
-
*
|
109
|
-
* Chrome cRest extension
|
110
|
-
* Poster FF-Plugin - make HTTP request
|
111
|
-
* JSONView FF-Plugin - view json in firefox
|
112
|
-
* JSONovich FF-Plugin
|
111
|
+
* {Getting started tutorial}[http://dev.blog.salesking.eu/api/]
|
112
|
+
* {SalesKing API Schema}[https://github.com/salesking/sk_api_schema]
|
113
|
+
* {Chrome cRest extension}[https://chrome.google.com/extensions/detail/baedhhmoaooldchehjhlpppaieoglhml]
|
114
|
+
* {Poster FF-Plugin - make HTTP request}[https://addons.mozilla.org/en-US/firefox/addon/2691/] (you must be logged into SalesKing)
|
115
|
+
* {JSONView FF-Plugin - view json in firefox}[https://addons.mozilla.org/de/firefox/addon/10869/]
|
116
|
+
* {JSONovich FF-Plugin}[https://addons.mozilla.org/de/firefox/addon/10122/]
|
113
117
|
|
114
118
|
== Tests / Specs
|
115
119
|
|
116
|
-
|
120
|
+
Please read the tests as they provide some more examples especially those in
|
121
|
+
spec/resources
|
117
122
|
|
123
|
+
Run the specs with:
|
118
124
|
rake coverage
|
119
125
|
|
120
126
|
Copyright (c) 2011 Georg Leciejewski, released under the MIT license
|
data/lib/sk_sdk/base.rb
CHANGED
@@ -4,11 +4,11 @@ require 'active_resource'
|
|
4
4
|
require 'active_resource/version'
|
5
5
|
# patches are for specific AR version
|
6
6
|
if ActiveResource::VERSION::MAJOR == 3
|
7
|
-
require 'sk_sdk/
|
8
|
-
require 'sk_sdk/
|
7
|
+
require 'sk_sdk/ar_patches/ar3/base'
|
8
|
+
require 'sk_sdk/ar_patches/ar3/validations'
|
9
9
|
elsif ActiveResource::VERSION::MAJOR < 3
|
10
|
-
require 'sk_sdk/
|
11
|
-
require 'sk_sdk/
|
10
|
+
require 'sk_sdk/ar_patches/ar2/validations'
|
11
|
+
require 'sk_sdk/ar_patches/ar2/base'
|
12
12
|
end
|
13
13
|
|
14
14
|
class SK::SDK::Base < ActiveResource::Base
|
data/lib/sk_sdk/oauth.rb
CHANGED
@@ -53,8 +53,7 @@ module SK::SDK
|
|
53
53
|
|
54
54
|
# URL to get the access_token, used in the second step after you have
|
55
55
|
# requested the authorization and gotten a code
|
56
|
-
# The token url is located at /oauth/token
|
57
|
-
# but can still be reached at /access_token so older libs still work
|
56
|
+
# The token url is located at /oauth/token
|
58
57
|
# === Parameter
|
59
58
|
# code<String>:: code received after auth
|
60
59
|
# === Returns
|
@@ -15,7 +15,8 @@ module OmniAuth
|
|
15
15
|
def initialize(app, client_id, client_secret, sk_url, scope)
|
16
16
|
@base_url = sk_url
|
17
17
|
@scope = scope
|
18
|
-
|
18
|
+
client_options = {:access_token_path => '/oauth/token'}
|
19
|
+
super(app, :salesking, client_id, client_secret, client_options)
|
19
20
|
end
|
20
21
|
|
21
22
|
#inject salesking url and scope
|
data/lib/sk_sdk/sync.rb
ADDED
@@ -0,0 +1,170 @@
|
|
1
|
+
module SK::SDK
|
2
|
+
|
3
|
+
# Provide methods for mapping and syncing the fields of a remote to local
|
4
|
+
# object.
|
5
|
+
# The class gets two objects(local/remote) and a field-map(Array) which
|
6
|
+
# maps the field-names between those two. Of course your objects MUST respond
|
7
|
+
# to the method names passed in the mapping.
|
8
|
+
#
|
9
|
+
# When syncing the corresponding fields, the names are simply #send to each
|
10
|
+
# object.
|
11
|
+
#
|
12
|
+
# After an object was updated you can check the #log for changes
|
13
|
+
#
|
14
|
+
# == Example
|
15
|
+
#
|
16
|
+
# map =[
|
17
|
+
# [:name, :full_name, :'someClass.set_local_name', :'SomeClass.set_remote_name'],
|
18
|
+
# [:street, :address1]
|
19
|
+
# ]
|
20
|
+
# map = SK::SDK::Sync.new(@local_user, @remote_user, map)
|
21
|
+
# map.update(:r) #Does not save! only sets the field values on the remote object
|
22
|
+
#
|
23
|
+
# == Mapping Explanation
|
24
|
+
#
|
25
|
+
# A mapping consist of the local and the remote field name. It can further
|
26
|
+
# contain transition methods if the value needs to be changed when set from
|
27
|
+
# one side to the other.
|
28
|
+
#
|
29
|
+
# Those methods will be called(eval'ed) and receive the value from the other
|
30
|
+
# side as param:
|
31
|
+
#
|
32
|
+
# Mappings are passed as an array:
|
33
|
+
# [
|
34
|
+
# [:local_field_name, :remote_field_name, "SomeClass.left_trans", "SomeClass.rigt_trans"]
|
35
|
+
# [:firstname, :first_name, :'SomeClass.set_local_name', :'SomeClass.set_remote_name']
|
36
|
+
# ]
|
37
|
+
class Sync
|
38
|
+
|
39
|
+
# The local object
|
40
|
+
attr_accessor :l_obj
|
41
|
+
# The remote object
|
42
|
+
attr_accessor :r_obj
|
43
|
+
# <Hash{Symbol=>Symbol, Symbol=>{Hash} }>::the field mapping
|
44
|
+
attr_reader :fields
|
45
|
+
# the outdated fields
|
46
|
+
attr_reader :outdated
|
47
|
+
# <Array[String]>::log field changes
|
48
|
+
attr_reader :log
|
49
|
+
|
50
|
+
# Takes a local and remote object which should respond to function defined
|
51
|
+
# in the mapping hash
|
52
|
+
# === Parameter
|
53
|
+
# l_obj<Object>::
|
54
|
+
# r_obj<Object>::
|
55
|
+
# field_map<Hash{Symbol=>Symbol, Symbol=>{Hash} }>::the field mapping
|
56
|
+
def initialize(l_obj, r_obj, field_map)
|
57
|
+
@l_obj = l_obj
|
58
|
+
@r_obj = r_obj
|
59
|
+
self.fields = field_map
|
60
|
+
@log = []
|
61
|
+
end
|
62
|
+
|
63
|
+
# === Parameter
|
64
|
+
# field_map<Array[Hash{}]>::
|
65
|
+
def fields=(field_map)
|
66
|
+
@fields = []
|
67
|
+
field_map.each do |fld|
|
68
|
+
@fields << Field.new(fld)
|
69
|
+
end
|
70
|
+
@fields
|
71
|
+
end
|
72
|
+
|
73
|
+
# Find a field by its local name
|
74
|
+
# === Parameter
|
75
|
+
# l_name<Symbol>:: local name
|
76
|
+
# === Return
|
77
|
+
# <Field>::
|
78
|
+
def field(l_name)
|
79
|
+
fields.find{|fld| fld.l_name == l_name}
|
80
|
+
end
|
81
|
+
|
82
|
+
# Check if the any of the fields are outdated
|
83
|
+
# Populates self.outdated with outdated local field names
|
84
|
+
# === Returns
|
85
|
+
# <Boolean>:: false if not outdated
|
86
|
+
def outdated?
|
87
|
+
@outdated = []
|
88
|
+
fields.each do |fld|
|
89
|
+
if fld.transition?
|
90
|
+
# call r_trans method with local val to compare local with remote val
|
91
|
+
# SomeTrans.remote_transfer_method( l_obj.field )
|
92
|
+
virtual_l_val = eval "#{fld.r_trans} l_obj.send( fld.l_name )"
|
93
|
+
@outdated << fld if virtual_l_val != r_obj.send( fld.r_name )
|
94
|
+
else
|
95
|
+
# no transfer method, directly compare values
|
96
|
+
@outdated << fld if r_obj.send( fld.r_name ) != l_obj.send( fld.l_name )
|
97
|
+
end
|
98
|
+
end
|
99
|
+
!@outdated.empty?
|
100
|
+
end
|
101
|
+
|
102
|
+
# update all local outdated fields with values from remote object
|
103
|
+
def update_local_outdated
|
104
|
+
update(:l, @outdated) if outdated?
|
105
|
+
end
|
106
|
+
# update all remote outdated fields with values from local object
|
107
|
+
def update_remote_outdated
|
108
|
+
update( :r, @outdated) if outdated?
|
109
|
+
end
|
110
|
+
|
111
|
+
# Update a side with the values from the other side.
|
112
|
+
# Populates the log with updated fields and values.
|
113
|
+
# === Parameter
|
114
|
+
# side<String|Symbol>:: the side to update l OR r
|
115
|
+
# flds<Array[Field] | nil>:: fields to update, if nil all fields are updated
|
116
|
+
def update(side, flds=nil)
|
117
|
+
raise ArgumentError, 'The side to update must be :l or :r' unless [:l, :r].include?(side)
|
118
|
+
target, source = (side==:l) ? [:l, :r] : [:r, :l]
|
119
|
+
# use set field/s or update all
|
120
|
+
flds ||= fields
|
121
|
+
target_obj, source_obj = self.send("#{target}_obj"), self.send("#{source}_obj")
|
122
|
+
flds.each do |fld|
|
123
|
+
target_name, source_name = fld.send("#{target}_name"), fld.send("#{source}_name")
|
124
|
+
# remember for log
|
125
|
+
old_val = target_obj.send(target_name) rescue 'empty'
|
126
|
+
# get new value through transfer method or direct
|
127
|
+
new_val = if fld.transition? #call transfer function
|
128
|
+
cur_trans = fld.send("#{target}_trans")
|
129
|
+
eval "#{cur_trans} source_obj.send( source_name )"
|
130
|
+
else # lookup directly on other side object
|
131
|
+
source_obj.send( source_name )
|
132
|
+
end
|
133
|
+
target_obj.send( "#{target_name}=" , new_val )
|
134
|
+
|
135
|
+
log << "#{target_name} was: #{old_val} updated from: #{source_name} with value: #{new_val}"
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
# A Sync::Field holds the local(left) and remote(right) field names and if
|
140
|
+
# available the transfer methods.
|
141
|
+
class Field
|
142
|
+
attr_reader :l_name, :r_name, :l_trans, :r_trans
|
143
|
+
|
144
|
+
# Create a new sync field. the local and remote name MUST be set.
|
145
|
+
# Transition methods are optional.
|
146
|
+
#
|
147
|
+
# == Example
|
148
|
+
|
149
|
+
# With options as array:
|
150
|
+
# opts = [:local_name, :remote_name, "SomeClass.left_trans", "SomeClass.rigt_trans"]
|
151
|
+
# fld = Field.new opts
|
152
|
+
#
|
153
|
+
# == Parameter
|
154
|
+
# opts<Hash>::
|
155
|
+
def initialize(opts)
|
156
|
+
if opts.is_a? Array
|
157
|
+
@l_trans, @r_trans = opts[2], opts[3] if opts.length == 4
|
158
|
+
@l_name = opts[0]
|
159
|
+
@r_name = opts[1]
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
def transition?
|
164
|
+
@l_trans && @r_trans
|
165
|
+
end
|
166
|
+
end # class Field
|
167
|
+
|
168
|
+
|
169
|
+
end # Sync
|
170
|
+
end
|
data/sk_sdk.gemspec
CHANGED
@@ -5,12 +5,12 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{sk_sdk}
|
8
|
-
s.version = "0.0.
|
8
|
+
s.version = "0.0.8"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Georg Leciejewski"]
|
12
|
-
s.date = %q{2011-
|
13
|
-
s.description = %q{Connect your business world with SalesKing. This gem gives ruby developers a jump-start for building SalesKing Business Apps.
|
12
|
+
s.date = %q{2011-09-02}
|
13
|
+
s.description = %q{Connect your business world with SalesKing. This gem gives ruby developers a jump-start for building SalesKing Business Apps. It provides classes to handle oAuth, make RESTfull API requests and parses JSON Schema }
|
14
14
|
s.email = %q{gl@salesking.eu}
|
15
15
|
s.extra_rdoc_files = [
|
16
16
|
"README.rdoc"
|
@@ -20,22 +20,22 @@ Gem::Specification.new do |s|
|
|
20
20
|
"README.rdoc",
|
21
21
|
"Rakefile",
|
22
22
|
"VERSION",
|
23
|
+
"ci/Gemfile",
|
23
24
|
"lib/sk_sdk.rb",
|
24
25
|
"lib/sk_sdk/README_Base.rdoc",
|
25
|
-
"lib/sk_sdk/
|
26
|
-
"lib/sk_sdk/
|
27
|
-
"lib/sk_sdk/
|
28
|
-
"lib/sk_sdk/
|
29
|
-
"lib/sk_sdk/ar_cli/patches/ar3/validations.rb",
|
26
|
+
"lib/sk_sdk/ar_patches/ar2/base.rb",
|
27
|
+
"lib/sk_sdk/ar_patches/ar2/validations.rb",
|
28
|
+
"lib/sk_sdk/ar_patches/ar3/base.rb",
|
29
|
+
"lib/sk_sdk/ar_patches/ar3/validations.rb",
|
30
30
|
"lib/sk_sdk/base.rb",
|
31
31
|
"lib/sk_sdk/oauth.rb",
|
32
32
|
"lib/sk_sdk/omni_auth/README.rdoc",
|
33
33
|
"lib/sk_sdk/omni_auth/salesking.rb",
|
34
34
|
"lib/sk_sdk/signed_request.rb",
|
35
|
+
"lib/sk_sdk/sync.rb",
|
35
36
|
"sk_sdk.gemspec",
|
36
37
|
"spec/resources_spec_helper.rb",
|
37
38
|
"spec/settings.yml",
|
38
|
-
"spec/sk_sdk/ar_cli_spec.rb",
|
39
39
|
"spec/sk_sdk/base_spec.rb",
|
40
40
|
"spec/sk_sdk/oauth_spec.rb",
|
41
41
|
"spec/sk_sdk/resources/README.rdoc",
|
@@ -44,6 +44,8 @@ Gem::Specification.new do |s|
|
|
44
44
|
"spec/sk_sdk/resources/invoice_spec.rb",
|
45
45
|
"spec/sk_sdk/resources/product_spec.rb",
|
46
46
|
"spec/sk_sdk/signed_request_spec.rb",
|
47
|
+
"spec/sk_sdk/sync_field_spec.rb",
|
48
|
+
"spec/sk_sdk/sync_spec.rb",
|
47
49
|
"spec/spec_helper.rb"
|
48
50
|
]
|
49
51
|
s.homepage = %q{http://github.com/salesking/sk_sdk}
|
@@ -57,18 +59,24 @@ Gem::Specification.new do |s|
|
|
57
59
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
58
60
|
s.add_runtime_dependency(%q<curb>, [">= 0"])
|
59
61
|
s.add_runtime_dependency(%q<activesupport>, [">= 0"])
|
60
|
-
s.
|
62
|
+
s.add_runtime_dependency(%q<sk_api_schema>, [">= 0"])
|
63
|
+
s.add_runtime_dependency(%q<activeresource>, [">= 0"])
|
64
|
+
s.add_development_dependency(%q<rspec>, [">= 0"])
|
61
65
|
s.add_development_dependency(%q<rcov>, [">= 0"])
|
62
66
|
else
|
63
67
|
s.add_dependency(%q<curb>, [">= 0"])
|
64
68
|
s.add_dependency(%q<activesupport>, [">= 0"])
|
65
|
-
s.add_dependency(%q<
|
69
|
+
s.add_dependency(%q<sk_api_schema>, [">= 0"])
|
70
|
+
s.add_dependency(%q<activeresource>, [">= 0"])
|
71
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
66
72
|
s.add_dependency(%q<rcov>, [">= 0"])
|
67
73
|
end
|
68
74
|
else
|
69
75
|
s.add_dependency(%q<curb>, [">= 0"])
|
70
76
|
s.add_dependency(%q<activesupport>, [">= 0"])
|
71
|
-
s.add_dependency(%q<
|
77
|
+
s.add_dependency(%q<sk_api_schema>, [">= 0"])
|
78
|
+
s.add_dependency(%q<activeresource>, [">= 0"])
|
79
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
72
80
|
s.add_dependency(%q<rcov>, [">= 0"])
|
73
81
|
end
|
74
82
|
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
CONNECTION = {
|
2
|
-
:site => "
|
3
|
-
:password => "
|
2
|
+
:site => "https://demo.dev.salesking.eu/api/",
|
3
|
+
:password => "demouser",
|
4
|
+
# :site => "http://demo.salesking.local:3000/api/",
|
5
|
+
# :password => "demo",
|
4
6
|
:user => "demo@salesking.eu"
|
5
7
|
} unless defined?(CONNECTION)
|
6
8
|
|
data/spec/sk_sdk/base_spec.rb
CHANGED
data/spec/sk_sdk/oauth_spec.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'resources_spec_helper'
|
3
3
|
|
4
4
|
unless sk_available?
|
5
5
|
puts "Sorry cannot connect to your SalesKing server, skipping real connections tests. Please check connection settings in spec_helper"
|
@@ -1,5 +1,5 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'resources_spec_helper'
|
3
3
|
|
4
4
|
unless sk_available?
|
5
5
|
puts "Sorry cannot connect to your SalesKing server, skipping real connections tests. Please check connection settings in spec_helper"
|
@@ -36,11 +36,14 @@ else
|
|
36
36
|
@doc.new?.should be_false
|
37
37
|
end
|
38
38
|
|
39
|
-
it "should fail create a doc" do
|
40
|
-
doc = CreditNote.new()
|
41
|
-
doc.save.should ==
|
42
|
-
|
43
|
-
|
39
|
+
it "should fail create a doc without unique number" do
|
40
|
+
doc = CreditNote.new(:number=>'001')
|
41
|
+
doc.save.should == true
|
42
|
+
doc2 = CreditNote.new(:number=>'001')
|
43
|
+
doc2.save.should == false
|
44
|
+
doc2.errors.count.should == 2
|
45
|
+
doc2.errors.on(:number).should == "has already been taken"
|
46
|
+
doc.destroy
|
44
47
|
end
|
45
48
|
|
46
49
|
it "should find a doc" do
|
@@ -58,11 +61,14 @@ else
|
|
58
61
|
@doc.lock_version.should > old_lock_version # because save returns the data
|
59
62
|
end
|
60
63
|
|
61
|
-
it "should fail edit
|
62
|
-
|
64
|
+
it "should fail edit with wrong number" do
|
65
|
+
doc1 = CreditNote.new(:number=>'002')
|
66
|
+
doc1.save.should == true
|
67
|
+
@doc.number = '002'
|
63
68
|
@doc.save.should == false
|
64
|
-
@doc.errors.count.should ==
|
65
|
-
@doc.errors.on(:
|
69
|
+
@doc.errors.count.should == 2
|
70
|
+
@doc.errors.on(:number).should == "has already been taken"
|
71
|
+
doc1.destroy
|
66
72
|
end
|
67
73
|
end
|
68
74
|
|
@@ -1,5 +1,5 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'resources_spec_helper'
|
3
3
|
|
4
4
|
unless sk_available?
|
5
5
|
puts "Sorry cannot connect to your SalesKing server, skipping real connections tests. Please check connection settings in spec_helper"
|
@@ -60,11 +60,14 @@ describe Invoice, "a new invoice" do
|
|
60
60
|
doc.destroy
|
61
61
|
end
|
62
62
|
|
63
|
-
it "should fail create a doc" do
|
64
|
-
doc = Invoice.new()
|
65
|
-
doc.save.should ==
|
66
|
-
|
67
|
-
|
63
|
+
it "should fail create a doc without unique number" do
|
64
|
+
doc = Invoice.new(:number=>'001')
|
65
|
+
doc.save.should == true
|
66
|
+
doc2 = Invoice.new(:number=>'001')
|
67
|
+
doc2.save.should == false
|
68
|
+
doc2.errors.count.should == 2
|
69
|
+
doc2.errors.on(:number).should == "has already been taken"
|
70
|
+
doc.destroy
|
68
71
|
end
|
69
72
|
|
70
73
|
end
|
@@ -99,11 +102,14 @@ describe Invoice, "Edit an invoice" do
|
|
99
102
|
@doc.notes_before.should == 'You will recieve the amout of:'
|
100
103
|
end
|
101
104
|
|
102
|
-
it "should fail edit
|
103
|
-
|
105
|
+
it "should fail edit with wrong number" do
|
106
|
+
doc1 = Invoice.new(:number=>'002')
|
107
|
+
doc1.save.should == true
|
108
|
+
@doc.number = '002'
|
104
109
|
@doc.save.should == false
|
105
|
-
@doc.errors.count.should ==
|
106
|
-
@doc.errors.on(:
|
110
|
+
@doc.errors.count.should == 2
|
111
|
+
@doc.errors.on(:number).should == "has already been taken"
|
112
|
+
doc1.destroy
|
107
113
|
end
|
108
114
|
end
|
109
115
|
|
@@ -1,5 +1,5 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'resources_spec_helper'
|
3
3
|
|
4
4
|
unless sk_available?
|
5
5
|
puts "Sorry cannot connect to your SalesKing server, skipping real connections tests. Please check connection settings in spec_helper"
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
describe SK::SDK::SignedRequest, "in general" do
|
4
4
|
|
@@ -12,9 +12,13 @@ describe SK::SDK::SignedRequest, "in general" do
|
|
12
12
|
|
13
13
|
it "should decode payload" do
|
14
14
|
a = SK::SDK::SignedRequest.new(@param, @set['secret'])
|
15
|
-
a.data.
|
15
|
+
a.data.should == @param_hash
|
16
16
|
a.payload.should_not be_nil
|
17
17
|
a.sign.should_not be_nil
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should validate" do
|
21
|
+
a = SK::SDK::SignedRequest.new(@param, @set['secret'])
|
18
22
|
a.should be_valid
|
19
23
|
end
|
20
24
|
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
|
3
|
+
describe SK::SDK::Sync::Field do
|
4
|
+
|
5
|
+
it "should init with array fields" do
|
6
|
+
flds = []
|
7
|
+
field_map.each do |fld|
|
8
|
+
flds << SK::SDK::Sync::Field.new(fld)
|
9
|
+
end
|
10
|
+
flds.length.should == field_map.length
|
11
|
+
flds.first.should be_a_kind_of SK::SDK::Sync::Field
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should set names fields" do
|
15
|
+
opts = field_map.first
|
16
|
+
fld = SK::SDK::Sync::Field.new(opts)
|
17
|
+
fld.l_name.should == opts[0]
|
18
|
+
fld.r_name.should == opts[1]
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should set transition methods" do
|
22
|
+
opts = field_map.last
|
23
|
+
fld = SK::SDK::Sync::Field.new(opts)
|
24
|
+
fld.l_trans.should == opts[2]
|
25
|
+
fld.r_trans.should == opts[3]
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
|
30
|
+
def field_map
|
31
|
+
[
|
32
|
+
[:firstname, :first_name],
|
33
|
+
[:street, :address1],
|
34
|
+
[:postcode, :zip],
|
35
|
+
[:city, :city],
|
36
|
+
[:gender, :gender, :'TransMethods.set_local_gender', :'TransMethods.set_remote_gender']
|
37
|
+
]
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
|
2
|
+
require 'spec/spec_helper'
|
3
|
+
|
4
|
+
describe SK::SDK::Sync do
|
5
|
+
|
6
|
+
before :each do
|
7
|
+
@l_obj = LocalContact.new
|
8
|
+
@r_obj = RemoteContact.new
|
9
|
+
@sync = SK::SDK::Sync.new(@l_obj, @r_obj, field_map)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should create fields" do
|
13
|
+
@sync.fields.length.should == field_map.length
|
14
|
+
@sync.fields.first.should be_a_kind_of SK::SDK::Sync::Field
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should raise error with wrong side" do
|
18
|
+
lambda{
|
19
|
+
@sync.update(:x)
|
20
|
+
}.should raise_error(ArgumentError)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should not be outdated" do
|
24
|
+
@sync.outdated?.should be_false # both objects are empty
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should find outdated fields" do
|
28
|
+
@l_obj.firstname = 'theo'
|
29
|
+
@sync.outdated?.should be_true
|
30
|
+
@sync.outdated.first.should == @sync.field(:firstname)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should update outdated remote fields" do
|
34
|
+
@l_obj.firstname = 'theo'
|
35
|
+
@sync.update_remote_outdated
|
36
|
+
|
37
|
+
@r_obj.first_name.should == @l_obj.firstname
|
38
|
+
@sync.log.should_not be_empty
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should update outdated local fields" do
|
42
|
+
@r_obj.first_name = 'Heinz'
|
43
|
+
@sync.update_local_outdated
|
44
|
+
@l_obj.firstname.should == @r_obj.first_name
|
45
|
+
@sync.log.length.should == 1
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should update outdated remote fields with transition" do
|
49
|
+
@l_obj.gender = 'female'
|
50
|
+
@sync.update_remote_outdated
|
51
|
+
|
52
|
+
@r_obj.gender.should == "f"
|
53
|
+
@sync.log.should_not be_empty
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should update outdated local fields with transition" do
|
57
|
+
@r_obj.gender = 'm'
|
58
|
+
@sync.update_local_outdated
|
59
|
+
@l_obj.gender.should == 'male'
|
60
|
+
@sync.log.length.should == 1
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should update all remote fields" do
|
64
|
+
@l_obj.firstname = 'John'
|
65
|
+
@l_obj.street = 'Sync Ave 666'
|
66
|
+
@l_obj.postcode = '96969'
|
67
|
+
@l_obj.city = 'Wichita'
|
68
|
+
@l_obj.gender = 'female'
|
69
|
+
@sync.update(:r)
|
70
|
+
|
71
|
+
@r_obj.first_name.should == @l_obj.firstname
|
72
|
+
@r_obj.address1.should == @l_obj.street
|
73
|
+
@r_obj.zip.should == @l_obj.postcode
|
74
|
+
@r_obj.city.should == @l_obj.city
|
75
|
+
@r_obj.gender.should == "f"
|
76
|
+
@sync.log.should_not be_empty
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should update all local fields" do
|
80
|
+
@r_obj.gender = 'm'
|
81
|
+
@r_obj.first_name = 'John'
|
82
|
+
@r_obj.address1 = 'Sync Ave 666'
|
83
|
+
@r_obj.zip = '96969'
|
84
|
+
@r_obj.city = 'Wichita'
|
85
|
+
@sync.update(:l)
|
86
|
+
|
87
|
+
@l_obj.firstname.should == @r_obj.first_name
|
88
|
+
@l_obj.street.should == @r_obj.address1
|
89
|
+
@l_obj.postcode.should == @r_obj.zip
|
90
|
+
@l_obj.city.should == @r_obj.city
|
91
|
+
@l_obj.gender.should == 'male'
|
92
|
+
@sync.log.length.should == 5
|
93
|
+
end
|
94
|
+
def field_map
|
95
|
+
[
|
96
|
+
[:firstname, :first_name],
|
97
|
+
[:street, :address1],
|
98
|
+
[:postcode, :zip],
|
99
|
+
[:city, :city],
|
100
|
+
[:gender, :gender, :'TransMethods.set_local_gender', :'TransMethods.set_remote_gender']
|
101
|
+
]
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
################################################################################
|
107
|
+
# Dummi Classes used in specs
|
108
|
+
################################################################################
|
109
|
+
class RemoteContact
|
110
|
+
attr_accessor :first_name, :address1, :zip, :city, :gender
|
111
|
+
end
|
112
|
+
|
113
|
+
class LocalContact
|
114
|
+
attr_accessor :firstname, :street, :postcode, :city, :gender
|
115
|
+
end
|
116
|
+
|
117
|
+
class TransMethods
|
118
|
+
def self.set_local_gender(remote_val)
|
119
|
+
return 'male' if remote_val == 'm'
|
120
|
+
return 'female' if remote_val == 'f'
|
121
|
+
end
|
122
|
+
def self.set_remote_gender(local_val)
|
123
|
+
return 'm' if local_val == 'male'
|
124
|
+
return 'f' if local_val == 'female'
|
125
|
+
end
|
126
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'yaml'
|
3
|
-
require '
|
3
|
+
require 'rspec'
|
4
4
|
require "active_support"
|
5
5
|
require "active_support/json"
|
6
6
|
require "#{File.dirname(__FILE__)}/../lib/sk_sdk"
|
7
7
|
require "#{File.dirname(__FILE__)}/../lib/sk_sdk/base"
|
8
|
+
require "#{File.dirname(__FILE__)}/../lib/sk_sdk/sync"
|
8
9
|
require "#{File.dirname(__FILE__)}/../lib/sk_sdk/oauth"
|
9
10
|
require "#{File.dirname(__FILE__)}/../lib/sk_sdk/signed_request"
|
10
|
-
require "#{File.dirname(__FILE__)}/../lib/sk_sdk/ar_cli"
|
11
11
|
|
12
12
|
|
13
13
|
puts "Testing with ActiveResource v: #{ActiveResource::VERSION::STRING}"
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sk_sdk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 15
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 8
|
10
|
+
version: 0.0.8
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Georg Leciejewski
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-09-02 00:00:00 +02:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -47,21 +47,21 @@ dependencies:
|
|
47
47
|
type: :runtime
|
48
48
|
version_requirements: *id002
|
49
49
|
- !ruby/object:Gem::Dependency
|
50
|
-
name:
|
50
|
+
name: sk_api_schema
|
51
51
|
prerelease: false
|
52
52
|
requirement: &id003 !ruby/object:Gem::Requirement
|
53
53
|
none: false
|
54
54
|
requirements:
|
55
|
-
- -
|
55
|
+
- - ">="
|
56
56
|
- !ruby/object:Gem::Version
|
57
|
-
hash:
|
57
|
+
hash: 3
|
58
58
|
segments:
|
59
|
-
-
|
60
|
-
version: "
|
61
|
-
type: :
|
59
|
+
- 0
|
60
|
+
version: "0"
|
61
|
+
type: :runtime
|
62
62
|
version_requirements: *id003
|
63
63
|
- !ruby/object:Gem::Dependency
|
64
|
-
name:
|
64
|
+
name: activeresource
|
65
65
|
prerelease: false
|
66
66
|
requirement: &id004 !ruby/object:Gem::Requirement
|
67
67
|
none: false
|
@@ -72,9 +72,37 @@ dependencies:
|
|
72
72
|
segments:
|
73
73
|
- 0
|
74
74
|
version: "0"
|
75
|
-
type: :
|
75
|
+
type: :runtime
|
76
76
|
version_requirements: *id004
|
77
|
-
|
77
|
+
- !ruby/object:Gem::Dependency
|
78
|
+
name: rspec
|
79
|
+
prerelease: false
|
80
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ">="
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
hash: 3
|
86
|
+
segments:
|
87
|
+
- 0
|
88
|
+
version: "0"
|
89
|
+
type: :development
|
90
|
+
version_requirements: *id005
|
91
|
+
- !ruby/object:Gem::Dependency
|
92
|
+
name: rcov
|
93
|
+
prerelease: false
|
94
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
95
|
+
none: false
|
96
|
+
requirements:
|
97
|
+
- - ">="
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
hash: 3
|
100
|
+
segments:
|
101
|
+
- 0
|
102
|
+
version: "0"
|
103
|
+
type: :development
|
104
|
+
version_requirements: *id006
|
105
|
+
description: "Connect your business world with SalesKing. This gem gives ruby developers a jump-start for building SalesKing Business Apps. It provides classes to handle oAuth, make RESTfull API requests and parses JSON Schema "
|
78
106
|
email: gl@salesking.eu
|
79
107
|
executables: []
|
80
108
|
|
@@ -87,22 +115,22 @@ files:
|
|
87
115
|
- README.rdoc
|
88
116
|
- Rakefile
|
89
117
|
- VERSION
|
118
|
+
- ci/Gemfile
|
90
119
|
- lib/sk_sdk.rb
|
91
120
|
- lib/sk_sdk/README_Base.rdoc
|
92
|
-
- lib/sk_sdk/
|
93
|
-
- lib/sk_sdk/
|
94
|
-
- lib/sk_sdk/
|
95
|
-
- lib/sk_sdk/
|
96
|
-
- lib/sk_sdk/ar_cli/patches/ar3/validations.rb
|
121
|
+
- lib/sk_sdk/ar_patches/ar2/base.rb
|
122
|
+
- lib/sk_sdk/ar_patches/ar2/validations.rb
|
123
|
+
- lib/sk_sdk/ar_patches/ar3/base.rb
|
124
|
+
- lib/sk_sdk/ar_patches/ar3/validations.rb
|
97
125
|
- lib/sk_sdk/base.rb
|
98
126
|
- lib/sk_sdk/oauth.rb
|
99
127
|
- lib/sk_sdk/omni_auth/README.rdoc
|
100
128
|
- lib/sk_sdk/omni_auth/salesking.rb
|
101
129
|
- lib/sk_sdk/signed_request.rb
|
130
|
+
- lib/sk_sdk/sync.rb
|
102
131
|
- sk_sdk.gemspec
|
103
132
|
- spec/resources_spec_helper.rb
|
104
133
|
- spec/settings.yml
|
105
|
-
- spec/sk_sdk/ar_cli_spec.rb
|
106
134
|
- spec/sk_sdk/base_spec.rb
|
107
135
|
- spec/sk_sdk/oauth_spec.rb
|
108
136
|
- spec/sk_sdk/resources/README.rdoc
|
@@ -111,6 +139,8 @@ files:
|
|
111
139
|
- spec/sk_sdk/resources/invoice_spec.rb
|
112
140
|
- spec/sk_sdk/resources/product_spec.rb
|
113
141
|
- spec/sk_sdk/signed_request_spec.rb
|
142
|
+
- spec/sk_sdk/sync_field_spec.rb
|
143
|
+
- spec/sk_sdk/sync_spec.rb
|
114
144
|
- spec/spec_helper.rb
|
115
145
|
has_rdoc: true
|
116
146
|
homepage: http://github.com/salesking/sk_sdk
|
data/lib/sk_sdk/ar_cli.rb
DELETED
@@ -1,33 +0,0 @@
|
|
1
|
-
require 'sk_sdk'
|
2
|
-
require 'sk_sdk/base'
|
3
|
-
|
4
|
-
module SK::SDK
|
5
|
-
class ArCli
|
6
|
-
# TODO deprecated
|
7
|
-
# Create a class for a given name
|
8
|
-
#
|
9
|
-
# === Example
|
10
|
-
#
|
11
|
-
# SK::SDK::ArCli.make(:client)
|
12
|
-
# c = Client.new
|
13
|
-
#
|
14
|
-
# SK::SDK::ArCli.make(:credit_note, SK::API)
|
15
|
-
# i = SK::API::CreditNote.new
|
16
|
-
#
|
17
|
-
# === Parameter
|
18
|
-
# name<String>:: lowercase, underscored name: line_item, client must be a
|
19
|
-
# valid title of a json schema
|
20
|
-
# obj_scope<Constant>:: class, module name under which to setup(namespace)
|
21
|
-
# the new class. Default to Object, example: SK::API
|
22
|
-
def self.make(name, obj_scope =nil)
|
23
|
-
class_name = name.to_s.camelize
|
24
|
-
# by default create class in Object scope
|
25
|
-
obj_scope ||= Object
|
26
|
-
# only define the class once
|
27
|
-
raise "Constant #{class_name} already defined in scope of #{obj_scope}!" if obj_scope.const_defined?(class_name)
|
28
|
-
# create a new class from given name:
|
29
|
-
# :line_item => # class LineItem < ActiveResource::Base
|
30
|
-
obj_scope.const_set( class_name, Class.new(SK::SDK::Base) )
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
data/spec/sk_sdk/ar_cli_spec.rb
DELETED
@@ -1,41 +0,0 @@
|
|
1
|
-
require 'spec/spec_helper'
|
2
|
-
require 'spec/resources_spec_helper'
|
3
|
-
|
4
|
-
describe SK::SDK::ArCli, "make new class" do
|
5
|
-
|
6
|
-
it "should create class" do
|
7
|
-
c = Client.new
|
8
|
-
c.first_name = 'herbert' # implicit setter
|
9
|
-
c.first_name.should == 'herbert' # implicit getter
|
10
|
-
c1 = Client.new
|
11
|
-
end
|
12
|
-
|
13
|
-
it "should have properties as attributes" do
|
14
|
-
c = Client.new :some_field => ''
|
15
|
-
c.attributes.should == {"some_field"=>""}
|
16
|
-
end
|
17
|
-
|
18
|
-
it "should create save method" do
|
19
|
-
c = Client.new
|
20
|
-
c.respond_to?(:save).should be_true
|
21
|
-
end
|
22
|
-
|
23
|
-
it "should have new_record?" do
|
24
|
-
c = Client.new
|
25
|
-
c.new_record?.should be_true
|
26
|
-
end
|
27
|
-
|
28
|
-
it "should raise error on second create" do
|
29
|
-
lambda{
|
30
|
-
SK::SDK::ArCli.make(:client)
|
31
|
-
}.should raise_error(RuntimeError, "Constant Client already defined in scope of Object!")
|
32
|
-
end
|
33
|
-
|
34
|
-
it "should allow create a second class in different scope" do
|
35
|
-
lambda{
|
36
|
-
SK::SDK::ArCli.make(:client, SK::API)
|
37
|
-
c = SK::API::Client.new
|
38
|
-
c.id
|
39
|
-
}.should_not raise_error(RuntimeError)
|
40
|
-
end
|
41
|
-
end
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|