cloudsight 0.0.5 → 0.0.9.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a2fe5db87751bdc8c72c250868e949cf1b045576
4
- data.tar.gz: eeb791589e465b21e8cbeffa9a64d8eb3927134b
3
+ metadata.gz: b9d0460a23e0f0707d9ddb9f2bb55498c620f850
4
+ data.tar.gz: 20c8412535ce925d41a25e69d1d5df650d4ac11b
5
5
  SHA512:
6
- metadata.gz: 9c8302acc57e8c5317b2163682c0c2ea9842031311ac775f4897cdd5e9a2b14040916e9e66b1786f1ff23a38520cc93286c7d0ae202b513d0606e731f3898d09
7
- data.tar.gz: 89d7a1386a9e85a10876eb0ef880d0d888284073ae88fe992492a4c5698c8db0cf1f9895b356edeed7170b6be725e854d4cc5b19ed56cbb63573d723e57eb592
6
+ metadata.gz: 4aaaf8b6c0a018ddd99b54e1b486c250a5f63240ed37d899797765fe5ba72f7396df4bd693c38bd45386c6c219789e8c0dc19341554f53a344089ad952f37b5c
7
+ data.tar.gz: 8a6dcc5478f4047437e5a045b702f8b320b72ebcb0ebef12dcbe06dac0a1c361409fb5ec6620b3928357a72dba22f8af33fa1d782696c09a27838e9b21806c56
@@ -0,0 +1,35 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /test/tmp/
9
+ /test/version_tmp/
10
+ /tmp/
11
+
12
+ ## Specific to RubyMotion:
13
+ .dat*
14
+ .repl_history
15
+ build/
16
+
17
+ ## Documentation cache and generated files:
18
+ /.yardoc/
19
+ /_yardoc/
20
+ /doc/
21
+ /rdoc/
22
+
23
+ ## Environment normalisation:
24
+ /.bundle/
25
+ /lib/bundler/man/
26
+
27
+ # for a library or gem, you might want to ignore these files since the code is
28
+ # intended to run in multiple environments; otherwise, check them in:
29
+ Gemfile.lock
30
+ .ruby-version
31
+ .ruby-gemset
32
+ .rspec_status
33
+
34
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
35
+ .rvmrc
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --require spec_helper
@@ -0,0 +1,19 @@
1
+ language: ruby
2
+ cache: bundler
3
+
4
+ script:
5
+ - bundle exec rspec
6
+
7
+ branches:
8
+ only:
9
+ - master
10
+
11
+ before_install:
12
+ - gem update --system
13
+ - gem update bundler
14
+
15
+ rvm:
16
+ - 2.1
17
+ - 2.2.0
18
+ - 2.3.0
19
+ - 2.4.0
data/README.md CHANGED
@@ -5,8 +5,8 @@ A simple CloudSight API Client
5
5
 
6
6
  | Project | Gem Release |
7
7
  |------------------------ | ----------------- |
