fb_graph2 0.0.7 → 0.0.8

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: 3c8a159c7d77db9a3e0dc1c216b48af33b13607b
4
- data.tar.gz: cd9d38bc8c9d472dbb2bdd46066a564b63cb1e68
3
+ metadata.gz: 37cb2d2c7a4656ed062f89cdd23f62c4d3330b75
4
+ data.tar.gz: e7245ddeb28a753a0c0a944090d9c2405bc91362
5
5
  SHA512:
6
- metadata.gz: 88849dbc9b87d5686b0c9aef2958e0a30fd796350d1d079c9bb44da9b55eee6b551dcc80b1c3de82001106cfcb3ca518425a8daa8f323d529b1e01c1ab0f0c3a
7
- data.tar.gz: 65dfae68dd22c6e6308c7df7e409bc42d2d6ee08ef556ca615593fab9de008441417a0cac46a7753c1ef74981f25e13e711d5ff46ed28d48baea2360ba54a6c7
6
+ metadata.gz: e9ffa26d19e497c0c528ef45a9b9d5745d1a0762d102d25a37080226a9d9d9f0eaf5b15a4b917335342927a5fc11b9ce22f5967b981ef3d202873e12a6a6cceb
7
+ data.tar.gz: 086e24af8d48fd1e0857cdbf55e1aec2b701c57cc176530952be8bc49ea491d20bd56f7640ebbd128185dc4e0a40bd7a693525177e0e3658fdef1151ecf58030
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ rvm:
2
+ - 2.0.0
3
+ - 2.1.2
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.7
1
+ 0.0.8
@@ -25,8 +25,6 @@ module FbGraph2
25
25
  Struct::AppLink::Native::Android
26
26
  when :windows_phone
27
27
  Struct::AppLink::Native::WindowsPhone
28
- else
29
- raise 'Unknown AppLink Type'
30
28
  end
31
29
  klass.new link
32
30
  end
@@ -24,6 +24,8 @@ module FbGraph2
24
24
  value = case type
25
25
  when :raw
26
26
  raw
27
+ when :int_flag
28
+ raw == 1
27
29
  when :date
28
30
  Date.strptime raw, '%m/%d/%Y' rescue raw
29
31
  when :time
@@ -0,0 +1,13 @@
1
+ module FbGraph2
2
+ class Auth < Rack::OAuth2::Client
3
+ def initialize(client_id, client_secret, options = {})
4
+ super options.merge(
5
+ identifier: client_id,
6
+ secret: client_secret,
7
+ host: URI.parse(FbGraph2.root_url).host,
8
+ authorize_endpoint: '/oauth/authorize',
9
+ token_endpoint: '/oauth/access_token'
10
+ )
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,81 @@
1
+ module FbGraph2
2
+ class Exception < StandardError
3
+ attr_accessor :status, :type, :code
4
+
5
+ class << self
6
+ def detect(status, body = {}, headers = {})
7
+ error = body[:error]
8
+ message = error.try(:[], :message)
9
+ klass = detect_from_header(headers, error) || detect_from_status(status)
10
+ if klass
11
+ klass.new message, error
12
+ else
13
+ new status, message, error
14
+ end
15
+ end
16
+
17
+ def detect_from_status(status)
18
+ case status
19
+ when 400
20
+ BadRequest
21
+ when 401
22
+ Unauthorized
23
+ when 404
24
+ NotFound
25
+ when 500
26
+ InternalServerError
27
+ end
28
+ end
29
+
30
+ def detect_from_header(headers, error)
31
+ key, value = headers.detect do |name, value|
32
+ name.upcase == "WWW-Authenticate".upcase
33
+ end || return
34
+ matched, klass = ERROR_HEADER_MATCHERS.detect do |matcher, klass_name|
35
+ matcher =~ value
36
+ end || return
37
+ klass
38
+ end
39
+ end
40
+
41
+ def initialize(status, message, error = {})
42
+ super message
43
+ self.status = status
44
+ self.type = error[:type]
45
+ self.code = error[:code]
46
+ end
47
+
48
+ class BadRequest < Exception
49
+ def initialize(message, details = {})
50
+ super 400, message, details
51
+ end
52
+ end
53
+
54
+ class Unauthorized < Exception
55
+ def initialize(message, details = {})
56
+ super 401, message, details
57
+ end
58
+ end
59
+
60
+ class NotFound < Exception
61
+ def initialize(message, details = {})
62
+ super 404, message, details
63
+ end
64
+ end
65
+
66
+ class InternalServerError < Exception
67
+ def initialize(message, details = {})
68
+ super 500, message, details
69
+ end
70
+ end
71
+
72
+ class InvalidToken < Unauthorized; end
73
+ class InvalidRequest < BadRequest; end
74
+
75
+ ERROR_HEADER_MATCHERS = {
76
+ /not_found/ => NotFound,
77
+ /invalid_token/ => InvalidToken,
78
+ /invalid_request/ => InvalidRequest
79
+ }
80
+ end
81
+ end
@@ -18,13 +18,13 @@ module FbGraph2
18
18
  self
