bitly-oauth 0.1.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 (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