yelp 1.0.0 → 2.0.0

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.
Files changed (51) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/Gemfile +3 -0
  4. data/LICENSE.txt +22 -504
  5. data/README.md +152 -0
  6. data/Rakefile +4 -24
  7. data/lib/yelp.rb +18 -13
  8. data/lib/yelp/burst_struct.rb +51 -0
  9. data/lib/yelp/client.rb +86 -86
  10. data/lib/yelp/configuration.rb +31 -0
  11. data/lib/yelp/endpoint/business.rb +42 -0
  12. data/lib/yelp/endpoint/search.rb +170 -0
  13. data/lib/yelp/error.rb +55 -0
  14. data/lib/yelp/version.rb +3 -0
  15. data/spec/fixtures/vcr_cassettes/business.yml +73 -0
  16. data/spec/fixtures/vcr_cassettes/search.yml +361 -0
  17. data/spec/fixtures/vcr_cassettes/search_bounding_box.yml +359 -0
  18. data/spec/fixtures/vcr_cassettes/search_by_coordinates.yml +387 -0
  19. data/spec/spec_helper.rb +14 -0
  20. data/spec/support/request_error.rb +11 -0
  21. data/spec/support/shared_configuration.rb +11 -0
  22. data/spec/yelp/burst_struct_spec.rb +124 -0
  23. data/spec/yelp/client_spec.rb +75 -0
  24. data/spec/yelp/configuration_spec.rb +44 -0
  25. data/spec/yelp/endpoint/business_spec.rb +26 -0
  26. data/spec/yelp/endpoint/search_spec.rb +72 -0
  27. data/spec/yelp/error_spec.rb +22 -0
  28. data/spec/yelp/yelp_spec.rb +10 -0
  29. data/tasks/console.rake +4 -0
  30. data/yelp.gemspec +32 -0
  31. metadata +252 -90
  32. data/CHANGELOG.rdoc +0 -48
  33. data/Manifest.txt +0 -24
  34. data/README.rdoc +0 -118
  35. data/TODO.txt +0 -6
  36. data/lib/yelp/neighborhood/request/base.rb +0 -13
  37. data/lib/yelp/neighborhood/request/geo_point.rb +0 -23
  38. data/lib/yelp/neighborhood/request/location.rb +0 -53
  39. data/lib/yelp/phone/request/number.rb +0 -24
  40. data/lib/yelp/record.rb +0 -16
  41. data/lib/yelp/request.rb +0 -44
  42. data/lib/yelp/response_format.rb +0 -36
  43. data/lib/yelp/review/request/base.rb +0 -31
  44. data/lib/yelp/review/request/bounding_box.rb +0 -37
  45. data/lib/yelp/review/request/geo_point.rb +0 -28
  46. data/lib/yelp/review/request/location.rb +0 -63
  47. data/test/test_client.rb +0 -11
  48. data/test/test_neighborhood_search.rb +0 -46
  49. data/test/test_phone_search.rb +0 -20
  50. data/test/test_review_search.rb +0 -168
  51. data/test/yelp_helper.rb +0 -45
