spark_api 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (257) hide show
  1. data/History.txt +139 -0
  2. data/LICENSE +14 -0
  3. data/README.md +153 -0
  4. data/Rakefile +18 -0
  5. data/VERSION +1 -0
  6. data/bin/spark_api +8 -0
  7. data/bin/spark_api~ +8 -0
  8. data/lib/spark_api.rb +46 -0
  9. data/lib/spark_api/authentication.rb +55 -0
  10. data/lib/spark_api/authentication/api_auth.rb +104 -0
  11. data/lib/spark_api/authentication/api_auth.rb~ +104 -0
  12. data/lib/spark_api/authentication/base_auth.rb +47 -0
  13. data/lib/spark_api/authentication/base_auth.rb~ +47 -0
  14. data/lib/spark_api/authentication/oauth2.rb +198 -0
  15. data/lib/spark_api/authentication/oauth2.rb~ +199 -0
  16. data/lib/spark_api/authentication/oauth2_impl/grant_type_base.rb +87 -0
  17. data/lib/spark_api/authentication/oauth2_impl/grant_type_base.rb~ +87 -0
  18. data/lib/spark_api/authentication/oauth2_impl/grant_type_code.rb +48 -0
  19. data/lib/spark_api/authentication/oauth2_impl/grant_type_code.rb~ +49 -0
  20. data/lib/spark_api/authentication/oauth2_impl/grant_type_password.rb +44 -0
  21. data/lib/spark_api/authentication/oauth2_impl/grant_type_password.rb~ +45 -0
  22. data/lib/spark_api/authentication/oauth2_impl/grant_type_refresh.rb +35 -0
  23. data/lib/spark_api/authentication/oauth2_impl/grant_type_refresh.rb~ +36 -0
  24. data/lib/spark_api/authentication/oauth2_impl/middleware.rb +38 -0
  25. data/lib/spark_api/authentication/oauth2_impl/middleware.rb~ +39 -0
  26. data/lib/spark_api/authentication/oauth2_impl/password_provider.rb +24 -0
  27. data/lib/spark_api/authentication/oauth2_impl/password_provider.rb~ +25 -0
  28. data/lib/spark_api/cli.rb +158 -0
  29. data/lib/spark_api/cli.rb~ +158 -0
  30. data/lib/spark_api/cli/api_auth.rb +8 -0
  31. data/lib/spark_api/cli/api_auth.rb~ +8 -0
  32. data/lib/spark_api/cli/oauth2.rb +14 -0
  33. data/lib/spark_api/cli/oauth2.rb~ +14 -0
  34. data/lib/spark_api/cli/setup.rb +47 -0
  35. data/lib/spark_api/cli/setup.rb~ +47 -0
  36. data/lib/spark_api/client.rb +27 -0
  37. data/lib/spark_api/configuration.rb +54 -0
  38. data/lib/spark_api/configuration.rb~ +54 -0
  39. data/lib/spark_api/configuration/yaml.rb +101 -0
  40. data/lib/spark_api/configuration/yaml.rb~ +101 -0
  41. data/lib/spark_api/connection.rb +42 -0
  42. data/lib/spark_api/faraday.rb +64 -0
  43. data/lib/spark_api/faraday.rb~ +64 -0
  44. data/lib/spark_api/models.rb +33 -0
  45. data/lib/spark_api/models.rb~ +33 -0
  46. data/lib/spark_api/models/account.rb +115 -0
  47. data/lib/spark_api/models/account.rb~ +115 -0
  48. data/lib/spark_api/models/base.rb +118 -0
  49. data/lib/spark_api/models/base.rb~ +118 -0
  50. data/lib/spark_api/models/connect_prefs.rb +10 -0
  51. data/lib/spark_api/models/connect_prefs.rb~ +10 -0
  52. data/lib/spark_api/models/constraint.rb +16 -0
  53. data/lib/spark_api/models/constraint.rb~ +16 -0
  54. data/lib/spark_api/models/contact.rb +49 -0
  55. data/lib/spark_api/models/contact.rb~ +49 -0
  56. data/lib/spark_api/models/custom_fields.rb +12 -0
  57. data/lib/spark_api/models/custom_fields.rb~ +12 -0
  58. data/lib/spark_api/models/document.rb +11 -0
  59. data/lib/spark_api/models/document.rb~ +11 -0
  60. data/lib/spark_api/models/finders.rb +45 -0
  61. data/lib/spark_api/models/finders.rb~ +45 -0
  62. data/lib/spark_api/models/idx_link.rb +47 -0
  63. data/lib/spark_api/models/idx_link.rb~ +47 -0
  64. data/lib/spark_api/models/listing.rb +197 -0
  65. data/lib/spark_api/models/listing.rb~ +197 -0
  66. data/lib/spark_api/models/listing_cart.rb +72 -0
  67. data/lib/spark_api/models/listing_cart.rb~ +72 -0
  68. data/lib/spark_api/models/market_statistics.rb +33 -0
  69. data/lib/spark_api/models/market_statistics.rb~ +33 -0
  70. data/lib/spark_api/models/message.rb +21 -0
  71. data/lib/spark_api/models/message.rb~ +21 -0
  72. data/lib/spark_api/models/note.rb +41 -0
  73. data/lib/spark_api/models/note.rb~ +41 -0
  74. data/lib/spark_api/models/notification.rb +42 -0
  75. data/lib/spark_api/models/notification.rb~ +42 -0
  76. data/lib/spark_api/models/open_house.rb +24 -0
  77. data/lib/spark_api/models/open_house.rb~ +24 -0
  78. data/lib/spark_api/models/photo.rb +70 -0
  79. data/lib/spark_api/models/photo.rb~ +70 -0
  80. data/lib/spark_api/models/property_types.rb +7 -0
  81. data/lib/spark_api/models/property_types.rb~ +7 -0
  82. data/lib/spark_api/models/saved_search.rb +16 -0
  83. data/lib/spark_api/models/saved_search.rb~ +16 -0
  84. data/lib/spark_api/models/shared_listing.rb +35 -0
  85. data/lib/spark_api/models/shared_listing.rb~ +35 -0
  86. data/lib/spark_api/models/standard_fields.rb +50 -0
  87. data/lib/spark_api/models/standard_fields.rb~ +50 -0
  88. data/lib/spark_api/models/subresource.rb +19 -0
  89. data/lib/spark_api/models/subresource.rb~ +19 -0
  90. data/lib/spark_api/models/system_info.rb +14 -0
  91. data/lib/spark_api/models/system_info.rb~ +14 -0
  92. data/lib/spark_api/models/tour_of_home.rb +24 -0
  93. data/lib/spark_api/models/tour_of_home.rb~ +24 -0
  94. data/lib/spark_api/models/video.rb +16 -0
  95. data/lib/spark_api/models/video.rb~ +16 -0
  96. data/lib/spark_api/models/virtual_tour.rb +18 -0
  97. data/lib/spark_api/models/virtual_tour.rb~ +18 -0
  98. data/lib/spark_api/multi_client.rb +59 -0
  99. data/lib/spark_api/multi_client.rb~ +59 -0
  100. data/lib/spark_api/paginate.rb +109 -0
  101. data/lib/spark_api/paginate.rb~ +109 -0
  102. data/lib/spark_api/primary_array.rb +29 -0
  103. data/lib/spark_api/primary_array.rb~ +29 -0
  104. data/lib/spark_api/request.rb +96 -0
  105. data/lib/spark_api/request.rb~ +96 -0
  106. data/lib/spark_api/response.rb +70 -0
  107. data/lib/spark_api/response.rb~ +70 -0
  108. data/lib/spark_api/version.rb +4 -0
  109. data/lib/spark_api/version.rb~ +4 -0
  110. data/script/console +6 -0
  111. data/script/console~ +6 -0
  112. data/script/example.rb +27 -0
  113. data/script/example.rb~ +27 -0
  114. data/spec/fixtures/accounts/all.json +160 -0
  115. data/spec/fixtures/accounts/my.json +74 -0
  116. data/spec/fixtures/accounts/my_portal.json +20 -0
  117. data/spec/fixtures/accounts/my_put.json +5 -0
  118. data/spec/fixtures/accounts/my_save.json +5 -0
  119. data/spec/fixtures/accounts/office.json +142 -0
  120. data/spec/fixtures/accounts/password_save.json +6 -0
  121. data/spec/fixtures/authentication_failure.json +7 -0
  122. data/spec/fixtures/base.json +13 -0
  123. data/spec/fixtures/contacts/contacts.json +28 -0
  124. data/spec/fixtures/contacts/my.json +19 -0
  125. data/spec/fixtures/contacts/new.json +11 -0
  126. data/spec/fixtures/contacts/new_empty.json +8 -0
  127. data/spec/fixtures/contacts/new_notify.json +11 -0
  128. data/spec/fixtures/contacts/post.json +10 -0
  129. data/spec/fixtures/contacts/tags.json +11 -0
  130. data/spec/fixtures/count.json +10 -0
  131. data/spec/fixtures/empty.json +3 -0
  132. data/spec/fixtures/errors/expired.json +7 -0
  133. data/spec/fixtures/errors/failure.json +5 -0
  134. data/spec/fixtures/errors/failure_with_constraint.json +17 -0
  135. data/spec/fixtures/errors/failure_with_msg.json +7 -0
  136. data/spec/fixtures/generic_delete.json +1 -0
  137. data/spec/fixtures/generic_failure.json +5 -0
  138. data/spec/fixtures/listing_carts/add_listing.json +13 -0
  139. data/spec/fixtures/listing_carts/add_listing_post.json +5 -0
  140. data/spec/fixtures/listing_carts/empty.json +5 -0
  141. data/spec/fixtures/listing_carts/listing_cart.json +19 -0
  142. data/spec/fixtures/listing_carts/new.json +12 -0
  143. data/spec/fixtures/listing_carts/post.json +10 -0
  144. data/spec/fixtures/listing_carts/remove_listing.json +13 -0
  145. data/spec/fixtures/listings/constraints.json +18 -0
  146. data/spec/fixtures/listings/constraints_with_pagination.json +24 -0
  147. data/spec/fixtures/listings/document_index.json +19 -0
  148. data/spec/fixtures/listings/multiple.json +69 -0
  149. data/spec/fixtures/listings/no_subresources.json +38 -0
  150. data/spec/fixtures/listings/open_houses.json +21 -0
  151. data/spec/fixtures/listings/photos/index.json +469 -0
  152. data/spec/fixtures/listings/photos/new.json +12 -0
  153. data/spec/fixtures/listings/photos/post.json +20 -0
  154. data/spec/fixtures/listings/put.json +5 -0
  155. data/spec/fixtures/listings/put_expiration_date.json +5 -0
  156. data/spec/fixtures/listings/saved_search.json +17 -0
  157. data/spec/fixtures/listings/shared_listing_get.json +14 -0
  158. data/spec/fixtures/listings/shared_listing_new.json +9 -0
  159. data/spec/fixtures/listings/shared_listing_post.json +10 -0
  160. data/spec/fixtures/listings/tour_of_homes.json +23 -0
  161. data/spec/fixtures/listings/videos_index.json +18 -0
  162. data/spec/fixtures/listings/virtual_tours_index.json +42 -0
  163. data/spec/fixtures/listings/with_documents.json +52 -0
  164. data/spec/fixtures/listings/with_permissions.json +44 -0
  165. data/spec/fixtures/listings/with_photos.json +110 -0
  166. data/spec/fixtures/listings/with_supplement.json +39 -0
  167. data/spec/fixtures/listings/with_videos.json +54 -0
  168. data/spec/fixtures/listings/with_vtour.json +48 -0
  169. data/spec/fixtures/logo_fbs.png +0 -0
  170. data/spec/fixtures/messages/new.json +14 -0
  171. data/spec/fixtures/messages/new_empty.json +7 -0
  172. data/spec/fixtures/messages/new_with_recipients.json +15 -0
  173. data/spec/fixtures/messages/post.json +5 -0
  174. data/spec/fixtures/notes/add.json +11 -0
  175. data/spec/fixtures/notes/agent_shared.json +11 -0
  176. data/spec/fixtures/notes/agent_shared_empty.json +7 -0
  177. data/spec/fixtures/notes/new.json +5 -0
  178. data/spec/fixtures/notifications/mark_read.json +1 -0
  179. data/spec/fixtures/notifications/new.json +8 -0
  180. data/spec/fixtures/notifications/new_empty.json +7 -0
  181. data/spec/fixtures/notifications/notifications.json +43 -0
  182. data/spec/fixtures/notifications/post.json +10 -0
  183. data/spec/fixtures/notifications/unread.json +10 -0
  184. data/spec/fixtures/oauth2/access.json +3 -0
  185. data/spec/fixtures/oauth2/access_with_old_refresh.json +5 -0
  186. data/spec/fixtures/oauth2/access_with_refresh.json +5 -0
  187. data/spec/fixtures/oauth2/authorization_code_body.json +7 -0
  188. data/spec/fixtures/oauth2/error.json +3 -0
  189. data/spec/fixtures/oauth2/password_body.json +7 -0
  190. data/spec/fixtures/oauth2/refresh_body.json +7 -0
  191. data/spec/fixtures/oauth2_error.json +3 -0
  192. data/spec/fixtures/property_types/property_types.json +31 -0
  193. data/spec/fixtures/session.json +10 -0
  194. data/spec/fixtures/standardfields/city.json +1031 -0
  195. data/spec/fixtures/standardfields/nearby.json +53 -0
  196. data/spec/fixtures/standardfields/standardfields.json +188 -0
  197. data/spec/fixtures/standardfields/stateorprovince.json +36 -0
  198. data/spec/fixtures/success.json +5 -0
  199. data/spec/json_helper.rb +76 -0
  200. data/spec/mock_helper.rb +124 -0
  201. data/spec/oauth2_helper.rb +68 -0
  202. data/spec/spec_helper.rb +48 -0
  203. data/spec/unit/flexmls_api_spec.rb~ +23 -0
  204. data/spec/unit/spark_api/authentication/api_auth_spec.rb +169 -0
  205. data/spec/unit/spark_api/authentication/api_auth_spec.rb~ +169 -0
  206. data/spec/unit/spark_api/authentication/base_auth_spec.rb +10 -0
  207. data/spec/unit/spark_api/authentication/base_auth_spec.rb~ +10 -0
  208. data/spec/unit/spark_api/authentication/oauth2_impl/grant_type_base_spec.rb +10 -0
  209. data/spec/unit/spark_api/authentication/oauth2_impl/grant_type_base_spec.rb~ +10 -0
  210. data/spec/unit/spark_api/authentication/oauth2_spec.rb +205 -0
  211. data/spec/unit/spark_api/authentication/oauth2_spec.rb~ +205 -0
  212. data/spec/unit/spark_api/authentication_spec.rb +38 -0
  213. data/spec/unit/spark_api/authentication_spec.rb~ +38 -0
  214. data/spec/unit/spark_api/configuration/yaml_spec.rb +72 -0
  215. data/spec/unit/spark_api/configuration/yaml_spec.rb~ +72 -0
  216. data/spec/unit/spark_api/configuration_spec.rb +122 -0
  217. data/spec/unit/spark_api/configuration_spec.rb~ +122 -0
  218. data/spec/unit/spark_api/faraday_spec.rb +90 -0
  219. data/spec/unit/spark_api/faraday_spec.rb~ +90 -0
  220. data/spec/unit/spark_api/models/account_spec.rb +176 -0
  221. data/spec/unit/spark_api/models/base_spec.rb +106 -0
  222. data/spec/unit/spark_api/models/connect_prefs_spec.rb +9 -0
  223. data/spec/unit/spark_api/models/constraint_spec.rb +19 -0
  224. data/spec/unit/spark_api/models/contact_spec.rb +108 -0
  225. data/spec/unit/spark_api/models/contact_spec.rb~ +108 -0
  226. data/spec/unit/spark_api/models/document_spec.rb +32 -0
  227. data/spec/unit/spark_api/models/listing_cart_spec.rb +127 -0
  228. data/spec/unit/spark_api/models/listing_cart_spec.rb~ +127 -0
  229. data/spec/unit/spark_api/models/listing_spec.rb +320 -0
  230. data/spec/unit/spark_api/models/listing_spec.rb~ +320 -0
  231. data/spec/unit/spark_api/models/message_spec.rb +47 -0
  232. data/spec/unit/spark_api/models/message_spec.rb~ +47 -0
  233. data/spec/unit/spark_api/models/note_spec.rb +63 -0
  234. data/spec/unit/spark_api/models/note_spec.rb~ +63 -0
  235. data/spec/unit/spark_api/models/notification_spec.rb +62 -0
  236. data/spec/unit/spark_api/models/notification_spec.rb~ +62 -0
  237. data/spec/unit/spark_api/models/open_house_spec.rb +39 -0
  238. data/spec/unit/spark_api/models/photo_spec.rb +92 -0
  239. data/spec/unit/spark_api/models/property_types_spec.rb +33 -0
  240. data/spec/unit/spark_api/models/saved_search_spec.rb +40 -0
  241. data/spec/unit/spark_api/models/shared_listing_spec.rb +45 -0
  242. data/spec/unit/spark_api/models/shared_listing_spec.rb~ +45 -0
  243. data/spec/unit/spark_api/models/standard_fields_spec.rb +60 -0
  244. data/spec/unit/spark_api/models/system_info_spec.rb +83 -0
  245. data/spec/unit/spark_api/models/tour_of_home_spec.rb +44 -0
  246. data/spec/unit/spark_api/models/video_spec.rb +36 -0
  247. data/spec/unit/spark_api/models/virtual_tour_spec.rb +44 -0
  248. data/spec/unit/spark_api/multi_client_spec.rb +56 -0
  249. data/spec/unit/spark_api/multi_client_spec.rb~ +56 -0
  250. data/spec/unit/spark_api/paginate_spec.rb +224 -0
  251. data/spec/unit/spark_api/paginate_spec.rb~ +224 -0
  252. data/spec/unit/spark_api/primary_array_spec.rb +41 -0
  253. data/spec/unit/spark_api/primary_array_spec.rb~ +41 -0
  254. data/spec/unit/spark_api/request_spec.rb +344 -0
  255. data/spec/unit/spark_api/request_spec.rb~ +344 -0
  256. data/spec/unit/spark_api_spec.rb +23 -0
  257. metadata +725 -0