19
19
  end
20
20
 
21
- def fetch(params = {})
22
- attributes = get params
21
+ def fetch(params = {}, options = {})
22
+ attributes = get params, options
23
23
  self.class.new(attributes[:id], attributes).authenticate access_token
24
24
  end
25
25
 
26
- def self.fetch(identifier, params = {})
27
- new(identifier).fetch params
26
+ def self.fetch(identifier, params = {}, options = {})
27
+ new(identifier).fetch params, options
28
28
  end
29
29
 
30
30
  def edge(edge, params = {}, options = {})
@@ -85,7 +85,11 @@ module FbGraph2
85
85
 
86
86
  def build_endpoint(options = {})
87
87
  File.join [
88
- File.join(FbGraph2.root_url, id.to_s),
88
+ File.join(
89
+ FbGraph2.root_url,
90
+ options[:api_version] || FbGraph2.api_version,
91
+ id.to_s
92
+ ),
89
93
  options[:edge],
90
94
  Util.as_identifier(options[:edge_scope])
91
95
  ].compact.collect(&:to_s)
@@ -103,12 +107,10 @@ module FbGraph2
103
107
  when 200...300
104
108
  _response_
105
109
  else
106
- # TODO: better exception structure
107
- raise response.body
110
+ raise Exception.detect(response.status, _response_, response.headers)
108
111
  end
109
112
  rescue MultiJson::DecodeError
110
- # TODO: better exception structure
111
- raise response.body
113
+ raise Exception.new(response.status, "Unparsable Response: #{response.body}")
112
114
  end
113
115
  end
114
116
  end
@@ -21,19 +21,28 @@ module FbGraph2
21
21
  register_attributes(
22
22
  raw: [
23
23
  :about, :attire, :band_members, :booking_agent, :can_post, :category, :checkins, :company_overview,
24
- :current_location, :description, :directed_by, :founded, :general_info, :general_manager, :hometown,
24
+ :current_location, :description, :directed_by, :founded, :general_info, :general_manager, :hometown, :hours,
25
25
  :is_permanently_closed, :is_published, :is_unclaimed, :likes, :link, :mission, :name, :phone, :press_contact,
26
- :products, :talking_about_count, :username, :website, :were_here_count,
26
+ :price_range, :products, :talking_about_count, :username, :website, :were_here_count,
27
27
  # NOTE: only within /:user_id/accounts context
28
28
  :perms
29
29
  ],
30
- time: [:created_time],
30
+ time: [
31
+ :created_time,
32
+ # NOTE: only as Struct::Work#start_date
33
+ :start_date, :end_date
34
+ ],
31
35
  date: [:birthday],
32
36
  page: [:best_page],
33
37
  photo: [:cover],
38
+ users: [
39
+ # NOTE: only as Struct::Work#projects
40
+ :with
41
+ ],
34
42
  custom: [
35
- :category_list, :context, :hours, :location, :parking, :price_range, :restaurant_services,
36
- :restaurant_specialties
43
+ :category_list, :context, :location, :parking, :restaurant_services, :restaurant_specialties,
44
+ # NOTE: undocumented
45
+ :payment_options
37
46
  ]
38
47
  )
39
48
 
@@ -44,7 +53,24 @@ module FbGraph2
44
53
  PageCategory.new page_category[:id], page_category
45
54
  end
46
55
  end
47
- # TODO: handle other custom attributes.
56
+ if attributes.include? :context
57
+ self.context = Struct::Context::PageContext.new attributes[:context]
58
+ end
59
+ if attributes.include? :location
60
+ self.location = Struct::Location.new attributes[:location]
61
+ end
62
+ if attributes.include? :parking
63
+ self.parking = Struct::Parking.new attributes[:parking]
64
+ end
65
+ if attributes.include? :restaurant_services
66
+ self.restaurant_services = Struct::RestaurantServices.new attributes[:restaurant_services]
67
+ end
68
+ if attributes.include? :restaurant_specialties
69
+ self.restaurant_specialties = Struct::RestaurantSpecialties.new attributes[:restaurant_specialties]
70
+ end
71
+ if attributes.include? :payment_options
72
+ self.payment_options = Struct::PaymentOptions.new attributes[:payment_options]
73
+ end
48
74
  end