@@ -0,0 +1,14 @@
1
+ require 'yelp'
2
+ require 'support/request_error'
3
+ require 'support/shared_configuration'
4
+ require 'vcr'
5
+
6
+ VCR.configure do |c|
7
+ c.cassette_library_dir = 'spec/fixtures/vcr_cassettes'
8
+ c.hook_into :webmock
9
+
10
+ c.filter_sensitive_data('<YELP_CONSUMER_KEY>') { ENV['YELP_CONSUMER_KEY'] }
11
+ c.filter_sensitive_data('<YELP_CONSUMER_SECRET>') { ENV['YELP_CONSUMER_SECRET'] }
12
+ c.filter_sensitive_data('<YELP_TOKEN>') { ENV['YELP_TOKEN'] }
13
+ c.filter_sensitive_data('<YELP_TOKEN_SECRET>') { ENV['YELP_TOKEN_SECRET'] }
14
+ end
@@ -0,0 +1,11 @@
1
+ shared_examples 'a request error' do
2
+ context 'API' do
3
+ let(:response_body) { "{\"error\": {\"text\": \"error message\", \"id\": \"INTERNAL_ERROR\"}}" }
4
+ let(:bad_response) { double('response', status: 400, body: response_body) }
5
+
6
+ it 'should raise an error' do
7
+ client.stub_chain(:connection, :get).and_return(bad_response)
8
+ expect { request }.to raise_error(Yelp::InternalError)
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ shared_context "shared configuration" do
2
+ let(:valid_api_keys) { Hash[consumer_key: 'abc',
3
+ consumer_secret: 'def',
4
+ token: 'ghi',
5
+ token_secret: 'jkl'] }
6
+ let(:real_api_keys) { Hash[consumer_key: ENV['YELP_CONSUMER_KEY'],
7
+ consumer_secret: ENV['YELP_CONSUMER_SECRET'],
8
+ token: ENV['YELP_TOKEN'],
9
+ token_secret: ENV['YELP_TOKEN_SECRET']] }
10
+ let(:invalid_api_keys) { valid_api_keys.merge(consumer_key: nil) }
11
+ end
@@ -0,0 +1,124 @@
1
+ require 'yelp/burst_struct'
2
+
3
+ describe BurstStruct::Burst do
4
+ describe '#foo' do
5
+ subject(:struct) { BurstStruct::Burst.new(foo: 'bar') }
6
+
7
+ context 'when a key exists' do
8
+ it 'should return' do
9
+ expect(struct.foo).to eql 'bar'
10
+ end
11
+ end
12
+
13
+ context 'when a key does not exist' do
14
+ it 'should not respond to it' do
15
+ expect(struct.respond_to? :super_foo).to eql false
16
+ end
17
+ end
18
+ end
19
+
20
+ context 'n deep nested hash' do
21
+ let(:hash) { Hash[ futurama: { characters: { robots: { best: 'bender' } } } ] }
22
+
23
+ subject(:struct) { BurstStruct::Burst.new(hash) }
24
+
25
+ describe '#foo#bar#baz#biz' do
26
+ it 'should return' do
27
+ expect(struct.futurama.characters.robots.best).to eql 'bender'
28
+ end
29
+ end
30
+ end
31
+
32
+ context 'arrays' do
33
+ let(:hash) { Hash[ businesses: [ { name: 'Yelp', location: 'San Francisco' },
34
+ { name: 'Ice Cream', flavor: 'Chocolate' },
35
+ [ { name: 'Moe', occupation: 'Bartender' } ] ] ] }
36
+
37
+ subject(:struct) { BurstStruct::Burst.new(hash) }
38
+
39
+ describe '#businesses[0].name' do
40
+ it 'should return' do
41
+ expect(struct.businesses[0].name).to eql 'Yelp'
42
+ expect(struct.businesses[0].location).to eql 'San Francisco'
43
+ end
44
+ end
45
+
46
+ describe '#business[1].name' do
47
+ it 'should return' do
48
+ expect(struct.businesses[1].name).to eql 'Ice Cream'
49
+ expect(struct.businesses[1].flavor).to eql 'Chocolate'
50
+ end
51
+ end
52
+
53
+ describe 'nested arrays' do
54
+ it 'should parse arrays all the way down' do
55
+ expect(struct.businesses[2][0].name).to eql 'Moe'
56
+ end
57
+ end
58
+ end
59
+
60
+ context 'large hash' do
61
+ let(:hash) do
62
+ { foo: 1,
63
+ bar: {
64
+ baz: 2,
65
+ bender: {
66
+ bending: {
67
+ rodriguez: true
68
+ }
69
+ }
70
+ },
71
+ fry: [
72
+ {past: true},
73
+ {present: true},
74
+ {future: true}
75
+ ],
76
+ turunga: 'leela',
77
+ 'hubert' => 'farnsworth',
78
+ zoidberg: [
79
+ 'doctor',
80
+ 'homeowner',
81
+ 'moviestar'
82
+ ]
83
+ }
84
+ end
85
+
86
+ subject(:struct) { BurstStruct::Burst.new(hash) }
87
+
88
+ it 'turns top level into a struct' do
89
+ expect(struct.foo).to eql 1
90
+ end
91
+
92
+ it 'recursively creates structs all the way down the hash' do
93
+ expect(struct.bar.baz).to equal 2
94
+ expect(struct.bar.bender.bending.rodriguez).to eql true
95
+ end
96
+
97
+ it 'creates arrays with hashes into new structs' do
98
+ expect(struct.fry[0].past).to eql true
99
+ expect(struct.fry[1].present).to eql true
100
+ expect(struct.fry[2].future).to eql true
101
+ end
102
+
103
+ it 'turns string keys into structs' do
104
+ expect(struct.hubert).to eql 'farnsworth'
105
+ end
106
+
107
+ it 'should maintain arrays with non hashes' do
108
+ expect(struct.zoidberg.size).to eql 3
109
+ expect(struct.zoidberg[0]).to eql 'doctor'
110
+ end
111
+ end
112
+
113
+ context 'deserialize' do
114
+ let(:hash) do
115
+ { name: 'Bender', company: 'Yelp', title: 'Bending Engineer' }
116
+ end
117
+
118
+ subject(:struct) { BurstStruct::Burst.new(hash) }
119
+
120
+ it 'should deserialize to the same json' do
121
+ expect(struct.to_json).to eql hash.to_json
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,75 @@
1
+ require 'spec_helper'
2
+
3
+ describe Yelp::Client do
4
+ include_context 'shared configuration'
5
+
6
+ let(:client) { Yelp::Client.new(api_keys) }
7
+ let(:api_keys) { valid_api_keys }
8
+
9
+ def configure_client_with_api_keys(api_keys)
10
+ client.configure do |config|
11
+ api_keys.each { |key, value| config.send("#{key}=", value) }
12
+ end
13
+ end
14
+
15
+ describe '#initialize' do
16
+ subject { client }
17
+
18
+ context 'with valid configuration' do
19
+ its(:configuration) { should be_a(Yelp::Configuration) }
20
+ its(:configuration) { should be_frozen }
21
+
22
+ it 'should not be reconfigurable' do
23
+ expect {
24
+ configure_client_with_api_keys(valid_api_keys)
25
+ }.to raise_error
26
+ end
27
+ end
28
+
29
+ context 'with invalid configuration' do
30
+ let(:api_keys) { invalid_api_keys }
31
+
32
+ it 'should raise an error when configuration is invalid' do
33
+ expect { client }.to raise_error
34
+ end
35
+ end
36
+ end
37
+
38
+ describe '#configure' do
39
+ subject { client.configuration }
40
+ let(:client) { Yelp::Client.new }
41
+
42
+ context 'with valid configuration' do
43
+ before { configure_client_with_api_keys(api_keys) }
44
+
45
+ it 'should set the configuration values' do
46
+ valid_api_keys.each do |key, value|
47
+ expect(client.configuration.send(key)).to eql(value)
48
+ end
49
+ end
50
+
51
+ it 'should not be reconfigurable' do
52
+ expect { configure_client_with_api_keys(valid_api_keys) }.to raise_error
53
+ end
54
+
55
+ it { should be_a(Yelp::Configuration) }
56
+ it { should be_frozen }
57
+ end
58
+
59
+ context 'with invalid configuration' do
60
+ it 'should raise an error' do
61
+ expect { configure_client_with_api_keys(invalid_api_keys) }.to raise_error
62
+ end
63
+ end
64
+ end
65
+
66
+ describe '#connection' do
67
+ let(:client) { Yelp::Client.new }
68
+
69
+ context 'without configuration' do
70
+ it 'should raise an error' do
71
+ expect { client.connection }.to raise_error
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,44 @@
1
+ require 'spec_helper'
2
+
3
+ describe Yelp::Configuration do
4
+ include_context 'shared configuration'
5
+
6
+ let(:api_keys) { valid_api_keys }
7
+ let(:configuration) { Yelp::Configuration.new(api_keys) }
8
+
9
+ describe '#initialize' do
10
+ subject { configuration }
11
+
12
+ Yelp::Configuration::AUTH_KEYS.each do |auth_key|
13
+ its(auth_key) { should eql(api_keys[auth_key]) }
14
+ end
15
+ end
16
+
17
+ describe '#auth_keys' do
18
+ subject { configuration.auth_keys }
19
+ it { should eql(api_keys) }
20
+ end
21
+
22
+ describe "#valid?" do
23
+ subject { configuration.valid? }
24
+
25
+ context "when keys are valid" do
26
+ it { should be_true }
27
+ end
28
+
29
+ context "when keys are not set" do
30
+ let(:api_keys) { Hash.new }
31
+ it { should be_false }
32
+ end
33
+
34
+ context "when a key is an empty string" do
35
+ let(:api_keys) { valid_api_keys.merge(consumer_key: '') }
36
+ it { should be_false }
37
+ end
38
+
39
+ context "when a key is nil" do
40
+ let(:api_keys) { valid_api_keys.merge(token: nil) }
41
+ it { should be_false }
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ describe Yelp::Endpoint::Business do
4
+ include_context 'shared configuration'
5
+
6
+ let(:api_keys) { real_api_keys }
7
+ let(:business) { 'yelp-san-francisco' }
8
+ let(:client) { Yelp::Client.new(api_keys) }
9
+
10
+ describe '#business' do
11
+ subject {
12
+ VCR.use_cassette('business') do
13
+ client.business(business)
14
+ end
15
+ }
16
+
17
+ it { should be_a(BurstStruct::Burst) }
18
+ its(:name) { should eql('Yelp') }
19
+ end
20
+
21
+ describe 'errors' do
22
+ it_behaves_like 'a request error' do
23
+ let(:request) { client.business(business) }
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,72 @@
1
+ require 'spec_helper'
2
+
3
+ describe Yelp::Endpoint::Search do
4
+ include_context 'shared configuration'
5
+
6
+ let(:api_keys) { real_api_keys }
7
+ let(:location) { 'San Francisco' }
8
+ let(:params) { Hash[term: 'restaurants',
9
+ category_filter: 'discgolf'] }
10
+ let(:client) { Yelp::Client.new(api_keys) }
11
+
12
+ describe '#search' do
13
+ subject(:results) {
14
+ VCR.use_cassette('search') do
15
+ client.search(location)
16
+ end
17
+ }
18
+
19
+ it { should be_a(BurstStruct::Burst) }
20
+ it 'should get results' do
21
+ expect(results.businesses.size).to be > 0
22
+ end
23
+ end
24
+
25
+ describe '#search_bounding_box' do
26
+ let(:bounding_box) { Hash[sw_latitude: 37.7577,
27
+ sw_longitude: -122.4376,
28
+ ne_latitude: 37.785381,
29
+ ne_longitude: -122.391681] }
30
+
31
+ subject(:results) {
32
+ VCR.use_cassette('search_bounding_box') do
33
+ client.search_by_bounding_box(bounding_box)
34
+ end
35
+ }
36
+
37
+ it 'should get results' do
38
+ expect(results.businesses.size).to be > 0
39
+ end
40
+ end
41
+
42
+ describe '#search_by_coordinates' do
43
+ let(:coordinates) { Hash[latitude: 37.7577,
44
+ longitude: -122.4376] }
45
+
46
+ subject(:results) {
47
+ VCR.use_cassette('search_by_coordinates') do
48
+ client.search_by_coordinates(coordinates)
49
+ end
50
+ }
51
+
52
+ it 'should get results' do
53
+ expect(results.businesses.size).to be > 0
54
+ end
55
+ end
56
+
57
+ describe 'errors' do
58
+ context 'search' do
59
+ it 'raises when #search_by_coordinates params are empty' do
60
+ expect { client.search_by_coordinates({}, params) }.to raise_error(Yelp::MissingLatLng)
61
+ end
62
+
63
+ it 'raises when #search_by_bounding_box params are empty' do
64
+ expect { client.search_by_bounding_box({}, params) }.to raise_error(Yelp::BoundingBoxNotComplete)
65
+ end
66
+ end
67
+
68
+ it_behaves_like 'a request error' do
69
+ let(:request) { client.search(location) }
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+ require 'yelp'
3
+
4
+ describe Yelp::Error do
5
+ context '#from_request' do
6
+ let(:response_body) { "{\"error\": {\"text\": \"error message\", \"id\": \"INTERNAL_ERROR\"}}" }
7
+ let(:good_response) { double('response', status: 200) }
8
+ let(:bad_response) { double('response', status: 400, body: response_body) }
9
+
10
+ it 'should not raise an error' do
11
+ expect {
12
+ Yelp::Error.check_for_error(good_response)
13
+ }.to_not raise_error
14
+ end
15
+
16
+ it 'should raise an internal error' do
17
+ expect {
18
+ Yelp::Error.check_for_error(bad_response)
19
+ }.to raise_error(Yelp::InternalError, 'error message')
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,10 @@
1
+ require 'spec_helper'
2
+
3
+ describe Yelp do
4
+ describe "#client" do
5
+ subject { Yelp.client }
6
+
7
+ it { should be_a(Yelp::Client) }
8
+ its(:configuration) { should be_nil }
9
+ end
10
+ end
@@ -0,0 +1,4 @@
1
+ desc "Open an irb session preloaded with this library"
2
+ task :console do
3
+ sh "pry --gem"
4
+ end
@@ -0,0 +1,32 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'yelp/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'yelp'
8
+ spec.version = Yelp::VERSION
9
+ spec.authors = ['Tomer Elmalem', 'Yelp']
10
+ spec.email = ['telmalem@gmail.com', 'partnerships@yelp.com']
11
+ spec.summary = %q{Ruby client library for the Yelp API}
12
+ spec.description = 'Provides easy way to interact with the Yelp API in any kind of application'
13
+ spec.homepage = 'https://github.com/yelp/yelp.rb'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_development_dependency 'bundler', '~> 1.5'
22
+ spec.add_development_dependency 'rake', '~> 10.0', '>= 10.0.0'
23
+ spec.add_development_dependency 'rspec', '~> 2.6'
24
+ spec.add_development_dependency 'pry', '~> 0.9', '>= 0.9.0'
25
+ spec.add_development_dependency 'vcr', '~> 2.8', '>= 2.8.0'
26
+ spec.add_development_dependency 'webmock', '~> 1.17', '>= 1.17.0'
27
+ spec.add_development_dependency 'yard', '~> 0.8'
28
+
29
+ spec.add_runtime_dependency 'faraday', '~> 0.8', '>= 0.8.0'
30
+ spec.add_runtime_dependency 'faraday_middleware', '~> 0.8', '>= 0.8.0'
31
+ spec.add_runtime_dependency 'simple_oauth', '~> 0.2', '>= 0.2.0'
32
+ end