extendi-instagram 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 (91) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +14 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +6 -0
  5. data/.yardopts +9 -0
  6. data/Gemfile +3 -0
  7. data/LICENSE.md +30 -0
  8. data/PATENTS.md +23 -0
  9. data/README.md +260 -0
  10. data/Rakefile +27 -0
  11. data/instagram.gemspec +50 -0
  12. data/lib/faraday/loud_logger.rb +78 -0
  13. data/lib/faraday/oauth2.rb +45 -0
  14. data/lib/faraday/raise_http_exception.rb +73 -0
  15. data/lib/instagram/api.rb +31 -0
  16. data/lib/instagram/client/comments.rb +62 -0
  17. data/lib/instagram/client/embedding.rb +28 -0
  18. data/lib/instagram/client/geographies.rb +29 -0
  19. data/lib/instagram/client/likes.rb +58 -0
  20. data/lib/instagram/client/locations.rb +75 -0
  21. data/lib/instagram/client/media.rb +82 -0
  22. data/lib/instagram/client/subscriptions.rb +211 -0
  23. data/lib/instagram/client/tags.rb +59 -0
  24. data/lib/instagram/client/users.rb +310 -0
  25. data/lib/instagram/client/utils.rb +28 -0
  26. data/lib/instagram/client.rb +21 -0
  27. data/lib/instagram/configuration.rb +125 -0
  28. data/lib/instagram/connection.rb +31 -0
  29. data/lib/instagram/error.rb +34 -0
  30. data/lib/instagram/oauth.rb +36 -0
  31. data/lib/instagram/request.rb +83 -0
  32. data/lib/instagram/response.rb +22 -0
  33. data/lib/instagram/version.rb +3 -0
  34. data/lib/instagram.rb +27 -0
  35. data/spec/faraday/response_spec.rb +101 -0
  36. data/spec/fixtures/access_token.json +9 -0
  37. data/spec/fixtures/approve_user.json +8 -0
  38. data/spec/fixtures/block_user.json +8 -0
  39. data/spec/fixtures/deny_user.json +8 -0
  40. data/spec/fixtures/follow_user.json +8 -0
  41. data/spec/fixtures/followed_by.json +1 -0
  42. data/spec/fixtures/follows.json +1 -0
  43. data/spec/fixtures/geography_recent_media.json +1 -0
  44. data/spec/fixtures/liked_media.json +1 -0
  45. data/spec/fixtures/location.json +1 -0
  46. data/spec/fixtures/location_recent_media.json +1 -0
  47. data/spec/fixtures/location_search.json +1 -0
  48. data/spec/fixtures/location_search_facebook.json +1 -0
  49. data/spec/fixtures/media.json +1 -0
  50. data/spec/fixtures/media_comment.json +1 -0
  51. data/spec/fixtures/media_comment_deleted.json +1 -0
  52. data/spec/fixtures/media_comments.json +1 -0
  53. data/spec/fixtures/media_liked.json +1 -0
  54. data/spec/fixtures/media_likes.json +1 -0
  55. data/spec/fixtures/media_popular.json +1 -0
  56. data/spec/fixtures/media_search.json +1 -0
  57. data/spec/fixtures/media_shortcode.json +1 -0
  58. data/spec/fixtures/media_unliked.json +1 -0
  59. data/spec/fixtures/mikeyk.json +1 -0
  60. data/spec/fixtures/oembed.json +14 -0
  61. data/spec/fixtures/recent_media.json +1 -0
  62. data/spec/fixtures/relationship.json +9 -0
  63. data/spec/fixtures/requested_by.json +12 -0
  64. data/spec/fixtures/shayne.json +1 -0
  65. data/spec/fixtures/subscription.json +12 -0
  66. data/spec/fixtures/subscription_deleted.json +1 -0
  67. data/spec/fixtures/subscription_payload.json +14 -0
  68. data/spec/fixtures/subscriptions.json +22 -0
  69. data/spec/fixtures/tag.json +1 -0
  70. data/spec/fixtures/tag_recent_media.json +1 -0
  71. data/spec/fixtures/tag_search.json +1 -0
  72. data/spec/fixtures/unblock_user.json +8 -0
  73. data/spec/fixtures/unfollow_user.json +8 -0
  74. data/spec/fixtures/user_media_feed.json +1 -0
  75. data/spec/fixtures/user_search.json +1 -0
  76. data/spec/instagram/api_spec.rb +285 -0
  77. data/spec/instagram/client/comments_spec.rb +71 -0
  78. data/spec/instagram/client/embedding_spec.rb +36 -0
  79. data/spec/instagram/client/geography_spec.rb +37 -0
  80. data/spec/instagram/client/likes_spec.rb +66 -0
  81. data/spec/instagram/client/locations_spec.rb +127 -0
  82. data/spec/instagram/client/media_spec.rb +99 -0
  83. data/spec/instagram/client/subscriptions_spec.rb +174 -0
  84. data/spec/instagram/client/tags_spec.rb +79 -0
  85. data/spec/instagram/client/users_spec.rb +432 -0
  86. data/spec/instagram/client/utils_spec.rb +32 -0
  87. data/spec/instagram/client_spec.rb +23 -0
  88. data/spec/instagram/request_spec.rb +56 -0
  89. data/spec/instagram_spec.rb +109 -0
  90. data/spec/spec_helper.rb +71 -0
  91. metadata +322 -0