@@ -0,0 +1,90 @@
1
+ require './spec/spec_helper'
2
+
3
+ # Test out the faraday connection stack.
4
+ describe SparkApi do
5
+ describe "SparkMiddleware" do
6
+ before(:all) do
7
+ stubs = Faraday::Adapter::Test::Stubs.new do |stub|
8
+ stub.post('/session') { [200, {}, '{"D": {
9
+ "Success": true,
10
+ "Results": [{
11
+ "AuthToken": "xxxxx",
12
+ "Expires": "2010-10-30T15:49:01-05:00",
13
+ "Roles": ["idx"]
14
+ }]
15
+ }}']
16
+ }
17
+ stub.get('/system') { [200, {}, '{"D": {
18
+ "Success": true,
19
+ "Results": [{
20
+ "Name": "My User",
21
+ "OfficeId": "20070830184014994915000000",
22
+ "Configuration": [],
23
+ "Id": "20101202170654111629000000",
24
+ "MlsId": "20000426143505724628000000",
25
+ "Office": "test office",
26
+ "Mls": "flexmls Web Demonstration Database"
27
+ }]}
28
+ }']
29
+ }
30
+ stub.get('/expired') { [401, {}, fixture('errors/expired.json')]
31
+ }
32
+ stub.get('/methodnotallowed') { [405, {}, '{"D": {
33
+ "Success": false,
34
+ "Message": "Method Not Allowed",
35
+ "Code": "1234"
36
+ }}']
37
+ }
38
+ stub.get('/epicfail') { [500, {}, '{"D": {
39
+ "Success": false,
40
+ "Message": "EPIC FAIL",
41
+ "Code": "0000"
42
+ }}']
43
+ }
44
+ stub.get('/unknownerror') { [499, {}, '{"D": {
45
+ "Success": false,
46
+ "Message": "Some random status error",
47
+ "Code": "0000"
48
+ }}']
49
+ }
50
+ stub.get('/invalidjson') { [200, {}, '{"OMG": "THIS IS NOT THE API JSON THAT I KNOW AND <3!!!"}'] }
51
+ stub.get('/garbage') { [200, {}, 'THIS IS TOTAL GARBAGE!'] }
52
+ end
53
+
54
+ @connection = test_connection(stubs)
55
+
56
+ end
57
+
58
+ it "should raised exception when token is expired" do
59
+ expect { @connection.get('/expired')}.to raise_error(SparkApi::PermissionDenied){ |e| e.code.should == SparkApi::ResponseCodes::SESSION_TOKEN_EXPIRED }
60
+ end
61
+
62
+ it "should raised exception on error" do
63
+ expect { @connection.get('/methodnotallowed')}.to raise_error(SparkApi::NotAllowed){ |e| e.message.should == "Method Not Allowed" }
64
+ expect { @connection.get('/epicfail')}.to raise_error(SparkApi::ClientError){ |e| e.status.should be(500) }
65
+ expect { @connection.get('/unknownerror')}.to raise_error(SparkApi::ClientError){ |e| e.status.should be(499) }
66
+ end
67
+
68
+ it "should raised exception on invalid responses" do
69
+ expect { @connection.get('/invalidjson')}.to raise_error(SparkApi::InvalidResponse)
70
+ # This should be caught in the request code
71
+ expect { @connection.get('/garbage')}.to raise_error(MultiJson::DecodeError)
72
+ end
73
+
74
+ it "should give me a session response" do
75
+ response = @connection.post('/session').body
76
+ response.success.should eq(true)
77
+ session = SparkApi::Authentication::Session.new(response.results[0])
78
+ session.auth_token.should eq("xxxxx")
79
+ end
80
+
81
+ it "should give me an api response" do
82
+ response = @connection.get('/system').body
83
+ response.success.should eq(true)
84
+ response.results.length.should be > 0
85
+ end
86
+
87
+ end
88
+
89
+ end
90
+
@@ -0,0 +1,90 @@
1
+ require './spec/spec_helper'
2
+
3
+ # Test out the faraday connection stack.
4
+ describe FlexmlsApi do
5
+ describe "FlexmlsMiddleware" do
6
+ before(:all) do
7
+ stubs = Faraday::Adapter::Test::Stubs.new do |stub|
8
+ stub.post('/session') { [200, {}, '{"D": {
9
+ "Success": true,
10
+ "Results": [{
11
+ "AuthToken": "xxxxx",
12
+ "Expires": "2010-10-30T15:49:01-05:00",
13
+ "Roles": ["idx"]
14
+ }]
15
+ }}']
16
+ }
17
+ stub.get('/system') { [200, {}, '{"D": {
18
+ "Success": true,
19
+ "Results": [{
20
+ "Name": "My User",
21
+ "OfficeId": "20070830184014994915000000",
22
+ "Configuration": [],
23
+ "Id": "20101202170654111629000000",
24
+ "MlsId": "20000426143505724628000000",
25
+ "Office": "test office",
26
+ "Mls": "flexmls Web Demonstration Database"
27
+ }]}
28
+ }']
29
+ }
30
+ stub.get('/expired') { [401, {}, fixture('errors/expired.json')]
31
+ }
32
+ stub.get('/methodnotallowed') { [405, {}, '{"D": {
33
+ "Success": false,
34
+ "Message": "Method Not Allowed",
35
+ "Code": "1234"
36
+ }}']
37
+ }
38
+ stub.get('/epicfail') { [500, {}, '{"D": {
39
+ "Success": false,
40
+ "Message": "EPIC FAIL",
41
+ "Code": "0000"
42
+ }}']
43
+ }
44
+ stub.get('/unknownerror') { [499, {}, '{"D": {
45
+ "Success": false,
46
+ "Message": "Some random status error",
47
+ "Code": "0000"
48
+ }}']
49
+ }
50
+ stub.get('/invalidjson') { [200, {}, '{"OMG": "THIS IS NOT THE API JSON THAT I KNOW AND <3!!!"}'] }
51
+ stub.get('/garbage') { [200, {}, 'THIS IS TOTAL GARBAGE!'] }
52
+ end
53
+
54
+ @connection = test_connection(stubs)
55
+
56
+ end
57
+
58
+ it "should raised exception when token is expired" do
59
+ expect { @connection.get('/expired')}.to raise_error(FlexmlsApi::PermissionDenied){ |e| e.code.should == FlexmlsApi::ResponseCodes::SESSION_TOKEN_EXPIRED }
60
+ end
61
+
62
+ it "should raised exception on error" do
63
+ expect { @connection.get('/methodnotallowed')}.to raise_error(FlexmlsApi::NotAllowed){ |e| e.message.should == "Method Not Allowed" }
64
+ expect { @connection.get('/epicfail')}.to raise_error(FlexmlsApi::ClientError){ |e| e.status.should be(500) }
65
+ expect { @connection.get('/unknownerror')}.to raise_error(FlexmlsApi::ClientError){ |e| e.status.should be(499) }
66
+ end
67
+
68
+ it "should raised exception on invalid responses" do
69
+ expect { @connection.get('/invalidjson')}.to raise_error(FlexmlsApi::InvalidResponse)
70
+ # This should be caught in the request code
71
+ expect { @connection.get('/garbage')}.to raise_error(MultiJson::DecodeError)
72
+ end
73
+
74
+ it "should give me a session response" do
75
+ response = @connection.post('/session').body
76
+ response.success.should eq(true)
77
+ session = FlexmlsApi::Authentication::Session.new(response.results[0])
78
+ session.auth_token.should eq("xxxxx")
79
+ end
80
+
81
+ it "should give me an api response" do
82
+ response = @connection.get('/system').body
83
+ response.success.should eq(true)
84
+ response.results.length.should be > 0
85
+ end
86
+
87
+ end
88
+
89
+ end
90
+
@@ -0,0 +1,176 @@
1
+ require './spec/spec_helper'
2
+
3
+ describe Account do
4
+ describe "units" do
5
+ before(:each) do
6
+ @account = Account.new({
7
+ "Name"=>"Sample User",
8
+ "Id"=>"20000426173054342350000000",
9
+ "Office"=>"Sample Office",
10
+ "Mls"=>"Sample MLS",
11
+ "MlsId"=>"20000426143505724628000000",
12
+ "Emails"=>[
13
+ {
14
+ "Type"=>"Work",
15
+ "Name"=>"My Work E-mail",
16
+ "Address"=>"work@test.com",
17
+ "Primary"=>true
18
+ },
19
+ {
20
+ "Type"=>"Home",
21
+ "Name"=>"My Home E-mail",
22
+ "Address"=>"home@test.com"
23
+ }
24
+ ],
25
+ "Phones"=>[
26
+ {
27
+ "Type"=>"Work",
28
+ "Name"=>"My Work Phone",
29
+ "Number"=>"701-555-1212",
30
+ "Primary"=>true
31
+ },
32
+ {
33
+ "Type"=>"Home",
34
+ "Name"=>"My Home Phone",
35
+ "Number"=>"702-555-1313"
36
+ }
37
+ ],
38
+ "Websites"=>[
39
+ {
40
+ "Type"=>"Work",
41
+ "Name"=>"My Work Website",
42
+ "Uri"=>"http://iamthebestagent.com",
43
+ "Primary"=>true
44
+ },
45
+ {
46
+ "Type"=>"Home",
47
+ "Name"=>"My Home Website",
48
+ "Uri"=>"http://myspace.com/lolcats"
49
+ }
50
+ ],
51
+ "Addresses"=>[
52
+ {
53
+ "Type"=>"Work",
54
+ "Name"=>"My Work Address",
55
+ "Address"=>"101 Main Ave, Phoenix, AZ 12345",
56
+ "Primary"=>true
57
+ },
58
+ {
59
+ "Type"=>"Home",
60
+ "Name"=>"My Home Address",
61
+ "Address"=>"102 Main Ave, Gilbert, AZ 54321"
62
+ }
63
+ ],
64
+ "Images"=>[
65
+ {
66
+ "Type"=>"Photo",
67
+ "Name"=>"My Photo 1",
68
+ "Uri"=>"http://photos.flexmls.com/az/...."
69
+ },
70
+ {
71
+ "Type"=>"Photo",
72
+ "Name"=>"My Photo two",
73
+ "Uri"=>"http://photos.flexmls.com/az/...."
74
+ },
75
+ {
76
+ "Type"=>"Logo",
77
+ "Name"=>"1 My Logo",
78
+ "Uri"=>"http://photos.flexmls.com/az/...."
79
+ },
80
+ {
81
+ "Type"=>"Logo",
82
+ "Name"=>"My Other Logo",
83
+ "Uri"=>"http://photos.flexmls.com/az/...."
84
+ },
85
+ {
86
+ "Type"=>"Logo",
87
+ "Name"=>"My Logo",
88
+ "Uri"=>"http://photos.flexmls.com/az/...."
89
+ }
90
+ ]
91
+ })
92
+ end
93
+
94
+ it "should respond to attributes" do
95
+ ['Name','Id','Mls','MlsId','Office'].each do |k|
96
+ (@account.send k.to_sym).should be_a(String)
97
+ end
98
+ end
99
+
100
+ it "should have primary subresources" do
101
+ @account.emails.primary.Address.should eq("work@test.com")
102
+ @account.phones.primary.Number.should eq("701-555-1212")
103
+ @account.addresses.primary.Address.should eq("101 Main Ave, Phoenix, AZ 12345")
104
+ @account.websites.primary.Uri.should eq("http://iamthebestagent.com")
105
+ end
106
+
107
+ it "should be able to provide a primary image" do
108
+ @account.primary_img("Photo").Name.should == 'My Photo 1'
109
+ @account.primary_img("Logo").Name.should == '1 My Logo'
110
+ end
111
+
112
+ after(:each) do
113
+ @acount = nil
114
+ end
115
+ end
116
+
117
+ describe "functionals" do
118
+ before(:each) do
119
+ stub_auth_request
120
+ end
121
+
122
+ context "/my/account", :support do
123
+ on_get_it "should get my account" do
124
+ stub_api_get("/my/account", 'accounts/my.json')
125
+ account = Account.my
126
+ account.Id.should eq("20000426173054342350000000")
127
+ account.websites.first.Name.should == 'My Work Website'
128
+ end
129
+
130
+ on_put_it "should save my portal account" do
131
+ stub_api_get("/my/account", 'accounts/my_portal.json')
132
+ stub_api_put("/my/account", 'accounts/my_save.json', 'accounts/my_put.json')
133
+ account = Account.my
134
+ account.Id.should eq("20110426173054342350000000")
135
+ account.GetEmailUpdates.should eq(false)
136
+ account.GetEmailUpdates = true
137
+ account.save!
138
+ account.GetEmailUpdates.should eq(true)
139
+ end
140
+ end
141
+
142
+ context "/accounts" do
143
+ on_get_it "should get all accounts" do
144
+ stub_api_get("/accounts", 'accounts/all.json')
145
+ accounts = Account.get
146
+ accounts.should be_an(Array)
147
+ accounts.length.should eq(3)
148
+ accounts.first.Id.should eq("20000426173054342350000000")
149
+ accounts.last.Id.should eq("20110126173054382350000000")
150
+ end
151
+ on_put_it "should save password" do
152
+ stub_api_get("/my/account", 'accounts/my.json')
153
+ account = Account.my
154
+ stub_api_put("/accounts/#{account.Id}", 'accounts/password_save.json', 'accounts/my.json')
155
+ account.Password = "1"
156
+ account.PasswordValidation = "1"
157
+ account.save.should be(true)
158
+ end
159
+ end
160
+
161
+ context "/accounts/by/office/<office_id>" do
162
+ on_get_it "should all office accounts" do
163
+ stub_api_get("/accounts/by/office/20030426173014239760000000", 'accounts/office.json')
164
+ accounts = Account.by_office("20030426173014239760000000")
165
+ accounts.should be_an(Array)
166
+ accounts.length.should eq(2)
167
+ accounts.each do |account|
168
+ accounts.first.OfficeId.should eq("20030426173014239760000000")
169
+ end
170
+ end
171
+ end
172
+
173
+ end
174
+
175
+ end
176
+
@@ -0,0 +1,106 @@
1
+ require './spec/spec_helper'
2
+
3
+ # Sample resource models for testing the base class
4
+ class MyExampleModel < Base
5
+ self.element_name = "example"
6
+ self.prefix = "/test/"
7
+ end
8
+
9
+ class MyDefaultModel < Base
10
+ end
11
+
12
+
13
+ describe Base, "Base model" do
14
+ describe "class methods" do
15
+ it "should set the element name" do
16
+ MyExampleModel.element_name.should eq("example")
17
+ MyDefaultModel.element_name.should eq("resource")
18
+ end
19
+ it "should set the prefix" do
20
+ MyExampleModel.prefix.should eq("/test/")
21
+ MyDefaultModel.prefix.should eq("/")
22
+ end
23
+ it "should set the path" do
24
+ MyExampleModel.path.should eq("/test/example")
25
+ MyDefaultModel.path.should eq("/resource")
26
+ end
27
+ describe "finders" do
28
+ before(:each) do
29
+ stub_auth_request
30
+ stub_api_get("/test/example", 'base.json')
31
+ end
32
+ it "should get all results" do
33
+ MyExampleModel.get.length.should == 2
34
+ end
35
+ it "should get first result" do
36
+ MyExampleModel.first.Id.should == 1
37
+ end
38
+ end
39
+ end
40
+
41
+ describe "attribute accessors, setters, and predicates" do
42
+ before(:each) do
43
+ stub_auth_request
44
+ stub_api_get("/test/example", 'base.json')
45
+ @model = MyExampleModel.first
46
+ end
47
+
48
+ it "should access existing attributes" do
49
+ @model.Name.should == 'My Example'
50
+ end
51
+
52
+ it "should raise errors on access to non-existant attributes" do
53
+ lambda { @model.Nonsense }.should raise_error(NoMethodError)
54
+ end
55
+
56
+ it "should set existing attributes" do
57
+ new_name = 'John Jacob Jingleheimerschmidt'
58
+ @model.Name = new_name
59
+ @model.Name.should == new_name
60
+ end
61
+
62
+ it "should set non-existant attributes" do
63
+ nonsense = 'nonsense'
64
+ @model.Nonsense = nonsense
65
+ @model.Nonsense.should == nonsense
66
+ end
67
+
68
+ it "should return a boolean for a predicate for an existing attribute" do
69
+ @model.Name?.should satisfy { |p| [true, false].include?(p) }
70
+ end
71
+
72
+ it "should raise an Error for a predicate for a non-existant attribute" do
73
+ lambda { @model.Nonsense? }.should raise_error(NoMethodError)
74
+ end
75
+
76
+ it "should repond_to existing attributes" do
77
+ @model.should respond_to(:Name)
78
+ end
79
+
80
+ it "should not respond_to non-existant attributes" do
81
+ @model.should_not respond_to(:Nonsense)
82
+ end
83
+
84
+ it "should respond_to a setter for an existing attribute" do
85
+ @model.should respond_to(:Name=)
86
+ end
87
+
88
+ it "should respond_to a setter for a non-existant attribute" do
89
+ @model.should respond_to(:Nonsense=)
90
+ end
91
+
92
+ it "should respond_to a predicate for an existing attribute" do
93
+ @model.should respond_to(:Name?)
94
+ end
95
+
96
+ it "should not respond_to a predicate for a non-existant attribute" do
97
+ @model.should_not respond_to(:Nonsense?)
98
+ end
99
+
100
+ it "should respond_to methods inherited from parent classes" do
101
+ @model.should respond_to(:freeze)
102
+ end
103
+
104
+ end
105
+
106
+ end