bitlyr 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. data/History.txt +146 -0
  2. data/LICENSE +20 -0
  3. data/README.md +97 -0
  4. data/README.rdoc +37 -0
  5. data/Rakefile +43 -0
  6. data/VERSION +1 -0
  7. data/bitlyr.gemspec +154 -0
  8. data/lib/bitlyr/client.rb +153 -0
  9. data/lib/bitlyr/country.rb +10 -0
  10. data/lib/bitlyr/day.rb +12 -0
  11. data/lib/bitlyr/error.rb +13 -0
  12. data/lib/bitlyr/lib/core_ext/hash.rb +27 -0
  13. data/lib/bitlyr/lib/core_ext/string.rb +5 -0
  14. data/lib/bitlyr/missing_url.rb +12 -0
  15. data/lib/bitlyr/realtime_link.rb +16 -0
  16. data/lib/bitlyr/referrer.rb +12 -0
  17. data/lib/bitlyr/response.rb +39 -0
  18. data/lib/bitlyr/strategy/access_token.rb +26 -0
  19. data/lib/bitlyr/strategy/api_key.rb +33 -0
  20. data/lib/bitlyr/strategy/base.rb +26 -0
  21. data/lib/bitlyr/strategy/oauth.rb +50 -0
  22. data/lib/bitlyr/url.rb +124 -0
  23. data/lib/bitlyr/user.rb +100 -0
  24. data/lib/bitlyr.rb +39 -0
  25. data/test/fixtures/9uX1TE.json +1 -0
  26. data/test/fixtures/9uX1TEclicks.json +1 -0
  27. data/test/fixtures/9uX1TEclicks2.json +1 -0
  28. data/test/fixtures/9uX1TEinfo.json +1 -0
  29. data/test/fixtures/9uX1TEinfo2.json +1 -0
  30. data/test/fixtures/auth_fail.json +1 -0
  31. data/test/fixtures/auth_success.json +1 -0
  32. data/test/fixtures/betaworks.json +1 -0
  33. data/test/fixtures/betaworks2.json +1 -0
  34. data/test/fixtures/betaworks_jmp.json +1 -0
  35. data/test/fixtures/betaworks_other_user.json +1 -0
  36. data/test/fixtures/bitly9uX1TE.json +1 -0
  37. data/test/fixtures/bitly_pro_domain.json +1 -0
  38. data/test/fixtures/clicks_by_day.json +1 -0
  39. data/test/fixtures/clicks_by_day1.json +1 -0
  40. data/test/fixtures/clicks_by_day2.json +1 -0
  41. data/test/fixtures/clicks_by_minute1_url.json +1 -0
  42. data/test/fixtures/clicks_by_minute2_url.json +1 -0
  43. data/test/fixtures/clicks_by_minute_hash.json +1 -0
  44. data/test/fixtures/clicks_by_minute_hashes.json +1 -0
  45. data/test/fixtures/country_hash.json +1 -0
  46. data/test/fixtures/country_hash2.json +1 -0
  47. data/test/fixtures/country_url.json +1 -0
  48. data/test/fixtures/failure.json +1 -0
  49. data/test/fixtures/invalid_bitly_pro_domain.json +1 -0
  50. data/test/fixtures/invalid_credentials.json +1 -0
  51. data/test/fixtures/invalid_domain.json +1 -0
  52. data/test/fixtures/invalid_user.json +1 -0
  53. data/test/fixtures/invalid_x_api_key.json +1 -0
  54. data/test/fixtures/lookup_multiple_url.json +1 -0
  55. data/test/fixtures/lookup_not_real_url.json +1 -0
  56. data/test/fixtures/lookup_single_url.json +1 -0
  57. data/test/fixtures/missing_hash.json +1 -0
  58. data/test/fixtures/multiple_info.json +1 -0
  59. data/test/fixtures/multiple_url_click.json +1 -0
  60. data/test/fixtures/multiple_urls.json +1 -0
  61. data/test/fixtures/not_bitly_pro_domain.json +1 -0
  62. data/test/fixtures/not_found_info.json +1 -0
  63. data/test/fixtures/referrer_hash.json +1 -0
  64. data/test/fixtures/referrer_hash2.json +1 -0
  65. data/test/fixtures/referrer_url.json +1 -0
  66. data/test/fixtures/success.json +1 -0
  67. data/test/fixtures/url_info.json +1 -0
  68. data/test/fixtures/user_clicks.json +32 -0
  69. data/test/fixtures/user_countries.json +60 -0
  70. data/test/fixtures/user_realtime_links.json +15 -0
  71. data/test/fixtures/user_referrers.json +1 -0
  72. data/test/fixtures/valid_user.json +1 -0
  73. data/test/integration/strategy/test_api_key.rb +20 -0
  74. data/test/integration/strategy/test_oauth.rb +52 -0
  75. data/test/integration/test_client.rb +1415 -0
  76. data/test/integration/test_user.rb +97 -0
  77. data/test/test_helper.rb +54 -0
  78. data/test/unit/core_ext/test_hash.rb +69 -0
  79. data/test/unit/core_ext/test_string.rb +14 -0
  80. data/test/unit/strategy/test_access_token.rb +14 -0
  81. data/test/unit/strategy/test_api_key.rb +11 -0
  82. data/test/unit/strategy/test_base.rb +71 -0
  83. data/test/unit/strategy/test_oauth.rb +32 -0
  84. data/test/unit/test_bitly.rb +43 -0
  85. data/test/unit/test_client.rb +21 -0
  86. data/test/unit/test_country.rb +20 -0
  87. data/test/unit/test_day.rb +22 -0
  88. data/test/unit/test_error.rb +11 -0
  89. data/test/unit/test_missing.rb +34 -0
  90. data/test/unit/test_realtime_link.rb +30 -0
  91. data/test/unit/test_referrer.rb +20 -0
  92. data/test/unit/test_response.rb +86 -0
  93. data/test/unit/test_url.rb +155 -0
  94. data/test/unit/test_user.rb +17 -0
  95. metadata +233 -0