49
75
  end
50
76
  end
@@ -0,0 +1,9 @@
1
+ module FbGraph2
2
+ class Struct
3
+ class AgeRange < Struct
4
+ register_attributes(
5
+ raw: [:min, :max]
6
+ )
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,18 @@
1
+ module FbGraph2
2
+ class Struct
3
+ module Context
4
+ class UserContext < Struct
5
+ register_attributes(
6
+ users: [:mutual_friends],
7
+ pages: [:mutual_likes]
8
+ )
9
+ end
10
+
11
+ class PageContext < Struct
12
+ register_attributes(
13
+ users: [:friends_who_like, :friends_tagged_at, :music_listen_friends, :video_watch_friends]
14
+ )
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,9 @@
1
+ module FbGraph2
2
+ class Struct
3
+ class Currency < Struct
4
+ register_attributes(
5
+ raw: [:user_currency, :currency_exchange, :currency_exchange_inverse, :usd_exchange, :usd_exchange_inverse, :currency_offset]
6
+ )
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ module FbGraph2
2
+ class Struct
3
+ class Education < Struct
4
+ register_attributes(
5
+ raw: [:type],
6
+ page: [:school, :year],
7
+ pages: [:concentration]
8
+ )
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ module FbGraph2
2
+ class Struct
3
+ class Location < Struct
4
+ register_attributes(
5
+ raw: [:country, :city, :longitude, :zip, :state, :street, :located_in, :latitude]
6
+ )
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module FbGraph2
2
+ class Struct
3
+ class Parking < Struct
4
+ register_attributes(
5
+ int_flag: [:street, :lot, :valet]
6
+ )
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module FbGraph2
2
+ class Struct
3
+ class PaymentOptions < Struct
4
+ register_attributes(
5
+ int_flag: [:amex, :cash_only, :discover, :mastercard, :visa]
6
+ )
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module FbGraph2
2
+ class Struct
3
+ class RestaurantServices < Struct
4
+ register_attributes(
5
+ int_flag: [:kids, :delivery, :walkins, :catering, :reserve, :groups, :waiter, :outdoor, :takeout]
6
+ )
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module FbGraph2
2
+ class Struct
3
+ class RestaurantSpecialties < Struct
4
+ register_attributes(
5
+ int_flag: [:coffee, :drinks, :breakfast, :dinner, :lunch]
6
+ )
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ module FbGraph2
2
+ class Struct
3
+ class Work < Struct
4
+ register_attributes(
5
+ page: [:employer, :location, :position],
6
+ pages: [:projects],
7
+ time: [:start_date, :end_date]
8
+ )
9
+ end
10
+ end
11
+ end
@@ -69,7 +69,21 @@ module FbGraph2
69
69
 
70
70
  def initialize(id, attributes = {})
71
71
  super
72
- # TODO: handle custom attributes.
72
+ if attributes.include? :age_range
73
+ self.age_range = Struct::AgeRange.new attributes[:age_range]
74
+ end
75
+ if attributes.include? :context
76
+ self.context = Struct::Context::UserContext.new attributes[:context]
77
+ end
78
+ if attributes.include? :currency
79
+ self.currency = Struct::Currency.new attributes[:currency]
80
+ end
81
+ if attributes.include? :education
82
+ self.education = Struct::Education.new attributes[:education]
83
+ end
84
+ if attributes.include? :work
85
+ self.work = Struct::Work.new attributes[:work]
86
+ end
73
87
  end
74
88
 
75
89
  def self.me(access_token)
data/lib/fb_graph2.rb CHANGED
@@ -2,8 +2,9 @@ require 'active_support/all'
2
2
  require 'rack/oauth2'
3
3
 
4
4
  module FbGraph2
5
- cattr_accessor :api_version, :gem_version, :logger, :debugging, :_http_config_, :object_classes
5
+ cattr_accessor :root_url, :api_version, :gem_version, :logger, :debugging, :_http_config_, :object_classes
6
6
 
7
+ self.root_url = 'https://graph.facebook.com'
7
8
  self.api_version = 'v2.0'
8
9
  self.gem_version = File.read(File.join(__dir__, '../VERSION')).delete("\n\r")
9
10
  self.logger = Logger.new(STDOUT)
@@ -11,10 +12,6 @@ module FbGraph2
11
12
  self.object_classes = Array.new
12
13
 
13
14
  class << self
14
- def root_url
15
- File.join('https://graph.facebook.com', api_version)
16
- end
17
-
18
15
  def debugging?
19
16
  !!self.debugging
20
17
  end