@@ -0,0 +1,71 @@
1
+ require File.expand_path('../../../spec_helper', __FILE__)
2
+
3
+ describe Instagram::Client do
4
+ Instagram::Configuration::VALID_FORMATS.each do |format|
5
+ context ".new(:format => '#{format}')" do
6
+
7
+ before do
8
+ @client = Instagram::Client.new(:format => format, :client_id => 'CID', :client_secret => 'CS', :access_token => 'AT')
9
+ end
10
+
11
+ describe ".media_comments" do
12
+
13
+ before do
14
+ stub_get("media/777/comments.#{format}").
15
+ with(:query => {:access_token => @client.access_token}).
16
+ to_return(:body => fixture("media_comments.#{format}"), :headers => {:content_type => "application/#{format}; charset=utf-8"})
17
+ end
18
+
19
+ it "should get the correct resource" do
20
+ @client.media_comments(777)
21
+ expect(a_get("media/777/comments.#{format}").
22
+ with(:query => {:access_token => @client.access_token})).
23
+ to have_been_made
24
+ end
25
+
26
+ it "should return an array of user search results" do
27
+ comments = @client.media_comments(777)
28
+ expect(comments).to be_a Array
29
+ expect(comments.first.text).to eq("Vet visit")
30
+ end
31
+ end
32
+
33
+ describe ".create_media_comment" do
34
+
35
+ before do
36
+ stub_post("media/777/comments.#{format}").
37
+ with(:body => {:text => "hi there", :access_token => @client.access_token}).
38
+ to_return(:body => fixture("media_comment.#{format}"), :headers => {:content_type => "application/#{format}; charset=utf-8"})
39
+ end
40
+
41
+ it "should get the correct resource" do
42
+ @client.create_media_comment(777, "hi there")
43
+ expect(a_post("media/777/comments.#{format}").
44
+ with(:body => {:text => "hi there", :access_token => @client.access_token})).
45
+ to have_been_made
46
+ end
47
+
48
+ it "should return the new comment when successful" do
49
+ comment = @client.create_media_comment(777, "hi there")
50
+ expect(comment.text).to eq("hi there")
51
+ end
52
+ end
53
+
54
+ describe ".delete_media_comment" do
55
+
56
+ before do
57
+ stub_delete("media/777/comments/1234.#{format}").
58
+ with(:query => {:access_token => @client.access_token}).
59
+ to_return(:body => fixture("media_comment_deleted.#{format}"), :headers => {:content_type => "application/#{format}; charset=utf-8"})
60
+ end
61
+
62
+ it "should get the correct resource" do
63
+ @client.delete_media_comment(777, 1234)
64
+ expect(a_delete("media/777/comments/1234.#{format}").
65
+ with(:query => {:access_token => @client.access_token})).
66
+ to have_been_made
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,36 @@
1
+ require File.expand_path('../../../spec_helper', __FILE__)
2
+
3
+ describe Instagram::Client do
4
+ Instagram::Configuration::VALID_FORMATS.each do |format|
5
+ context ".new(:format => '#{format}')" do
6
+ before do
7
+ @client = Instagram::Client.new(:format => format, :client_id => 'CID', :client_secret => 'CS', :access_token => 'AT')
8
+ end
9
+
10
+ describe ".oembed" do
11
+ before do
12
+ stub_get("oembed").
13
+ with(:query => {:access_token => @client.access_token, :url => "http://instagram.com/p/abcdef"}).
14
+ to_return(:body => fixture("oembed.#{format}"), :headers => {:content_type => "application/#{format}; charset=utf-8"})
15
+ end
16
+
17
+ it "should get the correct resource" do
18
+ @client.oembed("http://instagram.com/p/abcdef")
19
+ expect(a_get("oembed?url=http://instagram.com/p/abcdef").
20
+ with(:query => {:access_token => @client.access_token})).
21
+ to have_been_made
22
+ end
23
+
24
+ it "should return the oembed information for an instagram media url" do
25
+ oembed = @client.oembed("http://instagram.com/p/abcdef")
26
+ expect(oembed.media_id).to eq("123657555223544123_41812344")
27
+ end
28
+
29
+ it "should return nil if a URL is not provided" do
30
+ oembed = @client.oembed
31
+ expect(oembed).to be_nil
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,37 @@
1
+ require File.expand_path('../../../spec_helper', __FILE__)
2
+
3
+ describe Instagram::Client do
4
+ Instagram::Configuration::VALID_FORMATS.each do |format|
5
+ context ".new(:format => '#{format}')" do
6
+ before do
7
+ @client = Instagram::Client.new(:format => format, :client_id => 'CID', :client_secret => 'CS', :access_token => 'AT')
8
+ end
9
+
10
+
11
+ describe ".geography_recent_media" do
12
+
13
+ context "with geography ID passed" do
14
+
15
+ before do
16
+ stub_get("geographies/12345/media/recent.#{format}").
17
+ with(:query => {:access_token => @client.access_token}).
18
+ to_return(:body => fixture("geography_recent_media.#{format}"), :headers => {:content_type => "application/#{format}; charset=utf-8"})
19
+ end
20
+
21
+ it "should get the correct resource" do
22
+ @client.geography_recent_media(12345)
23
+ expect(a_get("geographies/12345/media/recent.#{format}").
24
+ with(:query => {:access_token => @client.access_token})).
25
+ to have_been_made
26
+ end
27
+
28
+ it "should return a list of recent media items within the specifed geography" do
29
+ recent_media = @client.geography_recent_media(12345)
30
+ expect(recent_media).to be_a Array
31
+ expect(recent_media.first.user.username).to eq("amandavan")
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,66 @@
1
+ require File.expand_path('../../../spec_helper', __FILE__)
2
+
3
+ describe Instagram::Client do
4
+ Instagram::Configuration::VALID_FORMATS.each do |format|
5
+ context ".new(:format => '#{format}')" do
6
+
7
+ before do
8
+ @client = Instagram::Client.new(:format => format, :client_id => 'CID', :client_secret => 'CS', :client_ips => '1.2.3.4', :access_token => 'AT')
9
+ end
10
+
11
+ describe ".media_likes" do
12
+
13
+ before do
14
+ stub_get("media/777/likes.#{format}").
15
+ with(:query => {:access_token => @client.access_token}).
16
+ to_return(:body => fixture("media_likes.#{format}"), :headers => {:content_type => "application/#{format}; charset=utf-8"})
17
+ end
18
+
19
+ it "should get the correct resource" do
20
+ @client.media_likes(777)
21
+ expect(a_get("media/777/likes.#{format}").
22
+ with(:query => {:access_token => @client.access_token})).
23
+ to have_been_made
24
+ end
25
+
26
+ it "should return an array of user search results" do
27
+ comments = @client.media_likes(777)
28
+ expect(comments).to be_a Array
29
+ expect(comments.first.username).to eq("chris")
30
+ end
31
+ end
32
+
33
+ describe ".like_media" do
34
+
35
+ before do
36
+ stub_post("media/777/likes.#{format}").
37
+ with(:body => {:access_token => @client.access_token}).
38
+ to_return(:body => fixture("media_liked.#{format}"), :headers => {:content_type => "application/#{format}; charset=utf-8"})
39
+ end
40
+
41
+ it "should get the correct resource" do
42
+ @client.like_media(777)
43
+ expect(a_post("media/777/likes.#{format}").
44
+ with(:body => {:access_token => @client.access_token})).
45
+ to have_been_made
46
+ end
47
+ end
48
+
49
+ describe ".unlike_media" do
50
+
51
+ before do
52
+ stub_delete("media/777/likes.#{format}").
53
+ with(:query => {:access_token => @client.access_token}).
54
+ to_return(:body => fixture("media_unliked.#{format}"), :headers => {:content_type => "application/#{format}; charset=utf-8"})
55
+ end
56
+
57
+ it "should get the correct resource" do
58
+ @client.unlike_media(777)
59
+ expect(a_delete("media/777/likes.#{format}").
60
+ with(:query => {:access_token => @client.access_token})).
61
+ to have_been_made
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,127 @@
1
+ require File.expand_path('../../../spec_helper', __FILE__)
2
+
3
+ describe Instagram::Client do
4
+ Instagram::Configuration::VALID_FORMATS.each do |format|
5
+ context ".new(:format => '#{format}')" do
6
+ before do
7
+ @client = Instagram::Client.new(:format => format, :client_id => 'CID', :client_secret => 'CS', :access_token => 'AT')
8
+ end
9
+
10
+ describe ".location" do
11
+
12
+ before do
13
+ stub_get("locations/514276.#{format}").
14
+ with(:query => {:access_token => @client.access_token}).
15
+ to_return(:body => fixture("location.#{format}"), :headers => {:content_type => "application/#{format}; charset=utf-8"})
16
+ end
17
+
18
+ it "should get the correct resource" do
19
+ @client.location(514276)
20
+ expect(a_get("locations/514276.#{format}").
21
+ with(:query => {:access_token => @client.access_token})).
22
+ to have_been_made
23
+ end
24
+
25
+ it "should return extended information of a given location" do
26
+ location = @client.location(514276)
27
+ expect(location.name).to eq("Instagram")
28
+ end
29
+ end
30
+
31
+ describe ".location_recent_media" do
32
+
33
+ before do
34
+ stub_get("locations/514276/media/recent.#{format}").
35
+ with(:query => {:access_token => @client.access_token}).
36
+ to_return(:body => fixture("location_recent_media.#{format}"), :headers => {:content_type => "application/#{format}; charset=utf-8"})
37
+ end
38
+
39
+ it "should get the correct resource" do
40
+ @client.location_recent_media(514276)
41
+ expect(a_get("locations/514276/media/recent.#{format}").
42
+ with(:query => {:access_token => @client.access_token})).
43
+ to have_been_made
44
+ end
45
+
46
+ it "should return a list of media taken at a given location" do
47
+ media = @client.location_recent_media(514276)
48
+ expect(media).to be_a Array
49
+ expect(media.first.user.username).to eq("josh")
50
+ end
51
+ end
52
+
53
+ describe ".location_search_lat_lng" do
54
+
55
+ before do
56
+ stub_get("locations/search.#{format}").
57
+ with(:query => {:access_token => @client.access_token}).
58
+ with(:query => {:lat => "37.7808851", :lng => "-122.3948632"}).
59
+ to_return(:body => fixture("location_search.#{format}"), :headers => {:content_type => "application/#{format}; charset=utf-8"})
60
+ end
61
+
62
+ it "should get the correct resource by lat/lng" do
63
+ @client.location_search("37.7808851", "-122.3948632")
64
+ expect(a_get("locations/search.#{format}").
65
+ with(:query => {:access_token => @client.access_token}).
66
+ with(:query => {:lat => "37.7808851", :lng => "-122.3948632"})).
67
+ to have_been_made
68
+ end
69
+
70
+ it "should return an array of user search results" do
71
+ locations = @client.location_search("37.7808851", "-122.3948632")
72
+ expect(locations).to be_a Array
73
+ expect(locations.first.name).to eq("Instagram")
74
+ end
75
+ end
76
+
77
+ describe ".location_search_lat_lng_distance" do
78
+
79
+ before do
80
+ stub_get("locations/search.#{format}").
81
+ with(:query => {:access_token => @client.access_token}).
82
+ with(:query => {:lat => "37.7808851", :lng => "-122.3948632", :distance => "5000"}).
83
+ to_return(:body => fixture("location_search.#{format}"), :headers => {:content_type => "application/#{format}; charset=utf-8"})
84
+ end
85
+
86
+ it "should get the correct resource by lat/lng/distance" do
87
+ @client.location_search("37.7808851", "-122.3948632", "5000")
88
+ expect(a_get("locations/search.#{format}").
89
+ with(:query => {:access_token => @client.access_token}).
90
+ with(:query => {:lat => "37.7808851", :lng => "-122.3948632", :distance => "5000"})).
91
+ to have_been_made
92
+ end
93
+
94
+ it "should return an array of user search results" do
95
+ locations = @client.location_search("37.7808851", "-122.3948632", "5000")
96
+ expect(locations).to be_a Array
97
+ expect(locations.first.name).to eq("Instagram")
98
+ end
99
+ end
100
+
101
+ describe ".location_search_facebook_places_id" do
102
+
103
+ before do
104
+ stub_get("locations/search.#{format}").
105
+ with(:query => {:access_token => @client.access_token}).
106
+ with(:query => {:facebook_places_id => "3fd66200f964a520c5f11ee3"}).
107
+ to_return(:body => fixture("location_search_facebook.#{format}"), :headers => {:content_type => "application/#{format}; charset=utf-8"})
108
+ end
109
+
110
+ it "should get the correct resource by facebook_places_id" do
111
+ @client.location_search("3fd66200f964a520c5f11ee3")
112
+ expect(a_get("locations/search.#{format}").
113
+ with(:query => {:access_token => @client.access_token}).
114
+ with(:query => {:facebook_places_id => "3fd66200f964a520c5f11ee3"})).
115
+ to have_been_made
116
+ end
117
+
118
+ it "should return an array of user search results" do
119
+ locations = @client.location_search("3fd66200f964a520c5f11ee3")
120
+ expect(locations).to be_a Array
121
+ expect(locations.first.name).to eq("Schiller's Liquor Bar")
122
+ end
123
+ end
124
+
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,99 @@
1
+ require File.expand_path('../../../spec_helper', __FILE__)
2
+
3
+ describe Instagram::Client do
4
+ Instagram::Configuration::VALID_FORMATS.each do |format|
5
+ context ".new(:format => '#{format}')" do
6
+ before do
7
+ @client = Instagram::Client.new(:format => format, :client_id => 'CID', :client_secret => 'CS', :access_token => 'AT')
8
+ end
9
+
10
+ describe ".media_item" do
11
+
12
+ before do
13
+ stub_get("media/18600493.#{format}").
14
+ with(:query => {:access_token => @client.access_token}).
15
+ to_return(:body => fixture("media.#{format}"), :headers => {:content_type => "application/#{format}; charset=utf-8"})
16
+ end
17
+
18
+ it "should get the correct resource" do
19
+ @client.media_item(18600493)
20
+ expect(a_get("media/18600493.#{format}").
21
+ with(:query => {:access_token => @client.access_token})).
22
+ to have_been_made
23
+ end
24
+
25
+ it "should return extended information of a given media item" do
26
+ media = @client.media_item(18600493)
27
+ expect(media.user.username).to eq("mikeyk")
28
+ end
29
+ end
30
+
31
+ describe ".media_shortcode" do
32
+
33
+ before do
34
+ stub_get('media/shortcode/BG9It').
35
+ with(:query => {:access_token => @client.access_token}).
36
+ to_return(:body => fixture("media_shortcode.#{format}"), :headers => {:content_type => "application/#{format}; charset=utf-8"})
37
+ end
38
+
39
+ it "should get the correct resource" do
40
+ @client.media_shortcode('BG9It')
41
+ expect(a_get('media/shortcode/BG9It').
42
+ with(:query => {:access_token => @client.access_token})).
43
+ to have_been_made
44
+ end
45
+
46
+ it "should return extended information of a given media item" do
47
+ media = @client.media_shortcode('BG9It')
48
+ expect(media.user.username).to eq('mikeyk')
49
+ end
50
+ end
51
+
52
+ describe ".media_popular" do
53
+
54
+ before do
55
+ stub_get("media/popular.#{format}").
56
+ with(:query => {:access_token => @client.access_token}).
57
+ to_return(:body => fixture("media_popular.#{format}"), :headers => {:content_type => "application/#{format}; charset=utf-8"})
58
+ end
59
+
60
+ it "should get the correct resource" do
61
+ @client.media_popular
62
+ expect(a_get("media/popular.#{format}").
63
+ with(:query => {:access_token => @client.access_token})).
64
+ to have_been_made
65
+ end
66
+
67
+ it "should return popular media items" do
68
+ media_popular = @client.media_popular
69
+ expect(media_popular).to be_a Array
70
+ media_popular.first.user.username == "babycamera"
71
+ end
72
+ end
73
+
74
+ describe ".media_search" do
75
+
76
+ before do
77
+ stub_get("media/search.#{format}").
78
+ with(:query => {:access_token => @client.access_token}).
79
+ with(:query => {:lat => "37.7808851", :lng => "-122.3948632"}).
80
+ to_return(:body => fixture("media_search.#{format}"), :headers => {:content_type => "application/#{format}; charset=utf-8"})
81
+ end
82
+
83
+ it "should get the correct resource" do
84
+ @client.media_search("37.7808851", "-122.3948632")
85
+ expect(a_get("media/search.#{format}").
86
+ with(:query => {:access_token => @client.access_token}).
87
+ with(:query => {:lat => "37.7808851", :lng => "-122.3948632"})).
88
+ to have_been_made
89
+ end
90
+
91
+ it "should return an array of user search results" do
92
+ media_search = @client.media_search("37.7808851", "-122.3948632")
93
+ expect(media_search).to be_a Array
94
+ expect(media_search.first.user.username).to eq("mikeyk")
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,174 @@
1
+ require File.expand_path('../../../spec_helper', __FILE__)
2
+
3
+ describe Instagram::Client do
4
+ Instagram::Configuration::VALID_FORMATS.each do |format|
5
+ context ".new(:format => '#{format}')" do
6
+
7
+ before do
8
+ @client = Instagram::Client.new(:format => format, :client_id => 'CID', :client_secret => 'CS', :access_token => 'AT')
9
+ end
10
+
11
+ describe ".subscriptions" do
12
+
13
+ before do
14
+ stub_get("subscriptions.#{format}").
15
+ with(:query => {:client_id => @client.client_id, :client_secret => @client.client_secret}).
16
+ to_return(:body => fixture("subscriptions.#{format}"), :headers => {:content_type => "application/#{format}; charset=utf-8"})
17
+ end
18
+
19
+ it "should get the correct resource" do
20
+ @client.subscriptions
21
+ expect(a_get("subscriptions.#{format}").
22
+ with(:query => {:client_id => @client.client_id, :client_secret => @client.client_secret})).
23
+ to have_been_made
24
+ end
25
+
26
+ it "should return an array of subscriptions" do
27
+ subscriptions = @client.subscriptions
28
+ expect(subscriptions).to be_a Array
29
+ expect(subscriptions.first.object).to eq("user")
30
+ end
31
+ end
32
+
33
+ describe ".create_subscription" do
34
+
35
+ before do
36
+ stub_post("subscriptions.#{format}").
37
+ with(:body => {:object => "user", :callback_url => "http://example.com/instagram/callback", :aspect => "media", :client_id => @client.client_id, :client_secret => @client.client_secret}).
38
+ to_return(:body => fixture("subscription.#{format}"), :headers => {:content_type => "application/#{format}; charset=utf-8"})
39
+ end
40
+
41
+ it "should get the correct resource" do
42
+ @client.create_subscription("user", :callback_url => "http://example.com/instagram/callback")
43
+ expect(a_post("subscriptions.#{format}").
44
+ with(:body => {:object => "user", :callback_url => "http://example.com/instagram/callback", :aspect => "media", :client_id => @client.client_id, :client_secret => @client.client_secret})).
45
+ to have_been_made
46
+ end
47
+
48
+ it "should return the new subscription when successful" do
49
+ subscription = @client.create_subscription("user", :callback_url => "http://example.com/instagram/callback")
50
+ expect(subscription.object).to eq("user")
51
+ end
52
+ end
53
+
54
+ describe ".delete_media_comment" do
55
+
56
+ before do
57
+ stub_delete("subscriptions.#{format}").
58
+ with(:query => {:object => "user", :client_id => @client.client_id, :client_secret => @client.client_secret}).
59
+ to_return(:body => fixture("subscription_deleted.#{format}"), :headers => {:content_type => "application/#{format}; charset=utf-8"})
60
+ end
61
+
62
+ it "should get the correct resource" do
63
+ @client.delete_subscription(:object => "user")
64
+ expect(a_delete("subscriptions.#{format}").
65
+ with(:query => {:object => "user", :client_id => @client.client_id, :client_secret => @client.client_secret})).
66
+ to have_been_made
67
+ end
68
+ end
69
+
70
+ describe ".validate_update" do
71
+
72
+ subject { @client.validate_update(body, headers) }
73
+
74
+ context "when calculated signature matches request signature" do
75
+
76
+ let(:body) { {foo: "bar"}.to_json }
77
+ let(:request_signature) { OpenSSL::HMAC.hexdigest('sha1', @client.client_secret, body) }
78
+ let(:headers) { {"X-Hub-Signature" => request_signature} }
79
+
80
+ it { expect(subject).to be_truthy }
81
+ end
82
+
83
+ context "when calculated signature does not match request signature" do
84
+
85
+ let(:body) { {foo: "bar"}.to_json }
86
+ let(:request_signature) { "going to fail" }
87
+ let(:headers) { {"X-Hub-Signature" => request_signature} }
88
+
89
+ it { expect(subject).to be_falsey }
90
+ end
91
+ end
92
+
93
+ describe ".process_subscriptions" do
94
+
95
+ context "without a callbacks block" do
96
+ it "should raise an ArgumentError" do
97
+ expect do
98
+ @client.process_subscription(nil)
99
+ end.to raise_error(ArgumentError)
100
+ end
101
+ end
102
+
103
+ context "with a callbacks block and valid JSON" do
104
+
105
+ before do
106
+ @json = fixture("subscription_payload.json").read
107
+ end
108
+
109
+ it "should issue a callback to on_user_changed" do
110
+ @client.process_subscription(@json) do |handler|
111
+ handler.on_user_changed do |user_id, payload|
112
+ expect(user_id).to eq("1234")
113
+ end
114
+ end
115
+ end
116
+
117
+ it "should issue a callback to on_tag_changed" do
118
+ @client.process_subscription(@json) do |handler|
119
+ handler.on_tag_changed do |tag_name, payload|
120
+ expect(tag_name).to eq("nofilter")
121
+ end
122
+ end
123
+ end
124
+
125
+ it "should issue both callbacks in one block" do
126
+ @client.process_subscription(@json) do |handler|
127
+
128
+ handler.on_user_changed do |user_id, payload|
129
+ expect(user_id).to eq("1234")
130
+ end
131
+
132
+ handler.on_tag_changed do |tag_name, payload|
133
+ expect(tag_name).to eq("nofilter")
134
+ end
135
+ end
136
+ end
137
+ end
138
+ end
139
+
140
+ context "with a valid signature" do
141
+
142
+ before do
143
+ @json = fixture("subscription_payload.json").read
144
+ end
145
+
146
+ it "should not raise an Instagram::InvalidSignature error" do
147
+ expect do
148
+ @client.process_subscription(@json, :signature => "f1dbe2b6184ac2131209c87bba8e0382d089a8a2") do |handler|
149
+ # hi
150
+ end
151
+ end.not_to raise_error
152
+ end
153
+ end
154
+
155
+ context "with an invalid signature" do
156
+
157
+ before do
158
+ @json = fixture("subscription_payload.json").read
159
+ end
160
+
161
+ it "should raise an Instagram::InvalidSignature error" do
162
+ invalid_signatures = ["31337H4X0R", nil]
163
+ invalid_signatures.each do |signature|
164
+ expect do
165
+ @client.process_subscription(@json, :signature => signature ) do |handler|
166
+ # hi
167
+ end
168
+ end.to raise_error(Instagram::InvalidSignature)
169
+ end
170
+ end
171
+ end
172
+ end
173
+ end
174
+ end