you_got_listed 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. data/.document +5 -0
  2. data/.gitignore +25 -0
  3. data/Gemfile +2 -0
  4. data/LICENSE +20 -0
  5. data/README.rdoc +226 -0
  6. data/Rakefile +18 -0
  7. data/lib/you_got_listed.rb +17 -0
  8. data/lib/you_got_listed/accounts.rb +9 -0
  9. data/lib/you_got_listed/agent.rb +24 -0
  10. data/lib/you_got_listed/client.rb +25 -0
  11. data/lib/you_got_listed/complex.rb +42 -0
  12. data/lib/you_got_listed/complexes.rb +53 -0
  13. data/lib/you_got_listed/error.rb +17 -0
  14. data/lib/you_got_listed/lead.rb +13 -0
  15. data/lib/you_got_listed/listing.rb +73 -0
  16. data/lib/you_got_listed/listings.rb +110 -0
  17. data/lib/you_got_listed/resource.rb +19 -0
  18. data/lib/you_got_listed/response.rb +25 -0
  19. data/lib/you_got_listed/version.rb +3 -0
  20. data/spec/fixtures/responses/error.xml +2 -0
  21. data/spec/spec.opts +1 -0
  22. data/spec/spec_helper.rb +18 -0
  23. data/spec/support/complex_helper.rb +82 -0
  24. data/spec/support/listing_helper.rb +59 -0
  25. data/spec/support/webmock_helper.rb +26 -0
  26. data/spec/you_got_listed/accounts_spec.rb +26 -0
  27. data/spec/you_got_listed/agent_spec.rb +94 -0
  28. data/spec/you_got_listed/client_spec.rb +17 -0
  29. data/spec/you_got_listed/complex_spec.rb +26 -0
  30. data/spec/you_got_listed/complexes_spec.rb +80 -0
  31. data/spec/you_got_listed/error_spec.rb +10 -0
  32. data/spec/you_got_listed/lead_spec.rb +56 -0
  33. data/spec/you_got_listed/listing_spec.rb +110 -0
  34. data/spec/you_got_listed/listings_spec.rb +229 -0
  35. data/spec/you_got_listed/resource_spec.rb +17 -0
  36. data/spec/you_got_listed/response_spec.rb +119 -0
  37. data/spec/you_got_listed_api_key.yml.example +1 -0
  38. data/you_got_listed.gemspec +31 -0
  39. metadata +231 -0
