bitly-oauth 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. data/History.txt +154 -0
  2. data/LICENSE +20 -0
  3. data/README.md +87 -0
  4. data/README.rdoc +35 -0
  5. data/Rakefile +42 -0
  6. data/VERSION +1 -0
  7. data/lib/bitly_oauth.rb +28 -0
  8. data/lib/bitly_oauth/access_token.rb +37 -0
  9. data/lib/bitly_oauth/client.rb +149 -0
  10. data/lib/bitly_oauth/country.rb +10 -0
  11. data/lib/bitly_oauth/day.rb +12 -0
  12. data/lib/bitly_oauth/error.rb +15 -0
  13. data/lib/bitly_oauth/lib/core_ext/hash.rb +27 -0
  14. data/lib/bitly_oauth/lib/core_ext/string.rb +5 -0
  15. data/lib/bitly_oauth/missing_url.rb +12 -0
  16. data/lib/bitly_oauth/realtime_link.rb +16 -0
  17. data/lib/bitly_oauth/referrer.rb +12 -0
  18. data/lib/bitly_oauth/referring_domain.rb +11 -0
  19. data/lib/bitly_oauth/response.rb +39 -0
  20. data/lib/bitly_oauth/url.rb +118 -0
  21. data/lib/bitly_oauth/user.rb +104 -0
  22. data/test/fixtures/9uX1TE.json +1 -0
  23. data/test/fixtures/9uX1TEclicks.json +1 -0
  24. data/test/fixtures/9uX1TEclicks2.json +1 -0
  25. data/test/fixtures/9uX1TEinfo.json +1 -0
  26. data/test/fixtures/9uX1TEinfo2.json +1 -0
  27. data/test/fixtures/auth_fail.json +1 -0
  28. data/test/fixtures/auth_success.json +1 -0
  29. data/test/fixtures/betaworks.json +1 -0
  30. data/test/fixtures/betaworks2.json +1 -0
  31. data/test/fixtures/betaworks_jmp.json +1 -0
  32. data/test/fixtures/betaworks_other_user.json +1 -0
  33. data/test/fixtures/bitly9uX1TE.json +1 -0
  34. data/test/fixtures/bitly_pro_domain.json +1 -0
  35. data/test/fixtures/clicks_by_day.json +1 -0
  36. data/test/fixtures/clicks_by_day1.json +1 -0
  37. data/test/fixtures/clicks_by_day2.json +1 -0
  38. data/test/fixtures/clicks_by_minute1_url.json +1 -0
  39. data/test/fixtures/clicks_by_minute2_url.json +1 -0
  40. data/test/fixtures/clicks_by_minute_hash.json +1 -0
  41. data/test/fixtures/clicks_by_minute_hashes.json +1 -0
  42. data/test/fixtures/country_hash.json +1 -0
  43. data/test/fixtures/country_hash2.json +1 -0
  44. data/test/fixtures/country_url.json +1 -0
  45. data/test/fixtures/failure.json +1 -0
  46. data/test/fixtures/invalid_bitly_pro_domain.json +1 -0
  47. data/test/fixtures/invalid_credentials.json +1 -0
  48. data/test/fixtures/invalid_domain.json +1 -0
  49. data/test/fixtures/invalid_user.json +1 -0
  50. data/test/fixtures/invalid_x_api_key.json +1 -0
  51. data/test/fixtures/lookup_multiple_url.json +1 -0
  52. data/test/fixtures/lookup_not_real_url.json +1 -0
  53. data/test/fixtures/lookup_single_url.json +1 -0
  54. data/test/fixtures/missing_hash.json +1 -0
  55. data/test/fixtures/multiple_info.json +1 -0
  56. data/test/fixtures/multiple_url_click.json +1 -0
  57. data/test/fixtures/multiple_urls.json +1 -0
  58. data/test/fixtures/not_bitly_pro_domain.json +1 -0
  59. data/test/fixtures/not_found_info.json +1 -0
  60. data/test/fixtures/referrer_hash.json +1 -0
  61. data/test/fixtures/referrer_hash2.json +1 -0
  62. data/test/fixtures/referrer_url.json +1 -0
  63. data/test/fixtures/success.json +1 -0
  64. data/test/fixtures/url_info.json +1 -0
  65. data/test/fixtures/user_clicks.json +32 -0
  66. data/test/fixtures/user_countries.json +60 -0
  67. data/test/fixtures/user_realtime_links.json +15 -0
  68. data/test/fixtures/user_referrers.json +1 -0
  69. data/test/fixtures/valid_user.json +1 -0
  70. data/test/integration/strategy/old_test_api_key.rb +20 -0
  71. data/test/integration/test_client.rb +709 -0
  72. data/test/integration/test_user.rb +97 -0
  73. data/test/test_helper.rb +54 -0
  74. data/test/unit/core_ext/test_hash.rb +69 -0
  75. data/test/unit/core_ext/test_string.rb +14 -0
  76. data/test/unit/test_bitly_oauth.rb +19 -0
  77. data/test/unit/test_client.rb +87 -0
  78. data/test/unit/test_country.rb +19 -0
  79. data/test/unit/test_day.rb +22 -0
  80. data/test/unit/test_error.rb +11 -0
  81. data/test/unit/test_missing.rb +34 -0
  82. data/test/unit/test_realtime_link.rb +30 -0
  83. data/test/unit/test_referrer.rb +19 -0
  84. data/test/unit/test_referring_domain.rb +21 -0
  85. data/test/unit/test_response.rb +86 -0
  86. data/test/unit/test_url.rb +156 -0
  87. data/test/unit/test_user.rb +17 -0
  88. metadata +215 -0
