cloudsight 0.0.5 → 0.0.9.1

Sign up to get free protection for your applications and to get access to all the features.
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