7digital 0.0.6 → 0.0.7

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 (269) hide show
  1. data/README.rdoc +136 -136
  2. data/lib/sevendigital.rb +53 -53
  3. data/lib/sevendigital/api_operator.rb +130 -130
  4. data/lib/sevendigital/api_operator_cached.rb +41 -41
  5. data/lib/sevendigital/api_request.rb +65 -65
  6. data/lib/sevendigital/client.rb +113 -113
  7. data/lib/sevendigital/client_configuration.rb +86 -86
  8. data/lib/sevendigital/client_digestors.rb +107 -107
  9. data/lib/sevendigital/client_managers.rb +47 -47
  10. data/lib/sevendigital/digestion_tract/api_response_digestor.rb +58 -58
  11. data/lib/sevendigital/digestion_tract/artist_digestor.rb +32 -32
  12. data/lib/sevendigital/digestion_tract/basket_digestor.rb +19 -19
  13. data/lib/sevendigital/digestion_tract/basket_item_digestor.rb +26 -26
  14. data/lib/sevendigital/digestion_tract/chart_item_digestor.rb +28 -28
  15. data/lib/sevendigital/digestion_tract/digestor.rb +71 -71
  16. data/lib/sevendigital/digestion_tract/download_url_digestor.rb +20 -20
  17. data/lib/sevendigital/digestion_tract/format_digestor.rb +22 -22
  18. data/lib/sevendigital/digestion_tract/label_digestor.rb +20 -20
  19. data/lib/sevendigital/digestion_tract/locker_digestor.rb +18 -18
  20. data/lib/sevendigital/digestion_tract/locker_release_digestor.rb +20 -20
  21. data/lib/sevendigital/digestion_tract/locker_track_digestor.rb +22 -22
  22. data/lib/sevendigital/digestion_tract/oauth_access_token_digestor.rb +14 -14
  23. data/lib/sevendigital/digestion_tract/oauth_request_token_digestor.rb +14 -14
  24. data/lib/sevendigital/digestion_tract/pager_digestor.rb +24 -24
  25. data/lib/sevendigital/digestion_tract/price_digestor.rb +25 -25
  26. data/lib/sevendigital/digestion_tract/release_digestor.rb +53 -53
  27. data/lib/sevendigital/digestion_tract/tag_digestor.rb +22 -22
  28. data/lib/sevendigital/digestion_tract/track_digestor.rb +38 -38
  29. data/lib/sevendigital/digestion_tract/user_card_digestor.rb +23 -23
  30. data/lib/sevendigital/digestion_tract/user_digestor.rb +20 -20
  31. data/lib/sevendigital/management/artist_manager.rb +99 -99
  32. data/lib/sevendigital/management/basket_manager.rb +29 -29
  33. data/lib/sevendigital/management/manager.rb +12 -12
  34. data/lib/sevendigital/management/oauth_manager.rb +23 -23
  35. data/lib/sevendigital/management/release_manager.rb +56 -56
  36. data/lib/sevendigital/management/tag_manager.rb +10 -10
  37. data/lib/sevendigital/management/track_manager.rb +28 -28
  38. data/lib/sevendigital/management/user_card_manager.rb +26 -26
  39. data/lib/sevendigital/management/user_manager.rb +71 -71
  40. data/lib/sevendigital/model/api_response.rb +25 -25
  41. data/lib/sevendigital/model/artist.rb +94 -94
  42. data/lib/sevendigital/model/basket.rb +15 -15
  43. data/lib/sevendigital/model/basket_item.rb +14 -14
  44. data/lib/sevendigital/model/card.rb +11 -11
  45. data/lib/sevendigital/model/chart_item.rb +9 -9
  46. data/lib/sevendigital/model/download_url.rb +7 -7
  47. data/lib/sevendigital/model/format.rb +7 -7
  48. data/lib/sevendigital/model/label.rb +7 -7
  49. data/lib/sevendigital/model/locker.rb +4 -4
  50. data/lib/sevendigital/model/locker_release.rb +9 -9
  51. data/lib/sevendigital/model/locker_track.rb +9 -9
  52. data/lib/sevendigital/model/price.rb +9 -9
  53. data/lib/sevendigital/model/release.rb +52 -52
  54. data/lib/sevendigital/model/sevendigital_error.rb +11 -11
  55. data/lib/sevendigital/model/sevendigital_object.rb +57 -57
  56. data/lib/sevendigital/model/tag.rb +7 -7
  57. data/lib/sevendigital/model/track.rb +83 -83
  58. data/lib/sevendigital/model/user.rb +63 -63
  59. data/lib/sevendigital/pager.rb +23 -23
  60. data/lib/sevendigital/peachy_patchy.rb +9 -9
  61. data/lib/sevendigital/proxy_police.rb +27 -27
  62. data/lib/sevendigital/version.rb +5 -5
  63. data/spec/api_operator_cached_spec.rb +178 -178
  64. data/spec/api_operator_spec.rb +336 -336
  65. data/spec/api_request_spec.rb +31 -31
  66. data/spec/client_configuration_spec.rb +79 -74
  67. data/spec/client_spec.rb +162 -162
  68. data/spec/coverage/assets/0.3.9/app.js +66 -0
  69. data/spec/coverage/assets/0.3.9/fancybox/blank.gif +0 -0
  70. data/spec/coverage/assets/0.3.9/fancybox/fancy_close.png +0 -0
  71. data/spec/coverage/assets/0.3.9/fancybox/fancy_loading.png +0 -0
  72. data/spec/coverage/assets/0.3.9/fancybox/fancy_nav_left.png +0 -0
  73. data/spec/coverage/assets/0.3.9/fancybox/fancy_nav_right.png +0 -0
  74. data/spec/coverage/assets/0.3.9/fancybox/fancy_shadow_e.png +0 -0
  75. data/spec/coverage/assets/0.3.9/fancybox/fancy_shadow_n.png +0 -0
  76. data/spec/coverage/assets/0.3.9/fancybox/fancy_shadow_ne.png +0 -0
  77. data/spec/coverage/assets/0.3.9/fancybox/fancy_shadow_nw.png +0 -0
  78. data/spec/coverage/assets/0.3.9/fancybox/fancy_shadow_s.png +0 -0
  79. data/spec/coverage/assets/0.3.9/fancybox/fancy_shadow_se.png +0 -0
  80. data/spec/coverage/assets/0.3.9/fancybox/fancy_shadow_sw.png +0 -0
  81. data/spec/coverage/assets/0.3.9/fancybox/fancy_shadow_w.png +0 -0
  82. data/spec/coverage/assets/0.3.9/fancybox/fancy_title_left.png +0 -0
  83. data/spec/coverage/assets/0.3.9/fancybox/fancy_title_main.png +0 -0
  84. data/spec/coverage/assets/0.3.9/fancybox/fancy_title_over.png +0 -0
  85. data/spec/coverage/assets/0.3.9/fancybox/fancy_title_right.png +0 -0
  86. data/spec/coverage/assets/0.3.9/fancybox/fancybox-x.png +0 -0
  87. data/spec/coverage/assets/0.3.9/fancybox/fancybox-y.png +0 -0
  88. data/spec/coverage/assets/0.3.9/fancybox/fancybox.png +0 -0
  89. data/spec/coverage/assets/0.3.9/fancybox/jquery.fancybox-1.3.1.css +363 -0
  90. data/spec/coverage/assets/0.3.9/fancybox/jquery.fancybox-1.3.1.pack.js +44 -0
  91. data/spec/coverage/assets/0.3.9/favicon.png +0 -0
  92. data/spec/coverage/assets/0.3.9/jquery-1.4.2.min.js +155 -0
  93. data/spec/coverage/assets/0.3.9/jquery.dataTables.min.js +152 -0
  94. data/spec/coverage/assets/0.3.9/jquery.timeago.js +141 -0
  95. data/spec/coverage/assets/0.3.9/jquery.url.js +174 -0
  96. data/spec/coverage/assets/0.3.9/loading.gif +0 -0
  97. data/spec/coverage/assets/0.3.9/magnify.png +0 -0
  98. data/spec/coverage/assets/0.3.9/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  99. data/spec/coverage/assets/0.3.9/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  100. data/spec/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  101. data/spec/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  102. data/spec/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  103. data/spec/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  104. data/spec/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  105. data/spec/coverage/assets/0.3.9/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  106. data/spec/coverage/assets/0.3.9/smoothness/images/ui-icons_222222_256x240.png +0 -0
  107. data/spec/coverage/assets/0.3.9/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  108. data/spec/coverage/assets/0.3.9/smoothness/images/ui-icons_454545_256x240.png +0 -0
  109. data/spec/coverage/assets/0.3.9/smoothness/images/ui-icons_888888_256x240.png +0 -0
  110. data/spec/coverage/assets/0.3.9/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  111. data/spec/coverage/assets/0.3.9/smoothness/jquery-ui-1.8.4.custom.css +295 -0
  112. data/spec/coverage/assets/0.3.9/stylesheet.css +341 -0
  113. data/spec/coverage/index.html +47481 -0
  114. data/spec/coverage/resultset.yml +3556 -0
  115. data/spec/data/config/sevendigital.yml +5 -5
  116. data/spec/data/configuration_env_override.yml +5 -5
  117. data/spec/data/configuration_override.yml +1 -1
  118. data/spec/digestion_tract/api_response_digestor_spec.rb +92 -92
  119. data/spec/digestion_tract/artist_digestor_spec.rb +81 -81
  120. data/spec/digestion_tract/basket_digestor_spec.rb +31 -31
  121. data/spec/digestion_tract/basket_item_digestor_spec.rb +58 -58
  122. data/spec/digestion_tract/chart_digestor_spec.rb +52 -52
  123. data/spec/digestion_tract/download_url_digestor_spec.rb +40 -40
  124. data/spec/digestion_tract/format_digestor_spec.rb +38 -38
  125. data/spec/digestion_tract/label_digestor_spec.rb +33 -33
  126. data/spec/digestion_tract/locker_digestor_spec.rb +30 -30
  127. data/spec/digestion_tract/locker_release_digestor_spec.rb +70 -70
  128. data/spec/digestion_tract/locker_track_digestor_spec.rb +56 -56
  129. data/spec/digestion_tract/oauth_access_token_digestor_spec.rb +34 -34
  130. data/spec/digestion_tract/oauth_request_token_digestor_spec.rb +34 -34
  131. data/spec/digestion_tract/pager_digestor_spec.rb +50 -50
  132. data/spec/digestion_tract/price_digestor_spec.rb +73 -73
  133. data/spec/digestion_tract/release_digestor_spec.rb +101 -101
  134. data/spec/digestion_tract/tag_digestor_spec.rb +46 -46
  135. data/spec/digestion_tract/track_digestor_spec.rb +104 -104
  136. data/spec/digestion_tract/user_card_digestor_spec.rb +58 -58
  137. data/spec/digestion_tract/user_digestor_spec.rb +44 -44
  138. data/spec/management/artist_manager_spec.rb +151 -151
  139. data/spec/management/basket_manager_spec.rb +77 -77
  140. data/spec/management/oauth_manager_spec.rb +72 -72
  141. data/spec/management/release_manager_spec.rb +200 -200
  142. data/spec/management/tag_manager_spec.rb +34 -34
  143. data/spec/management/track_manager_spec.rb +107 -107
  144. data/spec/management/user_card_manager_spec.rb +78 -78
  145. data/spec/management/user_manager_spec.rb +202 -202
  146. data/spec/model/api_response_spec.rb +48 -48
  147. data/spec/model/artist_spec.rb +154 -154
  148. data/spec/model/basket_spec.rb +62 -62
  149. data/spec/model/coverage/assets/0.3.9/app.js +66 -0
  150. data/spec/model/coverage/assets/0.3.9/fancybox/blank.gif +0 -0
  151. data/spec/model/coverage/assets/0.3.9/fancybox/fancy_close.png +0 -0
  152. data/spec/model/coverage/assets/0.3.9/fancybox/fancy_loading.png +0 -0
  153. data/spec/model/coverage/assets/0.3.9/fancybox/fancy_nav_left.png +0 -0
  154. data/spec/model/coverage/assets/0.3.9/fancybox/fancy_nav_right.png +0 -0
  155. data/spec/model/coverage/assets/0.3.9/fancybox/fancy_shadow_e.png +0 -0
  156. data/spec/model/coverage/assets/0.3.9/fancybox/fancy_shadow_n.png +0 -0
  157. data/spec/model/coverage/assets/0.3.9/fancybox/fancy_shadow_ne.png +0 -0
  158. data/spec/model/coverage/assets/0.3.9/fancybox/fancy_shadow_nw.png +0 -0
  159. data/spec/model/coverage/assets/0.3.9/fancybox/fancy_shadow_s.png +0 -0
  160. data/spec/model/coverage/assets/0.3.9/fancybox/fancy_shadow_se.png +0 -0
  161. data/spec/model/coverage/assets/0.3.9/fancybox/fancy_shadow_sw.png +0 -0
  162. data/spec/model/coverage/assets/0.3.9/fancybox/fancy_shadow_w.png +0 -0
  163. data/spec/model/coverage/assets/0.3.9/fancybox/fancy_title_left.png +0 -0
  164. data/spec/model/coverage/assets/0.3.9/fancybox/fancy_title_main.png +0 -0
  165. data/spec/model/coverage/assets/0.3.9/fancybox/fancy_title_over.png +0 -0
  166. data/spec/model/coverage/assets/0.3.9/fancybox/fancy_title_right.png +0 -0
  167. data/spec/model/coverage/assets/0.3.9/fancybox/fancybox-x.png +0 -0
  168. data/spec/model/coverage/assets/0.3.9/fancybox/fancybox-y.png +0 -0
  169. data/spec/model/coverage/assets/0.3.9/fancybox/fancybox.png +0 -0
  170. data/spec/model/coverage/assets/0.3.9/fancybox/jquery.fancybox-1.3.1.css +363 -0
  171. data/spec/model/coverage/assets/0.3.9/fancybox/jquery.fancybox-1.3.1.pack.js +44 -0
  172. data/spec/model/coverage/assets/0.3.9/favicon.png +0 -0
  173. data/spec/model/coverage/assets/0.3.9/jquery-1.4.2.min.js +155 -0
  174. data/spec/model/coverage/assets/0.3.9/jquery.dataTables.min.js +152 -0
  175. data/spec/model/coverage/assets/0.3.9/jquery.timeago.js +141 -0
  176. data/spec/model/coverage/assets/0.3.9/jquery.url.js +174 -0
  177. data/spec/model/coverage/assets/0.3.9/loading.gif +0 -0
  178. data/spec/model/coverage/assets/0.3.9/magnify.png +0 -0
  179. data/spec/model/coverage/assets/0.3.9/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  180. data/spec/model/coverage/assets/0.3.9/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  181. data/spec/model/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  182. data/spec/model/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  183. data/spec/model/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  184. data/spec/model/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  185. data/spec/model/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  186. data/spec/model/coverage/assets/0.3.9/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  187. data/spec/model/coverage/assets/0.3.9/smoothness/images/ui-icons_222222_256x240.png +0 -0
  188. data/spec/model/coverage/assets/0.3.9/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  189. data/spec/model/coverage/assets/0.3.9/smoothness/images/ui-icons_454545_256x240.png +0 -0
  190. data/spec/model/coverage/assets/0.3.9/smoothness/images/ui-icons_888888_256x240.png +0 -0
  191. data/spec/model/coverage/assets/0.3.9/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  192. data/spec/model/coverage/assets/0.3.9/smoothness/jquery-ui-1.8.4.custom.css +295 -0
  193. data/spec/model/coverage/assets/0.3.9/stylesheet.css +341 -0
  194. data/spec/model/coverage/index.html +8637 -0
  195. data/spec/model/coverage/resultset.yml +642 -0
  196. data/spec/model/release_spec.rb +122 -122
  197. data/spec/model/sevendigital_object_spec.rb +73 -73
  198. data/spec/model/track_spec.rb +144 -144
  199. data/spec/model/user_spec.rb +160 -160
  200. data/spec/pager_spec.rb +7 -7
  201. data/spec/peachy_spec_helper_patch.rb +6 -6
  202. data/spec/proxy_police_spec.rb +69 -69
  203. data/spec/sevendigital_spec.rb +51 -70
  204. data/spec/sevendigital_spec.yml +4 -4
  205. data/spec/spec_helper.rb +64 -64
  206. data/spec/test-xml/methods/artist/browse.xml +21 -21
  207. data/spec/test-xml/methods/artist/byTag/top.xml +50 -50
  208. data/spec/test-xml/methods/artist/chart.xml +30 -30
  209. data/spec/test-xml/methods/artist/details.xml +9 -9
  210. data/spec/test-xml/methods/artist/releases.xml +544 -544
  211. data/spec/test-xml/methods/artist/search.xml +18 -18
  212. data/spec/test-xml/methods/artist/similar.xml +39 -39
  213. data/spec/test-xml/methods/artist/tags.xml +11 -11
  214. data/spec/test-xml/methods/artist/toptracks.xml +279 -279
  215. data/spec/test-xml/methods/basket/additem.xml +23 -23
  216. data/spec/test-xml/methods/basket/create.xml +10 -10
  217. data/spec/test-xml/methods/basket/index.xml +23 -23
  218. data/spec/test-xml/methods/basket/removeitem.xml +10 -10
  219. data/spec/test-xml/methods/oauth/accesstoken.xml +5 -5
  220. data/spec/test-xml/methods/oauth/requesttoken.xml +5 -5
  221. data/spec/test-xml/methods/release/bydate.xml +173 -173
  222. data/spec/test-xml/methods/release/bytag/top.xml +150 -150
  223. data/spec/test-xml/methods/release/chart.xml +181 -181
  224. data/spec/test-xml/methods/release/details.xml +48 -48
  225. data/spec/test-xml/methods/release/recommend.xml +89 -89
  226. data/spec/test-xml/methods/release/search.xml +194 -194
  227. data/spec/test-xml/methods/release/tags.xml +27 -27
  228. data/spec/test-xml/methods/release/tracks.xml +28 -28
  229. data/spec/test-xml/methods/tag/index.xml +16 -16
  230. data/spec/test-xml/methods/track/chart.xml +149 -149
  231. data/spec/test-xml/methods/track/details.xml +30 -30
  232. data/spec/test-xml/methods/track/search.xml +159 -159
  233. data/spec/test-xml/methods/user/locker.xml +49 -49
  234. data/spec/test-xml/methods/user/payment/card/add.xml +7 -7
  235. data/spec/test-xml/methods/user/payment/card/index.xml +7 -7
  236. data/spec/test-xml/methods/user/purchase/basket.xml +49 -0
  237. data/spec/test-xml/methods/user/purchase/item.xml +48 -48
  238. data/spec/test-xml/methods/user/signUp.xml +5 -5
  239. data/spec/test-xml/objects/artist.xml +6 -6
  240. data/spec/test-xml/objects/artist_chart_item.xml +7 -7
  241. data/spec/test-xml/objects/artist_list.xml +22 -22
  242. data/spec/test-xml/objects/artist_list_empty.xml +4 -4
  243. data/spec/test-xml/objects/basket.xml +21 -21
  244. data/spec/test-xml/objects/basket_item.xml +11 -11
  245. data/spec/test-xml/objects/basket_item_list.xml +25 -25
  246. data/spec/test-xml/objects/basket_item_list_empty.xml +1 -1
  247. data/spec/test-xml/objects/download_url.xml +7 -7
  248. data/spec/test-xml/objects/locker.xml +47 -47
  249. data/spec/test-xml/objects/locker_release.xml +40 -40
  250. data/spec/test-xml/objects/locker_release_list.xml +87 -87
  251. data/spec/test-xml/objects/locker_release_list_empty.xml +4 -4
  252. data/spec/test-xml/objects/locker_release_one_item_list.xml +43 -43
  253. data/spec/test-xml/objects/locker_track.xml +25 -25
  254. data/spec/test-xml/objects/locker_track_list.xml +26 -26
  255. data/spec/test-xml/objects/locker_track_list_empty.xml +2 -2
  256. data/spec/test-xml/objects/oauth_access_token.xml +3 -3
  257. data/spec/test-xml/objects/oauth_request_token.xml +3 -3
  258. data/spec/test-xml/objects/price.xml +7 -7
  259. data/spec/test-xml/objects/release.xml +40 -40
  260. data/spec/test-xml/objects/release_chart_item.xml +39 -39
  261. data/spec/test-xml/objects/release_list.xml +18 -18
  262. data/spec/test-xml/objects/release_list_empty.xml +4 -4
  263. data/spec/test-xml/objects/response.xml +38 -38
  264. data/spec/test-xml/objects/tag.xml +4 -4
  265. data/spec/test-xml/objects/track.xml +33 -33
  266. data/spec/test-xml/objects/track_chart_item.xml +27 -27
  267. data/spec/test-xml/objects/user.xml +4 -4
  268. data/spec/test-xml/objects/user_payment_card.xml +5 -5
  269. metadata +193 -3