8
- | gem name | gem-release |
9
- | version | [![Gem Version](https://badge.fury.io/rb/gem-release.png)](http://badge.fury.io/rb/gem-release) |
8
+ | gem name | cloudsight |
9
+ | version | [![Gem Version](https://badge.fury.io/rb/cloudsight.svg)](https://badge.fury.io/rb/cloudsight)
10
10
  | continuous integration | [![Build Status](https://secure.travis-ci.org/cloudsight/cloudsight-ruby.png?branch=master)](https://travis-ci.org/cloudsight/cloudsight-ruby) |
11
11
 
12
12
  Installation
@@ -0,0 +1,4 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ task :default do
4
+ end
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "cloudsight"
5
+ require "pry"
6
+
7
+ Pry.start
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -6,30 +6,29 @@ require 'cloudsight/version'
6
6
  Gem::Specification.new do |s|
7
7
  s.name = 'cloudsight'
8
8
  s.version = Cloudsight::VERSION
9
- s.date = '2015-11-05'
10
9
  s.summary = "CloudSight API Client"
11
10
  s.description = "A simple CloudSight API Client for Image Recognition"
12
- s.authors = ['Brad Folkens']
13
- s.email = 'brad@cloudsightapi.com'
11
+ s.authors = ['Brad Folkens', 'Jack McCallum', 'Chris Weilemann']
12
+ s.email = 'oss@cloudsight.ai'
14
13
  s.homepage = 'http://github.com/cloudsight/cloudsight-ruby'
15
14
  s.license = 'MIT'
16
15
  s.platform = Gem::Platform::RUBY
17
16
 
18
- s.files = [
19
- 'lib/cloudsight.rb',
20
- 'Gemfile',
21
- 'Gemfile.lock',
22
- 'MIT-LICENSE',
23
- 'README.md',
24
- 'cloudsight.gemspec'
25
- ]
17
+ s.files = `git ls-files`.split($/)
18
+ s.executables = s.files.grep(%r{^bin/}).map { |f| File.basename(f) }
19
+ s.test_files = s.files.grep(%r{^(test|spec|features)/})
20
+
26
21
  s.require_paths = [%q{lib}]
27
22
 
28
- s.required_ruby_version = Gem::Requirement.new('>= 1.9.1')
23
+ s.required_ruby_version = Gem::Requirement.new('>= 2.1')
29
24
 
30
- s.add_dependency 'json'
31
- s.add_dependency 'rest-client', '~>1.6'
25
+ s.add_dependency 'json', '~> 2.1'
26
+ s.add_dependency 'rest-client', '~> 2.0'
32
27
 
33
28
  s.add_development_dependency 'bundler', '~> 1.6'
34
- s.add_development_dependency 'rake'
29
+ s.add_development_dependency 'rake', '~> 12.0'
30
+ s.add_development_dependency 'rspec', '~> 3.6'
31
+ s.add_development_dependency 'pry', '~> 0.10'
32
+ s.add_development_dependency 'webmock', '~> 3.0'
33
+ s.add_development_dependency 'simple_oauth', '~> 0.3'
35
34
  end
@@ -2,7 +2,7 @@ require 'rubygems'
2
2
  require 'rest-client'
3
3
  begin
4
4
  require 'simple_oauth'
5
- rescue LoadError => err
5
+ rescue LoadError
6
6
  # Tolerate not having this unless it's actually configured
7
7
  end
8
8
  require 'json'
@@ -11,129 +11,26 @@ module Cloudsight
11
11
  BASE_URL = 'https://api.cloudsight.ai'
12
12
 
13
13
  class << self
14
+ FIELDS = %w(api_key oauth_options base_url)
15
+ attr_accessor(*FIELDS)
16
+
14
17
  def oauth_options=(val)
15
- raise RuntimeError.new("Could not load the simple_oauth gem. Install it with `gem install simple_oauth`.") unless defined?(SimpleOAuth::Header)
18
+ raise RuntimeError.new(
19
+ "Could not load the simple_oauth gem. Install it with `gem install simple_oauth`."
20
+ ) unless defined?(SimpleOAuth::Header)
16
21
 
17
22
  val = val.inject({}) {|memo, (k, v)| memo[k.to_sym] = v; memo }
18
- @@oauth_options = val
19
- end
20
-
21
- def api_key=(val)
22
- @@api_key = val
23
- end
24
-
25
- def api_key
26
- @@api_key if defined?(@@api_key)
27
- end
28
-
29
- def oauth_options
30
- @@oauth_options if defined?(@@oauth_options)
31
- end
32
-
33
- def base_url=(val)
34
- @@base_url = val
23
+ @oauth_options = val
35
24
  end
36
25
 
37
26
  def base_url
38
- @@base_url ||= BASE_URL
39
- end
40
- end
41
-
42
- class Util
43
- def self.post(url, params, headers = {})
44
- headers['Authorization'] = authorization_header(:post, url, params)
45
- RestClient.post(url, params, headers)
46
- rescue RestClient::Exception => e
47
- e.response
48
- end
49
-
50
- def self.get(url, headers = {})
51
- headers['Authorization'] = authorization_header(:get, url)
52
- RestClient.get(url, headers)
53
- rescue RestClient::Exception => e
54
- e.response
55
- end
56
-
57
- def self.authorization_header(http_method, url, params = {})
58
- if Cloudsight.api_key
59
- "CloudSight #{Cloudsight.api_key}"
60
- else
61
- # Exclude image file when generating OAuth header
62
- filtered_payload = params.dup
63
- filtered_payload.delete('image_request[image]')
64
-
65
- oauth = SimpleOAuth::Header.new(http_method, url, filtered_payload, Cloudsight.oauth_options || {})
66
- oauth.to_s
67
- end
68
- end
69
- end
70
-
71
- class Request
72
- def self.send(options = {})
73
- raise RuntimeError.new("Need to define either oauth_options or api_key") unless Cloudsight.api_key || Cloudsight.oauth_options
74
- url = "#{Cloudsight::base_url}/image_requests"
75
-
76
- params = {}
77
- [:locale, :language, :latitude, :longitude, :altitude, :device_id, :ttl].each do |attr|
78
- params["image_request[#{attr}]"] = options[attr] if options.has_key?(attr)
79
- end
80
-
81
- if options[:focus]
82
- params['focus[x]'] = options[:focus][:x]
83
- params['focus[y]'] = options[:focus][:y]
84
- end
85
-
86
- params['image_request[remote_image_url]'] = options[:url] if options.has_key?(:url)
87
- params['image_request[image]'] = options[:file] if options.has_key?(:file)
88
-
89
- response = Util.post(url, params)
90
- data = JSON.parse(response.body)
91
- raise ResponseException.new(data['error']) if data['error']
92
- raise UnexpectedResponseException.new(response.body) unless data['token']
93
-
94
- data
95
- end
96
-
97
- def self.repost(token, options = {})
98
- url = "#{Cloudsight::base_url}/image_requests/#{token}/repost"
99
-
100
- response = Util.post(url, options)
101
- return true if response.code == 200 and response.body.to_s.strip.empty?
102
-
103
- data = JSON.parse(response.body)
104
- raise ResponseException.new(data['error']) if data['error']
105
- raise UnexpectedResponseException.new(response.body) unless data['token']
106
-
107
- data
27
+ @base_url ||= BASE_URL
108
28
  end
109
29
  end
110
30
 
111
- class Response
112
- def self.get(token, options = {})
113
- url = "#{Cloudsight::base_url}/image_responses/#{token}"
114
-
115
- response = Util.get(url)
116
- data = JSON.parse(response.body)
117
- raise ResponseException.new(data['error']) if data['error']
118
- raise UnexpectedResponseException.new(response.body) unless data['status']
119
-
120
- data
121
- end
122
-
123
- def self.retrieve(token, options = {})
124
- options = { poll_wait: 1 }.merge(options)
125
-
126
- data = nil
127
- loop do
128
- sleep options[:poll_wait]
129
- data = Cloudsight::Response.get(token, options)
130
- yield data if block_given?
131
- break if data['status'] != 'not completed' and data['status'] != 'in progress'
132
- end
133
-
134
- data
135
- end
136
- end
31
+ require 'cloudsight/api'
32
+ require 'cloudsight/request'
33
+ require 'cloudsight/response'
137
34
 
138
35
  class ResponseException < Exception; end
139
36
  class UnexpectedResponseException < Exception; end
@@ -0,0 +1,32 @@
1
+ module Cloudsight
2
+ class Api
3
+ class << self
4
+ def post(url, params, headers = {})
5
+ headers['Authorization'] = authorization_header(:post, url, params)
6
+ RestClient.post(url, params, headers)
7
+ rescue RestClient::Exception => e
8
+ e.response
9
+ end
10
+
11
+ def get(url, headers = {})
12
+ headers['Authorization'] = authorization_header(:get, url)
13
+ RestClient.get(url, headers)
14
+ rescue RestClient::Exception => e
15
+ e.response
16
+ end
17
+
18
+ def authorization_header(http_method, url, params = {})
19
+ if Cloudsight.api_key
20
+ "CloudSight #{Cloudsight.api_key}"
21
+ else
22
+ # Exclude image file when generating OAuth header
23
+ filtered_payload = params.dup
24
+ filtered_payload.delete('image_request[image]')
25
+
26
+ oauth = SimpleOAuth::Header.new(http_method, url, filtered_payload, Cloudsight.oauth_options || {})
27
+ oauth.to_s
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,47 @@
1
+ module Cloudsight
2
+ class Request
3
+ class << self
4
+ def send(options = {})
5
+ raise RuntimeError.new("Need to define either oauth_options or api_key") unless Cloudsight.api_key || Cloudsight.oauth_options
6
+ url = "#{Cloudsight::base_url}/image_requests"
7
+
8
+ params = construct_params(options)
9
+ response = Api.post(url, params)
10
+ data = JSON.parse(response.body)
11
+ raise ResponseException.new(data['error']) if data['error']
12
+ raise UnexpectedResponseException.new(response.body) unless data['token']
13
+
14
+ data
15
+ end
16
+
17
+ def repost(token, options = {})
18
+ url = "#{Cloudsight::base_url}/image_requests/#{token}/repost"
19
+
20
+ response = Api.post(url, options)
21
+ return true if response.code == 200 and response.body.to_s.strip.empty?
22
+
23
+ data = JSON.parse(response.body)
24
+ raise ResponseException.new(data['error']) if data['error']
25
+ raise UnexpectedResponseException.new(response.body) unless data['token']
26
+
27
+ data
28
+ end
29
+
30
+ def construct_params(options)
31
+ params = {}
32
+ [:locale, :language, :latitude, :longitude, :altitude, :device_id, :ttl].each do |attr|
33
+ params["image_request[#{attr}]"] = options[attr] if options.has_key?(attr)
34
+ end
35
+
36
+ if options[:focus]
37
+ params['focus[x]'] = options[:focus][:x]
38
+ params['focus[y]'] = options[:focus][:y]
39
+ end
40
+
41
+ params['image_request[remote_image_url]'] = options[:url] if options.has_key?(:url)
42
+ params['image_request[image]'] = options[:file] if options.has_key?(:file)
43
+ params
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,30 @@
1
+ module Cloudsight
2
+ class Response
3
+ class << self
4
+ def get(token, options = {})
5
+ url = "#{Cloudsight::base_url}/image_responses/#{token}"
6
+
7
+ response = Api.get(url)
8
+ data = JSON.parse(response.body)
9
+ raise ResponseException.new(data['error']) if data['error']
10
+ raise UnexpectedResponseException.new(response.body) unless data['status']
11
+
12
+ data
13
+ end
14
+
15
+ def retrieve(token, options = {})
16
+ options = { poll_wait: 1 }.merge(options)
17
+
18
+ data = nil
19
+ loop do
20
+ sleep options[:poll_wait]
21
+ data = Cloudsight::Response.get(token, options)
22
+ yield data if block_given?
23
+ break if data['status'] != 'not completed' and data['status'] != 'in progress'
24
+ end
25
+
26
+ data
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,3 @@
1
+ module Cloudsight
2
+ VERSION = "0.0.9.1"
3
+ end
@@ -0,0 +1,75 @@
1
+ require 'spec_helper'
2
+ require 'simple_oauth'
3
+
4
+ RSpec.describe Cloudsight::Api do
5
+
6
+ describe '#authorization_header' do
7
+ context 'with an api_key' do
8
+ it 'returns the proper header' do
9
+ Cloudsight.api_key = 'test_api_key'
10
+ header = described_class.authorization_header(:get, 'test')
11
+ expect(header).to eq 'CloudSight test_api_key'
12
+ end
13
+ end
14
+
15
+ context 'with simple oauth' do
16
+ it 'returns the proper header' do
17
+ Cloudsight.oauth_options = {
18
+ consumer_key: 'test_consumer_key',
19
+ consumer_secret: 'test_consumer_secret'
20
+ }
21
+
22
+ header = described_class.authorization_header(:get, 'https://example.com', { image_request: {} })
23
+ expect(header).to match(/OAuth oauth_consumer_key=/)
24
+ end
25
+ end
26
+ end
27
+
28
+ describe '#post' do
29
+ let(:url) { 'https://example.com' }
30
+
31
+ it 'should post with the correct params' do
32
+ allow(described_class).to receive(:authorization_header).and_return("CloudSight test_api_key")
33
+
34
+ expect(RestClient).to receive(:post).with(
35
+ url, {}, {"Authorization"=>"CloudSight test_api_key"}
36
+ )
37
+
38
+ described_class.post(url, {})
39
+ end
40
+
41
+ it 'should return the response if there is one' do
42
+ allow(described_class).to receive(:authorization_header).and_return("CloudSight test_api_key")
43
+
44
+ allow(RestClient).to receive(:post).with(
45
+ url, {}, {"Authorization"=>"CloudSight test_api_key"}
46
+ ).and_raise(RestClient::Exception)
47
+
48
+ expect { described_class.post(url, {}) }.to_not raise_error
49
+ end
50
+ end
51
+
52
+ describe '#get' do
53
+ let(:url) { 'https://example.com' }
54
+
55
+ it 'should post with the correct params' do
56
+ allow(described_class).to receive(:authorization_header).and_return("CloudSight test_api_key")
57
+
58
+ expect(RestClient).to receive(:get).with(
59
+ url, {"Authorization"=>"CloudSight test_api_key"}
60
+ )
61
+
62
+ described_class.get(url, {})
63
+ end
64
+
65
+ it 'should return the response if there is one' do
66
+ allow(described_class).to receive(:authorization_header).and_return("CloudSight test_api_key")
67
+
68
+ allow(RestClient).to receive(:get).with(
69
+ url, {"Authorization"=>"CloudSight test_api_key"}
70
+ ).and_raise(RestClient::Exception)
71
+
72
+ expect { described_class.get(url, {}) }.to_not raise_error
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,123 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Cloudsight::Request do
4
+
5
+ before(:each) do
6
+ Cloudsight.api_key = 'test_api_key'
7
+ end
8
+
9
+ describe '#construct_params' do
10
+ let(:params) do
11
+ {
12
+ locale: 'en',
13
+ language: 'en',
14
+ latitude: '5',
15
+ longitude: '5',
16
+ altitude: '5',
17
+ device_id: '5',
18
+ ttl: '5',
19
+ url: 'test_url',
20
+ file: 'test_file',
21
+ focus: {
22
+ x: '5',
23
+ y: '5'
24
+ }
25
+ }
26
+ end
27
+
28
+ it 'correctly constructs the params' do
29
+ options = described_class.construct_params(params)
30
+ expect(options).to eq(
31
+ {
32
+ 'image_request[locale]' => 'en',
33
+ 'image_request[language]' => 'en',
34
+ 'image_request[latitude]' => '5',
35
+ 'image_request[longitude]' => '5',
36
+ 'image_request[altitude]' => '5',
37
+ 'image_request[device_id]' => '5',
38
+ 'image_request[ttl]' => '5',
39
+ 'image_request[remote_image_url]' => 'test_url',
40
+ 'image_request[image]' => 'test_file',
41
+ 'focus[x]' => '5',
42
+ 'focus[y]' => '5'
43
+ }
44
+ )
45
+ end
46
+ end
47
+
48
+ describe '#send' do
49
+ let(:params) { { locale: 'en', url: 'test_url' } }
50
+
51
+ it 'returns the proper result' do
52
+ stub_post(
53
+ path: '/image_requests',
54
+ body: { "image_request"=>{ "locale"=>"en", "remote_image_url"=>"test_url" } },
55
+ response: fixture_file('image_request.json')
56
+ )
57
+
58
+ response = described_class.send(params)
59
+
60
+ expect(response["token"]).to eq "sample_token"
61
+ expect(response["url"]).to eq "https://example.com/image.jpg"
62
+ expect(response["status"]).to eq "not completed"
63
+ end
64
+
65
+ it 'responds correctly to a response exception error' do
66
+ stub_post(
67
+ path: '/image_requests',
68
+ body: { "image_request"=>{ "locale"=>"en", "remote_image_url"=>"test_url" } },
69
+ response: fixture_file('error_response.json')
70
+ )
71
+
72
+ expect { described_class.send(params) }.to raise_error Cloudsight::ResponseException
73
+ end
74
+
75
+ it 'responds correctly to an unexpected response' do
76
+ stub_post(
77
+ path: '/image_requests',
78
+ body: { "image_request"=>{ "locale"=>"en", "remote_image_url"=>"test_url" } },
79
+ response: fixture_file('unexpected_response.json')
80
+ )
81
+
82
+ expect { described_class.send(params) }.to raise_error Cloudsight::UnexpectedResponseException
83
+ end
84
+ end
85
+
86
+ describe '#repost' do
87
+ let(:params) { { image_request: { locale: 'en', remote_image_url: 'test_url' } } }
88
+
89
+ it 'returns the proper result' do
90
+ stub_post(
91
+ path: '/image_requests/sample_token/repost',
92
+ body: { "image_request"=>{ "locale"=>"en", "remote_image_url"=>"test_url" } },
93
+ response: fixture_file('image_request.json')
94
+ )
95
+
96
+ response = described_class.repost('sample_token', params)
97
+
98
+ expect(response["token"]).to eq "sample_token"
99
+ expect(response["url"]).to eq "https://example.com/image.jpg"
100
+ expect(response["status"]).to eq "not completed"
101
+ end
102
+
103
+ it 'responds correctly to a response exception error' do
104
+ stub_post(
105
+ path: '/image_requests/sample_token/repost',
106
+ body: { "image_request"=>{ "locale"=>"en", "remote_image_url"=>"test_url" } },
107
+ response: fixture_file('error_response.json')
108
+ )
109
+
110
+ expect { described_class.repost('sample_token', params) }.to raise_error Cloudsight::ResponseException
111
+ end
112
+
113
+ it 'responds correctly to an unexpected response' do
114
+ stub_post(
115
+ path: '/image_requests/sample_token/repost',
116
+ body: { "image_request"=>{ "locale"=>"en", "remote_image_url"=>"test_url" } },
117
+ response: fixture_file('unexpected_response.json')
118
+ )
119
+
120
+ expect { described_class.repost('sample_token', params) }.to raise_error Cloudsight::UnexpectedResponseException
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,74 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Cloudsight::Response do
4
+ before(:each) do
5
+ Cloudsight.api_key = 'test_api_key'
6
+ end
7
+
8
+ describe '#get' do
9
+ it 'returns the proper result' do
10
+ stub_get(
11
+ path: '/image_responses/sample_token',
12
+ response: fixture_file('completed_response.json')
13
+ )
14
+
15
+ response = described_class.get('sample_token')
16
+
17
+ expect(response["token"]).to eq "sample_token"
18
+ expect(response["url"]).to eq "http://www.example.com/your_headphones_image.jpg"
19
+ expect(response["status"]).to eq "completed"
20
+ end
21
+
22
+ it 'responds correctly to a response exception error' do
23
+ stub_get(
24
+ path: '/image_responses/sample_token',
25
+ response: fixture_file('error_response.json')
26
+ )
27
+
28
+ expect { described_class.get('sample_token') }.to raise_error Cloudsight::ResponseException
29
+ end
30
+
31
+ it 'responds correctly to an unexpected response' do
32
+ stub_get(
33
+ path: '/image_responses/sample_token',
34
+ response: fixture_file('unexpected_response.json')
35
+ )
36
+
37
+ expect { described_class.get('sample_token') }.to raise_error Cloudsight::UnexpectedResponseException
38
+ end
39
+ end
40
+
41
+ describe '#retrieve' do
42
+ it 'returns the proper result' do
43
+ stub_polling(3, 'image_request.json', 'completed_response.json', '/image_responses/sample_token')
44
+
45
+ response = described_class.retrieve('sample_token', poll_wait: 0.01)
46
+
47
+ expect(response["token"]).to eq "sample_token"
48
+ expect(response["url"]).to eq "http://www.example.com/your_headphones_image.jpg"
49
+ expect(response["status"]).to eq "completed"
50
+ end
51
+
52
+ it 'responds correctly to a response exception error' do
53
+ stub_polling(3, 'image_request.json', 'error_response.json', '/image_responses/sample_token')
54
+
55
+ expect { described_class.retrieve('sample_token', poll_wait: 0.01) }.to raise_error Cloudsight::ResponseException
56
+ end
57
+
58
+ it 'responds correctly to an unexpected response' do
59
+ stub_polling(3, 'image_request.json', 'unexpected_response.json', '/image_responses/sample_token')
60
+
61
+ expect { described_class.retrieve('sample_token', poll_wait: 0.01) }.to raise_error Cloudsight::UnexpectedResponseException
62
+ end
63
+ end
64
+ end
65
+
66
+ def stub_polling(num_retries, file_1, file_2, path)
67
+ retries = 0
68
+ while retries < num_retries
69
+ stub_get(path: path, response: fixture_file(file_1))
70
+ retries += 1
71
+ end
72
+
73
+ stub_get(path: path, response: fixture_file(file_2))
74
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+ require 'simple_oauth'
3
+
4
+ RSpec.describe Cloudsight do
5
+ context 'initialization' do
6
+ it 'should assign the proper basic attributes' do
7
+ Cloudsight.api_key = 'test_api_key'
8
+ Cloudsight.base_url = 'test_base_url'
9
+
10
+ expect(Cloudsight.api_key) .to eq 'test_api_key'
11
+ expect(Cloudsight.base_url).to eq 'test_base_url'
12
+ end
13
+
14
+ it 'should configure the oauth_options correctly' do
15
+ Cloudsight.oauth_options = {
16
+ consumer_key: 'test_consumer_key',
17
+ consumer_secret: 'test_consumer_secret'
18
+ }
19
+
20
+ expect(Cloudsight.oauth_options[:consumer_key]).to eq 'test_consumer_key'
21
+ expect(Cloudsight.oauth_options[:consumer_secret]).to eq 'test_consumer_secret'
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,8 @@
1
+ {
2
+ "status" : "completed",
3
+ "name" : "red beats by dre headphones",
4
+ "flags" : [],
5
+ "ttl" : 60,
6
+ "url" : "http://www.example.com/your_headphones_image.jpg",
7
+ "token" : "sample_token"
8
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "status" : "completed",
3
+ "name" : "red beats by dre headphones",
4
+ "error": "test_error",
5
+ "flags" : [],
6
+ "ttl" : 60,
7
+ "url" : "http://www.example.com/your_headphones_image.jpg",
8
+ "token" : "sample_token"
9
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "token": "sample_token",
3
+ "url": "https://example.com/image.jpg",
4
+ "status": "not completed"
5
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "name" : "red beats by dre headphones",
3
+ "flags" : [],
4
+ "ttl" : 60,
5
+ "url" : "http://www.example.com/your_headphones_image.jpg"
6
+ }
@@ -0,0 +1,55 @@
1
+ require 'bundler/setup'
2
+ require 'cloudsight'
3
+ require 'webmock/rspec'
4
+ require 'pry'
5
+
6
+ RSpec.configure do |config|
7
+ # Enable flags like --only-failures and --next-failure
8
+ config.example_status_persistence_file_path = ".rspec_status"
9
+
10
+ # Disable RSpec exposing methods globally on `Module` and `main`
11
+ config.disable_monkey_patching!
12
+
13
+ config.expect_with :rspec do |c|
14
+ c.syntax = :expect
15
+ end
16
+
17
+ config.after(:each) do
18
+ Cloudsight.api_key = nil
19
+ Cloudsight.oauth_options = {}
20
+ Cloudsight.base_url = nil
21
+ end
22
+
23
+ end
24
+
25
+ def stub_get(path:, response:, status: 200, message: nil)
26
+ stub_request(:get, Cloudsight::BASE_URL + path).to_return(
27
+ status: status,
28
+ body: response,
29
+ exception: message
30
+ )
31
+ end
32
+
33
+ def stub_post(path:, body: {}, response: {}, status: 200, message: nil)
34
+ stub_request(:post, Cloudsight::BASE_URL + path).with(
35
+ body: hash_including(body)
36
+ ).to_return(
37
+ status: status,
38
+ body: response,
39
+ exception: message
40
+ )
41
+ end
42
+
43
+ def fixture_file(filename, options={})
44
+ return '' if filename == ''
45
+ file_path = File.expand_path(File.dirname(__FILE__) + '/fixtures/' + filename)
46
+ fixture = File.read(file_path)
47
+
48
+ case File.extname(file_path)
49
+ when '.json'
50
+ options[:parse] ? JSON.parse(fixture) : fixture
51
+ else
52
+ fixture
53
+ end
54
+ end
55
+
metadata CHANGED
@@ -1,43 +1,45 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cloudsight
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.9.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brad Folkens
8
+ - Jack McCallum
9
+ - Chris Weilemann
8
10
  autorequire:
9
11
  bindir: bin
10
12
  cert_chain: []
11
- date: 2015-11-05 00:00:00.000000000 Z
13
+ date: 2017-08-11 00:00:00.000000000 Z
12
14
  dependencies:
13
15
  - !ruby/object:Gem::Dependency
14
16
  name: json
15
17
  requirement: !ruby/object:Gem::Requirement
16
18
  requirements:
17
- - - ">="
19
+ - - "~>"
18
20
  - !ruby/object:Gem::Version
19
- version: '0'
21
+ version: '2.1'
20
22
  type: :runtime
21
23
  prerelease: false
22
24
  version_requirements: !ruby/object:Gem::Requirement
23
25
  requirements:
24
- - - ">="
26
+ - - "~>"
25
27
  - !ruby/object:Gem::Version
26
- version: '0'
28
+ version: '2.1'
27
29
  - !ruby/object:Gem::Dependency
28
30
  name: rest-client
29
31
  requirement: !ruby/object:Gem::Requirement
30
32
  requirements:
31
33
  - - "~>"
32
34
  - !ruby/object:Gem::Version
33
- version: '1.6'
35
+ version: '2.0'
34
36
  type: :runtime
35
37
  prerelease: false
36
38
  version_requirements: !ruby/object:Gem::Requirement
37
39
  requirements:
38
40
  - - "~>"
39
41
  - !ruby/object:Gem::Version
40
- version: '1.6'
42
+ version: '2.0'
41
43
  - !ruby/object:Gem::Dependency
42
44
  name: bundler
43
45
  requirement: !ruby/object:Gem::Requirement
@@ -56,28 +58,104 @@ dependencies:
56
58
  name: rake
57
59
  requirement: !ruby/object:Gem::Requirement
58
60
  requirements:
59
- - - ">="
61
+ - - "~>"
62
+ - !ruby/object:Gem::Version
63
+ version: '12.0'
64
+ type: :development
65
+ prerelease: false
66
+ version_requirements: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - "~>"
69
+ - !ruby/object:Gem::Version
70
+ version: '12.0'
71
+ - !ruby/object:Gem::Dependency
72
+ name: rspec
73
+ requirement: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - "~>"
76
+ - !ruby/object:Gem::Version
77
+ version: '3.6'
78
+ type: :development
79
+ prerelease: false
80
+ version_requirements: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - "~>"
83
+ - !ruby/object:Gem::Version
84
+ version: '3.6'
85
+ - !ruby/object:Gem::Dependency
86
+ name: pry
87
+ requirement: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - "~>"
90
+ - !ruby/object:Gem::Version
91
+ version: '0.10'
92
+ type: :development
93
+ prerelease: false
94
+ version_requirements: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - "~>"
97
+ - !ruby/object:Gem::Version
98
+ version: '0.10'
99
+ - !ruby/object:Gem::Dependency
100
+ name: webmock
101
+ requirement: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - "~>"
60
104
  - !ruby/object:Gem::Version
61
- version: '0'
105
+ version: '3.0'
62
106
  type: :development
63
107
  prerelease: false
64
108
  version_requirements: !ruby/object:Gem::Requirement
65
109
  requirements:
66
- - - ">="
110
+ - - "~>"
111
+ - !ruby/object:Gem::Version
112
+ version: '3.0'
113
+ - !ruby/object:Gem::Dependency
114
+ name: simple_oauth
115
+ requirement: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - "~>"
118
+ - !ruby/object:Gem::Version
119
+ version: '0.3'
120
+ type: :development
121
+ prerelease: false
122
+ version_requirements: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - "~>"
67
125
  - !ruby/object:Gem::Version
68
- version: '0'
126
+ version: '0.3'
69
127
  description: A simple CloudSight API Client for Image Recognition
70
- email: brad@cloudsightapi.com
71
- executables: []
128
+ email: oss@cloudsight.ai
129
+ executables:
130
+ - console
131
+ - setup
72
132
  extensions: []
73
133
  extra_rdoc_files: []
74
134
  files:
135
+ - ".gitignore"
136
+ - ".rspec"
137
+ - ".travis.yml"
75
138
  - Gemfile
76
- - Gemfile.lock
77
139
  - MIT-LICENSE
78
140
  - README.md
141
+ - Rakefile
142
+ - bin/console
143
+ - bin/setup
79
144
  - cloudsight.gemspec
80
145
  - lib/cloudsight.rb
146
+ - lib/cloudsight/api.rb
147
+ - lib/cloudsight/request.rb
148
+ - lib/cloudsight/response.rb
149
+ - lib/cloudsight/version.rb
150
+ - spec/cloudsight/api_spec.rb
151
+ - spec/cloudsight/request_spec.rb
152
+ - spec/cloudsight/response_spec.rb
153
+ - spec/cloudsight_spec.rb
154
+ - spec/fixtures/completed_response.json
155
+ - spec/fixtures/error_response.json
156
+ - spec/fixtures/image_request.json
157
+ - spec/fixtures/unexpected_response.json
158
+ - spec/spec_helper.rb
81
159
  homepage: http://github.com/cloudsight/cloudsight-ruby
82
160
  licenses:
83
161
  - MIT
@@ -90,7 +168,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
90
168
  requirements:
91
169
  - - ">="
92
170
  - !ruby/object:Gem::Version
93
- version: 1.9.1
171
+ version: '2.1'
94
172
  required_rubygems_version: !ruby/object:Gem::Requirement
95
173
  requirements:
96
174
  - - ">="
@@ -102,4 +180,13 @@ rubygems_version: 2.6.12
102
180
  signing_key:
103
181
  specification_version: 4
104
182
  summary: CloudSight API Client
105
- test_files: []
183
+ test_files:
184
+ - spec/cloudsight/api_spec.rb
185
+ - spec/cloudsight/request_spec.rb
186
+ - spec/cloudsight/response_spec.rb
187
+ - spec/cloudsight_spec.rb
188
+ - spec/fixtures/completed_response.json
189
+ - spec/fixtures/error_response.json
190
+ - spec/fixtures/image_request.json
191
+ - spec/fixtures/unexpected_response.json
192
+ - spec/spec_helper.rb
@@ -1,36 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- cloudsight (0.0.2)
5
- json
6
- rest-client (~> 1.6)
7
-
8
- GEM
9
- remote: https://rubygems.org/
10
- specs:
11
- domain_name (0.5.20170404)
12
- unf (>= 0.0.5, < 1.0.0)
13
- http-cookie (1.0.3)
14
- domain_name (~> 0.5)
15
- json (2.1.0)
16
- mime-types (2.99.3)
17
- netrc (0.11.0)
18
- rake (12.0.0)
19
- rest-client (1.8.0)
20
- http-cookie (>= 1.0.2, < 2.0)
21
- mime-types (>= 1.16, < 3.0)
22
- netrc (~> 0.7)
23
- unf (0.1.4)
24
- unf_ext
25
- unf_ext (0.0.7.4)
26
-
27
- PLATFORMS
28
- ruby
29
-
30
- DEPENDENCIES
31
- bundler (~> 1.6)
32
- cloudsight!
33
- rake
34
-
35
- BUNDLED WITH
36
- 1.13.7