sk_sdk 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.rdoc +28 -7
- data/Rakefile +4 -3
- data/VERSION +1 -1
- data/lib/sk_sdk/README_ArCli.rdoc +79 -0
- data/lib/sk_sdk/ar_cli/patches/ar2/base.rb +40 -0
- data/lib/sk_sdk/ar_cli/patches/ar2/validations.rb +30 -0
- data/lib/sk_sdk/ar_cli/patches/ar3/base.rb +23 -0
- data/lib/sk_sdk/ar_cli/patches/ar3/validations.rb +13 -0
- data/lib/sk_sdk/ar_cli.rb +70 -0
- data/lib/sk_sdk/oauth.rb +35 -14
- data/lib/sk_sdk/signed_request.rb +1 -1
- data/sk_sdk.gemspec +24 -8
- data/spec/settings.yml +7 -0
- data/spec/sk_sdk/ar_cli_spec.rb +61 -0
- data/spec/sk_sdk/oauth_spec.rb +44 -0
- data/spec/sk_sdk/signed_request_spec.rb +21 -0
- data/spec/spec_helper.rb +24 -0
- metadata +35 -8
- data/spec/oauth_spec.rb +0 -0
data/README.rdoc
CHANGED
@@ -1,9 +1,8 @@
|
|
1
1
|
= SalesKing SDK
|
2
2
|
|
3
|
-
A bunch of classes to get a quick start creating SalesKing App's, using oAuth
|
4
|
-
the API.
|
3
|
+
A bunch of classes to get a quick start creating SalesKing App's, using oAuth
|
4
|
+
and the API.
|
5
5
|
|
6
|
-
Still in a very early stage
|
7
6
|
|
8
7
|
== Install
|
9
8
|
|
@@ -11,14 +10,36 @@ Still in a very early stage
|
|
11
10
|
|
12
11
|
Dependencies (gem's):
|
13
12
|
|
14
|
-
*
|
13
|
+
* activesupport
|
14
|
+
* activeresource
|
15
15
|
* curb
|
16
16
|
|
17
|
-
==
|
17
|
+
== Classes
|
18
18
|
|
19
|
-
|
19
|
+
All classes must be explicitly required
|
20
20
|
|
21
|
-
require 'sk_sdk/
|
21
|
+
require 'sk_sdk/signed_request'
|
22
22
|
require 'sk_sdk/oauth'
|
23
|
+
require 'sk_sdk/ar_cli'
|
24
|
+
|
25
|
+
|
26
|
+
=== oAuth
|
27
|
+
|
28
|
+
Handling oAuth related URL's and getting an access token
|
29
|
+
|
30
|
+
=== SignedRequest
|
31
|
+
|
32
|
+
Helping in de/encoding of signed_request param
|
33
|
+
|
34
|
+
=== API client
|
35
|
+
|
36
|
+
Create classes out if thin air to CRUD SalesKing object's using activeresource
|
37
|
+
README: https://github.com/salesking/sk_sdk/blob/master/lib/sk_sdk/README_ArCli.rdoc
|
38
|
+
|
39
|
+
== Usage
|
40
|
+
|
41
|
+
Read specs: https://github.com/salesking/sk_sdk/tree/master/spec/sk_sdk
|
42
|
+
|
43
|
+
|
23
44
|
|
24
45
|
Copyright (c) 2011 Georg Leciejewski, released under the MIT license
|
data/Rakefile
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'rake'
|
3
3
|
require 'rake/rdoctask'
|
4
|
-
require 'spec/rake/spectask'
|
4
|
+
require 'spec/rake/spectask'
|
5
5
|
|
6
6
|
begin
|
7
7
|
require 'jeweler'
|
@@ -17,7 +17,8 @@ begin
|
|
17
17
|
# gem.add_dependency 'sk_api_schema'
|
18
18
|
# gem.add_dependency 'sk_api_builder'
|
19
19
|
# gem.add_dependency 'activeresource'
|
20
|
-
gem.add_development_dependency "rspec"
|
20
|
+
gem.add_development_dependency "rspec", "< 2"
|
21
|
+
gem.add_development_dependency "rcov"
|
21
22
|
end
|
22
23
|
Jeweler::GemcutterTasks.new
|
23
24
|
rescue LoadError
|
@@ -39,7 +40,7 @@ desc "Generate code coverage"
|
|
39
40
|
Spec::Rake::SpecTask.new(:coverage) do |t|
|
40
41
|
t.spec_files = spec_files
|
41
42
|
t.rcov = true
|
42
|
-
t.rcov_opts = ['--exclude', 'spec,/var/lib/gems']
|
43
|
+
t.rcov_opts = ['--exclude', 'spec,/var/lib/gems,/usr/local/lib']
|
43
44
|
end
|
44
45
|
|
45
46
|
desc 'Generate documentation.'
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.3
|
@@ -0,0 +1,79 @@
|
|
1
|
+
= SalesKing API Client
|
2
|
+
|
3
|
+
Create classes, descendants of ActiveResource::Base, to CRUD SalesKing objects.
|
4
|
+
|
5
|
+
This does NOT rely on parsing the JSON Schema, since activeresource creates the
|
6
|
+
getter/Setter methods(less restrict). The client adds some patches to AR to fix
|
7
|
+
json parsing issues.
|
8
|
+
|
9
|
+
== Install
|
10
|
+
|
11
|
+
gem install sk_sdk
|
12
|
+
|
13
|
+
Dependencies (gem's):
|
14
|
+
|
15
|
+
* activeresupport
|
16
|
+
* activeresource
|
17
|
+
|
18
|
+
== Usage
|
19
|
+
|
20
|
+
SalesKing's api interface is RESTful(mostly) and returns & accepts JSON data.
|
21
|
+
All resources such as clients, invoices, products can be accessed via URL's
|
22
|
+
through standard HTTP methods GET, POST, PUT and DELETE.
|
23
|
+
see available methods here:
|
24
|
+
https://github.com/salesking/sk_api_schema/tree/master/json
|
25
|
+
|
26
|
+
ActiveResource provides a wrapper around the whole url/request stuff and makes
|
27
|
+
usage of the new classes pretty straight forward:
|
28
|
+
|
29
|
+
require "sk_sdk/ar_client"
|
30
|
+
SK::SDK::ArCli.make(:client)
|
31
|
+
# Create class within any namespace
|
32
|
+
module; King; end
|
33
|
+
SK::SDK::ArCli.make(:credit_note, King)
|
34
|
+
|
35
|
+
Now the classes are available, but needs some connection settings first. Those Must
|
36
|
+
be set for each class separate
|
37
|
+
|
38
|
+
[Client, CreditNote].each do |i|
|
39
|
+
i.send(:set_connection, {:site => 'my_sub.salesking.eu',
|
40
|
+
:user => 'demo@salesking.eu',
|
41
|
+
:password => 'password' })
|
42
|
+
client = Client.new(:last_name=> 'Meister')
|
43
|
+
client.first_name = "Bau"
|
44
|
+
client.save
|
45
|
+
credit_note = King::CreditNote.new
|
46
|
+
|
47
|
+
Also see ActiveResource readme:
|
48
|
+
https://github.com/rails/rails/tree/master/activeresource
|
49
|
+
|
50
|
+
Want to know more about REST style webservices?
|
51
|
+
* http://en.wikipedia.org/wiki/Representational_State_Transfer
|
52
|
+
* http://www.google.com/search?q=REST+site%3Awww.infoq.com
|
53
|
+
|
54
|
+
=== Authentification & Safety
|
55
|
+
|
56
|
+
Authentification can be done with oAuth2 but this client still uses HTTP basic
|
57
|
+
using your SalesKing login email and password.
|
58
|
+
|
59
|
+
For a production environment be advised to create a user, per api client, and
|
60
|
+
restrict his rights with our build in role-system!
|
61
|
+
SalesKing only supports HTTPS.
|
62
|
+
|
63
|
+
=== API Tutorial and Tools
|
64
|
+
|
65
|
+
Since browsers do not support PUT/DELETE methods you can use CURL, a linux
|
66
|
+
command-line http client, for testing. And of course any http library supporting
|
67
|
+
http-basic-auth can be used.
|
68
|
+
|
69
|
+
* Getting started: http://dev.blog.salesking.eu/api/
|
70
|
+
* Chrome cRest extension https://chrome.google.com/extensions/detail/baedhhmoaooldchehjhlpppaieoglhml
|
71
|
+
* Poster FF-Plugin - make HTTP request https://addons.mozilla.org/en-US/firefox/addon/2691/ (you must be logged into SalesKing)
|
72
|
+
* JSONView FF-Plugin - view json in firefox https://addons.mozilla.org/de/firefox/addon/10869/
|
73
|
+
* JSONovich FF-Plugin - https://addons.mozilla.org/de/firefox/addon/10122/
|
74
|
+
|
75
|
+
== Tests / Specs
|
76
|
+
|
77
|
+
rake coverage
|
78
|
+
|
79
|
+
Copyright (c) 2011 Georg Leciejewski, released under the MIT license
|
@@ -0,0 +1,40 @@
|
|
1
|
+
#temp patch as_json on decimals introduced by rails. which collpases with ruby-yail
|
2
|
+
class BigDecimal
|
3
|
+
def as_json
|
4
|
+
self.to_f
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
module ActiveResource
|
9
|
+
# Overridden methods to suit SalesKing.
|
10
|
+
# Some changes might be kicked when AR 3.0 is out
|
11
|
+
class Base
|
12
|
+
|
13
|
+
# override encode because json is also returned nested by SalesKing
|
14
|
+
def encode(options={})
|
15
|
+
case self.class.format
|
16
|
+
when ActiveResource::Formats[:xml]
|
17
|
+
self.class.format.encode(attributes, {:root => self.class.element_name}.merge(options))
|
18
|
+
else # json also nested
|
19
|
+
self.class.format.encode( {self.class.element_name => attributes}, options)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# override ARes method to parse only the client part
|
24
|
+
def load_attributes_from_response(response)
|
25
|
+
if response['Content-Length'] != "0" && response.body.strip.size > 0
|
26
|
+
load( self.class.format.decode(response.body)[self.class.element_name] )
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Overridden to grab the data(= clients-collection) from json:
|
31
|
+
# { 'collection'=> will_paginate infos,
|
32
|
+
# 'links' => prev/next links
|
33
|
+
# 'clients'=> [data], << what we need
|
34
|
+
# }
|
35
|
+
def self.instantiate_collection(collection, prefix_options = {})
|
36
|
+
collection = collection[ self.element_name.pluralize ] if collection.is_a?(Hash)
|
37
|
+
collection.collect! { |record| instantiate_record(record, prefix_options) }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module ActiveResource
|
2
|
+
|
3
|
+
module Validations
|
4
|
+
# Validate a resource and save (POST) it to the remote web service.
|
5
|
+
def save_with_validation
|
6
|
+
save_without_validation
|
7
|
+
true
|
8
|
+
rescue ResourceInvalid => error
|
9
|
+
case error.response['Content-Type']
|
10
|
+
when /xml/ #PATCH
|
11
|
+
errors.from_xml(error.response.body)
|
12
|
+
when /json/ #PATCH
|
13
|
+
errors.from_json(error.response.body)
|
14
|
+
end
|
15
|
+
false
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class Errors
|
20
|
+
|
21
|
+
# Patched cause we dont need no attribute name magic .. and its just simpler
|
22
|
+
def from_array(messages)
|
23
|
+
clear
|
24
|
+
messages.each do |msg|
|
25
|
+
add msg[0], msg[1]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end #Errors
|
29
|
+
|
30
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module ActiveResource
|
2
|
+
# Overridden methods to suit SalesKing.
|
3
|
+
# Some changes might be kicked when AR 3.0 is out
|
4
|
+
class Base
|
5
|
+
|
6
|
+
# override ARes method to parse only the client part
|
7
|
+
def load_attributes_from_response(response)
|
8
|
+
if response['Content-Length'] != "0" && response.body.strip.size > 0
|
9
|
+
load( self.class.format.decode(response.body)[self.class.element_name] )
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
# Overridden to grab the data(= clients-collection) from json:
|
14
|
+
# { 'collection'=> will_paginate infos,
|
15
|
+
# 'links' => prev/next links
|
16
|
+
# 'clients'=> [data], << what we need
|
17
|
+
# }
|
18
|
+
def self.instantiate_collection(collection, prefix_options = {})
|
19
|
+
collection = collection[ self.element_name.pluralize ] if collection.is_a?(Hash)
|
20
|
+
collection.collect! { |record| instantiate_record(record, prefix_options) }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module ActiveResource
|
2
|
+
class Errors < ActiveModel::Errors
|
3
|
+
# Patched cause we dont need no attribute name magic .. and its just simpler
|
4
|
+
# orig version is looking up the humanized name of the attribute in the error
|
5
|
+
# message, which we dont supply => only field name is used in returned error msg
|
6
|
+
def from_array(messages, save_cache=false)
|
7
|
+
clear unless save_cache
|
8
|
+
messages.each do |msg|
|
9
|
+
add msg[0], msg[1]
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end #Errors
|
13
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'active_resource'
|
3
|
+
require 'active_resource/version'
|
4
|
+
# patches are for specific AR version
|
5
|
+
if ActiveResource::VERSION::MAJOR == 3
|
6
|
+
require 'sk_sdk/ar_cli/patches/ar3/base'
|
7
|
+
require 'sk_sdk/ar_cli/patches/ar3/validations'
|
8
|
+
elsif ActiveResource::VERSION::MAJOR < 3
|
9
|
+
require 'sk_sdk/ar_cli/patches/ar2/validations'
|
10
|
+
require 'sk_sdk/ar_cli/patches/ar2/base'
|
11
|
+
end
|
12
|
+
|
13
|
+
# schema gem
|
14
|
+
#require 'sk_api_schema'
|
15
|
+
|
16
|
+
module SK::SDK
|
17
|
+
class ArCli
|
18
|
+
# Create a class for a given name
|
19
|
+
#
|
20
|
+
# === Example
|
21
|
+
#
|
22
|
+
# SK::SDK::ArCli.make(:client)
|
23
|
+
# c = Client.new
|
24
|
+
#
|
25
|
+
# SK::SDK::ArCli.make(:credit_note, SK::API)
|
26
|
+
# i = SK::API::CreditNote.new
|
27
|
+
#
|
28
|
+
# === Parameter
|
29
|
+
# name<String>:: lowercase, underscored name: line_item, client must be a
|
30
|
+
# valid title of a json schema
|
31
|
+
# obj_scope<Constant>:: class, module name under which to setup(namespace)
|
32
|
+
# the new class. Default to Object, example: SK::API
|
33
|
+
def self.make(name, obj_scope =nil)
|
34
|
+
class_name = name.to_s.camelize
|
35
|
+
# by default create class in Object scope
|
36
|
+
obj_scope ||= Object
|
37
|
+
# only define the class once
|
38
|
+
raise "Constant #{class_name} already defined in scope of #{obj_scope}!" if obj_scope.const_defined?(class_name)
|
39
|
+
# create a new class from given name:
|
40
|
+
# :line_item => # class LineItem < ActiveResource::Base
|
41
|
+
klass = obj_scope.const_set(class_name, Class.new(ActiveResource::Base))
|
42
|
+
klass.class_eval do
|
43
|
+
self.extend(ClassMethods)
|
44
|
+
self.send(:include, InstanceMethods) # include is private
|
45
|
+
end
|
46
|
+
klass.format = :json # bug in AR must be set here
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
module ClassMethods
|
51
|
+
# Define the connection to be used when talking to a salesking server
|
52
|
+
def set_connection(opts)
|
53
|
+
self.site = opts[:site]
|
54
|
+
self.user = opts[:user]
|
55
|
+
self.password = opts[:password]
|
56
|
+
self.format = opts[:format].to_sym
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
module InstanceMethods
|
61
|
+
# hook before init in activeresource base because json comes in nested:
|
62
|
+
# {client={data}
|
63
|
+
def initialize(attributes = {})
|
64
|
+
attr = attributes[self.class.element_name] || attributes
|
65
|
+
super(attr)
|
66
|
+
end
|
67
|
+
|
68
|
+
def save; save_with_validation; end
|
69
|
+
end
|
70
|
+
end
|
data/lib/sk_sdk/oauth.rb
CHANGED
@@ -14,40 +14,61 @@ module SK::SDK
|
|
14
14
|
@app_redirect_url = opts['app_redirect_url']
|
15
15
|
@app_canvas_slug = opts['app_canvas_slug']
|
16
16
|
@sk_url = opts['sk_url']
|
17
|
-
|
17
|
+
@sub_domain = opts['sub_domain']
|
18
18
|
end
|
19
19
|
|
20
|
+
# URL showing the auth dialog to the user
|
21
|
+
#
|
22
|
+
# === Returns
|
23
|
+
# <String>:: URL with parameter
|
20
24
|
def auth_dialog
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
"#{sk_url}/oauth/authorize
|
25
|
+
params = { :client_id => @app_id,
|
26
|
+
:redirect_uri=> @app_redirect_url,
|
27
|
+
:scope => @app_scope }
|
28
|
+
"#{sk_url}/oauth/authorize?#{to_url_params(params)}"
|
25
29
|
end
|
26
30
|
|
27
|
-
#
|
31
|
+
# The app's canvas url inside SalesKing
|
32
|
+
# === Returns
|
33
|
+
# <String>:: URL
|
28
34
|
def sk_canvas_url
|
29
35
|
"#{sk_url}/app/#{@app_canvas_slug}"
|
30
36
|
end
|
31
37
|
|
38
|
+
# URL to get the access_token, used in the second step after you have
|
39
|
+
# requested the authorization and gotten a code
|
40
|
+
# === Parameter
|
41
|
+
# code<String>:: code received after auth
|
42
|
+
# === Returns
|
43
|
+
# <String>:: Url with parameter
|
44
|
+
def token_url(code)
|
45
|
+
params = { :client_id => @app_id,
|
46
|
+
:client_secret => @app_secret,
|
47
|
+
:redirect_uri => @app_redirect_url,
|
48
|
+
:code => code }
|
49
|
+
"#{sk_url}/oauth/access_token?#{to_url_params(params)}"
|
50
|
+
end
|
51
|
+
|
32
52
|
# Makes a GET request to the access_token endpoint in SK and receives the
|
33
53
|
# oauth/access token
|
34
54
|
def get_token(code)
|
35
|
-
|
36
|
-
# :client_secret => @app_secret,
|
37
|
-
# :redirect_uri => @app_redirect_url,
|
38
|
-
# :code => code }
|
39
|
-
url = "#{sk_url}/oauth/access_token?code=#{code}&client_id=#{@app_id}&client_secret=#{@app_secret}&redirect_uri=#{CGI::escape @app_redirect_url }"
|
40
|
-
c = Curl::Easy.perform(url)
|
55
|
+
c = Curl::Easy.perform( token_url( code ) )
|
41
56
|
# grab token from response body, containing json string
|
42
57
|
ActiveSupport::JSON.decode(c.body_str)
|
43
58
|
end
|
44
59
|
|
45
60
|
# Each company has it's own subdomain so the url must be dynamic.
|
46
|
-
# This is
|
61
|
+
# This is achieved by replacing the * with the subdomain from the session
|
47
62
|
# === Returns
|
48
63
|
# <String>:: url
|
49
64
|
def sk_url
|
50
|
-
@sk_url.gsub('*', sub_domain)
|
65
|
+
@sk_url.gsub('*', sub_domain).gsub(/\/\z/, '' )
|
66
|
+
end
|
67
|
+
|
68
|
+
def to_url_params(params_hash)
|
69
|
+
out = []
|
70
|
+
params_hash.each { |k,v| out << "#{CGI::escape k.to_s}=#{CGI::escape v.to_s}" }
|
71
|
+
out.join('&')
|
51
72
|
end
|
52
73
|
|
53
74
|
end
|
data/sk_sdk.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
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.3"
|
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-03-
|
12
|
+
s.date = %q{2011-03-14}
|
13
13
|
s.description = %q{Connect your business world with SalesKing. This gem gives ruby developers a jump-start for building SalesKing Business Apps. Under the hood 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 = [
|
@@ -21,17 +21,30 @@ Gem::Specification.new do |s|
|
|
21
21
|
"Rakefile",
|
22
22
|
"VERSION",
|
23
23
|
"lib/sk_sdk.rb",
|
24
|
+
"lib/sk_sdk/README_ArCli.rdoc",
|
25
|
+
"lib/sk_sdk/ar_cli.rb",
|
26
|
+
"lib/sk_sdk/ar_cli/patches/ar2/base.rb",
|
27
|
+
"lib/sk_sdk/ar_cli/patches/ar2/validations.rb",
|
28
|
+
"lib/sk_sdk/ar_cli/patches/ar3/base.rb",
|
29
|
+
"lib/sk_sdk/ar_cli/patches/ar3/validations.rb",
|
24
30
|
"lib/sk_sdk/oauth.rb",
|
25
31
|
"lib/sk_sdk/signed_request.rb",
|
26
32
|
"sk_sdk.gemspec",
|
27
|
-
"spec/
|
33
|
+
"spec/settings.yml",
|
34
|
+
"spec/sk_sdk/ar_cli_spec.rb",
|
35
|
+
"spec/sk_sdk/oauth_spec.rb",
|
36
|
+
"spec/sk_sdk/signed_request_spec.rb",
|
37
|
+
"spec/spec_helper.rb"
|
28
38
|
]
|
29
39
|
s.homepage = %q{http://github.com/salesking/sk_sdk}
|
30
40
|
s.require_paths = ["lib"]
|
31
|
-
s.rubygems_version = %q{1.
|
41
|
+
s.rubygems_version = %q{1.6.2}
|
32
42
|
s.summary = %q{SalesKing SDK Ruby}
|
33
43
|
s.test_files = [
|
34
|
-
"spec/
|
44
|
+
"spec/sk_sdk/ar_cli_spec.rb",
|
45
|
+
"spec/sk_sdk/oauth_spec.rb",
|
46
|
+
"spec/sk_sdk/signed_request_spec.rb",
|
47
|
+
"spec/spec_helper.rb"
|
35
48
|
]
|
36
49
|
|
37
50
|
if s.respond_to? :specification_version then
|
@@ -40,16 +53,19 @@ Gem::Specification.new do |s|
|
|
40
53
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
41
54
|
s.add_runtime_dependency(%q<curb>, [">= 0"])
|
42
55
|
s.add_runtime_dependency(%q<activesupport>, [">= 0"])
|
43
|
-
s.add_development_dependency(%q<rspec>, ["
|
56
|
+
s.add_development_dependency(%q<rspec>, ["< 2"])
|
57
|
+
s.add_development_dependency(%q<rcov>, [">= 0"])
|
44
58
|
else
|
45
59
|
s.add_dependency(%q<curb>, [">= 0"])
|
46
60
|
s.add_dependency(%q<activesupport>, [">= 0"])
|
47
|
-
s.add_dependency(%q<rspec>, ["
|
61
|
+
s.add_dependency(%q<rspec>, ["< 2"])
|
62
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
48
63
|
end
|
49
64
|
else
|
50
65
|
s.add_dependency(%q<curb>, [">= 0"])
|
51
66
|
s.add_dependency(%q<activesupport>, [">= 0"])
|
52
|
-
s.add_dependency(%q<rspec>, ["
|
67
|
+
s.add_dependency(%q<rspec>, ["< 2"])
|
68
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
53
69
|
end
|
54
70
|
end
|
55
71
|
|
data/spec/settings.yml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
sk_url: http://*.horsts-lokal.local
|
2
|
+
app_canvas_slug: canvas-page
|
3
|
+
app_id: 2d83d570635ee19c
|
4
|
+
app_secret: eb4005858e4947e4228a12a6b7306ee0
|
5
|
+
app_redirect_url: http://localhorst:4567
|
6
|
+
app_scope: "api/payments:read api/invoices:read"
|
7
|
+
session_secret: very_long_random_to_encode_the_session
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
|
3
|
+
describe SK::SDK::ArCli, "make new class" do
|
4
|
+
|
5
|
+
before :all do
|
6
|
+
SK::SDK::ArCli.make(:client)
|
7
|
+
Client.set_connection( CONNECTION )
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should create class" do
|
11
|
+
c = Client.new
|
12
|
+
c.first_name = 'herbert' # implicit setter
|
13
|
+
c.first_name.should == 'herbert' # implicit getter
|
14
|
+
c1 = Client.new
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should have properties as attributes" do
|
18
|
+
c = Client.new :some_field => ''
|
19
|
+
c.attributes.should == {"some_field"=>""}
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should create save method" do
|
23
|
+
c = Client.new
|
24
|
+
c.respond_to?(:save).should be_true
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should have new_record?" do
|
28
|
+
c = Client.new
|
29
|
+
c.new_record?.should be_true
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should raise error on second create" do
|
33
|
+
lambda{
|
34
|
+
SK::SDK::ArCli.make(:client)
|
35
|
+
}.should raise_error(RuntimeError, "Constant Client already defined in scope of Object!")
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should allow create a second class in different scope" do
|
39
|
+
lambda{
|
40
|
+
SK::SDK::ArCli.make(:client, SK::API)
|
41
|
+
c = SK::API::Client.new
|
42
|
+
c.id
|
43
|
+
}.should_not raise_error(RuntimeError)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe SK::SDK::ArCli, "with real connection" do
|
48
|
+
|
49
|
+
before :all do
|
50
|
+
SK::SDK::ArCli.make(:client) unless Object.const_defined?('Client')
|
51
|
+
Client.set_connection( CONNECTION )
|
52
|
+
#TODO check if sk is available
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should save" do
|
56
|
+
c = Client.new :organisation=>"Rack'n Roll"
|
57
|
+
c.save.should be_true
|
58
|
+
c.id.should_not be_empty
|
59
|
+
c.number.should_not be_empty
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
|
3
|
+
describe SK::SDK::Oauth, "in general" do
|
4
|
+
|
5
|
+
before :each do
|
6
|
+
#setup test oAuth-data to work with
|
7
|
+
load_settings
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should create a new instance" do
|
11
|
+
lambda{ SK::SDK::Oauth.new(@set)}.should_not raise_error
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should get salesking url" do
|
15
|
+
a = SK::SDK::Oauth.new(@set)
|
16
|
+
a.sub_domain = 'alki'
|
17
|
+
a.sk_url.should == "http://alki.horsts-lokal.local"
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should get auth_dialog url" do
|
21
|
+
a = SK::SDK::Oauth.new(@set)
|
22
|
+
a.sub_domain = 'alki'
|
23
|
+
a.auth_dialog.should include "http://alki.horsts-lokal.local/oauth/authorize?"
|
24
|
+
a.auth_dialog.should include @set['app_id']
|
25
|
+
a.auth_dialog.should include CGI::escape @set['app_redirect_url']
|
26
|
+
a.auth_dialog.should include CGI::escape @set['app_scope']
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should get sk_canvas_url" do
|
30
|
+
a = SK::SDK::Oauth.new(@set)
|
31
|
+
a.sub_domain = 'alki'
|
32
|
+
a.sk_canvas_url.should == "http://alki.horsts-lokal.local/app/canvas-page"
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should get token_url" do
|
36
|
+
a = SK::SDK::Oauth.new(@set)
|
37
|
+
a.sub_domain = 'alki'
|
38
|
+
url = a.token_url('some-code')
|
39
|
+
url.should include @set['app_id']
|
40
|
+
url.should include @set['app_secret']
|
41
|
+
url.should include CGI::escape @set['app_redirect_url']
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
|
3
|
+
describe SK::SDK::SignedRequest, "in general" do
|
4
|
+
|
5
|
+
before :each do
|
6
|
+
#setup test oAuth-data to work with
|
7
|
+
load_settings
|
8
|
+
# fake request
|
9
|
+
@param_hash = {'hello' =>'coder', 'algorithm' => 'HMAC-SHA256'}
|
10
|
+
@param = SK::SDK::SignedRequest.signed_param( ActiveSupport::JSON.encode(@param_hash), @set['app_secret'] )
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should decode payload" do
|
14
|
+
a = SK::SDK::SignedRequest.new(@param, @set['app_secret'])
|
15
|
+
a.data.should_not be_nil
|
16
|
+
a.payload.should_not be_nil
|
17
|
+
a.sign.should_not be_nil
|
18
|
+
a.should be_valid
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'yaml'
|
3
|
+
require 'spec'
|
4
|
+
require "active_support"
|
5
|
+
require "active_support/json"
|
6
|
+
require "#{File.dirname(__FILE__)}/../lib/sk_sdk"
|
7
|
+
require "#{File.dirname(__FILE__)}/../lib/sk_sdk/oauth"
|
8
|
+
require "#{File.dirname(__FILE__)}/../lib/sk_sdk/signed_request"
|
9
|
+
require "#{File.dirname(__FILE__)}/../lib/sk_sdk/ar_cli"
|
10
|
+
|
11
|
+
|
12
|
+
puts "Testing with ActiveResource v: #{ActiveResource::VERSION::STRING}."
|
13
|
+
|
14
|
+
|
15
|
+
def load_settings
|
16
|
+
@set ||= YAML.load_file(File.join(File.dirname(__FILE__), 'settings.yml'))
|
17
|
+
end
|
18
|
+
|
19
|
+
CONNECTION = {
|
20
|
+
:site => "http://demo.salesking.local:3000/api/",
|
21
|
+
:user => "demo@salesking.eu",
|
22
|
+
:password => "demo",
|
23
|
+
:format => :json
|
24
|
+
} unless defined?(CONNECTION)
|
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: 25
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 3
|
10
|
+
version: 0.0.3
|
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-03-
|
18
|
+
date: 2011-03-14 00:00:00 +01:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -50,6 +50,20 @@ dependencies:
|
|
50
50
|
name: rspec
|
51
51
|
prerelease: false
|
52
52
|
requirement: &id003 !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - <
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
hash: 7
|
58
|
+
segments:
|
59
|
+
- 2
|
60
|
+
version: "2"
|
61
|
+
type: :development
|
62
|
+
version_requirements: *id003
|
63
|
+
- !ruby/object:Gem::Dependency
|
64
|
+
name: rcov
|
65
|
+
prerelease: false
|
66
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
53
67
|
none: false
|
54
68
|
requirements:
|
55
69
|
- - ">="
|
@@ -59,7 +73,7 @@ dependencies:
|
|
59
73
|
- 0
|
60
74
|
version: "0"
|
61
75
|
type: :development
|
62
|
-
version_requirements: *
|
76
|
+
version_requirements: *id004
|
63
77
|
description: "Connect your business world with SalesKing. This gem gives ruby developers a jump-start for building SalesKing Business Apps. Under the hood it provides classes to handle oAuth, make RESTfull API requests and parses JSON Schema "
|
64
78
|
email: gl@salesking.eu
|
65
79
|
executables: []
|
@@ -74,10 +88,20 @@ files:
|
|
74
88
|
- Rakefile
|
75
89
|
- VERSION
|
76
90
|
- lib/sk_sdk.rb
|
91
|
+
- lib/sk_sdk/README_ArCli.rdoc
|
92
|
+
- lib/sk_sdk/ar_cli.rb
|
93
|
+
- lib/sk_sdk/ar_cli/patches/ar2/base.rb
|
94
|
+
- lib/sk_sdk/ar_cli/patches/ar2/validations.rb
|
95
|
+
- lib/sk_sdk/ar_cli/patches/ar3/base.rb
|
96
|
+
- lib/sk_sdk/ar_cli/patches/ar3/validations.rb
|
77
97
|
- lib/sk_sdk/oauth.rb
|
78
98
|
- lib/sk_sdk/signed_request.rb
|
79
99
|
- sk_sdk.gemspec
|
80
|
-
- spec/
|
100
|
+
- spec/settings.yml
|
101
|
+
- spec/sk_sdk/ar_cli_spec.rb
|
102
|
+
- spec/sk_sdk/oauth_spec.rb
|
103
|
+
- spec/sk_sdk/signed_request_spec.rb
|
104
|
+
- spec/spec_helper.rb
|
81
105
|
has_rdoc: true
|
82
106
|
homepage: http://github.com/salesking/sk_sdk
|
83
107
|
licenses: []
|
@@ -108,9 +132,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
108
132
|
requirements: []
|
109
133
|
|
110
134
|
rubyforge_project:
|
111
|
-
rubygems_version: 1.
|
135
|
+
rubygems_version: 1.6.2
|
112
136
|
signing_key:
|
113
137
|
specification_version: 3
|
114
138
|
summary: SalesKing SDK Ruby
|
115
139
|
test_files:
|
116
|
-
- spec/
|
140
|
+
- spec/sk_sdk/ar_cli_spec.rb
|
141
|
+
- spec/sk_sdk/oauth_spec.rb
|
142
|
+
- spec/sk_sdk/signed_request_spec.rb
|
143
|
+
- spec/spec_helper.rb
|
data/spec/oauth_spec.rb
DELETED
File without changes
|