@@ -1,179 +1,179 @@
1
- require "spec_helper"
2
- require 'ostruct'
3
-
4
- describe "ApiOperatorCached" do
5
-
6
- before do
7
- @client = stub(Sevendigital::Client)
8
- @client.stub!(:verbose?).and_return(false)
9
- @client.stub!(:very_verbose?).and_return(false)
10
- @cache = stub(Hash)
11
- @cached_operator = Sevendigital::ApiOperatorCached.new(@client, @cache)
12
- @stub_api_request = stub_api_request()
13
- end
14
-
15
- it "should not look into cache if request requires signature" do
16
- http_response = stub_http_response
17
- @stub_api_request.stub!(:requires_signature?).and_return(true)
18
- @cached_operator.stub(:create_request_uri).and_return("key")
19
- @cache.should_not_receive(:get)
20
- @cached_operator.should_receive(:make_http_request).with(@stub_api_request).and_return(http_response)
21
- @cached_operator.should_receive(:digest_http_response).with(http_response)
22
- @cached_operator.call_api(@stub_api_request)
23
- end
24
-
25
- it "should not cache api response if request was signed" do
26
-
27
- http_response = stub_http_response
28
- @stub_api_request.stub!(:requires_signature?).and_return(true)
29
- @cached_operator.stub(:create_request_uri).and_return("key")
30
-
31
- @cached_operator.stub!(:make_http_request).and_return(http_response)
32
- @cached_operator.stub!(:digest_http_response)
33
- @cache.should_not_receive(:set)
34
- @cached_operator.call_api(@stub_api_request)
35
- end
36
-
37
- it "should not make an http request if response already in cache and not out of date " do
38
- http_response = stub_http_response
39
- @cached_operator.stub(:create_request_uri).and_return("key")
40
- @cache.stub!(:get).with("key").and_return(http_response)
41
- @cached_operator.stub!(:response_out_of_date?).with(http_response).and_return(false)
42
- @cached_operator.should_not_receive(:make_http_request)
43
- @cached_operator.should_receive(:digest_http_response).with(http_response)
44
- @cached_operator.call_api(@stub_api_request)
45
- end
46
-
47
- it "should make an http request if cached response is out of date " do
48
-
49
- expired_http_response = stub_http_response
50
- fresh_http_response = stub_http_response
51
- @cached_operator.stub(:create_request_uri).and_return("key")
52
- @cache.stub!(:get).with("key").and_return(expired_http_response)
53
- @cached_operator.stub!(:response_out_of_date?).with(expired_http_response).and_return(true)
54
-
55
- @cache.stub!(:set).and_return(nil)
56
- @cached_operator.should_receive(:make_http_request).and_return(fresh_http_response)
57
- @cached_operator.should_receive(:digest_http_response).with(fresh_http_response)
58
- @cached_operator.call_api(@stub_api_request)
59
- end
60
-
61
- it "should make an http request if response not yet in cache, digest it and return the result " do
62
- api_response = stub_api_response()
63
- http_response = fake_http_response()
64
-
65
- @cached_operator.stub(:create_request_uri).and_return("key")
66
- @cache.stub!(:get).with("key").and_return(nil)
67
- @cache.stub!(:set).and_return(nil)
68
- @cached_operator.should_receive(:make_http_request).with(@stub_api_request).and_return(http_response)
69
- @cached_operator.should_receive(:digest_http_response).with(http_response).and_return(api_response)
70
-
71
- response = @cached_operator.call_api(@stub_api_request)
72
- response.should == api_response
73
- end
74
-
75
- it "should cache uncached api response if request was not signed" do
76
- http_response = stub_http_response()
77
-
78
- @cached_operator.stub(:create_request_uri).and_return("key")
79
- @cache.stub!(:get).with("key").and_return(nil)
80
- @cached_operator.stub!(:make_http_request).and_return(http_response)
81
- @cached_operator.stub!(:digest_http_response)
82
-
83
- @cache.should_receive(:set).with("key", http_response).and_return(nil)
84
- @cached_operator.call_api(@stub_api_request)
85
- end
86
-
87
- it "response should be out of date if it's past its cache max age" do
88
- now = Time.now.utc
89
- yesterday = now - 24*60*60
90
- max_age = 12*60*60
91
-
92
- http_response = stub_http_response
93
- http_response.stub!(:header).and_return({
94
- "cache-control" => "private, max-age=#{max_age}",
95
- "Date" => yesterday.httpdate
96
- })
97
-
98
- @cached_operator.response_out_of_date?(http_response, now).should == true
99
-
100
- end
101
-
102
-
103
- it "response should not be out of date if it's within its cache max age" do
104
- now = Time.now.utc
105
- yesterday = now - 24*60*60
106
- max_age = 48*60*60
107
-
108
- http_response = stub_http_response
109
- http_response.stub!(:header).and_return({
110
- "cache-control" => "private, max-age=#{max_age}",
111
- "Date" => yesterday.httpdate
112
- })
113
-
114
- @cached_operator.response_out_of_date?(http_response, now).should == false
115
-
116
- end
117
-
118
- it "response should be out of date if it is missing caching headers" do
119
-
120
- http_response = stub_http_response
121
- http_response.stub!(:header).and_return({})
122
- @cached_operator.response_out_of_date?(http_response, Time.now.utc).should == true
123
-
124
- http_response.stub!(:header).and_return({
125
- "Date" => Time.now.utc.httpdate
126
- })
127
- @cached_operator.response_out_of_date?(http_response, Time.now.utc).should == true
128
-
129
- end
130
-
131
- it "response should be out of date if no max-age has been specified" do
132
-
133
- http_response = stub_http_response
134
- http_response.stub!(:header).and_return({"cache-control" => "no-cache", "Date" => Time.now.utc.httpdate})
135
- @cached_operator.response_out_of_date?(http_response, Time.now.utc).should == true
136
-
137
- end
138
-
139
- it "response should be out of date if it is missing Date header" do
140
-
141
- http_response = stub_http_response
142
- http_response.stub!(:header).and_return({"cache-control" => "private, max-age=#{2**30}"})
143
- @cached_operator.response_out_of_date?(http_response, Time.now.utc).should == true
144
-
145
- end
146
-
147
-
148
- def fake_http_response
149
- return Net::HTTP.new("1.1", 200, "response_body")
150
- end
151
-
152
- def stub_http_response
153
- http_response = stub(Net::HTTP)
154
- http_response
155
- end
156
-
157
- def stub_time(time)
158
- Time.stub!(:now).and_return(time)
159
- end
160
-
161
- def stub_api_response
162
- api_response = stub(Sevendigital::ApiResponse)
163
- api_response.stub!(:out_of_date?).and_return(false)
164
- api_response
165
- end
166
-
167
- def stub_api_request
168
- api_request = stub(Sevendigital::ApiRequest)
169
-
170
- api_request.stub!(:parameters).and_return({})
171
- api_request.stub!(:api_service).and_return(nil)
172
- api_request.stub!(:api_method).and_return("m")
173
- api_request.stub!(:requires_signature?).and_return(false)
174
- api_request.stub!(:requires_secure_connection?).and_return(false)
175
- api_request.stub!(:ensure_country_is_set)
176
- return api_request
177
- end
178
-
1
+ require "spec_helper"
2
+ require 'ostruct'
3
+
4
+ describe "ApiOperatorCached" do
5
+
6
+ before do
7
+ @client = stub(Sevendigital::Client)
8
+ @client.stub!(:verbose?).and_return(false)
9
+ @client.stub!(:very_verbose?).and_return(false)
10
+ @cache = stub(Hash)
11
+ @cached_operator = Sevendigital::ApiOperatorCached.new(@client, @cache)
12
+ @stub_api_request = stub_api_request()
13
+ end
14
+
15
+ it "should not look into cache if request requires signature" do
16
+ http_response = stub_http_response
17
+ @stub_api_request.stub!(:requires_signature?).and_return(true)
18
+ @cached_operator.stub(:create_request_uri).and_return("key")
19
+ @cache.should_not_receive(:get)
20
+ @cached_operator.should_receive(:make_http_request).with(@stub_api_request).and_return(http_response)
21
+ @cached_operator.should_receive(:digest_http_response).with(http_response)
22
+ @cached_operator.call_api(@stub_api_request)
23
+ end
24
+
25
+ it "should not cache api response if request was signed" do
26
+
27
+ http_response = stub_http_response
28
+ @stub_api_request.stub!(:requires_signature?).and_return(true)
29
+ @cached_operator.stub(:create_request_uri).and_return("key")
30
+
31
+ @cached_operator.stub!(:make_http_request).and_return(http_response)
32
+ @cached_operator.stub!(:digest_http_response)
33
+ @cache.should_not_receive(:set)
34
+ @cached_operator.call_api(@stub_api_request)
35
+ end
36
+
37
+ it "should not make an http request if response already in cache and not out of date " do
38
+ http_response = stub_http_response
39
+ @cached_operator.stub(:create_request_uri).and_return("key")
40
+ @cache.stub!(:get).with("key").and_return(http_response)
41
+ @cached_operator.stub!(:response_out_of_date?).with(http_response).and_return(false)
42
+ @cached_operator.should_not_receive(:make_http_request)
43
+ @cached_operator.should_receive(:digest_http_response).with(http_response)
44
+ @cached_operator.call_api(@stub_api_request)
45
+ end
46
+
47
+ it "should make an http request if cached response is out of date " do
48
+
49
+ expired_http_response = stub_http_response
50
+ fresh_http_response = stub_http_response
51
+ @cached_operator.stub(:create_request_uri).and_return("key")
52
+ @cache.stub!(:get).with("key").and_return(expired_http_response)
53
+ @cached_operator.stub!(:response_out_of_date?).with(expired_http_response).and_return(true)
54
+
55
+ @cache.stub!(:set).and_return(nil)
56
+ @cached_operator.should_receive(:make_http_request).and_return(fresh_http_response)
57
+ @cached_operator.should_receive(:digest_http_response).with(fresh_http_response)
58
+ @cached_operator.call_api(@stub_api_request)
59
+ end
60
+
61
+ it "should make an http request if response not yet in cache, digest it and return the result " do
62
+ api_response = stub_api_response()
63
+ http_response = fake_http_response()
64
+
65
+ @cached_operator.stub(:create_request_uri).and_return("key")
66
+ @cache.stub!(:get).with("key").and_return(nil)
67
+ @cache.stub!(:set).and_return(nil)
68
+ @cached_operator.should_receive(:make_http_request).with(@stub_api_request).and_return(http_response)
69
+ @cached_operator.should_receive(:digest_http_response).with(http_response).and_return(api_response)
70
+
71
+ response = @cached_operator.call_api(@stub_api_request)
72
+ response.should == api_response
73
+ end
74
+
75
+ it "should cache uncached api response if request was not signed" do
76
+ http_response = stub_http_response()
77
+
78
+ @cached_operator.stub(:create_request_uri).and_return("key")
79
+ @cache.stub!(:get).with("key").and_return(nil)
80
+ @cached_operator.stub!(:make_http_request).and_return(http_response)
81
+ @cached_operator.stub!(:digest_http_response)
82
+
83
+ @cache.should_receive(:set).with("key", http_response).and_return(nil)
84
+ @cached_operator.call_api(@stub_api_request)
85
+ end
86
+
87
+ it "response should be out of date if it's past its cache max age" do
88
+ now = Time.now.utc
89
+ yesterday = now - 24*60*60
90
+ max_age = 12*60*60
91
+
92
+ http_response = stub_http_response
93
+ http_response.stub!(:header).and_return({
94
+ "cache-control" => "private, max-age=#{max_age}",
95
+ "Date" => yesterday.httpdate
96
+ })
97
+
98
+ @cached_operator.response_out_of_date?(http_response, now).should == true
99
+
100
+ end
101
+
102
+
103
+ it "response should not be out of date if it's within its cache max age" do
104
+ now = Time.now.utc
105
+ yesterday = now - 24*60*60
106
+ max_age = 48*60*60
107
+
108
+ http_response = stub_http_response
109
+ http_response.stub!(:header).and_return({
110
+ "cache-control" => "private, max-age=#{max_age}",
111
+ "Date" => yesterday.httpdate
112
+ })
113
+
114
+ @cached_operator.response_out_of_date?(http_response, now).should == false
115
+
116
+ end
117
+
118
+ it "response should be out of date if it is missing caching headers" do
119
+
120
+ http_response = stub_http_response
121
+ http_response.stub!(:header).and_return({})
122
+ @cached_operator.response_out_of_date?(http_response, Time.now.utc).should == true
123
+
124
+ http_response.stub!(:header).and_return({
125
+ "Date" => Time.now.utc.httpdate
126
+ })
127
+ @cached_operator.response_out_of_date?(http_response, Time.now.utc).should == true
128
+
129
+ end
130
+
131
+ it "response should be out of date if no max-age has been specified" do
132
+
133
+ http_response = stub_http_response
134
+ http_response.stub!(:header).and_return({"cache-control" => "no-cache", "Date" => Time.now.utc.httpdate})
135
+ @cached_operator.response_out_of_date?(http_response, Time.now.utc).should == true
136
+
137
+ end
138
+
139
+ it "response should be out of date if it is missing Date header" do
140
+
141
+ http_response = stub_http_response
142
+ http_response.stub!(:header).and_return({"cache-control" => "private, max-age=#{2**30}"})
143
+ @cached_operator.response_out_of_date?(http_response, Time.now.utc).should == true
144
+
145
+ end
146
+
147
+
148
+ def fake_http_response
149
+ return Net::HTTP.new("1.1", 200, "response_body")
150
+ end
151
+
152
+ def stub_http_response
153
+ http_response = stub(Net::HTTP)
154
+ http_response
155
+ end
156
+
157
+ def stub_time(time)
158
+ Time.stub!(:now).and_return(time)
159
+ end
160
+
161
+ def stub_api_response
162
+ api_response = stub(Sevendigital::ApiResponse)
163
+ api_response.stub!(:out_of_date?).and_return(false)
164
+ api_response
165
+ end
166
+
167
+ def stub_api_request
168
+ api_request = stub(Sevendigital::ApiRequest)
169
+
170
+ api_request.stub!(:parameters).and_return({})
171
+ api_request.stub!(:api_service).and_return(nil)
172
+ api_request.stub!(:api_method).and_return("m")
173
+ api_request.stub!(:requires_signature?).and_return(false)
174
+ api_request.stub!(:requires_secure_connection?).and_return(false)
175
+ api_request.stub!(:ensure_country_is_set)
176
+ return api_request
177
+ end
178
+
179
179
  end
