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.
- data/History.txt +139 -0
- data/LICENSE +14 -0
- data/README.md +153 -0
- data/Rakefile +18 -0
- data/VERSION +1 -0
- data/bin/spark_api +8 -0
- data/bin/spark_api~ +8 -0
- data/lib/spark_api.rb +46 -0
- data/lib/spark_api/authentication.rb +55 -0
- data/lib/spark_api/authentication/api_auth.rb +104 -0
- data/lib/spark_api/authentication/api_auth.rb~ +104 -0
- data/lib/spark_api/authentication/base_auth.rb +47 -0
- data/lib/spark_api/authentication/base_auth.rb~ +47 -0
- data/lib/spark_api/authentication/oauth2.rb +198 -0
- data/lib/spark_api/authentication/oauth2.rb~ +199 -0
- data/lib/spark_api/authentication/oauth2_impl/grant_type_base.rb +87 -0
- data/lib/spark_api/authentication/oauth2_impl/grant_type_base.rb~ +87 -0
- data/lib/spark_api/authentication/oauth2_impl/grant_type_code.rb +48 -0
- data/lib/spark_api/authentication/oauth2_impl/grant_type_code.rb~ +49 -0
- data/lib/spark_api/authentication/oauth2_impl/grant_type_password.rb +44 -0
- data/lib/spark_api/authentication/oauth2_impl/grant_type_password.rb~ +45 -0
- data/lib/spark_api/authentication/oauth2_impl/grant_type_refresh.rb +35 -0
- data/lib/spark_api/authentication/oauth2_impl/grant_type_refresh.rb~ +36 -0
- data/lib/spark_api/authentication/oauth2_impl/middleware.rb +38 -0
- data/lib/spark_api/authentication/oauth2_impl/middleware.rb~ +39 -0
- data/lib/spark_api/authentication/oauth2_impl/password_provider.rb +24 -0
- data/lib/spark_api/authentication/oauth2_impl/password_provider.rb~ +25 -0
- data/lib/spark_api/cli.rb +158 -0
- data/lib/spark_api/cli.rb~ +158 -0
- data/lib/spark_api/cli/api_auth.rb +8 -0
- data/lib/spark_api/cli/api_auth.rb~ +8 -0
- data/lib/spark_api/cli/oauth2.rb +14 -0
- data/lib/spark_api/cli/oauth2.rb~ +14 -0
- data/lib/spark_api/cli/setup.rb +47 -0
- data/lib/spark_api/cli/setup.rb~ +47 -0
- data/lib/spark_api/client.rb +27 -0
- data/lib/spark_api/configuration.rb +54 -0
- data/lib/spark_api/configuration.rb~ +54 -0
- data/lib/spark_api/configuration/yaml.rb +101 -0
- data/lib/spark_api/configuration/yaml.rb~ +101 -0
- data/lib/spark_api/connection.rb +42 -0
- data/lib/spark_api/faraday.rb +64 -0
- data/lib/spark_api/faraday.rb~ +64 -0
- data/lib/spark_api/models.rb +33 -0
- data/lib/spark_api/models.rb~ +33 -0
- data/lib/spark_api/models/account.rb +115 -0
- data/lib/spark_api/models/account.rb~ +115 -0
- data/lib/spark_api/models/base.rb +118 -0
- data/lib/spark_api/models/base.rb~ +118 -0
- data/lib/spark_api/models/connect_prefs.rb +10 -0
- data/lib/spark_api/models/connect_prefs.rb~ +10 -0
- data/lib/spark_api/models/constraint.rb +16 -0
- data/lib/spark_api/models/constraint.rb~ +16 -0
- data/lib/spark_api/models/contact.rb +49 -0
- data/lib/spark_api/models/contact.rb~ +49 -0
- data/lib/spark_api/models/custom_fields.rb +12 -0
- data/lib/spark_api/models/custom_fields.rb~ +12 -0
- data/lib/spark_api/models/document.rb +11 -0
- data/lib/spark_api/models/document.rb~ +11 -0
- data/lib/spark_api/models/finders.rb +45 -0
- data/lib/spark_api/models/finders.rb~ +45 -0
- data/lib/spark_api/models/idx_link.rb +47 -0
- data/lib/spark_api/models/idx_link.rb~ +47 -0
- data/lib/spark_api/models/listing.rb +197 -0
- data/lib/spark_api/models/listing.rb~ +197 -0
- data/lib/spark_api/models/listing_cart.rb +72 -0
- data/lib/spark_api/models/listing_cart.rb~ +72 -0
- data/lib/spark_api/models/market_statistics.rb +33 -0
- data/lib/spark_api/models/market_statistics.rb~ +33 -0
- data/lib/spark_api/models/message.rb +21 -0
- data/lib/spark_api/models/message.rb~ +21 -0
- data/lib/spark_api/models/note.rb +41 -0
- data/lib/spark_api/models/note.rb~ +41 -0
- data/lib/spark_api/models/notification.rb +42 -0
- data/lib/spark_api/models/notification.rb~ +42 -0
- data/lib/spark_api/models/open_house.rb +24 -0
- data/lib/spark_api/models/open_house.rb~ +24 -0
- data/lib/spark_api/models/photo.rb +70 -0
- data/lib/spark_api/models/photo.rb~ +70 -0
- data/lib/spark_api/models/property_types.rb +7 -0
- data/lib/spark_api/models/property_types.rb~ +7 -0
- data/lib/spark_api/models/saved_search.rb +16 -0
- data/lib/spark_api/models/saved_search.rb~ +16 -0
- data/lib/spark_api/models/shared_listing.rb +35 -0
- data/lib/spark_api/models/shared_listing.rb~ +35 -0
- data/lib/spark_api/models/standard_fields.rb +50 -0
- data/lib/spark_api/models/standard_fields.rb~ +50 -0
- data/lib/spark_api/models/subresource.rb +19 -0
- data/lib/spark_api/models/subresource.rb~ +19 -0
- data/lib/spark_api/models/system_info.rb +14 -0
- data/lib/spark_api/models/system_info.rb~ +14 -0
- data/lib/spark_api/models/tour_of_home.rb +24 -0
- data/lib/spark_api/models/tour_of_home.rb~ +24 -0
- data/lib/spark_api/models/video.rb +16 -0
- data/lib/spark_api/models/video.rb~ +16 -0
- data/lib/spark_api/models/virtual_tour.rb +18 -0
- data/lib/spark_api/models/virtual_tour.rb~ +18 -0
- data/lib/spark_api/multi_client.rb +59 -0
- data/lib/spark_api/multi_client.rb~ +59 -0
- data/lib/spark_api/paginate.rb +109 -0
- data/lib/spark_api/paginate.rb~ +109 -0
- data/lib/spark_api/primary_array.rb +29 -0
- data/lib/spark_api/primary_array.rb~ +29 -0
- data/lib/spark_api/request.rb +96 -0
- data/lib/spark_api/request.rb~ +96 -0
- data/lib/spark_api/response.rb +70 -0
- data/lib/spark_api/response.rb~ +70 -0
- data/lib/spark_api/version.rb +4 -0
- data/lib/spark_api/version.rb~ +4 -0
- data/script/console +6 -0
- data/script/console~ +6 -0
- data/script/example.rb +27 -0
- data/script/example.rb~ +27 -0
- data/spec/fixtures/accounts/all.json +160 -0
- data/spec/fixtures/accounts/my.json +74 -0
- data/spec/fixtures/accounts/my_portal.json +20 -0
- data/spec/fixtures/accounts/my_put.json +5 -0
- data/spec/fixtures/accounts/my_save.json +5 -0
- data/spec/fixtures/accounts/office.json +142 -0
- data/spec/fixtures/accounts/password_save.json +6 -0
- data/spec/fixtures/authentication_failure.json +7 -0
- data/spec/fixtures/base.json +13 -0
- data/spec/fixtures/contacts/contacts.json +28 -0
- data/spec/fixtures/contacts/my.json +19 -0
- data/spec/fixtures/contacts/new.json +11 -0
- data/spec/fixtures/contacts/new_empty.json +8 -0
- data/spec/fixtures/contacts/new_notify.json +11 -0
- data/spec/fixtures/contacts/post.json +10 -0
- data/spec/fixtures/contacts/tags.json +11 -0
- data/spec/fixtures/count.json +10 -0
- data/spec/fixtures/empty.json +3 -0
- data/spec/fixtures/errors/expired.json +7 -0
- data/spec/fixtures/errors/failure.json +5 -0
- data/spec/fixtures/errors/failure_with_constraint.json +17 -0
- data/spec/fixtures/errors/failure_with_msg.json +7 -0
- data/spec/fixtures/generic_delete.json +1 -0
- data/spec/fixtures/generic_failure.json +5 -0
- data/spec/fixtures/listing_carts/add_listing.json +13 -0
- data/spec/fixtures/listing_carts/add_listing_post.json +5 -0
- data/spec/fixtures/listing_carts/empty.json +5 -0
- data/spec/fixtures/listing_carts/listing_cart.json +19 -0
- data/spec/fixtures/listing_carts/new.json +12 -0
- data/spec/fixtures/listing_carts/post.json +10 -0
- data/spec/fixtures/listing_carts/remove_listing.json +13 -0
- data/spec/fixtures/listings/constraints.json +18 -0
- data/spec/fixtures/listings/constraints_with_pagination.json +24 -0
- data/spec/fixtures/listings/document_index.json +19 -0
- data/spec/fixtures/listings/multiple.json +69 -0
- data/spec/fixtures/listings/no_subresources.json +38 -0
- data/spec/fixtures/listings/open_houses.json +21 -0
- data/spec/fixtures/listings/photos/index.json +469 -0
- data/spec/fixtures/listings/photos/new.json +12 -0
- data/spec/fixtures/listings/photos/post.json +20 -0
- data/spec/fixtures/listings/put.json +5 -0
- data/spec/fixtures/listings/put_expiration_date.json +5 -0
- data/spec/fixtures/listings/saved_search.json +17 -0
- data/spec/fixtures/listings/shared_listing_get.json +14 -0
- data/spec/fixtures/listings/shared_listing_new.json +9 -0
- data/spec/fixtures/listings/shared_listing_post.json +10 -0
- data/spec/fixtures/listings/tour_of_homes.json +23 -0
- data/spec/fixtures/listings/videos_index.json +18 -0
- data/spec/fixtures/listings/virtual_tours_index.json +42 -0
- data/spec/fixtures/listings/with_documents.json +52 -0
- data/spec/fixtures/listings/with_permissions.json +44 -0
- data/spec/fixtures/listings/with_photos.json +110 -0
- data/spec/fixtures/listings/with_supplement.json +39 -0
- data/spec/fixtures/listings/with_videos.json +54 -0
- data/spec/fixtures/listings/with_vtour.json +48 -0
- data/spec/fixtures/logo_fbs.png +0 -0
- data/spec/fixtures/messages/new.json +14 -0
- data/spec/fixtures/messages/new_empty.json +7 -0
- data/spec/fixtures/messages/new_with_recipients.json +15 -0
- data/spec/fixtures/messages/post.json +5 -0
- data/spec/fixtures/notes/add.json +11 -0
- data/spec/fixtures/notes/agent_shared.json +11 -0
- data/spec/fixtures/notes/agent_shared_empty.json +7 -0
- data/spec/fixtures/notes/new.json +5 -0
- data/spec/fixtures/notifications/mark_read.json +1 -0
- data/spec/fixtures/notifications/new.json +8 -0
- data/spec/fixtures/notifications/new_empty.json +7 -0
- data/spec/fixtures/notifications/notifications.json +43 -0
- data/spec/fixtures/notifications/post.json +10 -0
- data/spec/fixtures/notifications/unread.json +10 -0
- data/spec/fixtures/oauth2/access.json +3 -0
- data/spec/fixtures/oauth2/access_with_old_refresh.json +5 -0
- data/spec/fixtures/oauth2/access_with_refresh.json +5 -0
- data/spec/fixtures/oauth2/authorization_code_body.json +7 -0
- data/spec/fixtures/oauth2/error.json +3 -0
- data/spec/fixtures/oauth2/password_body.json +7 -0
- data/spec/fixtures/oauth2/refresh_body.json +7 -0
- data/spec/fixtures/oauth2_error.json +3 -0
- data/spec/fixtures/property_types/property_types.json +31 -0
- data/spec/fixtures/session.json +10 -0
- data/spec/fixtures/standardfields/city.json +1031 -0
- data/spec/fixtures/standardfields/nearby.json +53 -0
- data/spec/fixtures/standardfields/standardfields.json +188 -0
- data/spec/fixtures/standardfields/stateorprovince.json +36 -0
- data/spec/fixtures/success.json +5 -0
- data/spec/json_helper.rb +76 -0
- data/spec/mock_helper.rb +124 -0
- data/spec/oauth2_helper.rb +68 -0
- data/spec/spec_helper.rb +48 -0
- data/spec/unit/flexmls_api_spec.rb~ +23 -0
- data/spec/unit/spark_api/authentication/api_auth_spec.rb +169 -0
- data/spec/unit/spark_api/authentication/api_auth_spec.rb~ +169 -0
- data/spec/unit/spark_api/authentication/base_auth_spec.rb +10 -0
- data/spec/unit/spark_api/authentication/base_auth_spec.rb~ +10 -0
- data/spec/unit/spark_api/authentication/oauth2_impl/grant_type_base_spec.rb +10 -0
- data/spec/unit/spark_api/authentication/oauth2_impl/grant_type_base_spec.rb~ +10 -0
- data/spec/unit/spark_api/authentication/oauth2_spec.rb +205 -0
- data/spec/unit/spark_api/authentication/oauth2_spec.rb~ +205 -0
- data/spec/unit/spark_api/authentication_spec.rb +38 -0
- data/spec/unit/spark_api/authentication_spec.rb~ +38 -0
- data/spec/unit/spark_api/configuration/yaml_spec.rb +72 -0
- data/spec/unit/spark_api/configuration/yaml_spec.rb~ +72 -0
- data/spec/unit/spark_api/configuration_spec.rb +122 -0
- data/spec/unit/spark_api/configuration_spec.rb~ +122 -0
- data/spec/unit/spark_api/faraday_spec.rb +90 -0
- data/spec/unit/spark_api/faraday_spec.rb~ +90 -0
- data/spec/unit/spark_api/models/account_spec.rb +176 -0
- data/spec/unit/spark_api/models/base_spec.rb +106 -0
- data/spec/unit/spark_api/models/connect_prefs_spec.rb +9 -0
- data/spec/unit/spark_api/models/constraint_spec.rb +19 -0
- data/spec/unit/spark_api/models/contact_spec.rb +108 -0
- data/spec/unit/spark_api/models/contact_spec.rb~ +108 -0
- data/spec/unit/spark_api/models/document_spec.rb +32 -0
- data/spec/unit/spark_api/models/listing_cart_spec.rb +127 -0
- data/spec/unit/spark_api/models/listing_cart_spec.rb~ +127 -0
- data/spec/unit/spark_api/models/listing_spec.rb +320 -0
- data/spec/unit/spark_api/models/listing_spec.rb~ +320 -0
- data/spec/unit/spark_api/models/message_spec.rb +47 -0
- data/spec/unit/spark_api/models/message_spec.rb~ +47 -0
- data/spec/unit/spark_api/models/note_spec.rb +63 -0
- data/spec/unit/spark_api/models/note_spec.rb~ +63 -0
- data/spec/unit/spark_api/models/notification_spec.rb +62 -0
- data/spec/unit/spark_api/models/notification_spec.rb~ +62 -0
- data/spec/unit/spark_api/models/open_house_spec.rb +39 -0
- data/spec/unit/spark_api/models/photo_spec.rb +92 -0
- data/spec/unit/spark_api/models/property_types_spec.rb +33 -0
- data/spec/unit/spark_api/models/saved_search_spec.rb +40 -0
- data/spec/unit/spark_api/models/shared_listing_spec.rb +45 -0
- data/spec/unit/spark_api/models/shared_listing_spec.rb~ +45 -0
- data/spec/unit/spark_api/models/standard_fields_spec.rb +60 -0
- data/spec/unit/spark_api/models/system_info_spec.rb +83 -0
- data/spec/unit/spark_api/models/tour_of_home_spec.rb +44 -0
- data/spec/unit/spark_api/models/video_spec.rb +36 -0
- data/spec/unit/spark_api/models/virtual_tour_spec.rb +44 -0
- data/spec/unit/spark_api/multi_client_spec.rb +56 -0
- data/spec/unit/spark_api/multi_client_spec.rb~ +56 -0
- data/spec/unit/spark_api/paginate_spec.rb +224 -0
- data/spec/unit/spark_api/paginate_spec.rb~ +224 -0
- data/spec/unit/spark_api/primary_array_spec.rb +41 -0
- data/spec/unit/spark_api/primary_array_spec.rb~ +41 -0
- data/spec/unit/spark_api/request_spec.rb +344 -0
- data/spec/unit/spark_api/request_spec.rb~ +344 -0
- data/spec/unit/spark_api_spec.rb +23 -0
- 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
|