queenbee 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2e2ecbf88bab97a30dc9d76d899d83235e11bffe
4
+ data.tar.gz: 1f4d8257dcbe653e9a02dd74f280a817a6ca5df2
5
+ SHA512:
6
+ metadata.gz: 8fcc250632939434fc3decdb721606b0d9fbcbcd05481d74888ff40f160f8abf226fe54033b10cea373df6b803d8d9670a00fb2ac35cccb0de27a652443e4757
7
+ data.tar.gz: 89eab4a4c89771376015ebd335a382e0f256365dd183955a957fe8c6f31aa2376175e8139ffac678dc641ba7c64eb8af10e46cbe72c774b7c26eaa3317f8cef7
data/README.md ADDED
@@ -0,0 +1,76 @@
1
+ # Queenbee
2
+
3
+ [![Build Status](https://semaphoreapp.com/api/v1/projects/7959e7f9-8fcb-4d10-85fe-79bc840b028c/262003/shields_badge.svg)](https://semaphoreapp.com/olimart/queenbee-ruby)
4
+
5
+ Simple gem for communicating with external API. Heavily inspired by stripe gem.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ gem 'queenbee'
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install queenbee
20
+
21
+ ## Usage
22
+
23
+ In your app
24
+
25
+ 1. Set token
26
+
27
+ ```ruby
28
+ Queenbee.token = ENV['QUEENBEE_TOKEN']
29
+ ```
30
+
31
+ 2. Send order
32
+
33
+ ```ruby
34
+ Queenbee::Order.create(
35
+ date: Time.now,
36
+ currency: 'cad',
37
+ client_email: 'client@email.com',
38
+ amount: '15',
39
+ total_price: '15',
40
+ city: 'Nancy',
41
+ country: 'France',
42
+ shipping: 0,
43
+ uid: SecureRandom.hex(4),
44
+ source: 'Stripe payment form'
45
+ )
46
+ ```
47
+
48
+ **For Sinatra app** you may need to add `require 'bundler/setup'`
49
+
50
+
51
+ ## Tests
52
+
53
+ ```ruby
54
+ rake test
55
+ ```
56
+
57
+ ## Complete list of parameters
58
+
59
+ - uid (string, must be unique per application)
60
+ - date (datetime. default to record creation timestamp. Should be used to send historic data)
61
+ - currency (string. i.e. 'CAD')
62
+ - amount (decimal)
63
+ - tax (decimal)
64
+ - shipping (decimal)
65
+ - total_price (decimal)
66
+ - gift (boolean, default false)
67
+ - coupon (boolean, default false)
68
+ - coupon_code (string)
69
+ - country (string. i.e. 'Canada')
70
+ - city (string)
71
+ - url (string)
72
+ - client_email (string)
73
+ - products_count (integer, default 1)
74
+ - subscribed_at (datetime. For recurring order)
75
+ - unsubscribed_at (datetime. For recurring order)
76
+ - fees (decimal)
@@ -0,0 +1,16 @@
1
+ module Queenbee
2
+ module APIOperations
3
+ module Create
4
+ module ClassMethods
5
+ def create(params={}, token=nil)
6
+ response, token = Queenbee.request(:post, self.url, token, params)
7
+ response
8
+ end
9
+ end
10
+
11
+ def self.included(base)
12
+ base.extend(ClassMethods)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,17 @@
1
+ module Queenbee
2
+ module APIOperations
3
+ module Update
4
+ module ClassMethods
5
+ def save(params = {}, token = nil)
6
+ url = self.url + '/' + params[:uid]
7
+ response, token = Queenbee.request(:put, url, token, params)
8
+ response
9
+ end
10
+ end
11
+
12
+ def self.included(base)
13
+ base.extend(ClassMethods)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,21 @@
1
+ module Queenbee
2
+ class APIResource < QueenbeeObject
3
+ def self.class_name
4
+ self.name.split('::')[-1]
5
+ end
6
+
7
+ def self.url()
8
+ if self == APIResource
9
+ raise NotImplementedError.new('APIResource is an abstract class. You should perform actions on its subclasses)')
10
+ end
11
+ "/#{CGI.escape(class_name.downcase)}s"
12
+ end
13
+
14
+ def url
15
+ unless id = self['id']
16
+ raise InvalidRequestError.new("Could not determine which URL to request: #{self.class} instance has invalid ID: #{id.inspect}", 'id')
17
+ end
18
+ "#{self.class.url}/#{CGI.escape(id)}"
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,4 @@
1
+ module Queenbee
2
+ class APIConnectionError < QueenbeeError
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Queenbee
2
+ class APIError < QueenbeeError
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Queenbee
2
+ class AuthenticationError < QueenbeeError
3
+ end
4
+ end
@@ -0,0 +1,10 @@
1
+ module Queenbee
2
+ class InvalidRequestError < QueenbeeError
3
+ attr_accessor :param
4
+
5
+ def initialize(message, param, http_status=nil, http_body=nil, json_body=nil)
6
+ super(message, http_status, http_body, json_body)
7
+ @param = param
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,20 @@
1
+ module Queenbee
2
+ class QueenbeeError < StandardError
3
+ attr_reader :message
4
+ attr_reader :http_status
5
+ attr_reader :http_body
6
+ attr_reader :json_body
7
+
8
+ def initialize(message=nil, http_status=nil, http_body=nil, json_body=nil)
9
+ @message = message
10
+ @http_status = http_status
11
+ @http_body = http_body
12
+ @json_body = json_body
13
+ end
14
+
15
+ def to_s
16
+ status_string = @http_status.nil? ? "" : "(Status #{@http_status}) "
17
+ "#{status_string}#{@message}"
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,6 @@
1
+ module Queenbee
2
+ class Order < APIResource
3
+ include Queenbee::APIOperations::Create
4
+ include Queenbee::APIOperations::Update
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ module Queenbee
2
+ class QueenbeeObject
3
+
4
+ end
5
+ end
@@ -0,0 +1,3 @@
1
+ module Queenbee
2
+ VERSION = "0.0.2"
3
+ end
data/lib/queenbee.rb ADDED
@@ -0,0 +1,143 @@
1
+ # Queenbee Ruby bindings
2
+ require "cgi"
3
+ require "set"
4
+ require "openssl"
5
+ require "json"
6
+ require "net/http"
7
+ require "uri"
8
+
9
+ # Version
10
+ require "queenbee/version"
11
+
12
+ # API operations
13
+ require "queenbee/api_operations/create"
14
+ require "queenbee/api_operations/update"
15
+
16
+ # Resources
17
+ require "queenbee/queenbee_object"
18
+ require "queenbee/api_resource"
19
+ require "queenbee/order"
20
+
21
+ # Errors
22
+ require "queenbee/errors/queenbee_error"
23
+ require "queenbee/errors/api_error"
24
+ require "queenbee/errors/api_connection_error"
25
+ require "queenbee/errors/invalid_request_error"
26
+ require "queenbee/errors/authentication_error"
27
+
28
+ module Queenbee
29
+ @api_base = "https://queenbee-yafoy.herokuapp.com/api"
30
+
31
+ class << self
32
+ attr_accessor :token, :api_base, :verify_ssl_certs, :api_version
33
+ end
34
+
35
+ def self.api_url(url="")
36
+ @api_base + url
37
+ end
38
+
39
+ def self.request(method, url, token, params={}, headers={})
40
+ unless token ||= @token
41
+ raise AuthenticationError.new("No token provided")
42
+ end
43
+
44
+ url = api_url(url)
45
+
46
+ begin
47
+ uri = URI(url)
48
+ request = Net::HTTP::Post.new(uri) if method == :post
49
+ request = Net::HTTP::Put.new(uri) if method == :put
50
+ request["User-Agent"] = "Queenbee gem"
51
+ request["Authorization"] = "Token token=\"#{token}\""
52
+ request["Content-Type"] = "application/json"
53
+ request.body = params.to_json
54
+
55
+ http = Net::HTTP.new(uri.hostname, uri.port)
56
+
57
+ # see http://www.rubyinside.com/how-to-cure-nethttps-risky-default-https-behavior-4010.html
58
+ # for info about ssl verification
59
+
60
+ http.use_ssl = true if uri.scheme == "https"
61
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE if uri.scheme == "https"
62
+
63
+ response = http.start {|h|
64
+ h.request(request)
65
+ }
66
+
67
+ # since http.request doesn't throw such exceptions, check them by status codes
68
+ handle_api_error(response.code, response.body)
69
+
70
+ rescue SocketError => e
71
+ handle_connection_error(e)
72
+ rescue NoMethodError => e
73
+ handle_connection_error(e)
74
+ rescue OpenSSL::SSL::SSLError => e
75
+ handle_connection_error(e)
76
+ rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH => e
77
+ handle_connection_error(e)
78
+ rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError,
79
+ Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e
80
+ handle_connection_error(e)
81
+ end
82
+
83
+ [response, token]
84
+ end
85
+
86
+ def self.retrieve(id, opts={})
87
+ instance = self.new(id, opts)
88
+ instance
89
+ end
90
+
91
+ def self.handle_connection_error(e)
92
+ case e
93
+ when SocketError
94
+ message = "Unexpected error when trying to connect to Queenbee."
95
+
96
+ when NoMethodError
97
+ message = "Unexpected HTTP response code"
98
+
99
+ else
100
+ message = "Unexpected error communicating with Queenbee."
101
+ end
102
+
103
+ raise APIConnectionError.new(message + "\n\n(Network error: #{e.message})")
104
+ end
105
+
106
+ def self.handle_api_error(rcode, rbody)
107
+ begin
108
+ error_obj = JSON.parse(rbody)
109
+ rescue JSON::ParserError
110
+ raise general_api_error(rcode, rbody)
111
+ end
112
+
113
+ case rcode
114
+ when 400, 404, 422
115
+ raise invalid_request_error error, rcode, rbody, error_obj
116
+ when 401
117
+ raise authentication_error error, rcode, rbody, error_obj
118
+ when 500
119
+ raise api_error error, rcode, rbody, error_obj
120
+ else
121
+ # raise api_error error, rcode, rbody, error_obj
122
+ end
123
+
124
+ end
125
+
126
+ def self.invalid_request_error(error, rcode, rbody, error_obj)
127
+ InvalidRequestError.new(error[:message], error[:param], rcode,
128
+ rbody, error_obj)
129
+ end
130
+
131
+ def self.authentication_error(error, rcode, rbody, error_obj)
132
+ AuthenticationError.new(error[:message], rcode, rbody, error_obj)
133
+ end
134
+
135
+ def self.api_error(error, rcode, rbody, error_obj)
136
+ APIError.new(error[:message], rcode, rbody, error_obj)
137
+ end
138
+
139
+ def self.general_api_error(rcode, rbody)
140
+ APIError.new("Invalid response object from API: #{rbody.inspect} " +
141
+ "(HTTP response code was #{rcode})", rcode, rbody)
142
+ end
143
+ end
@@ -0,0 +1,56 @@
1
+ require File.expand_path("../../test_helper", __FILE__)
2
+
3
+ module Queenbee
4
+ class OrderTest < Test::Unit::TestCase
5
+ should "create should return status 201" do
6
+ response = Queenbee::Order.create(
7
+ date: "2014-07-01 14:50:28",
8
+ currency: "CAD", city: "Paris",
9
+ country: "Canada", client_email: "d@email.com",
10
+ uid: SecureRandom.hex(4))
11
+ assert_equal "201", response.code
12
+ end
13
+
14
+ should "raise Queenbee::AuthenticationError if not token provided" do
15
+ Queenbee.token = nil
16
+ assert_raises(Queenbee::AuthenticationError) {Queenbee::Order.create}
17
+ end
18
+
19
+ should "raise Queenbee::InvalidRequestError if not enough parameters" do
20
+ begin
21
+ rescue JSON::ParserError
22
+ assert_raises(Queenbee::InvalidRequestError) { Queenbee::Order.create }
23
+ end
24
+ end
25
+
26
+ should "Update should return 200" do
27
+ uid = SecureRandom.hex(4)
28
+ response1 = Queenbee::Order.create(
29
+ date: "2014-07-01 14:50:28",
30
+ currency: "CAD", city: "Paris",
31
+ country: "Canada", client_email: "d@email.com",
32
+ uid: uid)
33
+ response = Queenbee::Order.save(
34
+ date: "2014-07-01 14:50:28",
35
+ currency: "CAD", city: "Paris",
36
+ country: "Canada", client_email: "kk@email.com",
37
+ uid: uid)
38
+ assert_equal "200", response.code
39
+ end
40
+
41
+ should "Update should return 404 if UID missing" do
42
+ response1 = Queenbee::Order.create(
43
+ date: "2014-07-01 14:50:28",
44
+ currency: "CAD", city: "Paris",
45
+ country: "Canada", client_email: "d@email.com",
46
+ uid: SecureRandom.hex(4))
47
+ response = Queenbee::Order.save(
48
+ date: "2014-07-01 14:50:28",
49
+ currency: "CAD", city: "Paris",
50
+ country: "Canada", client_email: "kk@email.com",
51
+ uid: "")
52
+ assert_equal "404", response.code
53
+ end
54
+
55
+ end
56
+ end
@@ -0,0 +1,14 @@
1
+ require 'queenbee'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ class Test::Unit::TestCase
6
+ setup do
7
+ Queenbee.api_base = 'http://localhost:3024/api'
8
+ Queenbee.token = '111'
9
+ end
10
+
11
+ teardown do
12
+ Queenbee.token = nil
13
+ end
14
+ end
metadata ADDED
@@ -0,0 +1,131 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: queenbee
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Olivier
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-10-08 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.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: json
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 1.8.1
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 1.8.1
55
+ - !ruby/object:Gem::Dependency
56
+ name: shoulda
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 3.4.0
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 3.4.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: test-unit
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: E-commerce analytics platform
84
+ email:
85
+ - olivier@yafoy.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - README.md
91
+ - lib/queenbee.rb
92
+ - lib/queenbee/api_operations/create.rb
93
+ - lib/queenbee/api_operations/update.rb
94
+ - lib/queenbee/api_resource.rb
95
+ - lib/queenbee/errors/api_connection_error.rb
96
+ - lib/queenbee/errors/api_error.rb
97
+ - lib/queenbee/errors/authentication_error.rb
98
+ - lib/queenbee/errors/invalid_request_error.rb
99
+ - lib/queenbee/errors/queenbee_error.rb
100
+ - lib/queenbee/order.rb
101
+ - lib/queenbee/queenbee_object.rb
102
+ - lib/queenbee/version.rb
103
+ - test/queenbee/order_test.rb
104
+ - test/test_helper.rb
105
+ homepage: https://github.com/olimart/queenbee-ruby
106
+ licenses:
107
+ - MIT
108
+ metadata: {}
109
+ post_install_message:
110
+ rdoc_options: []
111
+ require_paths:
112
+ - lib
113
+ required_ruby_version: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ required_rubygems_version: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - ">="
121
+ - !ruby/object:Gem::Version
122
+ version: '0'
123
+ requirements: []
124
+ rubyforge_project:
125
+ rubygems_version: 2.4.8
126
+ signing_key:
127
+ specification_version: 4
128
+ summary: Gem to send e-commerce orders to the Queenbee central app.
129
+ test_files:
130
+ - test/queenbee/order_test.rb
131
+ - test/test_helper.rb