@@ -0,0 +1,26 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe YouGotListed::Accounts do
4
+
5
+ before do
6
+ @ygl = new_ygl
7
+ @accounts = YouGotListed::Accounts.new(@ygl)
8
+ end
9
+
10
+ context "search" do
11
+ before do
12
+ VCR.use_cassette('accounts.search') do
13
+ @response = @accounts.search
14
+ end
15
+ end
16
+
17
+ it "should be a success" do
18
+ @response.success?.should be_true
19
+ end
20
+
21
+ it "should set accounts on the response" do
22
+ @response.ygl_response.accounts.should be_kind_of(Hashie::Rash)
23
+ end
24
+ end
25
+
26
+ end
@@ -0,0 +1,94 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe YouGotListed::Agent do
4
+
5
+ before do
6
+ @ygl = new_ygl
7
+ @agent = YouGotListed::Agent.new(@ygl)
8
+ end
9
+
10
+ context "find_all" do
11
+ before do
12
+ VCR.use_cassette('agent.find_all') do
13
+ @response = @agent.find_all
14
+ end
15
+ end
16
+
17
+ it "should be a success" do
18
+ @response.success?.should be_true
19
+ end
20
+
21
+ it "should return an array of agents" do
22
+ @response.agents.agent.should_not be_nil
23
+ @response.agents.agent.should be_kind_of(Array)
24
+ end
25
+ end
26
+
27
+ context "successful find" do
28
+ before do
29
+ VCR.use_cassette('agent.find_all') do
30
+ @valid_agent_id = @agent.find_all.agents.agent.first.id
31
+ end
32
+ VCR.use_cassette('agent.find') do
33
+ @response = @agent.find(@valid_agent_id)
34
+ end
35
+ end
36
+
37
+ it "should be a success" do
38
+ @response.success?.should be_true
39
+ end
40
+
41
+ it "should return an array of agents" do
42
+ @response.agents.agent.should_not be_nil
43
+ @response.agents.agent.should be_kind_of(Hashie::Rash)
44
+ end
45
+ end
46
+
47
+ context "unsuccessful find" do
48
+ it "should raise an exception" do
49
+ lambda {
50
+ VCR.use_cassette('agent.find.error') do
51
+ @response = @agent.find('AG-001-0499957')
52
+ end
53
+ }.should raise_exception(YouGotListed::Error, "YouGotListed Error: Invalid user id. (code: 301)")
54
+ end
55
+ end
56
+
57
+ context "successful find_by_id" do
58
+ before do
59
+ VCR.use_cassette('agent.find_all') do
60
+ @valid_agent_id = @agent.find_all.agents.agent.first.id
61
+ end
62
+ VCR.use_cassette('agent.find') do
63
+ @response = @agent.find_by_id(@valid_agent_id)
64
+ end
65
+ end
66
+
67
+ it "should be a success" do
68
+ @response.success?.should be_true
69
+ end
70
+
71
+ it "should return an array of agents" do
72
+ @response.agents.agent.should_not be_nil
73
+ @response.agents.agent.should be_kind_of(Hashie::Rash)
74
+ end
75
+ end
76
+
77
+ context "unsuccessful find_by_id" do
78
+ it "should raise an exception" do
79
+ lambda {
80
+ VCR.use_cassette('agent.find.error') do
81
+ @response = @agent.find_by_id('AG-001-0499957')
82
+ end
83
+ }.should_not raise_exception
84
+ end
85
+
86
+ it "should not be a success" do
87
+ VCR.use_cassette('agent.find.error') do
88
+ @response = @agent.find_by_id('AG-001-0499957')
89
+ end
90
+ @response.success?.should be_false
91
+ end
92
+ end
93
+
94
+ end
@@ -0,0 +1,17 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe YouGotListed::Client do
4
+
5
+ before do
6
+ @ygl = new_ygl
7
+ end
8
+
9
+ it "should set the api_key" do
10
+ @ygl.class.default_params.should == {:key => YGL_API_KEY}
11
+ end
12
+
13
+ it "should set the base uri" do
14
+ @ygl.class.base_uri.should == "https://yougotlistings.com/api"
15
+ end
16
+
17
+ end
@@ -0,0 +1,26 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe YouGotListed::Complex do
4
+
5
+ before do
6
+ @ygl = new_ygl
7
+ @complex = YouGotListed::Complex.new(valid_complex_rash, @ygl)
8
+ end
9
+
10
+ it "should return photos for pictures" do
11
+ @complex.pictures.should == @complex.photos.photo
12
+ end
13
+
14
+ it "should create methods from all hash keys" do
15
+ @complex.should respond_to("id", "name", "addresses", "public_notes", "photos", "listings")
16
+ end
17
+
18
+ it "should return an array of properties" do
19
+ @complex.properties.should be_kind_of(Array)
20
+ @complex.properties.each do |property|
21
+ property.should be_kind_of(YouGotListed::Listing)
22
+ end
23
+ @complex.properties.size.should == 2
24
+ end
25
+
26
+ end
@@ -0,0 +1,80 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe YouGotListed::Complexes do
4
+
5
+ before do
6
+ @ygl = new_ygl
7
+ @complexes = YouGotListed::Complexes.new(@ygl)
8
+ end
9
+
10
+ context "search" do
11
+ before do
12
+ VCR.use_cassette('complexes.search') do
13
+ @response = @complexes.search
14
+ end
15
+ end
16
+
17
+ it { @response.should be_kind_of(YouGotListed::Complexes::SearchResponse) }
18
+ it { @response.success?.should be_true }
19
+
20
+ context "search response" do
21
+ it { @response.should be_kind_of(YouGotListed::Response) }
22
+ it { @response.should respond_to(:property_complexes, :paginator) }
23
+
24
+ it "should return an array of property_complexes" do
25
+ @response.property_complexes.should be_kind_of(Array)
26
+ @response.property_complexes.each do |property|
27
+ property.should be_kind_of(YouGotListed::Complex)
28
+ end
29
+ end
30
+
31
+ it "should return a will_paginate collection" do
32
+ @response.paginator.should be_kind_of(WillPaginate::Collection)
33
+ @response.paginator.collect{|p| p.id}.should == @response.property_complexes.collect{|p| p.id}
34
+ end
35
+ end
36
+ end
37
+
38
+ context "find_by_id" do
39
+ context "valid id" do
40
+ before do
41
+ VCR.use_cassette('complexes.search') do
42
+ @valid_complex_id = @complexes.search.property_complexes.first.id
43
+ end
44
+ VCR.use_cassette('complexes.find_by_id') do
45
+ @complex = @complexes.find_by_id(@valid_complex_id)
46
+ end
47
+ end
48
+
49
+ it { @complex.should be_kind_of(YouGotListed::Complex) }
50
+ end
51
+
52
+ context "missing id" do
53
+ before do
54
+ VCR.use_cassette('complexes.find_by_id_missing') do
55
+ @complex = @complexes.find_by_id('CSM-111-382')
56
+ end
57
+ end
58
+
59
+ it { @complex.should be_nil }
60
+ end
61
+
62
+ context "invalid id" do
63
+ it "should not raise an exception" do
64
+ lambda {
65
+ VCR.use_cassette('complexes.find_by_id_invalid') do
66
+ @complex = @complexes.find_by_id('CAM')
67
+ end
68
+ }.should_not raise_exception
69
+ end
70
+
71
+ it "should be nil" do
72
+ VCR.use_cassette('complexes.find_by_id_invalid') do
73
+ @complex = @complexes.find_by_id('CAM')
74
+ end
75
+ @complex.should be_nil
76
+ end
77
+ end
78
+ end
79
+
80
+ end
@@ -0,0 +1,10 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe YouGotListed::Error do
4
+
5
+ it "should set a message" do
6
+ @error = YouGotListed::Error.new(300, 'Account retrieving failed.')
7
+ @error.message.should == "YouGotListed Error: Account retrieving failed. (code: 300)"
8
+ end
9
+
10
+ end
@@ -0,0 +1,56 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe YouGotListed::Lead do
4
+
5
+ before do
6
+ @ygl = new_ygl
7
+ @lead = YouGotListed::Lead.new(@ygl)
8
+ @success_params = {:first_name => "You", :last_name => "GotListed", :email => "ygl@gmail.com"}
9
+ @failed_params = {}
10
+ end
11
+
12
+ context "create" do
13
+ context "a successful creation" do
14
+ it "should not raise an exception" do
15
+ lambda {
16
+ VCR.use_cassette('lead.create.error') do
17
+ @response = @lead.create(@success_params)
18
+ end
19
+ }.should_not raise_exception
20
+ end
21
+ end
22
+
23
+ context "a failed creation" do
24
+ it "should raise an exception" do
25
+ lambda {
26
+ VCR.use_cassette('lead.create.error') do
27
+ @response = @lead.create(@failed_params)
28
+ end
29
+ }.should_not raise_exception
30
+ end
31
+ end
32
+ end
33
+
34
+ context "create!" do
35
+ context "a successful creation" do
36
+ it "should not raise an exception" do
37
+ lambda {
38
+ VCR.use_cassette('lead.create.error') do
39
+ @response = @lead.create!(@success_params)
40
+ end
41
+ }.should_not raise_exception
42
+ end
43
+ end
44
+
45
+ context "a failed creation" do
46
+ it "should raise an exception" do
47
+ lambda {
48
+ VCR.use_cassette('lead.create.error') do
49
+ @response = @lead.create!(@failed_params)
50
+ end
51
+ }.should raise_exception(YouGotListed::Error, "YouGotListed Error: Lead first name not specified. (code: 303)")
52
+ end
53
+ end
54
+ end
55
+
56
+ end
@@ -0,0 +1,110 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe YouGotListed::Listing do
4
+
5
+ before do
6
+ @ygl = new_ygl
7
+ @listing = YouGotListed::Listing.new(valid_listing_rash, @ygl)
8
+ end
9
+
10
+ it "should create methods from all hash keys" do
11
+ @listing.should respond_to(
12
+ "unit_level", "pet", "include_hot_water", "square_footage", "external_id", "zip", "student_policy",
13
+ "building_id", "parking", "split", "city", "neighborhood", "fee", "heat_source", "street_name",
14
+ "price", "building_type", "include_heat", "beds", "id", "agency_id", "status", "source",
15
+ "longitude", "available_date", "include_electricity", "latitude", "street_number", "unit",
16
+ "include_gas", "state", "baths", "photos"
17
+ )
18
+ end
19
+
20
+ it "should return ygl id for id" do
21
+ @listing.id.should == "BOS-182-933"
22
+ end
23
+
24
+ it "should return the city - neighborhood for town_neighborhood" do
25
+ @listing.town_neighborhood.should == 'Boston - Fenway'
26
+ end
27
+
28
+ it "should return the city_neighborhood search param for city_neighborhood" do
29
+ @listing.city_neighborhood.should == 'Boston:Fenway'
30
+ end
31
+
32
+ it "should return photos for pictures" do
33
+ @listing.pictures.should == @listing.photos.photo
34
+ end
35
+
36
+ context "default similar listings" do
37
+ before do
38
+ VCR.use_cassette('listing.similar_listings') do
39
+ @similar_props = @listing.similar_listings
40
+ end
41
+ end
42
+
43
+ it "should return an array of listings" do
44
+ @similar_props.should be_kind_of(Array)
45
+ @similar_props.should have_at_most(6).listings
46
+ @similar_props.collect{|x| x.id}.should_not include(@listing.id)
47
+ end
48
+ end
49
+
50
+ context "similar listings with custom limit" do
51
+ before do
52
+ VCR.use_cassette('listing.similar_listings') do
53
+ @similar_props = @listing.similar_listings(4)
54
+ end
55
+ end
56
+
57
+ it "should return an array of listings" do
58
+ @similar_props.should be_kind_of(Array)
59
+ @similar_props.should have_at_most(4).listings
60
+ @similar_props.collect{|x| x.id}.should_not include(@listing.id)
61
+ end
62
+ end
63
+
64
+ context "mls_listing" do
65
+ before do
66
+ @listing = YouGotListed::Listing.new(valid_listing_rash.merge(:source => 'MLS'), @ygl)
67
+ end
68
+
69
+ it "should be a mls_listing" do
70
+ @listing.mls_listing?.should be_true
71
+ end
72
+ end
73
+
74
+ context "main_picture" do
75
+ it "should return the first photo" do
76
+ @listing.main_picture.should == @listing.pictures.first
77
+ @listing.main_picture.should == "http://yougotlistings.com/photos/AC-000-103/500141.jpg"
78
+ end
79
+
80
+ it "should return nil if no pictures" do
81
+ @listing.stub!(:pictures).and_return(nil)
82
+ @listing.main_picture.should be_nil
83
+ end
84
+ end
85
+
86
+ context "latitude" do
87
+ it "should return a float" do
88
+ @listing.latitude.should be_kind_of(Float)
89
+ @listing.latitude.should == 42.346182
90
+ end
91
+
92
+ it "should return nil if blank" do
93
+ @listing = YouGotListed::Listing.new(valid_listing_rash.merge(:latitude => ''), @ygl)
94
+ @listing.latitude.should be_nil
95
+ end
96
+ end
97
+
98
+ context "longitude" do
99
+ it "should return a float" do
100
+ @listing.longitude.should be_kind_of(Float)
101
+ @listing.longitude.should == -71.104427
102
+ end
103
+
104
+ it "should return nil if blank" do
105
+ @listing = YouGotListed::Listing.new(valid_listing_rash.merge(:longitude => ''), @ygl)
106
+ @listing.longitude.should be_nil
107
+ end
108
+ end
109
+
110
+ end
@@ -0,0 +1,229 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe YouGotListed::Listings do
4
+
5
+ before do
6
+ @ygl = new_ygl
7
+ @listings = YouGotListed::Listings.new(@ygl)
8
+ end
9
+
10
+ context "search" do
11
+ before do
12
+ VCR.use_cassette('listings.search') do
13
+ @response = @listings.search
14
+ end
15
+ end
16
+
17
+ it { @response.should be_kind_of(YouGotListed::Listings::SearchResponse) }
18
+ it { @response.success?.should be_true }
19
+
20
+ context "search response" do
21
+ it { @response.should be_kind_of(YouGotListed::Response) }
22
+ it { @response.should respond_to(:properties, :paginator) }
23
+
24
+ it "should return an array of properties" do
25
+ @response.properties.should be_kind_of(Array)
26
+ @response.properties.each do |property|
27
+ property.should be_kind_of(YouGotListed::Listing)
28
+ end
29
+ end
30
+
31
+ it "should return a will_paginate collection" do
32
+ @response.paginator.should be_kind_of(WillPaginate::Collection)
33
+ @response.paginator.collect{|p| p.id}.should == @response.properties.collect{|p| p.id}
34
+ end
35
+ end
36
+ end
37
+
38
+ context "mls_search" do
39
+ before do
40
+ VCR.use_cassette('listings.mls_search') do
41
+ @response = @listings.search(:include_mls => "1")
42
+ @response.properties.first.stub!(:source).and_return('MLS')
43
+ end
44
+ end
45
+
46
+ context "search response" do
47
+ it { @response.mls_results?.should be_true }
48
+ end
49
+ end
50
+
51
+ context "featured" do
52
+ before do
53
+ VCR.use_cassette('listings.featured') do
54
+ @response = @listings.featured
55
+ end
56
+ end
57
+
58
+ it "should only return featured properties" do
59
+ @response.properties.find_all{|p| p.tags && p.tags.tag.include?('Featured Rentals')}.size.should == @response.properties.size
60
+ end
61
+ end
62
+
63
+ context "find_by_id" do
64
+ context "valid id" do
65
+ before do
66
+ VCR.use_cassette('listings.search') do
67
+ @valid_listing_id = @listings.search.properties.first.id
68
+ end
69
+ VCR.use_cassette('listings.find_by_id') do
70
+ @listing = @listings.find_by_id(@valid_listing_id)
71
+ end
72
+ end
73
+
74
+ it { @listing.should be_kind_of(YouGotListed::Listing) }
75
+ end
76
+
77
+ context "missing id" do
78
+ before do
79
+ VCR.use_cassette('listings.find_by_id_missing') do
80
+ @listing = @listings.find_by_id('CAM-111-3823475')
81
+ end
82
+ end
83
+
84
+ it { @listing.should be_nil }
85
+ end
86
+
87
+ context "invalid id" do
88
+ it "should not raise an exception" do
89
+ lambda {
90
+ VCR.use_cassette('listings.find_by_id_invalid') do
91
+ @listing = @listings.find_by_id('CAM')
92
+ end
93
+ }.should_not raise_exception
94
+ end
95
+
96
+ it "should be nil" do
97
+ VCR.use_cassette('listings.find_by_id_invalid') do
98
+ @listing = @listings.find_by_id('CAM')
99
+ end
100
+ @listing.should be_nil
101
+ end
102
+ end
103
+ end
104
+
105
+ context "find_all" do
106
+ before do
107
+ search_params = {:max_rent => "2000"}
108
+ VCR.use_cassette('listings.find_all') do
109
+ @properties = @listings.find_all(search_params)
110
+ end
111
+ end
112
+
113
+ it { @properties.should be_kind_of(Array)}
114
+
115
+ it "should only return properties" do
116
+ @properties.each do |p|
117
+ p.should be_kind_of(YouGotListed::Listing)
118
+ end
119
+ end
120
+ end
121
+
122
+ context "find_all_by_ids" do
123
+ before do
124
+ VCR.use_cassette('listings.search') do
125
+ @find_ids = @listings.search.properties.collect{|p| p.id}
126
+ end
127
+ VCR.use_cassette("listings.search_with_off_market") do
128
+ @response = @listings.search(:include_off_market => "1")
129
+ @total_pages = @response.paginator.total_pages
130
+ end
131
+ (1..@total_pages).each do |page_num|
132
+ if property_id = find_off_market_property(@listings, page_num)
133
+ @off_market_id = property_id
134
+ break
135
+ end
136
+ end
137
+ @find_ids_with_off_market = @find_ids.clone
138
+ @find_ids_with_off_market << @off_market_id if @off_market_id
139
+ end
140
+
141
+ context "passing an array of ids" do
142
+ before do
143
+ VCR.use_cassette('listings.find_all_by_ids.array') do
144
+ @properties = @listings.find_all_by_ids(@find_ids)
145
+ end
146
+ end
147
+
148
+ it { @properties.should be_kind_of(Array) }
149
+
150
+ it "should only return properties for requested ids" do
151
+ @properties.each do |p|
152
+ @find_ids.should include(p.id)
153
+ end
154
+ end
155
+ end
156
+
157
+ context "passing an string of ids" do
158
+ before do
159
+ VCR.use_cassette('listings.find_all_by_ids.string') do
160
+ @properties = @listings.find_all_by_ids(@find_ids.join(','))
161
+ end
162
+ end
163
+
164
+ it { @properties.should be_kind_of(Array) }
165
+ end
166
+
167
+ context "should not return off market properties if directed not to" do
168
+ before do
169
+ VCR.use_cassette('listings.find_all_by_ids.no_off_market') do
170
+ @properties = @listings.find_all_by_ids(@find_ids_with_off_market, false)
171
+ end
172
+ end
173
+
174
+ it { @properties.size.should_not == @find_ids_with_off_market.size }
175
+ it { @properties.collect{|p| p.id}.should_not include(@off_market_id) }
176
+ end
177
+
178
+ context "should find all properties including the mls properties" do
179
+ before do
180
+ VCR.use_cassette("listings.search_with_mls") do
181
+ @response = @listings.search(:include_mls => "1")
182
+ @total_pages = @response.paginator.total_pages
183
+ end
184
+ (1..@total_pages).each do |page_num|
185
+ if property_id = find_mls_property(@listings, page_num)
186
+ @mls_id = property_id
187
+ break
188
+ end
189
+ end
190
+ @find_ids_with_mls = @find_ids.clone
191
+ @find_ids_with_mls << @mls_id if @mls_id
192
+ VCR.use_cassette('listings.find_all_by_ids.include_mls') do
193
+ @properties = @listings.find_all_by_ids(@find_ids_with_mls)
194
+ end
195
+ end
196
+
197
+ it { @properties.size.should == @find_ids_with_mls.size }
198
+
199
+ it "should only return properties for requested ids" do
200
+ @properties.each do |p|
201
+ @find_ids_with_mls.should include(p.id)
202
+ end
203
+ end
204
+ end
205
+ end
206
+
207
+ def find_off_market_property(listings, page_id = 1)
208
+ VCR.use_cassette("listings.search_with_off_market.#{page_id}") do
209
+ response = listings.search(:include_off_market => "1", :page_index => page_id)
210
+ if property = response.properties.find{|p| p.status == "OFFMARKET"}
211
+ return property.id
212
+ else
213
+ return nil
214
+ end
215
+ end
216
+ end
217
+
218
+ def find_mls_property(listings, page_id = 1)
219
+ VCR.use_cassette("listings.search_with_mls.#{page_id}") do
220
+ response = listings.search(:include_mls => "1", :page_index => page_id)
221
+ if property = response.properties.find{|p| p.source == "MLS"}
222
+ return property.id
223
+ else
224
+ return nil
225
+ end
226
+ end
227
+ end
228
+
229
+ end