@@ -4,6 +4,58 @@ describe FbGraph2::Node do
4
4
  let(:klass) { FbGraph2::Node }
5
5
  let(:instance) { klass.new 'identifier' }
6
6
 
7
+ describe 'API Versioning' do
8
+ before do
9
+ @original = FbGraph2.api_version
10
+ end
11
+
12
+ after do
13
+ FbGraph2.api_version = @original
14
+ end
15
+
16
+ describe 'via global setting' do
17
+ before do
18
+ FbGraph2.api_version = 'v2.x'
19
+ end
20
+
21
+ describe '#fetch' do
22
+ it 'should use api_version globally' do
23
+ expect do
24
+ instance.fetch
25
+ end.to request_to 'v2.x/identifier', :get, api_version_in_path: true
26
+ end
27
+ end
28
+
29
+ describe '#edge' do
30
+ it 'should use api_version globally' do
31
+ expect do
32
+ instance.edge :foo
33
+ end.to request_to 'v2.x/identifier/foo', :get, api_version_in_path: true
34
+ end
35
+ end
36
+ end
37
+
38
+ describe 'via per-call option' do
39
+ describe '#fetch' do
40
+ it 'should use api_version locally' do
41
+ expect do
42
+ instance.fetch nil, api_version: 'v2.y'
43
+ end.to request_to 'v2.y/identifier', :get, api_version_in_path: true
44
+ FbGraph2.api_version.should == @original
45
+ end
46
+ end
47
+
48
+ describe '#edge' do
49
+ it 'should use api_version locally' do
50
+ expect do
51
+ instance.edge :foo, {}, api_version: 'v2.y'
52
+ end.to request_to 'v2.y/identifier/foo', :get, api_version_in_path: true
53
+ FbGraph2.api_version.should == @original
54
+ end
55
+ end
56
+ end
57
+ end
58
+
7
59
  context 'class' do
8
60
  subject { klass }
9
61
  it { should_not respond_to :register_attributes }
@@ -14,7 +66,7 @@ describe FbGraph2::Node do
14
66
  it 'should call API' do
15
67
  expect do
16
68
  klass.fetch 'foo'
17
- end.to request_to '/foo'
69
+ end.to request_to 'foo'
18
70
  end
19
71
  end
20
72
  end
@@ -51,8 +103,8 @@ describe FbGraph2::Node do
51
103
  instance.fetch
52
104
  end
53
105
  end.to raise_error { |e|
54
- e.should be_instance_of RuntimeError
55
- e.message.should == mock_json('error/400/2500')
106
+ e.should be_instance_of FbGraph2::Exception::BadRequest
107
+ e.message.should == mock_json('error/400/2500')[:error][:message]
56
108
  }
57
109
  end
58
110
  end
@@ -64,8 +116,8 @@ describe FbGraph2::Node do
64
116
  instance.fetch
65
117
  end
66
118
  end.to raise_error { |e|
67
- e.should be_instance_of RuntimeError
68
- e.message.should == mock_json('error/invalid_format')
119
+ e.should be_instance_of FbGraph2::Exception
120
+ e.message.should == "Unparsable Response: #{mock_json('error/invalid_format')}"
69
121
  }
70
122
  end
71
123
  end
@@ -7,7 +7,7 @@ describe FbGraph2 do
7
7
  context 'as default' do
8
8
  its(:logger) { should be_a Logger }
9
9
  its(:api_version) { should == 'v2.0' }
10
- its(:root_url) { should == 'https://graph.facebook.com/v2.0' }
10
+ its(:root_url) { should == 'https://graph.facebook.com' }
11
11
  its(:object_classes) { should contain_exactly *FbGraph2::Node.subclasses }
12
12
  it { should_not be_debugging }
13
13
  end
@@ -17,11 +17,6 @@ describe FbGraph2 do
17
17
  it { should be_debugging }
18
18
  end
19
19
 
20
- describe '.api_version' do
21
- before { FbGraph2.api_version = 'v2.x' }
22
- its(:root_url) { should == 'https://graph.facebook.com/v2.x' }
23
- end
24
-
25
20
  describe '.http_client' do
26
21
  context 'with http_config' do
27
22
  before do
@@ -4,7 +4,7 @@ module MockGraph
4
4
  def mock_graph(method, path, response_path, options = {})