@@ -0,0 +1 @@
1
+ {"status_code": 200, "data": {"clicks_by_day": [{"global_hash": "9DguyN", "hash": "9DguyN", "user_hash": "9DguyN", "clicks": [{"clicks": 1, "day_start": 1290488400}, {"clicks": 0, "day_start": 1290402000}, {"clicks": 0, "day_start": 1290315600}, {"clicks": 1, "day_start": 1290229200}, {"clicks": 0, "day_start": 1290142800}, {"clicks": 0, "day_start": 1290056400}, {"clicks": 0, "day_start": 1289970000}]}, {"global_hash": "dpC5ns", "hash": "dvxi6W", "user_hash": "dvxi6W", "clicks": [{"clicks": 1, "day_start": 1290488400}, {"clicks": 0, "day_start": 1290402000}, {"clicks": 0, "day_start": 1290315600}, {"clicks": 0, "day_start": 1290229200}, {"clicks": 0, "day_start": 1290142800}, {"clicks": 0, "day_start": 1290056400}, {"clicks": 0, "day_start": 1289970000}]}]}, "status_txt": "OK"}
@@ -0,0 +1 @@
1
+ {"status_code": 200, "data": {"clicks_by_day": [{"global_hash": "9DguyN", "hash": "9DguyN", "user_hash": "9DguyN", "clicks": [{"clicks": 1, "day_start": 1290488400}, {"clicks": 0, "day_start": 1290402000}, {"clicks": 0, "day_start": 1290315600}, {"clicks": 1, "day_start": 1290229200}, {"clicks": 0, "day_start": 1290142800}, {"clicks": 0, "day_start": 1290056400}, {"clicks": 0, "day_start": 1289970000}]}]}, "status_txt": "OK"}
@@ -0,0 +1 @@
1
+ {"status_code": 200, "data": {"clicks_by_day": [{"global_hash": "9DguyN", "hash": "9DguyN", "user_hash": "9DguyN", "clicks": [{"clicks": 2, "day_start": 1290488400}, {"clicks": 0, "day_start": 1290402000}, {"clicks": 0, "day_start": 1290315600}, {"clicks": 1, "day_start": 1290229200}, {"clicks": 0, "day_start": 1290142800}, {"clicks": 0, "day_start": 1290056400}, {"clicks": 0, "day_start": 1289970000}]}]}, "status_txt": "OK"}
@@ -0,0 +1 @@
1
+ {"status_code": 200, "data": {"clicks_by_minute": [{"short_url": "http://j.mp/9DguyN", "global_hash": "9DguyN", "user_hash": "9DguyN", "clicks": [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}]}, "status_txt": "OK"}
@@ -0,0 +1 @@
1
+ {"status_code": 200, "data": {"clicks_by_minute": [{"short_url": "http://j.mp/9DguyN", "global_hash": "9DguyN", "user_hash": "9DguyN", "clicks": [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}]}, "status_txt": "OK"}
@@ -0,0 +1 @@
1
+ {"status_code": 200, "data": {"clicks_by_minute": [{"global_hash": "9DguyN", "hash": "9DguyN", "user_hash": "9DguyN", "clicks": [0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}]}, "status_txt": "OK"}
@@ -0,0 +1 @@
1
+ {"status_code": 200, "data": {"clicks_by_minute": [{"global_hash": "9DguyN", "hash": "9DguyN", "user_hash": "9DguyN", "clicks": [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}, {"global_hash": "dpC5ns", "hash": "dvxi6W", "user_hash": "dvxi6W", "clicks": [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}]}, "status_txt": "OK"}
@@ -0,0 +1 @@
1
+ {"status_code": 200, "data": {"global_hash": "djZ9g4", "hash": "djZ9g4", "user_hash": "djZ9g4", "countries": [{"country": "US", "clicks": 58}, {"country": "GB", "clicks": 14}, {"country": null, "clicks": 14}, {"country": "BR", "clicks": 6}, {"country": "CA", "clicks": 6}, {"country": "FR", "clicks": 5}, {"country": "AU", "clicks": 4}, {"country": "IN", "clicks": 4}, {"country": "DE", "clicks": 3}, {"country": "TW", "clicks": 3}, {"country": "IT", "clicks": 2}, {"country": "NO", "clicks": 2}, {"country": "PL", "clicks": 2}, {"country": "BE", "clicks": 1}, {"country": "BG", "clicks": 1}, {"country": "CI", "clicks": 1}, {"country": "CZ", "clicks": 1}, {"country": "ES", "clicks": 1}, {"country": "GR", "clicks": 1}, {"country": "HK", "clicks": 1}, {"country": "KR", "clicks": 1}, {"country": "MY", "clicks": 1}, {"country": "PH", "clicks": 1}, {"country": "PT", "clicks": 1}, {"country": "SE", "clicks": 1}, {"country": "VE", "clicks": 1}]}, "status_txt": "OK"}
@@ -0,0 +1 @@
1
+ {"status_code": 200, "data": {"global_hash": "djZ9g4", "hash": "djZ9g4", "user_hash": "djZ9g4", "countries": [{"country": "US", "clicks": 59}, {"country": "GB", "clicks": 14}, {"country": null, "clicks": 14}, {"country": "BR", "clicks": 6}, {"country": "CA", "clicks": 6}, {"country": "FR", "clicks": 5}, {"country": "AU", "clicks": 4}, {"country": "IN", "clicks": 4}, {"country": "DE", "clicks": 3}, {"country": "TW", "clicks": 3}, {"country": "IT", "clicks": 2}, {"country": "NO", "clicks": 2}, {"country": "PL", "clicks": 2}, {"country": "BE", "clicks": 1}, {"country": "BG", "clicks": 1}, {"country": "CI", "clicks": 1}, {"country": "CZ", "clicks": 1}, {"country": "ES", "clicks": 1}, {"country": "GR", "clicks": 1}, {"country": "HK", "clicks": 1}, {"country": "KR", "clicks": 1}, {"country": "MY", "clicks": 1}, {"country": "PH", "clicks": 1}, {"country": "PT", "clicks": 1}, {"country": "SE", "clicks": 1}, {"country": "VE", "clicks": 1}]}, "status_txt": "OK"}
@@ -0,0 +1 @@
1
+ {"status_code": 200, "data": {"short_url": "http://bit.ly/djZ9g4", "global_hash": "djZ9g4", "user_hash": "djZ9g4", "countries": [{"country": "US", "clicks": 58}, {"country": "GB", "clicks": 14}, {"country": null, "clicks": 14}, {"country": "BR", "clicks": 6}, {"country": "CA", "clicks": 6}, {"country": "FR", "clicks": 5}, {"country": "AU", "clicks": 4}, {"country": "IN", "clicks": 4}, {"country": "DE", "clicks": 3}, {"country": "TW", "clicks": 3}, {"country": "IT", "clicks": 2}, {"country": "NO", "clicks": 2}, {"country": "PL", "clicks": 2}, {"country": "BE", "clicks": 1}, {"country": "BG", "clicks": 1}, {"country": "CI", "clicks": 1}, {"country": "CZ", "clicks": 1}, {"country": "ES", "clicks": 1}, {"country": "GR", "clicks": 1}, {"country": "HK", "clicks": 1}, {"country": "KR", "clicks": 1}, {"country": "MY", "clicks": 1}, {"country": "PH", "clicks": 1}, {"country": "PT", "clicks": 1}, {"country": "SE", "clicks": 1}, {"country": "VE", "clicks": 1}]}, "status_txt": "OK"}
@@ -0,0 +1 @@
1
+ { "status_code": 400, "status_txt": "Bad Request", "data": { } }
@@ -0,0 +1 @@
1
+ {"status_code": 500, "data": null, "status_txt": "INVALID_DOMAIN"}
@@ -0,0 +1 @@
1
+ { "data": [ ], "status_code": 500, "status_txt": "INVALID_LOGIN" }
@@ -0,0 +1 @@
1
+ { "data": [ ], "status_code": 500, "status_txt": "INVALID_ARG_DOMAIN" }
@@ -0,0 +1 @@
1
+ { "status_code": 200, "status_txt": "OK", "data": { "valid": 0 } }
@@ -0,0 +1 @@
1
+ { "data": [ ], "status_code": 500, "status_txt": "INVALID_X_APIKEY" }
@@ -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 = BitlyOAuth::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 bitly-oauth error when unsuccessful" do
13
+ assert_raise BitlyOAuthError do
14
+ stub_get(%r{http://api\.bit\.ly/v3}, 'failure.json')
15
+ strategy = BitlyOAuth::Strategy::ApiKey.new(login_fixture, api_key_fixture)
16
+ strategy.request(:get, "/")
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,709 @@
1
+ require 'test_helper'
2
+
3
+ class TestClient < Test::Unit::TestCase
4
+ context "with a valid client" do
5
+ context "with the OAuth Strategy" do
6
+ setup do
7
+ @client = BitlyOAuth::Client.new("id", "secret")
8
+ @client.set_access_token_from_token('token')
9
+ end
10
+
11
+ context "validating another account credentials" do
12
+ context "with valid credentials" do
13
+ setup do
14
+ stub_get(%r{https://api-ssl\.bit\.ly/v3/validate?.*x_login=correct.*}, "valid_user.json")
15
+ end
16
+
17
+ should "return true" do
18
+ assert @client.validate('correct', 'well_done')
19
+ end
20
+
21
+ should "return true for valid? as well" do
22
+ assert @client.valid?('correct', 'well_done')
23
+ end
24
+ end
25
+
26
+ context "with invalid credentials" do
27
+ setup do
28
+ stub_get(%r{https://api-ssl\.bit\.ly/v3/validate?.*x_login=wrong.*},"invalid_user.json")
29
+ end
30
+
31
+ should "return false" do
32
+ assert !@client.validate('wrong','so_very_wrong')
33
+ end
34
+
35
+ should "return false for valid? too" do
36
+ assert !@client.valid?('wrong','so_very_wrong')
37
+ end
38
+ end
39
+ end
40
+
41
+ context "checking a bitly pro domain" do
42
+ context "with a bitly pro domain" do
43
+ setup do
44
+ stub_get(%r|https://api-ssl\.bit\.ly/v3/bitly_pro_domain?.*domain=nyti\.ms.*|, 'bitly_pro_domain.json')
45
+ end
46
+
47
+ should "return true" do
48
+ assert @client.bitly_pro_domain('nyti.ms')
49
+ end
50
+ end
51
+
52
+ context "with a non bitly pro domain" do
53
+ setup do
54
+ stub_get(%r|https://api-ssl\.bit\.ly/v3/bitly_pro_domain?.*domain=philnash\.co\.uk.*|, 'not_bitly_pro_domain.json')
55
+ end
56
+
57
+ should "return false" do
58
+ assert !@client.bitly_pro_domain('philnash.co.uk')
59
+ end
60
+ end
61
+
62
+ context "with an invalid domain" do
63
+ setup do
64
+ stub_get(%r|https://api-ssl\.bit\.ly/v3/bitly_pro_domain?.*domain=philnash.*|, 'invalid_bitly_pro_domain.json')
65
+ end
66
+
67
+ should "raise an error" do
68
+ assert_raise BitlyOAuth::Error do
69
+ @client.bitly_pro_domain('philnash')
70
+ end
71
+ end
72
+ end
73
+ end
74
+
75
+ context "shortening a url" do
76
+ context "with just the url" do
77
+ setup do
78
+ @long_url = "http://betaworks.com/"
79
+ stub_get(%r|https://api-ssl\.bit\.ly/v3/shorten\?.*longUrl=#{CGI.escape(@long_url)}.*|, ['betaworks.json', 'betaworks2.json'])
80
+ @url = @client.shorten(@long_url)
81
+ end
82
+
83
+ should "return a url object" do
84
+ assert_instance_of BitlyOAuth::Url, @url
85
+ end
86
+
87
+ should "shorten the url" do
88
+ assert_equal 'http://bit.ly/9uX1TE', @url.short_url
89
+ end
90
+
91
+ should "return the original long url" do
92
+ assert_equal @long_url, @url.long_url
93
+ end
94
+
95
+ should "return a hash" do
96
+ assert_equal '9uX1TE', @url.user_hash
97
+ end
98
+
99
+ should "return a global hash" do
100
+ assert_equal '18H1ET', @url.global_hash
101
+ end
102
+
103
+ should "be a new hash the first time" do
104
+ assert @url.new_hash?
105
+ end
106
+
107
+ should "not be a new hash the second time" do
108
+ new_url = @client.shorten(@long_url)
109
+ assert !new_url.new_hash?
110
+ assert_not_same @url, new_url
111
+ end
112
+ end
113
+
114
+ context "with extra options" do
115
+ context "with the j.mp domain" do
116
+ setup do
117
+ stub_get("https://api-ssl.bit.ly/v3/shorten?longUrl=#{CGI.escape('http://betaworks.com/')}&access_token=token&domain=j.mp", 'betaworks_jmp.json')
118
+ @url = @client.shorten('http://betaworks.com/', :domain => "j.mp")
119
+ end
120
+
121
+ should "return a j.mp short url" do
122
+ assert_equal "http://j.mp/9uX1TE", @url.short_url
123
+ end
124
+ end
125
+
126
+ context "with another domain" do
127
+ setup do
128
+ stub_get("https://api-ssl.bit.ly/v3/shorten?longUrl=#{CGI.escape('http://betaworks.com/')}&access_token=token&domain=nyti.ms", 'invalid_domain.json')
129
+ end
130
+
131
+ should "raise an error" do
132
+ assert_raise BitlyOAuth::Error do
133
+ url = @client.shorten('http://betaworks.com/', :domain => "nyti.ms")
134
+ end
135
+ end
136
+ end
137
+
138
+ context "with another user details" do
139
+ context "with correct details" do
140
+ setup do
141
+ @long_url = "http://betaworks.com/"
142
+ stub_get(%r{https://api-ssl\.bit\.ly/v3/shorten?.*longUrl=#{CGI.escape('http://betaworks.com/')}.*}, 'betaworks.json')
143
+ stub_get("https://api-ssl.bit.ly/v3/shorten?longUrl=#{CGI.escape('http://betaworks.com/')}&access_token=token&x_login=other_account&x_apiKey=other_apiKey", 'betaworks_other_user.json' )
144
+ @normal_url = @client.shorten(@long_url)
145
+ @other_user_url = @client.shorten(@long_url, :x_login => 'other_account', :x_apiKey => 'other_apiKey')
146
+ end
147
+
148
+ should "return a different hash" do
149
+ assert_not_equal @normal_url.user_hash, @other_user_url.user_hash
150
+ end
151
+
152
+ should "return a new hash" do
153
+ assert @other_user_url.new_hash?
154
+ end
155
+ end
156
+
157
+ context "without an api key" do
158
+ setup do
159
+ stub_get("https://api-ssl.bit.ly/v3/shorten?longUrl=#{CGI.escape('http://betaworks.com/')}&access_token=token&x_login=other_account", 'invalid_x_api_key.json' )
160
+ end
161
+
162
+ should "raise an error" do
163
+ assert_raise BitlyOAuth::Error do
164
+ @client.shorten('http://betaworks.com/', :x_login => 'other_account')
165
+ end
166
+ end
167
+ end
168
+ end
169
+ end
170
+ end
171
+
172
+ context "expanding a url" do
173
+ context "a single url" do
174
+ context "with a hash" do
175
+ setup do
176
+ @hash = '9uX1TE'
177
+ stub_get(%r|https://api-ssl\.bit\.ly/v3/expand\?.*hash=9uX1TE.*|, '9uX1TE.json')
178
+ @url = @client.expand(@hash)
179
+ end
180
+
181
+ should 'return a url object' do
182
+ assert_instance_of BitlyOAuth::Url, @url
183
+ end
184
+
185
+ should 'return the original hash' do
186
+ assert_equal @hash, @url.user_hash
187
+ end
188
+
189
+ should "return a global hash" do
190
+ assert_equal '18H1ET', @url.global_hash
191
+ end
192
+
193
+ should 'return a long url' do
194
+ assert_equal 'http://betaworks.com/', @url.long_url
195
+ end
196
+
197
+ should 'return a short url' do
198
+ assert_equal "http://bit.ly/#{@hash}", @url.short_url
199
+ end
200
+ end
201
+
202
+ context "with the short url" do
203
+ setup do
204
+ @short_url = 'http://bit.ly/9uX1TE'
205
+ stub_get(%r|https://api-ssl\.bit\.ly/v3/expand\?.*shortUrl=http%3A%2F%2Fbit\.ly%2F9uX1TE.*|, 'bitly9uX1TE.json')
206
+ @url = @client.expand(@short_url)
207
+ end
208
+
209
+ should 'return a url object' do
210
+ assert_instance_of BitlyOAuth::Url, @url
211
+ end
212
+
213
+ should 'return the original hash' do
214
+ assert_equal "9uX1TE", @url.user_hash
215
+ end
216
+
217
+ should "return a global hash" do
218
+ assert_equal '18H1ET', @url.global_hash
219
+ end
220
+
221
+ should 'return a long url' do
222
+ assert_equal 'http://betaworks.com/', @url.long_url
223
+ end
224
+
225
+ should 'return a short url' do
226
+ assert_equal "http://bit.ly/9uX1TE", @url.short_url
227
+ end
228
+ end
229
+
230
+ context "that doesn't exist" do
231
+ setup do
232
+ @shortUrl = 'http://bit.ly/9uX1TEsd'
233
+ stub_get(%r|https://api-ssl\.bit\.ly/v3/expand\?.*shortUrl=http%3A%2F%2Fbit\.ly%2F9uX1TEsd.*|, 'missing_hash.json')
234
+ @url = @client.expand(@shortUrl)
235
+ end
236
+ should 'return a missing url' do
237
+ assert_instance_of BitlyOAuth::MissingUrl, @url
238
+ end
239
+ should 'return an error' do
240
+ assert_equal 'NOT_FOUND', @url.error
241
+ end
242
+ should 'return the original url' do
243
+ assert_equal @shortUrl, @url.short_url
244
+ end
245
+ end
246
+ end
247
+ context "multiple urls" do
248
+ setup do
249
+ @hash = '9uX1TE'
250
+ @short_url = 'http://bit.ly/cEFx9W'
251
+ stub_get("https://api-ssl.bit.ly/v3/expand?hash=9uX1TE&shortUrl=http%3A%2F%2Fbit.ly%2FcEFx9W&access_token=token", 'multiple_urls.json')
252
+ @urls = @client.expand([@hash, @short_url])
253
+ end
254
+ should "return an array of results" do
255
+ assert_instance_of Array, @urls
256
+ end
257
+ should "return an array of bitly urls" do
258
+ @urls.each { |url| assert_instance_of BitlyOAuth::Url, url }
259
+ end
260
+ should "return the original url" do
261
+ assert_equal 'http://betaworks.com/', @urls[0].long_url
262
+ assert_equal 'http://philnash.co.uk', @urls[1].long_url
263
+ end
264
+ end
265
+ end
266
+
267
+ context "clicks for urls" do
268
+ context "with multiple urls" do
269
+ setup do
270
+ @hash = '9uX1TE'
271
+ @short_url = 'http://bit.ly/cEFx9W'
272
+ stub_get("https://api-ssl.bit.ly/v3/clicks?hash=9uX1TE&shortUrl=http%3A%2F%2Fbit.ly%2FcEFx9W&access_token=token", 'multiple_url_click.json')
273
+ @urls = @client.clicks([@hash, @short_url])
274
+ end
275
+
276
+ should "return an array of results" do
277
+ assert_instance_of Array, @urls
278
+ end
279
+ should "return an array of bitly urls" do
280
+ @urls.each { |url| assert_instance_of BitlyOAuth::Url, url }
281
+ end
282
+ should "return the user and global clicks for each url" do
283
+ assert_equal 0, @urls[0].user_clicks
284
+ assert_equal 67, @urls[0].global_clicks
285
+ assert_equal 0, @urls[1].user_clicks
286
+ assert_equal 0, @urls[1].global_clicks
287
+ end
288
+ end
289
+ end
290
+
291
+ context "looking up" do
292
+ context "a single url" do
293
+ setup do
294
+ @url = "http://code.google.com/p/bitly-api/"
295
+ stub_get("https://api-ssl.bit.ly/v3/lookup?url=#{CGI.escape(@url)}&access_token=token", 'lookup_single_url.json')
296
+ @lookup = @client.lookup(@url)
297
+ end
298
+ should "return a url object" do
299
+ assert_instance_of BitlyOAuth::Url, @lookup
300
+ end
301
+ should "return the original url" do
302
+ assert_equal @url, @lookup.long_url
303
+ end
304
+ should "return the global hash" do
305
+ assert_equal '1oDCU', @lookup.global_hash
306
+ end
307
+ should 'return the short url' do
308
+ assert_equal 'http://bit.ly/1oDCU', @lookup.short_url
309
+ end
310
+ end
311
+ context "multiple urls" do
312
+ setup do
313
+ @url1 = 'http://betaworks.com/'
314
+ @url2 = 'http://code.google.com/p/bitly-api/'
315
+ stub_get("https://api-ssl.bit.ly/v3/lookup?url=#{CGI.escape(@url1)}&url=#{CGI.escape(@url2)}&access_token=token", 'lookup_multiple_url.json')
316
+ @lookup = @client.lookup([@url1, @url2])
317
+ end
318
+ should 'return an array' do
319
+ assert_instance_of Array, @lookup
320
+ end
321
+ should 'return an array of urls' do
322
+ @lookup.each { |url| assert_instance_of BitlyOAuth::Url, url }
323
+ end
324
+ should 'return the original urls in order' do
325
+ assert_equal @url1, @lookup[0].long_url
326
+ assert_equal @url2, @lookup[1].long_url
327
+ end
328
+ should 'return global hashes' do
329
+ assert_equal 'aboutus', @lookup[0].global_hash
330
+ assert_equal '1oDCU', @lookup[1].global_hash
331
+ end
332
+ should 'return short urls' do
333
+ assert_equal 'http://bit.ly/aboutus', @lookup[0].short_url
334
+ assert_equal 'http://bit.ly/1oDCU', @lookup[1].short_url
335
+ end
336
+ end
337
+ context "a non existant url" do
338
+ setup do
339
+ @url = "asdf://www.google.com/not/a/real/link"
340
+ stub_get("https://api-ssl.bit.ly/v3/lookup?url=#{CGI.escape(@url)}&access_token=token", 'lookup_not_real_url.json')
341
+ @lookup = @client.lookup(@url)
342
+ end
343
+ should 'return a missing url' do
344
+ assert_instance_of BitlyOAuth::MissingUrl, @lookup
345
+ end
346
+ should 'return the original url' do
347
+ assert_equal @url, @lookup.long_url
348
+ end
349
+ should 'return the error' do
350
+ assert_equal 'NOT_FOUND', @lookup.error
351
+ end
352
+ end
353
+ end
354
+
355
+ context "info for urls" do
356
+ context "a single url" do
357
+ setup do
358
+ @url = "http://bit.ly/1YKMfY"
359
+ stub_get("https://api-ssl.bit.ly/v3/info?shortUrl=#{CGI.escape(@url)}&access_token=token", "url_info.json")
360
+ @info = @client.info(@url)
361
+ end
362
+ should "return a url object" do
363
+ assert_instance_of BitlyOAuth::Url, @info
364
+ end
365
+ should "return the original short url" do
366
+ assert_equal @url, @info.short_url
367
+ end
368
+ should "return the global hash" do
369
+ assert_equal '1YKMfY', @info.global_hash
370
+ end
371
+ should "return the user hash" do
372
+ assert_equal '1YKMfY', @info.user_hash
373
+ end
374
+ should "return the creator" do
375
+ assert_equal 'bitly', @info.created_by
376
+ end
377
+ should "return the title" do
378
+ assert_equal 'betaworks', @info.title
379
+ end
380
+ end
381
+ context "a single hash" do
382
+ setup do
383
+ @hash = "1YKMfY"
384
+ stub_get("https://api-ssl.bit.ly/v3/info?hash=#{@hash}&access_token=token", "url_info.json")
385
+ @info = @client.info(@hash)
386
+ end
387
+ should "return a url object" do
388
+ assert_instance_of BitlyOAuth::Url, @info
389
+ end
390
+ should "return the original short url" do
391
+ assert_equal "http://bit.ly/#{@hash}", @info.short_url
392
+ end
393
+ should "return the global hash" do
394
+ assert_equal @hash, @info.global_hash
395
+ end
396
+ should "return the user hash" do
397
+ assert_equal @hash, @info.user_hash
398
+ end
399
+ should "return the creator" do
400
+ assert_equal 'bitly', @info.created_by
401
+ end
402
+ should "return the title" do
403
+ assert_equal 'betaworks', @info.title
404
+ end
405
+ end
406
+ context "multiple urls with urls and hashes" do
407
+ setup do
408
+ @url = 'http://bit.ly/1YKMfY'
409
+ @hash = '9uX1TE'
410
+ stub_get("https://api-ssl.bit.ly/v3/info?shortUrl=#{CGI.escape(@url)}&hash=#{@hash}&access_token=token", "multiple_info.json")
411
+ @infos = @client.info([@url, @hash])
412
+ end
413
+ should 'return an array' do
414
+ assert_instance_of Array, @infos
415
+ end
416
+ should 'return an array of urls' do
417
+ @infos.each { |url| assert_instance_of BitlyOAuth::Url, url }
418
+ end
419
+ should 'return the original urls in order' do
420
+ assert_equal @url, @infos[0].short_url
421
+ assert_equal @hash, @infos[1].user_hash
422
+ end
423
+ should 'return info for each' do
424
+ assert_equal 'bitly', @infos[0].created_by
425
+ assert_equal 'philnash', @infos[1].created_by
426
+ end
427
+ end
428
+ context "a nonexistant url" do
429
+ setup do
430
+ @url = 'http://bit.ly/1YKMfYasb'
431
+ stub_get("https://api-ssl.bit.ly/v3/info?shortUrl=#{CGI.escape(@url)}&access_token=token", 'not_found_info.json')
432
+ @info = @client.info(@url)
433
+ end
434
+ should "return a missing url" do
435
+ assert_instance_of BitlyOAuth::MissingUrl, @info
436
+ end
437
+ should 'return the original url' do
438
+ assert_equal @url, @info.short_url
439
+ end
440
+ should 'return the error' do
441
+ assert_equal 'NOT_FOUND', @info.error
442
+ end
443
+ end
444
+ end
445
+
446
+ context "referrers for url" do
447
+ context "a single url" do
448
+ setup do
449
+ @url = 'http://bit.ly/djZ9g4'
450
+ stub_get("https://api-ssl.bit.ly/v3/referrers?shortUrl=#{CGI.escape(@url)}&access_token=token", 'referrer_url.json')
451
+ @client_url = @client.referrers(@url)
452
+ end
453
+ should 'return a url object' do
454
+ assert_instance_of BitlyOAuth::Url, @client_url
455
+ end
456
+ should 'return the original short url' do
457
+ assert_equal @url, @client_url.short_url
458
+ end
459
+ should 'return the global hash' do
460
+ assert_equal 'djZ9g4', @client_url.global_hash
461
+ end
462
+ should 'return the user hash' do
463
+ assert_equal 'djZ9g4', @client_url.user_hash
464
+ end
465
+ should 'return an array of referrers' do
466
+ assert_instance_of Array, @client_url.referrers
467
+ end
468
+ should 'return a referrer' do
469
+ assert_instance_of BitlyOAuth::Referrer, @client_url.referrers.first
470
+ end
471
+ should 'return the clicks and referrer from that url' do
472
+ assert_equal 'direct', @client_url.referrers.first.referrer
473
+ assert_equal 62, @client_url.referrers.first.clicks
474
+ end
475
+ end
476
+ context "a single hash" do
477
+ setup do
478
+ @hash = 'djZ9g4'
479
+ stub_get("https://api-ssl.bit.ly/v3/referrers?hash=#{CGI.escape(@hash)}&access_token=token", 'referrer_url.json')
480
+ @client_url = @client.referrers(@hash)
481
+ end
482
+ should 'return a url object' do
483
+ assert_instance_of BitlyOAuth::Url, @client_url
484
+ end
485
+ should 'return the original short url' do
486
+ assert_equal "http://bit.ly/#{@hash}", @client_url.short_url
487
+ end
488
+ should 'return the global hash' do
489
+ assert_equal @hash, @client_url.global_hash
490
+ end
491
+ should 'return the user hash' do
492
+ assert_equal @hash, @client_url.user_hash
493
+ end
494
+ should 'return an array of referrers' do
495
+ assert_instance_of Array, @client_url.referrers
496
+ end
497
+ should 'return a referrer' do
498
+ assert_instance_of BitlyOAuth::Referrer, @client_url.referrers.first
499
+ end
500
+ should 'return the clicks and referrer from that url' do
501
+ assert_equal 'direct', @client_url.referrers.first.referrer
502
+ assert_equal 62, @client_url.referrers.first.clicks
503
+ end
504
+ end
505
+
506
+ context "an array" do
507
+ should "raise an argument error" do
508
+ assert_raises ArgumentError do
509
+ @client.referrers(['http://bit.ly/djZ9g4'])
510
+ end
511
+ end
512
+ end
513
+ end
514
+
515
+ context "countries for url" do
516
+ context "a single url" do
517
+ setup do
518
+ @url = 'http://bit.ly/djZ9g4'
519
+ stub_get("https://api-ssl.bit.ly/v3/countries?shortUrl=#{CGI.escape(@url)}&access_token=token", 'country_url.json')
520
+ @client_url = @client.countries(@url)
521
+ end
522
+ should 'return a url object' do
523
+ assert_instance_of BitlyOAuth::Url, @client_url
524
+ end
525
+ should 'return the original short url' do
526
+ assert_equal @url, @client_url.short_url
527
+ end
528
+ should 'return the global hash' do
529
+ assert_equal 'djZ9g4', @client_url.global_hash
530
+ end
531
+ should 'return the user hash' do
532
+ assert_equal 'djZ9g4', @client_url.user_hash
533
+ end
534
+ should 'return an array of countries' do
535
+ assert_instance_of Array, @client_url.countries
536
+ end
537
+ should 'return a country' do
538
+ assert_instance_of BitlyOAuth::Country, @client_url.countries.first
539
+ end
540
+ should 'return the clicks and country from that url' do
541
+ assert_equal 'US', @client_url.countries.first.country
542
+ assert_equal 58, @client_url.countries.first.clicks
543
+ end
544
+ end
545
+ context "a single hash" do
546
+ setup do
547
+ @hash = 'djZ9g4'
548
+ stub_get("https://api-ssl.bit.ly/v3/countries?hash=#{CGI.escape(@hash)}&access_token=token", 'country_hash.json')
549
+ @client_url = @client.countries(@hash)
550
+ end
551
+ should 'return a url object' do
552
+ assert_instance_of BitlyOAuth::Url, @client_url
553
+ end
554
+ should 'return the original short url' do
555
+ assert_equal "http://bit.ly/#{@hash}", @client_url.short_url
556
+ end
557
+ should 'return the global hash' do
558
+ assert_equal @hash, @client_url.global_hash
559
+ end
560
+ should 'return the user hash' do
561
+ assert_equal @hash, @client_url.user_hash
562
+ end
563
+ should 'return an array of countries' do
564
+ assert_instance_of Array, @client_url.countries
565
+ end
566
+ should 'return a country' do
567
+ assert_instance_of BitlyOAuth::Country, @client_url.countries.first
568
+ end
569
+ should 'return the clicks and country from that url' do
570
+ assert_equal 'US', @client_url.countries.first.country
571
+ assert_equal 58, @client_url.countries.first.clicks
572
+ end
573
+ end
574
+
575
+ context "an array" do
576
+ should "raise an argument error" do
577
+ assert_raises ArgumentError do
578
+ @client.countries(['http://bit.ly/djZ9g4'])
579
+ end
580
+ end
581
+ end
582
+ end
583
+
584
+ context "clicks by minute for urls" do
585
+ context "with a single short url" do
586
+ setup do
587
+ @short_url = "http://j.mp/9DguyN"
588
+ stub_get("https://api-ssl.bit.ly/v3/clicks_by_minute?shortUrl=#{CGI.escape(@short_url)}&access_token=token", 'clicks_by_minute1_url.json')
589
+ @url = @client.clicks_by_minute(@short_url)
590
+ end
591
+ should "return a url object" do
592
+ assert_instance_of BitlyOAuth::Url, @url
593
+ end
594
+ should 'return the original hash' do
595
+ assert_equal "9DguyN", @url.user_hash
596
+ end
597
+ should "return a global hash" do
598
+ assert_equal '9DguyN', @url.global_hash
599
+ end
600
+ should 'return a short url' do
601
+ assert_equal @short_url, @url.short_url
602
+ end
603
+ should 'return an array of clicks by minute' do
604
+ assert_instance_of Array, @url.clicks_by_minute
605
+ assert_equal 0, @url.clicks_by_minute[0]
606
+ assert_equal 1, @url.clicks_by_minute[1]
607
+ end
608
+ end
609
+ context "with a single hash" do
610
+ setup do
611
+ @hash = '9DguyN'
612
+ stub_get("https://api-ssl.bit.ly/v3/clicks_by_minute?hash=#{@hash}&access_token=token", 'clicks_by_minute_hash.json')
613
+ @url = @client.clicks_by_minute(@hash)
614
+ end
615
+ should 'return a url object' do
616
+ assert_instance_of BitlyOAuth::Url, @url
617
+ end
618
+ should 'return the original hash' do
619
+ assert_equal "9DguyN", @url.user_hash
620
+ end
621
+ should "return a global hash" do
622
+ assert_equal '9DguyN', @url.global_hash
623
+ end
624
+ should 'return an array of clicks by minute' do
625
+ assert_instance_of Array, @url.clicks_by_minute
626
+ assert_equal 0, @url.clicks_by_minute[0]
627
+ assert_equal 1, @url.clicks_by_minute[6]
628
+ end
629
+ end
630
+ context "with multiple hashes" do
631
+ setup do
632
+ @hash1 = '9DguyN'
633
+ @hash2 = 'dvxi6W'
634
+ @hashes = [@hash1, @hash2]
635
+ stub_get("https://api-ssl.bit.ly/v3/clicks_by_minute?hash=#{@hash1}&hash=#{@hash2}&access_token=token", 'clicks_by_minute_hashes.json')
636
+ @urls = @client.clicks_by_minute(@hashes)
637
+ end
638
+ should 'return an array of urls' do
639
+ assert_instance_of Array, @urls
640
+ assert_instance_of BitlyOAuth::Url, @urls[0]
641
+ assert_instance_of BitlyOAuth::Url, @urls[1]
642
+ end
643
+ should 'return the original hashes in order' do
644
+ assert_equal @hash1, @urls[0].user_hash
645
+ assert_equal @hash2, @urls[1].user_hash
646
+ end
647
+ should 'return arrays of clicks for each hash' do
648
+ assert_instance_of Array, @urls[0].clicks_by_minute
649
+ assert_instance_of Array, @urls[1].clicks_by_minute
650
+ end
651
+ end
652
+ end
653
+
654
+ context "clicks by day for urls" do
655
+ setup do
656
+ @hash1 = "9DguyN"
657
+ @hash2 = "dvxi6W"
658
+ @hashes = [@hash1, @hash2]
659
+ end
660
+ context "for multiple hashes" do
661
+ setup do
662
+ stub_get("https://api-ssl.bit.ly/v3/clicks_by_day?hash=9DguyN&hash=dvxi6W&access_token=token", 'clicks_by_day.json')
663
+ @urls = @client.clicks_by_day(@hashes)
664
+ end
665
+ should "return an array of urls" do
666
+ assert_instance_of Array, @urls
667
+ assert_instance_of BitlyOAuth::Url, @urls[0]
668
+ assert_instance_of BitlyOAuth::Url, @urls[1]
669
+ end
670
+ should "return an array of days for each url" do
671
+ assert_instance_of Array, @urls[0].clicks_by_day
672
+ assert_instance_of BitlyOAuth::Day, @urls[0].clicks_by_day[0]
673
+ end
674
+ should "return a Time for the day" do
675
+ assert_instance_of Time, @urls[0].clicks_by_day[0].day_start
676
+ assert_equal Time.parse('2010/11/23'), @urls[0].clicks_by_day[0].day_start
677
+ end
678
+ should 'return the number of clicks for that day' do
679
+ assert_equal 1, @urls[0].clicks_by_day[0].clicks
680
+ end
681
+ end
682
+ context "with optional days parameter" do
683
+ should 'add days to url' do
684
+ stub_get("https://api-ssl.bit.ly/v3/clicks_by_day?hash=9DguyN&hash=dvxi6W&access_token=token&days=30", 'clicks_by_day.json')
685
+ @urls = @client.clicks_by_day(@hashes, :days => 30)
686
+ end
687
+
688
+ should 'not add other parameters' do
689
+ stub_get("https://api-ssl.bit.ly/v3/clicks_by_day?hash=9DguyN&hash=dvxi6W&access_token=token&days=30", 'clicks_by_day.json')
690
+ @urls = @client.clicks_by_day(@hashes, :days => 30, :something_else => 'bacon')
691
+ end
692
+ end
693
+ end
694
+ end
695
+
696
+ context "without valid credentials" do
697
+ setup do
698
+ @client = BitlyOAuth::Client.new('rubbish', 'wrong')
699
+ @client.set_access_token_from_token('lies')
700
+ stub_get(%r|https://api-ssl\.bit\.ly/v3/shorten?.*|, 'invalid_credentials.json')
701
+ end
702
+ should "raise an error on any call" do
703
+ assert_raise BitlyOAuth::Error do
704
+ @client.shorten('http://google.com')
705
+ end
706
+ end
707
+ end
708
+ end
709
+ end