@@ -1,337 +1,337 @@
1
- require "spec_helper"
2
- require 'ostruct'
3
- require 'oauth'
4
-
5
- describe "ApiOperator" do
6
-
7
- before do
8
- response_digestor = stub(Sevendigital::ApiResponseDigestor)
9
- response_digestor.stub!(:from_http_response). and_return(fake_digested_response)
10
-
11
- stub_api_client(test_configuration, response_digestor)
12
-
13
- Net::HTTP.stub!(:get_response).and_return(fake_api_response)
14
-
15
- @api_operator = Sevendigital::ApiOperator.new(@client)
16
-
17
- @stub_api_request = stub_api_request()
18
-
19
- end
20
-
21
- it "should create http request uri based on api method and client configuration" do
22
-
23
- api_request = Sevendigital::ApiRequest.new(:GET, "api/method", {:param1 => "value", :paramTwo => 2})
24
-
25
- uri = @api_operator.create_request_uri(api_request)
26
-
27
- uri.kind_of?(URI).should == true
28
-
29
- uri.to_s.should =~ /http:\/\/base.api.url\/version\/api\/method/
30
- uri.to_s.should =~ /[\?\&]param1=value/
31
- uri.to_s.should =~ /[\?\&]paramTwo=2/
32
-
33
- end
34
-
35
- it "should URL encode parameters accourding to OAuth spec" do
36
-
37
- api_request = Sevendigital::ApiRequest.new(:GET, "api/method", {:param1 => "a+b@c.d", :paramTwo => "<a b>"})
38
-
39
- uri = @api_operator.create_request_uri(api_request)
40
-
41
- uri.to_s.should =~ /[\?\&]param1=a%2Bb%40c.d/
42
- uri.to_s.should =~ /[\?\&]paramTwo=%3Ca%20b%3E/
43
-
44
- end
45
-
46
- it "should create http GET request" do
47
-
48
- api_request = Sevendigital::ApiRequest.new(:GET, "api/method", {:param1 => "value", :paramTwo => 2})
49
-
50
- client, request = @api_operator.create_http_request(api_request)
51
-
52
- request.class.should == Net::HTTP::Get
53
-
54
- end
55
-
56
- it "should create http POST request" do
57
-
58
- api_request = Sevendigital::ApiRequest.new(:POST, "api/method", {:param1 => "value", :paramTwo => 2})
59
-
60
- client, request = @api_operator.create_http_request(api_request)
61
-
62
- request.class.should == Net::HTTP::Post
63
-
64
- end
65
-
66
- it "should create http DELETE request" do
67
-
68
- api_request = Sevendigital::ApiRequest.new(:DELETE, "api/method", {:param1 => "value", :paramTwo => 2})
69
-
70
- client, request = @api_operator.create_http_request(api_request)
71
-
72
- request.class.should == Net::HTTP::Delete
73
-
74
- end
75
-
76
- it "should create http PUT request" do
77
-
78
- api_request = Sevendigital::ApiRequest.new(:PUT, "api/method", {:param1 => "value", :paramTwo => 2})
79
-
80
- client, request = @api_operator.create_http_request(api_request)
81
-
82
- request.class.should == Net::HTTP::Put
83
-
84
- end
85
-
86
- it "should have empty body if no form parameters provided" do
87
-
88
- api_request = Sevendigital::ApiRequest.new(:GET, "api/method", {:param1 => "value", :paramTwo => 2})
89
-
90
- client, request = @api_operator.create_http_request(api_request)
91
-
92
- request.instance_variable_get("@body").empty?.should == true
93
-
94
- end
95
-
96
- it "should set up any form parameters in body" do
97
-
98
- api_request = Sevendigital::ApiRequest.new(:GET, "api/method", {:param1 => "value", :paramTwo => 2})
99
- api_request.form_parameters[:shop_id] = "1234"
100
- api_request.form_parameters[:email] = "test+email@example.com"
101
- api_request.form_parameters[:ignore] = nil
102
-
103
- client, request = @api_operator.create_http_request(api_request)
104
-
105
- #request.instance_variable_get("@body").should == "email=test%40example.com&shopId=1234"
106
- request.instance_variable_get("@body").should =~ /email=test%2Bemail%40example.com/
107
- request.instance_variable_get("@body").should =~ /shopId=1234/
108
- end
109
-
110
- it "should create HTTPS request uri based on api method that requires secure connection and client configuration" do
111
-
112
- api_request = Sevendigital::ApiRequest.new(:GET, "api/method", {:param1 => "value", :paramTwo => 2})
113
- api_request.require_secure_connection
114
-
115
- uri = @api_operator.create_request_uri(api_request)
116
-
117
- uri.kind_of?(URI).should == true
118
-
119
- uri.to_s.should =~ /https:\/\/base.api.url\/version\/api\/method/
120
- uri.to_s.should =~ /[\?\&]param1=value/
121
- uri.to_s.should =~ /[\?\&]paramTwo=2/
122
-
123
- end
124
-
125
- it "should create http request uri based on api method for non standard api service" do
126
-
127
- @client.should_receive(:api_host_and_version).with(:media).and_return(["media-base.api.url","media-version"])
128
-
129
- api_request = Sevendigital::ApiRequest.new(:GET, "api/method", {:param1 => "value", :paramTwo => 2})
130
- api_request.api_service = :media
131
- uri = @api_operator.create_request_uri(api_request)
132
-
133
- uri.kind_of?(URI).should == true
134
-
135
- uri.to_s.should =~ /http:\/\/media-base.api.url\/media-version\/api\/method/
136
- uri.to_s.should =~ /[\?\&]param1=value/
137
- uri.to_s.should =~ /[\?\&]paramTwo=2/
138
-
139
- end
140
-
141
- it "should make HTTP request and get http response" do
142
-
143
- http_response = fake_api_response
144
-
145
- @stub_http_request = stub(Net::HTTP::Get)
146
- @stub_http_client = stub(Net::HTTP)
147
-
148
- @api_operator.should_receive(:create_http_request).with(@stub_api_request).and_return([@stub_http_client, @stub_http_request])
149
-
150
- @stub_http_client.should_receive(:request).with(@stub_http_request).and_return(http_response)
151
-
152
- response = @api_operator.make_http_request(@stub_api_request)
153
-
154
- response.should == http_response
155
-
156
- end
157
-
158
- it "should digest the HTTP response and get it out" do
159
-
160
- http_response = fake_api_response
161
- digested_response = fake_digested_response
162
-
163
- @client.api_response_digestor.should_receive(:from_http_response).with(http_response).and_return(digested_response)
164
-
165
- response = @api_operator.digest_http_response(http_response)
166
-
167
- response.should == digested_response
168
-
169
- end
170
-
171
- it "should call API by making an http request and digesting the response" do
172
-
173
- http_response = fake_api_response
174
- digested_response = fake_digested_response
175
-
176
- @api_operator.should_receive(:make_http_request).and_return(http_response)
177
-
178
- @client.api_response_digestor.should_receive(:from_http_response).with(http_response).and_return(digested_response)
179
-
180
- response = @api_operator.call_api(@stub_api_request)
181
-
182
- response.should == digested_response
183
-
184
- end
185
-
186
- it "should throw an exception if response is not ok" do
187
-
188
- failed_response = fake_digested_response(false)
189
- failed_response.stub!(:error_code).and_return(4000)
190
- failed_response.stub!(:error_message).and_return("error")
191
- @api_operator.should_receive(:make_http_request).and_return(fake_api_response)
192
- @client.api_response_digestor.stub!(:from_http_response).and_return(failed_response)
193
-
194
- running { @api_operator.call_api(@stub_api_request) }.should raise_error(Sevendigital::SevendigitalError) { |error|
195
- error.error_code.should == 4000
196
- error.error_message.should == "error"
197
- }
198
-
199
- end
200
-
201
- it "should create a 2-legged signed HTTP request" do
202
- api_request = Sevendigital::ApiRequest.new(:GET, "api/method", {:param1 => "value", :paramTwo => 2})
203
- api_request.require_signature
204
- http_client, http_request = @api_operator.create_http_request(api_request)
205
- http_client.use_ssl?.should == false
206
- http_request.path.should =~ /api\/method/
207
- http_request.path.should =~ /param1=value/
208
- http_request["Authorization"].should =~ /OAuth oauth_consumer_key="oauth_consumer_key"/
209
- http_request["Authorization"].should =~ / oauth_signature=/
210
- # http_request["Authorization"].should !=~ / oauth_token="token"/
211
- end
212
-
213
- it "should create a 3-legged signed HTTP request" do
214
- api_request = Sevendigital::ApiRequest.new(:GET, "api/method", {:param1 => "value", :paramTwo => 2})
215
- api_request.require_signature
216
- api_request.token = OAuth::AccessToken.new(@client.oauth_consumer, "token", "secret")
217
- http_client, http_request = @api_operator.create_http_request(api_request)
218
- http_client.use_ssl?.should == false
219
- http_request.path.should =~ /api\/method/
220
- http_request.path.should =~ /param1=value/
221
- http_request["Authorization"].should =~ /OAuth oauth_consumer_key="oauth_consumer_key"/
222
- http_request["Authorization"].should =~ / oauth_signature=/
223
- http_request["Authorization"].should =~ / oauth_token="token"/
224
- end
225
-
226
- it "should create a 3-legged signed HTTPS request" do
227
- api_request = Sevendigital::ApiRequest.new(:GET, "api/method", {:param1 => "value", :paramTwo => 2})
228
- api_request.require_signature
229
- api_request.require_secure_connection
230
- api_request.token = OAuth::AccessToken.new(@client.oauth_consumer, "token", "secret")
231
- http_client, http_request = @api_operator.create_http_request(api_request)
232
- http_client.inspect.should =~ /base\.api\.url:443/
233
- http_client.use_ssl?.should == true
234
- http_client.verify_mode.should == OpenSSL::SSL::VERIFY_NONE
235
- http_request.path.should =~ /api\/method/
236
- http_request.path.should =~ /param1=value/
237
- http_request["Authorization"].should =~ /OAuth oauth_consumer_key="oauth_consumer_key"/
238
- http_request["Authorization"].should =~ / oauth_signature=/
239
- http_request["Authorization"].should =~ / oauth_token="token"/
240
- end
241
-
242
- it "should create a standard HTTP request" do
243
- api_request = Sevendigital::ApiRequest.new(:GET, "api/method", {:param1 => "value", :paramTwo => 2})
244
- http_client, http_request = @api_operator.create_http_request(api_request)
245
- http_client.inspect.should =~ /base\.api\.url:80/
246
- http_client.use_ssl?.should == false
247
- http_request.path.should =~ /api\/method/
248
- http_request.path.should =~ /param1=value/
249
- http_request.path.should =~ /oauth_consumer_key=oauth_consumer_key/
250
- end
251
-
252
- it "should add custom user agent info to created HTTP request" do
253
-
254
- @client.stub!(:user_agent_info).and_return("7digital Gem")
255
-
256
- api_request = Sevendigital::ApiRequest.new(:GET, "api/method", {:param1 => "value", :paramTwo => 2})
257
- http_client, http_request = @api_operator.create_http_request(api_request)
258
- http_request["User-agent"].should =~ /7digital Gem/
259
- end
260
-
261
- it "get_request_uri should return oauth sign URI if api request requires signature" do
262
-
263
- api_request = Sevendigital::ApiRequest.new(:GET, "api/method", {:param1 => "value", :paramTwo => 2})
264
- api_request.token = OAuth::AccessToken.new(nil, "token", "token_secret")
265
- api_request.require_signature
266
- api_request.require_secure_connection
267
- signed_uri = @api_operator.get_request_uri(api_request)
268
-
269
- signed_uri.should =~ /oauth_signature=/
270
- signed_uri.should =~ /oauth_consumer_key=oauth_consumer_key&/
271
- signed_uri.should =~ /oauth_token=token&/
272
- signed_uri.should =~ /https:\/\/base.api.url\/version\/api\/method/
273
- end
274
-
275
- it "get_request_uri should return simple request URI if api request does not require signature" do
276
-
277
- api_request = Sevendigital::ApiRequest.new(:GET, "api/method", {:param1 => "value", :paramTwo => 2})
278
- signed_uri = @api_operator.get_request_uri(api_request)
279
-
280
- signed_uri.match(/oauth_signature=/).should == nil
281
- signed_uri.should =~ /oauth_consumer_key=oauth_consumer_key/
282
- signed_uri.should =~ /http:\/\/base.api.url\/version\/api\/method/
283
- end
284
-
285
- it "get_request_uri should return secure request URI if api request does not require signature" do
286
-
287
- api_request = Sevendigital::ApiRequest.new(:GET, "api/method", {:param1 => "value", :paramTwo => 2})
288
- api_request.require_secure_connection
289
- signed_uri = @api_operator.get_request_uri(api_request)
290
-
291
- signed_uri.match(/oauth_signature=/).should == nil
292
- signed_uri.should =~ /oauth_consumer_key=oauth_consumer_key/
293
- signed_uri.should =~ /https:\/\/base.api.url\/version\/api\/method/
294
- end
295
-
296
- def test_configuration
297
- configuration = OpenStruct.new
298
- configuration.oauth_consumer_key = "oauth_consumer_key"
299
- return configuration
300
- end
301
-
302
- def fake_api_response(code = 200, body = "response_body")
303
- return Net::HTTP.new("1.1", code, body)
304
- end
305
-
306
- def fake_digested_response(is_ok = true)
307
- proxy = stub(Peachy::Proxy)#.new('<response status="ok"><content>test</content></response>')
308
- proxy.stub!(:ok?).and_return(is_ok)
309
- proxy
310
- end
311
-
312
- def stub_api_client(configuration, response_digestor)
313
- @client = stub(Sevendigital::Client)
314
- @client.stub!(:configuration).and_return(configuration)
315
- @client.stub!(:oauth_consumer).and_return(OAuth::Consumer.new( configuration.oauth_consumer_key, configuration.oauth_consumer_secret))
316
- @client.stub!(:api_response_digestor).and_return(response_digestor)
317
- @client.stub!(:default_parameters).and_return({:country => 'sk'})
318
- @client.stub!(:user_agent_info).and_return("7digital")
319
- @client.stub!(:verbose?).and_return(false)
320
- @client.stub!(:very_verbose?).and_return(false)
321
- @client.stub!(:api_host_and_version).and_return(["base.api.url","version"])
322
-
323
- end
324
-
325
- def stub_api_request
326
- api_request = stub(Sevendigital::ApiRequest)
327
-
328
- api_request.stub!(:parameters).and_return({})
329
- api_request.stub!(:api_service).and_return(nil)
330
- api_request.stub!(:api_method).and_return("m")
331
- api_request.stub!(:requires_signature?).and_return(false)
332
- api_request.stub!(:requires_secure_connection?).and_return(false)
333
- api_request.stub!(:ensure_country_is_set)
334
- return api_request
335
- end
336
-
1
+ require "spec_helper"
2
+ require 'ostruct'
3
+ require 'oauth'
4
+
5
+ describe "ApiOperator" do
6
+
7
+ before do
8
+ response_digestor = stub(Sevendigital::ApiResponseDigestor)
9
+ response_digestor.stub!(:from_http_response). and_return(fake_digested_response)
10
+
11
+ stub_api_client(test_configuration, response_digestor)
12
+
13
+ Net::HTTP.stub!(:get_response).and_return(fake_api_response)
14
+
15
+ @api_operator = Sevendigital::ApiOperator.new(@client)
16
+
17
+ @stub_api_request = stub_api_request()
18
+
19
+ end
20
+
21
+ it "should create http request uri based on api method and client configuration" do
22
+
23
+ api_request = Sevendigital::ApiRequest.new(:GET, "api/method", {:param1 => "value", :paramTwo => 2})
24
+
25
+ uri = @api_operator.create_request_uri(api_request)
26
+
27
+ uri.kind_of?(URI).should == true
28
+
29
+ uri.to_s.should =~ /http:\/\/base.api.url\/version\/api\/method/
30
+ uri.to_s.should =~ /[\?\&]param1=value/
31
+ uri.to_s.should =~ /[\?\&]paramTwo=2/
32
+
33
+ end
34
+
35
+ it "should URL encode parameters accourding to OAuth spec" do
36
+
37
+ api_request = Sevendigital::ApiRequest.new(:GET, "api/method", {:param1 => "a+b@c.d", :paramTwo => "<a b>"})
38
+
39
+ uri = @api_operator.create_request_uri(api_request)
40
+
41
+ uri.to_s.should =~ /[\?\&]param1=a%2Bb%40c.d/
42
+ uri.to_s.should =~ /[\?\&]paramTwo=%3Ca%20b%3E/
43
+
44
+ end
45
+
46
+ it "should create http GET request" do
47
+
48
+ api_request = Sevendigital::ApiRequest.new(:GET, "api/method", {:param1 => "value", :paramTwo => 2})
49
+
50
+ client, request = @api_operator.create_http_request(api_request)
51
+
52
+ request.class.should == Net::HTTP::Get
53
+
54
+ end
55
+
56
+ it "should create http POST request" do
57
+
58
+ api_request = Sevendigital::ApiRequest.new(:POST, "api/method", {:param1 => "value", :paramTwo => 2})
59
+
60
+ client, request = @api_operator.create_http_request(api_request)
61
+
62
+ request.class.should == Net::HTTP::Post
63
+
64
+ end
65
+
66
+ it "should create http DELETE request" do
67
+
68
+ api_request = Sevendigital::ApiRequest.new(:DELETE, "api/method", {:param1 => "value", :paramTwo => 2})
69
+
70
+ client, request = @api_operator.create_http_request(api_request)
71
+
72
+ request.class.should == Net::HTTP::Delete
73
+
74
+ end
75
+
76
+ it "should create http PUT request" do
77
+
78
+ api_request = Sevendigital::ApiRequest.new(:PUT, "api/method", {:param1 => "value", :paramTwo => 2})
79
+
80
+ client, request = @api_operator.create_http_request(api_request)
81
+
82
+ request.class.should == Net::HTTP::Put
83
+
84
+ end
85
+
86
+ it "should have empty body if no form parameters provided" do
87
+
88
+ api_request = Sevendigital::ApiRequest.new(:GET, "api/method", {:param1 => "value", :paramTwo => 2})
89
+
90
+ client, request = @api_operator.create_http_request(api_request)
91
+
92
+ request.instance_variable_get("@body").empty?.should == true
93
+
94
+ end
95
+
96
+ it "should set up any form parameters in body" do
97
+
98
+ api_request = Sevendigital::ApiRequest.new(:GET, "api/method", {:param1 => "value", :paramTwo => 2})
99
+ api_request.form_parameters[:shop_id] = "1234"
100
+ api_request.form_parameters[:email] = "test+email@example.com"
101
+ api_request.form_parameters[:ignore] = nil
102
+
103
+ client, request = @api_operator.create_http_request(api_request)
104
+
105
+ #request.instance_variable_get("@body").should == "email=test%40example.com&shopId=1234"
106
+ request.instance_variable_get("@body").should =~ /email=test%2Bemail%40example.com/
107
+ request.instance_variable_get("@body").should =~ /shopId=1234/
108
+ end
109
+
110
+ it "should create HTTPS request uri based on api method that requires secure connection and client configuration" do
111
+
112
+ api_request = Sevendigital::ApiRequest.new(:GET, "api/method", {:param1 => "value", :paramTwo => 2})
113
+ api_request.require_secure_connection
114
+
115
+ uri = @api_operator.create_request_uri(api_request)
116
+
117
+ uri.kind_of?(URI).should == true
118
+
119
+ uri.to_s.should =~ /https:\/\/base.api.url\/version\/api\/method/
120
+ uri.to_s.should =~ /[\?\&]param1=value/
121
+ uri.to_s.should =~ /[\?\&]paramTwo=2/
122
+
123
+ end
124
+
125
+ it "should create http request uri based on api method for non standard api service" do
126
+
127
+ @client.should_receive(:api_host_and_version).with(:media).and_return(["media-base.api.url","media-version"])
128
+
129
+ api_request = Sevendigital::ApiRequest.new(:GET, "api/method", {:param1 => "value", :paramTwo => 2})
130
+ api_request.api_service = :media
131
+ uri = @api_operator.create_request_uri(api_request)
132
+
133
+ uri.kind_of?(URI).should == true
134
+
135
+ uri.to_s.should =~ /http:\/\/media-base.api.url\/media-version\/api\/method/
136
+ uri.to_s.should =~ /[\?\&]param1=value/
137
+ uri.to_s.should =~ /[\?\&]paramTwo=2/
138
+
139
+ end
140
+
141
+ it "should make HTTP request and get http response" do
142
+
143
+ http_response = fake_api_response
144
+
145
+ @stub_http_request = stub(Net::HTTP::Get)
146
+ @stub_http_client = stub(Net::HTTP)
147
+
148
+ @api_operator.should_receive(:create_http_request).with(@stub_api_request).and_return([@stub_http_client, @stub_http_request])
149
+
150
+ @stub_http_client.should_receive(:request).with(@stub_http_request).and_return(http_response)
151
+
152
+ response = @api_operator.make_http_request(@stub_api_request)
153
+
154
+ response.should == http_response
155
+
156
+ end
157
+
158
+ it "should digest the HTTP response and get it out" do
159
+
160
+ http_response = fake_api_response
161
+ digested_response = fake_digested_response
162
+
163
+ @client.api_response_digestor.should_receive(:from_http_response).with(http_response).and_return(digested_response)
164
+
165
+ response = @api_operator.digest_http_response(http_response)
166
+
167
+ response.should == digested_response
168
+
169
+ end
170
+
171
+ it "should call API by making an http request and digesting the response" do
172
+
173
+ http_response = fake_api_response
174
+ digested_response = fake_digested_response
175
+
176
+ @api_operator.should_receive(:make_http_request).and_return(http_response)
177
+
178
+ @client.api_response_digestor.should_receive(:from_http_response).with(http_response).and_return(digested_response)
179
+
180
+ response = @api_operator.call_api(@stub_api_request)
181
+
182
+ response.should == digested_response
183
+
184
+ end
185
+
186
+ it "should throw an exception if response is not ok" do
187
+
188
+ failed_response = fake_digested_response(false)
189
+ failed_response.stub!(:error_code).and_return(4000)
190
+ failed_response.stub!(:error_message).and_return("error")
191
+ @api_operator.should_receive(:make_http_request).and_return(fake_api_response)
192
+ @client.api_response_digestor.stub!(:from_http_response).and_return(failed_response)
193
+
194
+ running { @api_operator.call_api(@stub_api_request) }.should raise_error(Sevendigital::SevendigitalError) { |error|
195
+ error.error_code.should == 4000
196
+ error.error_message.should == "error"
197
+ }
198
+
199
+ end
200
+
201
+ it "should create a 2-legged signed HTTP request" do
202
+ api_request = Sevendigital::ApiRequest.new(:GET, "api/method", {:param1 => "value", :paramTwo => 2})
203
+ api_request.require_signature
204
+ http_client, http_request = @api_operator.create_http_request(api_request)
205
+ http_client.use_ssl?.should == false
206
+ http_request.path.should =~ /api\/method/
207
+ http_request.path.should =~ /param1=value/
208
+ http_request["Authorization"].should =~ /OAuth oauth_consumer_key="oauth_consumer_key"/
209
+ http_request["Authorization"].should =~ / oauth_signature=/
210
+ # http_request["Authorization"].should !=~ / oauth_token="token"/
211
+ end
212
+
213
+ it "should create a 3-legged signed HTTP request" do
214
+ api_request = Sevendigital::ApiRequest.new(:GET, "api/method", {:param1 => "value", :paramTwo => 2})
215
+ api_request.require_signature
216
+ api_request.token = OAuth::AccessToken.new(@client.oauth_consumer, "token", "secret")
217
+ http_client, http_request = @api_operator.create_http_request(api_request)
218
+ http_client.use_ssl?.should == false
219
+ http_request.path.should =~ /api\/method/
220
+ http_request.path.should =~ /param1=value/
221
+ http_request["Authorization"].should =~ /OAuth oauth_consumer_key="oauth_consumer_key"/
222
+ http_request["Authorization"].should =~ / oauth_signature=/
223
+ http_request["Authorization"].should =~ / oauth_token="token"/
224
+ end
225
+
226
+ it "should create a 3-legged signed HTTPS request" do
227
+ api_request = Sevendigital::ApiRequest.new(:GET, "api/method", {:param1 => "value", :paramTwo => 2})
228
+ api_request.require_signature
229
+ api_request.require_secure_connection
230
+ api_request.token = OAuth::AccessToken.new(@client.oauth_consumer, "token", "secret")
231
+ http_client, http_request = @api_operator.create_http_request(api_request)
232
+ http_client.inspect.should =~ /base\.api\.url:443/
233
+ http_client.use_ssl?.should == true
234
+ http_client.verify_mode.should == OpenSSL::SSL::VERIFY_NONE
235
+ http_request.path.should =~ /api\/method/
236
+ http_request.path.should =~ /param1=value/
237
+ http_request["Authorization"].should =~ /OAuth oauth_consumer_key="oauth_consumer_key"/
238
+ http_request["Authorization"].should =~ / oauth_signature=/
239
+ http_request["Authorization"].should =~ / oauth_token="token"/
240
+ end
241
+
242
+ it "should create a standard HTTP request" do
243
+ api_request = Sevendigital::ApiRequest.new(:GET, "api/method", {:param1 => "value", :paramTwo => 2})
244
+ http_client, http_request = @api_operator.create_http_request(api_request)
245
+ http_client.inspect.should =~ /base\.api\.url:80/
246
+ http_client.use_ssl?.should == false
247
+ http_request.path.should =~ /api\/method/
248
+ http_request.path.should =~ /param1=value/
249
+ http_request.path.should =~ /oauth_consumer_key=oauth_consumer_key/
250
+ end
251
+
252
+ it "should add custom user agent info to created HTTP request" do
253
+
254
+ @client.stub!(:user_agent_info).and_return("7digital Gem")
255
+
256
+ api_request = Sevendigital::ApiRequest.new(:GET, "api/method", {:param1 => "value", :paramTwo => 2})
257
+ http_client, http_request = @api_operator.create_http_request(api_request)
258
+ http_request["User-agent"].should =~ /7digital Gem/
259
+ end
260
+
261
+ it "get_request_uri should return oauth sign URI if api request requires signature" do
262
+
263
+ api_request = Sevendigital::ApiRequest.new(:GET, "api/method", {:param1 => "value", :paramTwo => 2})
264
+ api_request.token = OAuth::AccessToken.new(nil, "token", "token_secret")
265
+ api_request.require_signature
266
+ api_request.require_secure_connection
267
+ signed_uri = @api_operator.get_request_uri(api_request)
268
+
269
+ signed_uri.should =~ /oauth_signature=/
270
+ signed_uri.should =~ /oauth_consumer_key=oauth_consumer_key&/
271
+ signed_uri.should =~ /oauth_token=token&/
272
+ signed_uri.should =~ /https:\/\/base.api.url\/version\/api\/method/
273
+ end
274
+
275
+ it "get_request_uri should return simple request URI if api request does not require signature" do
276
+
277
+ api_request = Sevendigital::ApiRequest.new(:GET, "api/method", {:param1 => "value", :paramTwo => 2})
278
+ signed_uri = @api_operator.get_request_uri(api_request)
279
+
280
+ signed_uri.match(/oauth_signature=/).should == nil
281
+ signed_uri.should =~ /oauth_consumer_key=oauth_consumer_key/
282
+ signed_uri.should =~ /http:\/\/base.api.url\/version\/api\/method/
283
+ end
284
+
285
+ it "get_request_uri should return secure request URI if api request does not require signature" do
286
+
287
+ api_request = Sevendigital::ApiRequest.new(:GET, "api/method", {:param1 => "value", :paramTwo => 2})
288
+ api_request.require_secure_connection
289
+ signed_uri = @api_operator.get_request_uri(api_request)
290
+
291
+ signed_uri.match(/oauth_signature=/).should == nil
292
+ signed_uri.should =~ /oauth_consumer_key=oauth_consumer_key/
293
+ signed_uri.should =~ /https:\/\/base.api.url\/version\/api\/method/
294
+ end
295
+
296
+ def test_configuration
297
+ configuration = OpenStruct.new
298
+ configuration.oauth_consumer_key = "oauth_consumer_key"
299
+ return configuration
300
+ end
301
+
302
+ def fake_api_response(code = 200, body = "response_body")
303
+ return Net::HTTP.new("1.1", code, body)
304
+ end
305
+
306
+ def fake_digested_response(is_ok = true)
307
+ proxy = stub(Peachy::Proxy)#.new('<response status="ok"><content>test</content></response>')
308
+ proxy.stub!(:ok?).and_return(is_ok)
309
+ proxy
310
+ end
311
+
312
+ def stub_api_client(configuration, response_digestor)
313
+ @client = stub(Sevendigital::Client)
314
+ @client.stub!(:configuration).and_return(configuration)
315
+ @client.stub!(:oauth_consumer).and_return(OAuth::Consumer.new( configuration.oauth_consumer_key, configuration.oauth_consumer_secret))
316
+ @client.stub!(:api_response_digestor).and_return(response_digestor)
317
+ @client.stub!(:default_parameters).and_return({:country => 'sk'})
318
+ @client.stub!(:user_agent_info).and_return("7digital")
319
+ @client.stub!(:verbose?).and_return(false)
320
+ @client.stub!(:very_verbose?).and_return(false)
321
+ @client.stub!(:api_host_and_version).and_return(["base.api.url","version"])
322
+
323
+ end
324
+
325
+ def stub_api_request
326
+ api_request = stub(Sevendigital::ApiRequest)
327
+
328
+ api_request.stub!(:parameters).and_return({})
329
+ api_request.stub!(:api_service).and_return(nil)
330
+ api_request.stub!(:api_method).and_return("m")
331
+ api_request.stub!(:requires_signature?).and_return(false)
332
+ api_request.stub!(:requires_secure_connection?).and_return(false)
333
+ api_request.stub!(:ensure_country_is_set)
334
+ return api_request
335
+ end
336
+
337
337
  end