5
5
  stub_request(
6
6
  method,
7
- endpoint_for(path)
7
+ endpoint_for(path, options)
8
8
  ).with(
9
9
  request_for(method, options)
10
10
  ).to_return(
@@ -23,21 +23,27 @@ module MockGraph
23
23
  end
24
24
 
25
25
  def mock_json(response_path)
26
- response_for(response_path)[:body].read
26
+ content = response_for(response_path)[:body].read
27
+ MultiJson.load(content).with_indifferent_access
28
+ rescue MultiJson::DecodeError
29
+ content
27
30
  end
28
31
 
29
- def request_to(path, method = :get)
32
+ def request_to(path, method = :get, options = {})
30
33
  raise_error { |e|
31
34
  e.should be_instance_of WebMock::NetConnectNotAllowedError
32
35
  e.message.should include("Unregistered request: #{method.to_s.upcase}")
33
- e.message.should include(endpoint_for path)
36
+ e.message.should include(endpoint_for path, options)
34
37
  }
35
38
  end
36
39
 
37
40
  private
38
41
 
39
- def endpoint_for(path)
40
- File.join(FbGraph2.root_url, path)
42
+ def endpoint_for(path, options = {})
43
+ api_version = unless options[:api_version_in_path]
44
+ options[:api_version] || FbGraph2.api_version
45
+ end
46
+ File.join FbGraph2.root_url, api_version.to_s, path
41
47
  end
42
48
 
43
49
  def request_for(method, options = {})
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fb_graph2
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - nov matake
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-06-06 00:00:00.000000000 Z
11
+ date: 2014-06-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httpclient
@@ -144,6 +144,7 @@ extensions: []
144
144
  extra_rdoc_files: []
145
145
  files:
146
146
  - ".gitignore"
147
+ - ".travis.yml"
147
148
  - Gemfile
148
149
  - LICENSE.txt
149
150
  - README.md
@@ -157,6 +158,7 @@ files:
157
158
  - lib/fb_graph2/app.rb
158
159
  - lib/fb_graph2/app_link_host.rb
159
160
  - lib/fb_graph2/attribute_assigner.rb
161
+ - lib/fb_graph2/auth.rb
160
162
  - lib/fb_graph2/collection.rb
161
163
  - lib/fb_graph2/comment.rb
162
164
  - lib/fb_graph2/domain.rb
@@ -226,6 +228,7 @@ files:
226
228
  - lib/fb_graph2/edge/translations.rb
227
229
  - lib/fb_graph2/edge/videos.rb
228
230
  - lib/fb_graph2/event.rb
231
+ - lib/fb_graph2/exception.rb
229
232
  - lib/fb_graph2/friend_list.rb
230
233
  - lib/fb_graph2/group.rb
231
234
  - lib/fb_graph2/group_doc.rb
@@ -247,18 +250,28 @@ files:
247
250
  - lib/fb_graph2/review.rb
248
251
  - lib/fb_graph2/struct.rb
249
252
  - lib/fb_graph2/struct/action.rb
253
+ - lib/fb_graph2/struct/age_range.rb
250
254
  - lib/fb_graph2/struct/app_event_type.rb
251
255
  - lib/fb_graph2/struct/app_link.rb
256
+ - lib/fb_graph2/struct/context.rb
257
+ - lib/fb_graph2/struct/currency.rb
258
+ - lib/fb_graph2/struct/education.rb
252
259
  - lib/fb_graph2/struct/group_file.rb
253
260
  - lib/fb_graph2/struct/image_source.rb
254
261
  - lib/fb_graph2/struct/invitable_friend.rb
262
+ - lib/fb_graph2/struct/location.rb
263
+ - lib/fb_graph2/struct/parking.rb
264
+ - lib/fb_graph2/struct/payment_options.rb
255
265
  - lib/fb_graph2/struct/permission.rb
256
266
  - lib/fb_graph2/struct/picture.rb
257
267
  - lib/fb_graph2/struct/poke.rb
268
+ - lib/fb_graph2/struct/restaurant_services.rb
269
+ - lib/fb_graph2/struct/restaurant_specialties.rb
258
270
  - lib/fb_graph2/struct/role.rb
259
271
  - lib/fb_graph2/struct/score.rb
260
272
  - lib/fb_graph2/struct/static_resource.rb
261
273
  - lib/fb_graph2/struct/subscription.rb
274
+ - lib/fb_graph2/struct/work.rb
262
275
  - lib/fb_graph2/thread.rb
263
276
  - lib/fb_graph2/translation.rb
264
277
  - lib/fb_graph2/user.rb
@@ -376,7 +389,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
376
389
  version: '0'
377
390
  requirements: []
378
391
  rubyforge_project:
379
- rubygems_version: 2.2.0
392
+ rubygems_version: 2.2.2
380
393
  signing_key:
381
394
  specification_version: 4
382
395
  summary: Facebook Graph API v2.0 Wrapper in Ruby