spark_api 1.3.24 → 1.3.25
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/Rakefile +9 -3
- data/VERSION +1 -1
- data/lib/spark_api/models.rb +2 -0
- data/lib/spark_api/models/base.rb +23 -0
- data/lib/spark_api/models/concerns/savable.rb +7 -11
- data/lib/spark_api/models/idx_link.rb +3 -8
- data/lib/spark_api/models/listing.rb +20 -1
- data/lib/spark_api/models/listing_cart.rb +15 -1
- data/lib/spark_api/models/portal_listing_cart.rb +13 -0
- data/lib/spark_api/models/saved_search.rb +22 -34
- data/lib/spark_api/models/sort.rb +11 -0
- data/script/bootstrap +7 -0
- data/script/ci_build +11 -0
- data/script/release +6 -0
- data/spec/fixtures/listings/put_reorder_photo.json +5 -0
- data/spec/fixtures/listings/reorder_photo.json +20 -0
- data/spec/fixtures/saved_searches/get.json +2 -1
- data/spec/fixtures/saved_searches/get_provided.json +22 -0
- data/spec/fixtures/saved_searches/without_newsfeed.json +20 -0
- data/spec/fixtures/sorts/get.json +31 -0
- data/spec/spec_helper.rb +11 -1
- data/spec/unit/spark_api/models/base_spec.rb +14 -3
- data/spec/unit/spark_api/models/listing_cart_spec.rb +39 -0
- data/spec/unit/spark_api/models/listing_spec.rb +17 -0
- data/spec/unit/spark_api/models/saved_search_spec.rb +34 -19
- data/spec/unit/spark_api/models/sort_spec.rb +19 -0
- metadata +40 -9
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
ZTVmZTkxOTdiYjI5YmE1N2UwN2Q5ZjQ3MmMxNDg1OTU2Njk4M2I0MQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
OWIyNTk5YjliMGVjM2RlNjM3M2IzZDAxY2JjYjUxYzRlNTYyYTUzMw==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
YjM2OWFhMDdhZDQ0MWQzZGZjYTVkODgyZGIxMmI2NTg1MzRmMWMwNDU4ZTQ3
|
10
|
+
ZGViMzU3MjhhODQyNWUxYzAwYzY4YzJhZTQzOTNhMzliM2M0OGJlNjQyNjAw
|
11
|
+
OGQ2YThjMzMxNDUxM2MwNDQxOGRiZWZhNDkyMWJlODg5NmJlMWU=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
NTk1Y2Y3ZDZiZjg2ODJiZDg2YjBmZTJjMjVhNjI0MjJkNThhMTQ0ZmRmY2Q4
|
14
|
+
OTg5OWIzMTdkNjZjMmU2MGZjODdmYjVjZDhlZDlmZGQ0YjIwYTFmY2MzM2Mw
|
15
|
+
NjcyZDUxYjI4M2JkYzk0MzlhMTUxZGJiNWQ0MGFiMThiMjgwOTk=
|
data/Rakefile
CHANGED
@@ -1,9 +1,15 @@
|
|
1
1
|
require "rubygems"
|
2
2
|
|
3
3
|
require 'rubygems/user_interaction'
|
4
|
-
require '
|
5
|
-
require '
|
6
|
-
require '
|
4
|
+
require 'rspec'
|
5
|
+
require 'rspec/core/rake_task'
|
6
|
+
require 'ci/reporter/rake/rspec'
|
7
|
+
require 'bundler/gem_tasks'
|
8
|
+
|
9
|
+
RSpec::Core::RakeTask.new do |t|
|
10
|
+
t.rspec_opts = ["-c", "-f progress"]
|
11
|
+
t.pattern = 'spec/**/*_spec.rb'
|
12
|
+
end
|
7
13
|
|
8
14
|
desc "Run all the tests"
|
9
15
|
task :default => :spec
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.3.
|
1
|
+
1.3.25
|
data/lib/spark_api/models.rb
CHANGED
@@ -24,11 +24,13 @@ require 'spark_api/models/notification'
|
|
24
24
|
require 'spark_api/models/open_house'
|
25
25
|
require 'spark_api/models/photo'
|
26
26
|
require 'spark_api/models/portal'
|
27
|
+
require 'spark_api/models/portal_listing_cart'
|
27
28
|
require 'spark_api/models/property_types'
|
28
29
|
require 'spark_api/models/rental_calendar'
|
29
30
|
require 'spark_api/models/saved_search'
|
30
31
|
require 'spark_api/models/search_template/quick_search'
|
31
32
|
require 'spark_api/models/shared_listing'
|
33
|
+
require 'spark_api/models/sort'
|
32
34
|
require 'spark_api/models/standard_fields'
|
33
35
|
require 'spark_api/models/system_info'
|
34
36
|
require 'spark_api/models/tour_of_home'
|
@@ -129,6 +129,19 @@ module SparkApi
|
|
129
129
|
attributes['Id']
|
130
130
|
end
|
131
131
|
|
132
|
+
def to_partial_path
|
133
|
+
"#{underscore(resource_pluralized)}/#{underscore(self.class.name.split('::').last)}"
|
134
|
+
end
|
135
|
+
|
136
|
+
# can be overridden
|
137
|
+
def resource_pluralized
|
138
|
+
resource = self.class.name.split('::').last
|
139
|
+
unless resource.split('').last == "s"
|
140
|
+
resource = resource + "s"
|
141
|
+
end
|
142
|
+
resource
|
143
|
+
end
|
144
|
+
|
132
145
|
protected
|
133
146
|
|
134
147
|
def write_attribute(attribute, value)
|
@@ -139,6 +152,16 @@ module SparkApi
|
|
139
152
|
end
|
140
153
|
end
|
141
154
|
|
155
|
+
private
|
156
|
+
|
157
|
+
def underscore(string)
|
158
|
+
string.to_s.gsub(/::/, '/').
|
159
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
160
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
161
|
+
tr("-", "_").
|
162
|
+
downcase
|
163
|
+
end
|
164
|
+
|
142
165
|
end
|
143
166
|
end
|
144
167
|
end
|
@@ -22,12 +22,17 @@ module SparkApi
|
|
22
22
|
|
23
23
|
def create!(arguments = {})
|
24
24
|
results = connection.post self.path, post_data.merge(params_for_save), arguments
|
25
|
-
|
25
|
+
update_attributes_after_create(results.first)
|
26
26
|
reset_dirty
|
27
27
|
params_for_save.clear
|
28
28
|
true
|
29
29
|
end
|
30
30
|
|
31
|
+
def update_attributes(attrs = {})
|
32
|
+
attrs.each{|k,v| public_send(:"#{k}=", v)}
|
33
|
+
save!
|
34
|
+
end
|
35
|
+
|
31
36
|
def update!(arguments = {})
|
32
37
|
return true unless changed? && persisted?
|
33
38
|
connection.put resource_uri, dirty_attributes, arguments
|
@@ -48,21 +53,12 @@ module SparkApi
|
|
48
53
|
|
49
54
|
private
|
50
55
|
|
51
|
-
def
|
56
|
+
def update_attributes_after_create(result)
|
52
57
|
attributes['Id'] = result['Id'] ? result['Id'] : parse_id(result['ResourceUri'])
|
53
58
|
result.delete('Id')
|
54
59
|
attributes.merge! result
|
55
60
|
end
|
56
61
|
|
57
|
-
# can be overridden
|
58
|
-
def resource_pluralized
|
59
|
-
resource = self.class.name.split('::').last
|
60
|
-
unless resource.split('').last == "s"
|
61
|
-
resource = resource + "s"
|
62
|
-
end
|
63
|
-
resource
|
64
|
-
end
|
65
|
-
|
66
62
|
end
|
67
63
|
|
68
64
|
end
|
@@ -1,6 +1,9 @@
|
|
1
1
|
module SparkApi
|
2
2
|
module Models
|
3
3
|
class IdxLink < Base
|
4
|
+
|
5
|
+
extend Finders
|
6
|
+
|
4
7
|
self.element_name="idxlinks"
|
5
8
|
|
6
9
|
LINK_TYPES = ["QuickSearch", "SavedSearch", "MyListings", "Roster"]
|
@@ -34,14 +37,6 @@ module SparkApi
|
|
34
37
|
|
35
38
|
private
|
36
39
|
|
37
|
-
def self.find_every(options)
|
38
|
-
raise NotImplementedError # TODO
|
39
|
-
end
|
40
|
-
|
41
|
-
def self.find_one(options)
|
42
|
-
raise NotImplementedError # TODO
|
43
|
-
end
|
44
|
-
|
45
40
|
def self.find_single(scope, options)
|
46
41
|
resp = SparkApi.client.get("/idxlinks/#{scope}", options)
|
47
42
|
new(resp.first)
|
@@ -191,7 +191,26 @@ module SparkApi
|
|
191
191
|
results = connection.put "#{self.class.path}/#{self.Id}/photos", arguments
|
192
192
|
true
|
193
193
|
end
|
194
|
-
|
194
|
+
|
195
|
+
def reorder_photo(photo_id, index)
|
196
|
+
unless Integer(index)
|
197
|
+
raise ArgumentError, "Photo reorder failed. '#{index}' is not a number."
|
198
|
+
end
|
199
|
+
|
200
|
+
begin
|
201
|
+
return reorder_photo!(photo_id, index)
|
202
|
+
rescue BadResourceRequest => e
|
203
|
+
SparkApi.logger.warn { "Failed to save resource #{self}: #{e.message}" }
|
204
|
+
rescue NotFound => e
|
205
|
+
SparkApi.logger.error { "Failed to save resource #{self}: #{e.message}" }
|
206
|
+
end
|
207
|
+
false
|
208
|
+
end
|
209
|
+
def reorder_photo!(photo_id, index)
|
210
|
+
connection.put "#{self.class.path}/#{self.Id}/photos/#{photo_id}", "Photos" => [{"Order"=>index}]
|
211
|
+
true
|
212
|
+
end
|
213
|
+
|
195
214
|
def editable?(editable_settings = [])
|
196
215
|
settings = Array(editable_settings)
|
197
216
|
editable = attributes.include?("Permissions") && self.Permissions["Editable"] == true
|
@@ -15,11 +15,12 @@ module SparkApi
|
|
15
15
|
def ListingIds=(listing_ids)
|
16
16
|
write_attribute("ListingIds", Array(listing_ids))
|
17
17
|
end
|
18
|
+
|
18
19
|
def Name=(name)
|
19
20
|
write_attribute("Name", name)
|
20
21
|
end
|
21
22
|
|
22
|
-
def path
|
23
|
+
def self.path
|
23
24
|
if @contact_id
|
24
25
|
"/contacts/#{@contact_id}/listingcarts"
|
25
26
|
else
|
@@ -27,6 +28,15 @@ module SparkApi
|
|
27
28
|
end
|
28
29
|
end
|
29
30
|
|
31
|
+
def filter
|
32
|
+
"ListingCart Eq '#{self.Id}'"
|
33
|
+
end
|
34
|
+
|
35
|
+
def listings(args = {})
|
36
|
+
return [] if attributes["ListingIds"].nil?
|
37
|
+
Listing.collect(connection.get("#{self.path}/#{self.Id}/listings", args))
|
38
|
+
end
|
39
|
+
|
30
40
|
def add_listing(listing)
|
31
41
|
ids = listing.respond_to?(:Id) ? listing.Id : listing
|
32
42
|
results = connection.post("#{self.resource_uri}", {"ListingIds" => Array(ids)})
|
@@ -52,6 +62,10 @@ module SparkApi
|
|
52
62
|
collect(connection.get("/#{self.element_name}/portal", arguments))
|
53
63
|
end
|
54
64
|
|
65
|
+
def deletable?
|
66
|
+
!attributes.has_key?("PortalCartType") || self.PortalCartType == "Custom"
|
67
|
+
end
|
68
|
+
|
55
69
|
end
|
56
70
|
end
|
57
71
|
end
|
@@ -8,6 +8,11 @@ module SparkApi
|
|
8
8
|
|
9
9
|
attr_accessor :newsfeeds
|
10
10
|
|
11
|
+
# Newsfeed restriction criteria for saved searches:
|
12
|
+
# http://alpha.sparkplatform.com/docs/api_services/newsfeed/restrictions#criteria
|
13
|
+
QUALIFYING_FIELDS_FOR_NEWSFEED = %w(BathsTotal BedsTotal City CountyOrParish ListPrice Location MlsStatus
|
14
|
+
PostalCode PropertyType RoomsTotal State)
|
15
|
+
|
11
16
|
self.element_name="savedsearches"
|
12
17
|
|
13
18
|
def initialize(attributes={})
|
@@ -19,12 +24,6 @@ module SparkApi
|
|
19
24
|
Class.new(self).tap do |provided|
|
20
25
|
provided.element_name = '/savedsearches'
|
21
26
|
provided.prefix = '/provided'
|
22
|
-
def provided_search?
|
23
|
-
true
|
24
|
-
end
|
25
|
-
def newsfeeds
|
26
|
-
[]
|
27
|
-
end
|
28
27
|
SparkApi.logger.info("#{self.name}.path: #{provided.path}")
|
29
28
|
end
|
30
29
|
end
|
@@ -33,6 +32,10 @@ module SparkApi
|
|
33
32
|
collect(connection.get("/#{self.element_name}/tags/#{tag}", arguments))
|
34
33
|
end
|
35
34
|
|
35
|
+
def favorite?
|
36
|
+
@attributes["Tags"] && @attributes["Tags"].include?( "Favorites")
|
37
|
+
end
|
38
|
+
|
36
39
|
# list contacts (private role)
|
37
40
|
def contacts
|
38
41
|
return [] unless persisted?
|
@@ -63,36 +66,23 @@ module SparkApi
|
|
63
66
|
end
|
64
67
|
|
65
68
|
def listings(args = {})
|
66
|
-
arguments = {:_filter => self.
|
67
|
-
arguments.merge!(:RequestMode => 'permissive') if
|
69
|
+
arguments = {:_filter => "SavedSearch Eq '#{self.Id}'"}
|
70
|
+
arguments.merge!(:RequestMode => 'permissive') if Provided?
|
68
71
|
@listings ||= Listing.collect(connection.get("/listings", arguments.merge(args)))
|
69
72
|
end
|
70
73
|
|
71
74
|
def newsfeeds
|
72
|
-
|
73
|
-
|
74
|
-
# the response from the api is just a bunch of hashes, but we can turn them into Newsfeed instances
|
75
|
-
@newsfeeds = response.map { |hash| Newsfeed.new(hash) }
|
76
|
-
end
|
77
|
-
@newsfeeds
|
78
|
-
end
|
79
|
-
|
80
|
-
def provided_search?
|
81
|
-
false
|
75
|
+
Newsfeed.collect(connection.get("#{self.class.path}/#{@attributes["Id"]}",
|
76
|
+
:_expand => "NewsFeeds").first["NewsFeeds"])
|
82
77
|
end
|
83
78
|
|
84
79
|
def can_have_newsfeed?
|
85
80
|
|
86
|
-
return false if provided_search?
|
87
81
|
return true if has_active_newsfeed? || has_inactive_newsfeed?
|
88
82
|
|
89
|
-
# Newsfeed restriction criteria for saved searches:
|
90
|
-
# http://alpha.sparkplatform.com/docs/api_services/newsfeed/restrictions#criteria
|
91
|
-
standard_fields = %w(BathsTotal BedsTotal City CountyOrParish ListPrice Location MlsStatus PostalCode PropertyType RoomsTotal State)
|
92
|
-
|
93
83
|
number_of_filters = 0
|
94
84
|
|
95
|
-
|
85
|
+
QUALIFYING_FIELDS_FOR_NEWSFEED.each do |field|
|
96
86
|
number_of_filters += 1 if self.Filter.include? field
|
97
87
|
end
|
98
88
|
|
@@ -101,24 +91,22 @@ module SparkApi
|
|
101
91
|
end
|
102
92
|
|
103
93
|
def has_active_newsfeed?
|
104
|
-
return false if provided_search?
|
105
|
-
|
106
94
|
if self.respond_to? "NewsFeedSubscriptionSummary"
|
107
95
|
self.NewsFeedSubscriptionSummary['ActiveSubscription']
|
108
96
|
else
|
109
|
-
|
110
|
-
|
97
|
+
search = connection.get "#{self.class.path}/#{@attributes['Id']}",
|
98
|
+
{"_expand" => "NewsFeedSubscriptionSummary"}
|
99
|
+
search.first["NewsFeedSubscriptionSummary"]["ActiveSubscription"]
|
111
100
|
end
|
112
101
|
end
|
113
102
|
|
114
103
|
def has_inactive_newsfeed?
|
115
|
-
|
116
|
-
|
117
|
-
if self.respond_to? "NewsFeedSubscriptionSummary"
|
118
|
-
!self.NewsFeedSubscriptionSummary['ActiveSubscription']
|
104
|
+
if self.respond_to?("NewsFeeds") && self.respond_to?("NewsFeedSubscriptionSummary")
|
105
|
+
self.NewsFeeds.any? && !self.NewsFeedSubscriptionSummary['ActiveSubscription']
|
119
106
|
else
|
120
|
-
|
121
|
-
|
107
|
+
search = connection.get("#{self.class.path}/#{@attributes['Id']}",
|
108
|
+
{"_expand" => "NewsFeedSubscriptionSummary, NewsFeeds"}).first
|
109
|
+
search["NewsFeeds"].any? && !search["NewsFeedSubscriptionSummary"]["ActiveSubscription"]
|
122
110
|
end
|
123
111
|
end
|
124
112
|
|
data/script/bootstrap
ADDED
data/script/ci_build
ADDED
data/script/release
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
{
|
2
|
+
"D": {
|
3
|
+
"Results": [
|
4
|
+
{
|
5
|
+
"Uri300": "http://photos.flexmls.com/fgo/20050505220032167405000000.jpg",
|
6
|
+
"ResourceUri": "/v1/listings/20050505200220759069000000/photos/20050505220032167405000000",
|
7
|
+
"Name": "Front",
|
8
|
+
"Primary": true,
|
9
|
+
"Uri800": "http://cdn.resize.flexmls.com/fgo/800x600/true/20050505220032167405000000-o.jpg",
|
10
|
+
"Id": "20050505220032167405000000",
|
11
|
+
"UriLarge": "http://photos.flexmls.com/fgo/20050505220032167405000000-o.jpg",
|
12
|
+
"Uri1024": "http://cdn.resize.flexmls.com/fgo/1024x768/true/20050505220032167405000000-o.jpg",
|
13
|
+
"Caption": "",
|
14
|
+
"Uri1280": "http://cdn.resize.flexmls.com/fgo/1280x1024/true/20050505220032167405000000-o.jpg",
|
15
|
+
"Uri640": "http://cdn.resize.flexmls.com/fgo/640x480/true/20050505220032167405000000-o.jpg",
|
16
|
+
"UriThumb": "http://photos.flexmls.com/fgo/20050505220032167405000000-t.jpg"
|
17
|
+
}
|
18
|
+
]
|
19
|
+
}
|
20
|
+
}
|
@@ -0,0 +1,22 @@
|
|
1
|
+
{
|
2
|
+
"D": {
|
3
|
+
"Success": true,
|
4
|
+
"Results": [
|
5
|
+
{
|
6
|
+
"ResourceUri": "/v1/savedsearches/20100815220615294367000000",
|
7
|
+
"Id": "20100815220615294367000000",
|
8
|
+
"Name": "Search name here",
|
9
|
+
"Filter": "City Eq 'Moorhead' And MlsStatus Eq 'Active' And PropertyType Eq 'A'",
|
10
|
+
"ContactIds": [
|
11
|
+
"20100815220615294367000000"
|
12
|
+
],
|
13
|
+
"Provided": true
|
14
|
+
},
|
15
|
+
{
|
16
|
+
"ResourceUri": "/v1/savedsearches/20100615220615292711000000",
|
17
|
+
"Id": "20100615220615292711000000",
|
18
|
+
"Name": "Second search name here"
|
19
|
+
}
|
20
|
+
]
|
21
|
+
}
|
22
|
+
}
|
@@ -0,0 +1,20 @@
|
|
1
|
+
{
|
2
|
+
"D": {
|
3
|
+
"Success": true,
|
4
|
+
"Results": [
|
5
|
+
{
|
6
|
+
"ResourceUri": "/v1/savedsearches/20100815220615294367000000",
|
7
|
+
"Id": "20100815220615294367000000",
|
8
|
+
"Name": "Search name here",
|
9
|
+
"ContactIds": [
|
10
|
+
"20100815220615294367000000"
|
11
|
+
],
|
12
|
+
"NewsFeedSubscriptionSummary": {
|
13
|
+
"ActiveSubscription": false
|
14
|
+
},
|
15
|
+
"NewsFeeds": []
|
16
|
+
}
|
17
|
+
|
18
|
+
]
|
19
|
+
}
|
20
|
+
}
|
@@ -0,0 +1,31 @@
|
|
1
|
+
{
|
2
|
+
"D": {
|
3
|
+
"Results": [
|
4
|
+
{
|
5
|
+
"ResourceUri": "/v1/searchtemplates/sorts/20120717212004874996000000",
|
6
|
+
"Id": "20130717212004874996000000",
|
7
|
+
"Name": "My Custom Listing Sort",
|
8
|
+
"OwnerId": "20000426173054342350000000",
|
9
|
+
"MlsId": "20000426143505724628000000",
|
10
|
+
"Inheritable": true,
|
11
|
+
"Inherited": false,
|
12
|
+
"Fields": [
|
13
|
+
{
|
14
|
+
"Domain": "StandardFields",
|
15
|
+
"GroupField": null,
|
16
|
+
"Field": "ListPrice",
|
17
|
+
"SortType": "Ascending"
|
18
|
+
},
|
19
|
+
{
|
20
|
+
"Domain": "StandardFields",
|
21
|
+
"GroupField": null,
|
22
|
+
"Field": "MlsStatus",
|
23
|
+
"SortType": "Descending"
|
24
|
+
}
|
25
|
+
],
|
26
|
+
"ModificationTimestamp": "2013-07-09T15:31:47Z"
|
27
|
+
}
|
28
|
+
],
|
29
|
+
"Success": true
|
30
|
+
}
|
31
|
+
}
|
data/spec/spec_helper.rb
CHANGED
@@ -1,5 +1,15 @@
|
|
1
|
-
|
1
|
+
if ENV['COVERAGE'] == "on"
|
2
|
+
require 'simplecov'
|
3
|
+
require 'simplecov-rcov'
|
4
|
+
SimpleCov.formatter = SimpleCov::Formatter::RcovFormatter
|
5
|
+
SimpleCov.start do
|
6
|
+
add_filter '/vendor'
|
7
|
+
add_filter '/spec'
|
8
|
+
add_filter '/test'
|
9
|
+
end
|
10
|
+
end
|
2
11
|
|
12
|
+
require "rubygems"
|
3
13
|
require "rspec"
|
4
14
|
require 'rspec/autorun'
|
5
15
|
require 'webmock/rspec'
|
@@ -1,9 +1,13 @@
|
|
1
1
|
require './spec/spec_helper'
|
2
2
|
|
3
3
|
# Sample resource models for testing the base class
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
module SparkApi
|
5
|
+
module Models
|
6
|
+
class MyExampleModel < Base
|
7
|
+
self.element_name = "example"
|
8
|
+
self.prefix = "/test/"
|
9
|
+
end
|
10
|
+
end
|
7
11
|
end
|
8
12
|
|
9
13
|
class MyDefaultModel < Base
|
@@ -153,4 +157,11 @@ describe Base, "Base model" do
|
|
153
157
|
|
154
158
|
end
|
155
159
|
|
160
|
+
describe "to_partial_path" do
|
161
|
+
it "should return the partial path" do
|
162
|
+
model = MyExampleModel.new()
|
163
|
+
model.to_partial_path.should eq("my_example_models/my_example_model")
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
156
167
|
end
|
@@ -133,4 +133,43 @@ describe ListingCart do
|
|
133
133
|
end
|
134
134
|
end
|
135
135
|
|
136
|
+
describe "#listings" do
|
137
|
+
it "should return the listings in the cart" do
|
138
|
+
resource = subject.class.new Id: 5, ListingIds: ["1234"]
|
139
|
+
stub_api_get("/#{subject.class.element_name}/#{resource.Id}/listings", 'listings/multiple.json')
|
140
|
+
resource.listings.should be_a(Array)
|
141
|
+
resource.listings.first.should be_a(Listing)
|
142
|
+
end
|
143
|
+
|
144
|
+
it "should return an empty array if there aren't any listings" do
|
145
|
+
resource = subject.class.new Id: 5
|
146
|
+
resource.listings.should be_a(Array)
|
147
|
+
resource.listings.count.should === 0
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
describe "filter" do
|
152
|
+
it "should return a filter string for the cart" do
|
153
|
+
resource = subject.class.new Id: 5
|
154
|
+
resource.filter.should eq("ListingCart Eq '5'")
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
describe "#deletable?" do
|
159
|
+
it "should return true for private custom carts" do
|
160
|
+
resource = subject.class.new
|
161
|
+
expect(resource.deletable?).to be_true
|
162
|
+
end
|
163
|
+
|
164
|
+
it "should return true for custom vow carts" do
|
165
|
+
resource = subject.class.new PortalCartType: "Custom"
|
166
|
+
expect(resource.deletable?).to be_true
|
167
|
+
end
|
168
|
+
|
169
|
+
it "should return false for vow carts" do
|
170
|
+
resource = subject.class.new PortalCartType: "Favorites"
|
171
|
+
expect(resource.deletable?).to be_false
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
136
175
|
end
|
@@ -251,6 +251,23 @@ describe Listing do
|
|
251
251
|
l.errors.size.should eq(1)
|
252
252
|
end
|
253
253
|
|
254
|
+
on_put_it "should reorder a photo" do
|
255
|
+
list_id = "20060725224713296297000000"
|
256
|
+
stub_api_get("/listings/#{list_id}", 'listings/with_photos.json')
|
257
|
+
stub_api_put("/listings/#{list_id}/photos/20110826220032167405000000", 'listings/put_reorder_photo.json', 'listings/reorder_photo.json')
|
258
|
+
l = Listing.find(list_id)
|
259
|
+
l.reorder_photo("20110826220032167405000000", "2")
|
260
|
+
l.photos.size.should eq(5)
|
261
|
+
end
|
262
|
+
|
263
|
+
on_put_it "should raise an exception when an index is not an Integer" do
|
264
|
+
list_id = "20060725224713296297000000"
|
265
|
+
stub_api_get("/listings/#{list_id}", 'listings/with_photos.json')
|
266
|
+
stub_api_put("/listings/#{list_id}/photos/2011082622003216740500000", 'listings/put_reorder_photo.json', 'listings/reorder_photo.json')
|
267
|
+
l = Listing.find(list_id)
|
268
|
+
expect{ l.reorder_photo("2011082622003216740500000", "asdf") }.to raise_error(ArgumentError)
|
269
|
+
end
|
270
|
+
|
254
271
|
context "with pagination" do
|
255
272
|
# This is really a bogus call, but we should make sure our
|
256
273
|
# pagination collection impl still behaves sanely
|
@@ -104,25 +104,24 @@ describe SavedSearch do
|
|
104
104
|
it "should return the searches listings" do
|
105
105
|
stub_api_get("/#{subject.class.element_name}/#{id}", 'saved_searches/get.json')
|
106
106
|
stub_api_get("/listings", 'listings/multiple.json',
|
107
|
-
{:_filter => "
|
107
|
+
{:_filter => "SavedSearch Eq '#{id}'"})
|
108
108
|
listings = subject.class.find(id).listings
|
109
109
|
listings.should be_an(Array)
|
110
110
|
listings[0].should be_a(Listing)
|
111
111
|
end
|
112
112
|
|
113
113
|
it "should include the permissive parameter for provided searches" do
|
114
|
-
stub_api_get("/provided/savedsearches/#{id}", 'saved_searches/
|
114
|
+
stub_api_get("/provided/savedsearches/#{id}", 'saved_searches/get_provided.json')
|
115
115
|
resource = subject.class.provided.find(id)
|
116
116
|
expect(SparkApi.client).to receive(:get).with("/listings",
|
117
|
-
{:_filter =>
|
117
|
+
{:_filter => "SavedSearch Eq '#{id}'", :RequestMode => 'permissive'})
|
118
118
|
resource.listings
|
119
119
|
end
|
120
120
|
|
121
121
|
it "should not include the permissive parameter for saved searches" do
|
122
122
|
stub_api_get("/#{subject.class.element_name}/#{id}", 'saved_searches/get.json')
|
123
123
|
resource = subject.class.find(id)
|
124
|
-
|
125
|
-
expect(SparkApi.client).to receive(:get).with("/listings", {:_filter => resource.Filter})
|
124
|
+
expect(SparkApi.client).to receive(:get).with("/listings", {:_filter => "SavedSearch Eq '#{id}'"})
|
126
125
|
resource.listings
|
127
126
|
end
|
128
127
|
|
@@ -165,17 +164,25 @@ describe SavedSearch do
|
|
165
164
|
end
|
166
165
|
end
|
167
166
|
|
168
|
-
describe "
|
167
|
+
describe "favorite?" do
|
168
|
+
it "should return true if the search has been tagged as a favorite" do
|
169
|
+
search = SavedSearch.new(Tags: ["Favorites"])
|
170
|
+
search.should be_favorite
|
171
|
+
end
|
169
172
|
|
170
|
-
it "should return false
|
171
|
-
|
172
|
-
|
173
|
-
resource.can_have_newsfeed?.should == false
|
173
|
+
it "should return false if the search has not been tagged as a favorite" do
|
174
|
+
search = SavedSearch.new
|
175
|
+
search.should_not be_favorite
|
174
176
|
end
|
177
|
+
end
|
178
|
+
|
179
|
+
describe "can_have_newsfeed?" do
|
175
180
|
|
176
181
|
it "should return false without at least three filter parameters" do
|
177
182
|
stub_api_get("/#{subject.class.element_name}/#{id}", 'saved_searches/get.json')
|
178
183
|
resource = subject.class.find(id)
|
184
|
+
resource.stub(:has_active_newsfeed?) { false }
|
185
|
+
resource.stub(:has_inactive_newsfeed?) { false }
|
179
186
|
resource.Filter = "City Eq 'Moorhead' And MlsStatus Eq 'Active'"
|
180
187
|
resource.can_have_newsfeed?.should == false
|
181
188
|
end
|
@@ -183,7 +190,6 @@ describe SavedSearch do
|
|
183
190
|
it "should return true with three filter parameters" do
|
184
191
|
stub_api_get("/#{subject.class.element_name}/#{id}", 'saved_searches/get.json')
|
185
192
|
resource = subject.class.find(id)
|
186
|
-
resource.stub(:provided_search?) { false }
|
187
193
|
resource.stub(:has_active_newsfeed?) { false }
|
188
194
|
resource.stub(:has_inactive_newsfeed?) { false }
|
189
195
|
resource.can_have_newsfeed?.should == true
|
@@ -197,13 +203,14 @@ describe SavedSearch do
|
|
197
203
|
stub_api_get("/#{subject.class.element_name}/#{id}", 'saved_searches/with_newsfeed.json',
|
198
204
|
{ "_expand" => "NewsFeedSubscriptionSummary" } )
|
199
205
|
resource = subject.class.find(id)
|
200
|
-
resource.stub(:provided_search?) { false }
|
201
206
|
resource.has_active_newsfeed?.should == true
|
202
207
|
end
|
203
208
|
|
204
|
-
it "should return false
|
205
|
-
stub_api_get("
|
206
|
-
|
209
|
+
it "should return false if the search doesn't have a newsfeed" do
|
210
|
+
stub_api_get("/#{subject.class.element_name}/#{id}", 'saved_searches/get.json')
|
211
|
+
stub_api_get("/#{subject.class.element_name}/#{id}", 'saved_searches/without_newsfeed.json',
|
212
|
+
{ "_expand" => "NewsFeedSubscriptionSummary" } )
|
213
|
+
resource = subject.class.find(id)
|
207
214
|
resource.has_active_newsfeed?.should == false
|
208
215
|
end
|
209
216
|
end
|
@@ -214,15 +221,17 @@ describe SavedSearch do
|
|
214
221
|
stub_api_get("/#{subject.class.element_name}/#{id}", 'saved_searches/with_inactive_newsfeed.json',
|
215
222
|
{ "_expand" => "NewsFeedSubscriptionSummary" } )
|
216
223
|
resource = subject.class.find(id)
|
217
|
-
resource.stub(:provided_search?) { false }
|
218
224
|
resource.has_inactive_newsfeed?.should == true
|
219
225
|
end
|
220
226
|
|
221
|
-
it "should return false
|
222
|
-
stub_api_get("
|
223
|
-
|
227
|
+
it "should return false if the search doesn't have a newsfeed" do
|
228
|
+
stub_api_get("/#{subject.class.element_name}/#{id}", 'saved_searches/get.json')
|
229
|
+
stub_api_get("/#{subject.class.element_name}/#{id}", 'saved_searches/without_newsfeed.json',
|
230
|
+
{ "_expand" => "NewsFeedSubscriptionSummary, NewsFeeds" } )
|
231
|
+
resource = subject.class.find(id)
|
224
232
|
resource.has_inactive_newsfeed?.should == false
|
225
233
|
end
|
234
|
+
|
226
235
|
end
|
227
236
|
|
228
237
|
describe "newsfeed" do
|
@@ -235,4 +244,10 @@ describe SavedSearch do
|
|
235
244
|
end
|
236
245
|
end
|
237
246
|
|
247
|
+
describe "QUALIFYING_FIELDS_FOR_NEWSFEED" do
|
248
|
+
it "should return an array" do
|
249
|
+
subject.class::QUALIFYING_FIELDS_FOR_NEWSFEED.should be_an(Array)
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
238
253
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require './spec/spec_helper'
|
2
|
+
|
3
|
+
describe Sort do
|
4
|
+
before(:each) do
|
5
|
+
stub_auth_request
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should include the finders module" do
|
9
|
+
Sort.should respond_to(:find)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should return sorts" do
|
13
|
+
stub_api_get("/searchtemplates/sorts", 'sorts/get.json')
|
14
|
+
sorts = Sort.find(:all)
|
15
|
+
sorts.should be_an(Array)
|
16
|
+
sorts.length.should eq(1)
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spark_api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.3.
|
4
|
+
version: 1.3.25
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brandon Hornseth
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-
|
12
|
+
date: 2015-07-06 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: faraday
|
@@ -192,21 +192,21 @@ dependencies:
|
|
192
192
|
- !ruby/object:Gem::Version
|
193
193
|
version: 0.9.9
|
194
194
|
- !ruby/object:Gem::Dependency
|
195
|
-
name:
|
195
|
+
name: rb-readline
|
196
196
|
requirement: !ruby/object:Gem::Requirement
|
197
197
|
requirements:
|
198
|
-
- -
|
198
|
+
- - ! '>='
|
199
199
|
- !ruby/object:Gem::Version
|
200
|
-
version: 0
|
200
|
+
version: '0'
|
201
201
|
type: :development
|
202
202
|
prerelease: false
|
203
203
|
version_requirements: !ruby/object:Gem::Requirement
|
204
204
|
requirements:
|
205
|
-
- -
|
205
|
+
- - ! '>='
|
206
206
|
- !ruby/object:Gem::Version
|
207
|
-
version: 0
|
207
|
+
version: '0'
|
208
208
|
- !ruby/object:Gem::Dependency
|
209
|
-
name: rb-
|
209
|
+
name: rb-fsevent
|
210
210
|
requirement: !ruby/object:Gem::Requirement
|
211
211
|
requirements:
|
212
212
|
- - ! '>='
|
@@ -220,7 +220,21 @@ dependencies:
|
|
220
220
|
- !ruby/object:Gem::Version
|
221
221
|
version: '0'
|
222
222
|
- !ruby/object:Gem::Dependency
|
223
|
-
name:
|
223
|
+
name: simplecov
|
224
|
+
requirement: !ruby/object:Gem::Requirement
|
225
|
+
requirements:
|
226
|
+
- - ! '>='
|
227
|
+
- !ruby/object:Gem::Version
|
228
|
+
version: '0'
|
229
|
+
type: :development
|
230
|
+
prerelease: false
|
231
|
+
version_requirements: !ruby/object:Gem::Requirement
|
232
|
+
requirements:
|
233
|
+
- - ! '>='
|
234
|
+
- !ruby/object:Gem::Version
|
235
|
+
version: '0'
|
236
|
+
- !ruby/object:Gem::Dependency
|
237
|
+
name: simplecov-rcov
|
224
238
|
requirement: !ruby/object:Gem::Requirement
|
225
239
|
requirements:
|
226
240
|
- - ! '>='
|
@@ -300,11 +314,13 @@ files:
|
|
300
314
|
- lib/spark_api/models/open_house.rb
|
301
315
|
- lib/spark_api/models/photo.rb
|
302
316
|
- lib/spark_api/models/portal.rb
|
317
|
+
- lib/spark_api/models/portal_listing_cart.rb
|
303
318
|
- lib/spark_api/models/property_types.rb
|
304
319
|
- lib/spark_api/models/rental_calendar.rb
|
305
320
|
- lib/spark_api/models/saved_search.rb
|
306
321
|
- lib/spark_api/models/search_template/quick_search.rb
|
307
322
|
- lib/spark_api/models/shared_listing.rb
|
323
|
+
- lib/spark_api/models/sort.rb
|
308
324
|
- lib/spark_api/models/standard_fields.rb
|
309
325
|
- lib/spark_api/models/subresource.rb
|
310
326
|
- lib/spark_api/models/system_info.rb
|
@@ -319,10 +335,13 @@ files:
|
|
319
335
|
- lib/spark_api/request.rb
|
320
336
|
- lib/spark_api/response.rb
|
321
337
|
- lib/spark_api/version.rb
|
338
|
+
- script/bootstrap
|
339
|
+
- script/ci_build
|
322
340
|
- script/combined_flow_example.rb
|
323
341
|
- script/console
|
324
342
|
- script/example.rb
|
325
343
|
- script/oauth2_example.rb
|
344
|
+
- script/release
|
326
345
|
- spec/fixtures/accounts/all.json
|
327
346
|
- spec/fixtures/accounts/my.json
|
328
347
|
- spec/fixtures/accounts/my_portal.json
|
@@ -387,7 +406,9 @@ files:
|
|
387
406
|
- spec/fixtures/listings/photos/rotate.json
|
388
407
|
- spec/fixtures/listings/put.json
|
389
408
|
- spec/fixtures/listings/put_expiration_date.json
|
409
|
+
- spec/fixtures/listings/put_reorder_photo.json
|
390
410
|
- spec/fixtures/listings/rental_calendar.json
|
411
|
+
- spec/fixtures/listings/reorder_photo.json
|
391
412
|
- spec/fixtures/listings/shared_listing_get.json
|
392
413
|
- spec/fixtures/listings/shared_listing_new.json
|
393
414
|
- spec/fixtures/listings/shared_listing_post.json
|
@@ -437,13 +458,16 @@ files:
|
|
437
458
|
- spec/fixtures/portal/post.json
|
438
459
|
- spec/fixtures/property_types/property_types.json
|
439
460
|
- spec/fixtures/saved_searches/get.json
|
461
|
+
- spec/fixtures/saved_searches/get_provided.json
|
440
462
|
- spec/fixtures/saved_searches/new.json
|
441
463
|
- spec/fixtures/saved_searches/post.json
|
442
464
|
- spec/fixtures/saved_searches/update.json
|
443
465
|
- spec/fixtures/saved_searches/with_inactive_newsfeed.json
|
444
466
|
- spec/fixtures/saved_searches/with_newsfeed.json
|
467
|
+
- spec/fixtures/saved_searches/without_newsfeed.json
|
445
468
|
- spec/fixtures/search_templates/quick_searches/get.json
|
446
469
|
- spec/fixtures/session.json
|
470
|
+
- spec/fixtures/sorts/get.json
|
447
471
|
- spec/fixtures/standardfields/city.json
|
448
472
|
- spec/fixtures/standardfields/nearby.json
|
449
473
|
- spec/fixtures/standardfields/standardfields.json
|
@@ -487,6 +511,7 @@ files:
|
|
487
511
|
- spec/unit/spark_api/models/saved_search_spec.rb
|
488
512
|
- spec/unit/spark_api/models/search_template/quick_search_spec.rb
|
489
513
|
- spec/unit/spark_api/models/shared_listing_spec.rb
|
514
|
+
- spec/unit/spark_api/models/sort_spec.rb
|
490
515
|
- spec/unit/spark_api/models/standard_fields_spec.rb
|
491
516
|
- spec/unit/spark_api/models/subresource_spec.rb
|
492
517
|
- spec/unit/spark_api/models/system_info_spec.rb
|
@@ -537,6 +562,7 @@ test_files:
|
|
537
562
|
- spec/fixtures/fields/order.json
|
538
563
|
- spec/fixtures/success.json
|
539
564
|
- spec/fixtures/session.json
|
565
|
+
- spec/fixtures/sorts/get.json
|
540
566
|
- spec/fixtures/oauth2_error.json
|
541
567
|
- spec/fixtures/base.json
|
542
568
|
- spec/fixtures/idx_links/get.json
|
@@ -597,6 +623,8 @@ test_files:
|
|
597
623
|
- spec/fixtures/saved_searches/update.json
|
598
624
|
- spec/fixtures/saved_searches/new.json
|
599
625
|
- spec/fixtures/saved_searches/with_newsfeed.json
|
626
|
+
- spec/fixtures/saved_searches/get_provided.json
|
627
|
+
- spec/fixtures/saved_searches/without_newsfeed.json
|
600
628
|
- spec/fixtures/saved_searches/get.json
|
601
629
|
- spec/fixtures/saved_searches/with_inactive_newsfeed.json
|
602
630
|
- spec/fixtures/messages/post.json
|
@@ -604,6 +632,8 @@ test_files:
|
|
604
632
|
- spec/fixtures/messages/new.json
|
605
633
|
- spec/fixtures/messages/new_empty.json
|
606
634
|
- spec/fixtures/messages/get.json
|
635
|
+
- spec/fixtures/listings/put_reorder_photo.json
|
636
|
+
- spec/fixtures/listings/reorder_photo.json
|
607
637
|
- spec/fixtures/listings/constraints.json
|
608
638
|
- spec/fixtures/listings/tour_of_homes_search.json
|
609
639
|
- spec/fixtures/listings/tour_of_homes.json
|
@@ -679,6 +709,7 @@ test_files:
|
|
679
709
|
- spec/unit/spark_api/models/account_spec.rb
|
680
710
|
- spec/unit/spark_api/models/listing_spec.rb
|
681
711
|
- spec/unit/spark_api/models/video_spec.rb
|
712
|
+
- spec/unit/spark_api/models/sort_spec.rb
|
682
713
|
- spec/unit/spark_api/models/saved_search_spec.rb
|
683
714
|
- spec/unit/spark_api/models/contact_spec.rb
|
684
715
|
- spec/unit/spark_api/models/portal_spec.rb
|