@@ -0,0 +1 @@
1
+ {"status_code": 200, "data": {"lookup": [{"url": "http://betaworks.com/", "short_url": "http://bit.ly/aboutus", "global_hash": "aboutus"}, {"url": "http://code.google.com/p/bitly-api/", "short_url": "http://bit.ly/1oDCU", "global_hash": "1oDCU"}]}, "status_txt": "OK"}
@@ -0,0 +1 @@
1
+ {"status_code": 200, "data": {"lookup": [{"url": "asdf://www.google.com/not/a/real/link", "error": "NOT_FOUND"}]}, "status_txt": "OK"}
@@ -0,0 +1 @@
1
+ {"status_code": 200, "data": {"lookup": [{"url": "http://code.google.com/p/bitly-api/", "short_url": "http://bit.ly/1oDCU", "global_hash": "1oDCU"}]}, "status_txt": "OK"}
@@ -0,0 +1 @@
1
+ { "status_code": 200, "status_txt": "OK", "data": { "expand": [ { "error": "NOT_FOUND", "short_url": "http:\/\/bit.ly\/9uX1TEsd" } ] } }
@@ -0,0 +1 @@
1
+ {"status_code": 200, "data": {"info": [{"global_hash": "18H1ET", "hash": "9uX1TE", "user_hash": "9uX1TE", "created_by": "philnash", "title": null}, {"short_url": "http://bit.ly/1YKMfY", "global_hash": "1YKMfY", "user_hash": "1YKMfY", "created_by": "bitly", "title": "betaworks"}]}, "status_txt": "OK"}
@@ -0,0 +1 @@
1
+ {"status_code": 200, "data": {"clicks": [{"short_url": "http://bit.ly/cEFx9W", "global_hash": "bDjgIR", "user_clicks": 0, "user_hash": "cEFx9W", "global_clicks": 0}, {"user_clicks": 0, "global_hash": "18H1ET", "hash": "9uX1TE", "user_hash": "9uX1TE", "global_clicks": 67}]}, "status_txt": "OK"}
@@ -0,0 +1 @@
1
+ { "status_code": 200, "status_txt": "OK", "data": { "expand": [ { "short_url": "http:\/\/bit.ly\/cEFx9W", "long_url": "http:\/\/philnash.co.uk", "user_hash": "cEFx9W", "global_hash": "bDjgIR" }, { "hash": "9uX1TE", "long_url": "http:\/\/betaworks.com\/", "user_hash": "9uX1TE", "global_hash": "18H1ET" } ] } }
@@ -0,0 +1 @@
1
+ {"status_code": 200, "data": {"domain": "philnash.co.uk", "bitly_pro_domain": false}, "status_txt": "OK"}
@@ -0,0 +1 @@
1
+ {"status_code": 200, "data": {"info": [{"short_url": "http://bit.ly/1YKMfYasb", "error": "NOT_FOUND"}]}, "status_txt": "OK"}
@@ -0,0 +1 @@
1
+ {"status_code": 200, "data": {"referrers": [{"referrer": "direct", "clicks": 62}, {"referrer": "http://twitter.com/bitly", "clicks": 21}, {"referrer": "http://twitter.com/", "clicks": 19}, {"url": "http://www.tweetdeck.com/", "referrer_app": "TweetDeck", "clicks": 8}, {"referrer": "http://bit.ly/djZ9g4", "clicks": 6}, {"referrer": "http://bit.ly/djZ9g4+", "clicks": 5}, {"referrer": "http://api.bit.ly/v3/referrers", "clicks": 3}, {"referrer": "http://twitter.com/atul/statuses/26029156685", "clicks": 2}, {"referrer": "http://bit.ly/a/sidebar", "clicks": 1}, {"referrer": "http://code.google.com/p/bitly-api/wiki/ApiDocumentation", "clicks": 1}, {"referrer": "http://mobile.twitter.com/bitly", "clicks": 1}, {"referrer": "http://mywbs.com", "clicks": 1}, {"referrer": "http://translate.googleusercontent.com/translate_c", "clicks": 1}, {"referrer": "http://twitter.com//atul/statuses/26029156685", "clicks": 1}, {"referrer": "http://twitter.com/home", "clicks": 1}, {"referrer": "http://untiny.me/", "clicks": 1}], "global_hash": "djZ9g4", "hash": "djZ9g4", "user_hash": "djZ9g4"}, "status_txt": "OK"}
@@ -0,0 +1 @@
1
+ {"status_code": 200, "data": {"referrers": [{"referrer": "direct", "clicks": 63}, {"referrer": "http://twitter.com/bitly", "clicks": 21}, {"referrer": "http://twitter.com/", "clicks": 19}, {"url": "http://www.tweetdeck.com/", "referrer_app": "TweetDeck", "clicks": 8}, {"referrer": "http://bit.ly/djZ9g4", "clicks": 6}, {"referrer": "http://bit.ly/djZ9g4+", "clicks": 5}, {"referrer": "http://api.bit.ly/v3/referrers", "clicks": 3}, {"referrer": "http://twitter.com/atul/statuses/26029156685", "clicks": 2}, {"referrer": "http://bit.ly/a/sidebar", "clicks": 1}, {"referrer": "http://code.google.com/p/bitly-api/wiki/ApiDocumentation", "clicks": 1}, {"referrer": "http://mobile.twitter.com/bitly", "clicks": 1}, {"referrer": "http://mywbs.com", "clicks": 1}, {"referrer": "http://translate.googleusercontent.com/translate_c", "clicks": 1}, {"referrer": "http://twitter.com//atul/statuses/26029156685", "clicks": 1}, {"referrer": "http://twitter.com/home", "clicks": 1}, {"referrer": "http://untiny.me/", "clicks": 1}], "global_hash": "djZ9g4", "hash": "djZ9g4", "user_hash": "djZ9g4"}, "status_txt": "OK"}
@@ -0,0 +1 @@
1
+ {"status_code": 200, "data": {"short_url": "http://bit.ly/djZ9g4", "global_hash": "djZ9g4", "user_hash": "djZ9g4", "referrers": [{"referrer": "direct", "clicks": 62}, {"referrer": "http://twitter.com/bitly", "clicks": 21}, {"referrer": "http://twitter.com/", "clicks": 19}, {"url": "http://www.tweetdeck.com/", "referrer_app": "TweetDeck", "clicks": 8}, {"referrer": "http://bit.ly/djZ9g4", "clicks": 6}, {"referrer": "http://bit.ly/djZ9g4+", "clicks": 5}, {"referrer": "http://api.bit.ly/v3/referrers", "clicks": 3}, {"referrer": "http://twitter.com/atul/statuses/26029156685", "clicks": 2}, {"referrer": "http://bit.ly/a/sidebar", "clicks": 1}, {"referrer": "http://code.google.com/p/bitly-api/wiki/ApiDocumentation", "clicks": 1}, {"referrer": "http://mobile.twitter.com/bitly", "clicks": 1}, {"referrer": "http://mywbs.com", "clicks": 1}, {"referrer": "http://translate.googleusercontent.com/translate_c", "clicks": 1}, {"referrer": "http://twitter.com//atul/statuses/26029156685", "clicks": 1}, {"referrer": "http://twitter.com/home", "clicks": 1}, {"referrer": "http://untiny.me/", "clicks": 1}]}, "status_txt": "OK"}
@@ -0,0 +1 @@
1
+ { "status_code": 200, "status_txt": "OK", "data": { } }
@@ -0,0 +1 @@
1
+ {"status_code": 200, "data": {"info": [{"short_url": "http://bit.ly/1YKMfY", "global_hash": "1YKMfY", "user_hash": "1YKMfY", "created_by": "bitly", "title": "betaworks"}]}, "status_txt": "OK"}
@@ -0,0 +1,32 @@
1
+ {
2
+ "status_code": 200,
3
+ "data": {
4
+ "days": 7,
5
+ "total_clicks": 29,
6
+ "clicks": [
7
+ {
8
+ "clicks": 4,
9
+ "day_start": 1291093200
10
+ }, {
11
+ "clicks": 6,
12
+ "day_start": 1291006800
13
+ }, {
14
+ "clicks": 1,
15
+ "day_start": 1290920400
16
+ }, {
17
+ "clicks": 2,
18
+ "day_start": 1290834000
19
+ }, {
20
+ "clicks": 8,
21
+ "day_start": 1290747600
22
+ }, {
23
+ "clicks": 5,
24
+ "day_start": 1290661200
25
+ }, {
26
+ "clicks": 3,
27
+ "day_start": 1290574800
28
+ }
29
+ ]
30
+ },
31
+ "status_txt": "OK"
32
+ }
@@ -0,0 +1,60 @@
1
+ {
2
+ "status_code": 200,
3
+ "data": {
4
+ "days": 7,
5
+ "countries": [
6
+ [
7
+ {
8
+ "country": "US",
9
+ "clicks": 4
10
+ }
11
+ ], [
12
+ {
13
+ "country": "US",
14
+ "clicks": 5
15
+ }, {
16
+ "country": "unknown",
17
+ "clicks": 1
18
+ }
19
+ ], [
20
+ {
21
+ "country": "unknown",
22
+ "clicks": 1
23
+ }
24
+ ], [
25
+ {
26
+ "country": "US",
27
+ "clicks": 2
28
+ }
29
+ ], [
30
+ {
31
+ "country": "US",
32
+ "clicks": 5
33
+ }, {
34
+ "country": "IN",
35
+ "clicks": 1
36
+ }, {
37
+ "country": "FR",
38
+ "clicks": 1
39
+ }, {
40
+ "country": "CA",
41
+ "clicks": 1
42
+ }
43
+ ], [
44
+ {
45
+ "country": "US",
46
+ "clicks": 5
47
+ }
48
+ ], [
49
+ {
50
+ "country": "CA",
51
+ "clicks": 2
52
+ }, {
53
+ "country": "US",
54
+ "clicks": 1
55
+ }
56
+ ]
57
+ ]
58
+ },
59
+ "status_txt": "OK"
60
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "status_code": 200,
3
+ "data": {
4
+ "realtime_links": [
5
+ {
6
+ "clicks": 15,
7
+ "user_hash": "i7JWw0"
8
+ }, {
9
+ "clicks": 1,
10
+ "user_hash": "eiRiMo"
11
+ }
12
+ ]
13
+ },
14
+ "status_txt": "OK"
15
+ }
@@ -0,0 +1 @@
1
+ {"status_code": 200, "data": {"referrers": [[{"referrer": "direct", "clicks": 1}], [], [{"referrer": "http://twitter.com/", "clicks": 1}], [], [], [], [{"referrer": "http://blog.bit.ly/post/76203780/bit-ly-api-contest-winners", "clicks": 1}]], "days": 7}, "status_txt": "OK"}
@@ -0,0 +1 @@
1
+ { "status_code": 200, "status_txt": "OK", "data": { "valid": 1 } }
@@ -0,0 +1,20 @@
1
+ require 'test_helper'
2
+
3
+ class TestApiKey < Test::Unit::TestCase
4
+ context "making a successful request" do
5
+ should "return a hash when successful" do
6
+ stub_get(%r{http://api\.bit\.ly/v3}, 'success.json')
7
+ strategy = Bitlyr::Strategy::ApiKey.new(login_fixture, api_key_fixture)
8
+ assert_kind_of Hash, strategy.request(:get, "/")
9
+ end
10
+ end
11
+ context "making an unsuccessful request" do
12
+ should "raise a bitlyr error when unsuccessful" do
13
+ assert_raise BitlyrError do
14
+ stub_get(%r{http://api\.bit\.ly/v3}, 'failure.json')
15
+ strategy = Bitlyr::Strategy::ApiKey.new(login_fixture, api_key_fixture)
16
+ strategy.request(:get, "/")
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,52 @@
1
+ require 'test_helper'
2
+
3
+ class TestOAuthStrategy < Test::Unit::TestCase
4
+ context "with an id and secret" do
5
+ setup do
6
+ @client_id = 'id'
7
+ @client_secret = 'secret'
8
+ @strategy = Bitlyr::Strategy::OAuth.new(@client_id, @client_secret)
9
+ end
10
+ should 'get access token from code' do
11
+ FakeWeb.register_uri(:post, %r|https://api-ssl.bit.ly/oauth/access_token|, { :body => "access_token=token&login=hello&apiKey=API_KEY", :content_type => 'application/x-www-form-urlencoded' })
12
+ access_token = @strategy.get_access_token_from_code('code', 'http://test.local')
13
+ assert_kind_of Bitlyr::Strategy::AccessToken, access_token
14
+ assert_equal @strategy.send(:client), access_token.client
15
+ assert_equal 'hello', access_token['login']
16
+ assert_equal 'API_KEY', access_token['apiKey']
17
+ end
18
+ should 'get access token from token' do
19
+ access_token = @strategy.get_access_token_from_token('token')
20
+ assert_kind_of Bitlyr::Strategy::AccessToken, access_token
21
+ assert_equal @strategy.send(:client), access_token.client
22
+ end
23
+ end
24
+ context "validating a login and apiKey" do
25
+ context "with valid login and apiKey" do
26
+ setup do
27
+ stub_get("https://api-ssl.bit.ly/v3/validate?x_login=test_account&x_apiKey=test_key&access_token=token", 'valid_user.json')
28
+ @strategy = Bitlyr::Strategy::OAuth.new('id', 'secret')
29
+ @strategy.set_access_token_from_token!('token')
30
+ end
31
+ should "return true when calling validate" do
32
+ assert @strategy.validate(login_fixture, api_key_fixture)
33
+ end
34
+ should "return true when calling valid?" do
35
+ assert @strategy.valid?(login_fixture, api_key_fixture)
36
+ end
37
+ end
38
+ context "with an invalid login and apiKey" do
39
+ setup do
40
+ stub_get("https://api-ssl.bit.ly/v3/validate?x_login=bogus&x_apiKey=info&access_token=token", 'invalid_user.json')
41
+ @strategy = Bitlyr::Strategy::OAuth.new('id', 'secret')
42
+ @strategy.set_access_token_from_token!('token')
43
+ end
44
+ should "return false when calling validate" do
45
+ assert !@strategy.validate("bogus", "info")
46
+ end
47
+ should "return false when calling valid?" do
48
+ assert !@strategy.valid?("bogus", "info")
49
+ end
50
+ end
51
+ end
52
+ end