drawbridge 0.2.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/.gitignore +17 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +22 -0
- data/README.md +52 -0
- data/Rakefile +10 -0
- data/drawbridge.gemspec +27 -0
- data/lib/drawbridge.rb +13 -0
- data/lib/drawbridge/adapter.rb +35 -0
- data/lib/drawbridge/config.rb +48 -0
- data/lib/drawbridge/debug.rb +18 -0
- data/lib/drawbridge/mapper.rb +214 -0
- data/lib/drawbridge/refinement_scrubber.rb +26 -0
- data/lib/drawbridge/request.rb +92 -0
- data/lib/drawbridge/result.rb +146 -0
- data/lib/drawbridge/transformer.rb +190 -0
- data/lib/drawbridge/version.rb +3 -0
- data/spec/debug_spec.rb +23 -0
- data/spec/helper.rb +18 -0
- data/spec/refinement_scrubber_spec.rb +68 -0
- data/spec/request_spec.rb +84 -0
- data/spec/result_spec.rb +388 -0
- data/spec/transformer_spec.rb +249 -0
- metadata +175 -0
data/spec/debug_spec.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe Drawbridge::Debug do
|
4
|
+
it "should return line" do
|
5
|
+
Drawbridge::Debug.draw_line.must_equal "*"*80
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should output debugg" do
|
9
|
+
Drawbridge.config.expects(:endeca_debug).returns(true)
|
10
|
+
Drawbridge::Debug.expects(:puts).at_most(3)
|
11
|
+
|
12
|
+
Drawbridge::Debug.log 'test', []
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should not do any debugging" do
|
16
|
+
Drawbridge.config.expects(:endeca_debug).returns(false)
|
17
|
+
Drawbridge::Debug.expects(:puts).never
|
18
|
+
|
19
|
+
Drawbridge::Debug.log 'test', []
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
data/spec/helper.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
lib = File.expand_path('../lib', __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
|
4
|
+
require "drawbridge"
|
5
|
+
require 'minitest/autorun'
|
6
|
+
require 'minitest/spec'
|
7
|
+
require 'minitest/mock'
|
8
|
+
require 'mocha/setup'
|
9
|
+
|
10
|
+
begin
|
11
|
+
require 'turn'
|
12
|
+
rescue LoadError
|
13
|
+
warn 'could not load turn gem'
|
14
|
+
end
|
15
|
+
|
16
|
+
Drawbridge.setup do |config|
|
17
|
+
config.endeca_debug = ENV.fetch('ENDECA_DEBUG') { false }
|
18
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe Drawbridge::RefinementScrubber do
|
4
|
+
|
5
|
+
describe '::scrub' do
|
6
|
+
|
7
|
+
describe 'aggregated refinements' do
|
8
|
+
let(:refinements) { Drawbridge::RefinementScrubber.scrub(aggr_refinements) }
|
9
|
+
let(:properties){ refinements[2]['dimensionvalues'].first['dimvalueproperties'] }
|
10
|
+
|
11
|
+
it 'should add an aggrbins key' do
|
12
|
+
properties['aggrbins'].wont_be_nil
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'should copy the data from DGraph.AggrBins' do
|
16
|
+
properties['aggrbins'].must_equal properties['dgraph.aggrbins']
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe 'non-aggregated refinements' do
|
21
|
+
let(:refinements) {Drawbridge::RefinementScrubber.scrub(non_aggr_refinements)}
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def aggr_refinements
|
27
|
+
[
|
28
|
+
{"dimensionid"=>5885, "dimensionname"=>"price_range"},
|
29
|
+
{"dimensionid"=>3, "dimensionname"=>"bedrooms"},
|
30
|
+
{
|
31
|
+
"dimensionid"=>5974,
|
32
|
+
"dimensionname"=>"_telco",
|
33
|
+
"dimensionvalues"=>
|
34
|
+
[
|
35
|
+
{
|
36
|
+
"dimvaluename"=>"Time Warner Cable",
|
37
|
+
"dimvalueproperties"=>
|
38
|
+
{
|
39
|
+
"dgraph.aggrbins"=>"10",
|
40
|
+
"sortname"=>"Time Warner",
|
41
|
+
"sortfield"=>"timewarner"
|
42
|
+
},
|
43
|
+
"numberofrecords"=>"332",
|
44
|
+
"dimvalueid"=>5978},
|
45
|
+
{
|
46
|
+
"dimvaluename"=>"Verizon FiOS",
|
47
|
+
"dimvalueproperties"=>
|
48
|
+
{
|
49
|
+
"dgraph.aggrbins"=>"33",
|
50
|
+
"sortbar"=>"vzn_sort_bar",
|
51
|
+
"sortname"=>"Verizon",
|
52
|
+
"sortfield"=>"verizon"
|
53
|
+
},
|
54
|
+
"numberofrecords"=>"627",
|
55
|
+
"dimvalueid"=>5976
|
56
|
+
}
|
57
|
+
]
|
58
|
+
}
|
59
|
+
]
|
60
|
+
end
|
61
|
+
|
62
|
+
def non_aggr_refinements
|
63
|
+
[
|
64
|
+
{"dimensionid"=>5885, "dimensionname"=>"price_range"},
|
65
|
+
{"dimensionid"=>3, "dimensionname"=>"bedrooms"}
|
66
|
+
]
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe Drawbridge::Request do
|
4
|
+
|
5
|
+
let(:uri) { 'http://example.com/some-api-path' }
|
6
|
+
let(:query) { 'query=foo' }
|
7
|
+
let(:default_timeout) { 5 }
|
8
|
+
let(:success_code) { 200 }
|
9
|
+
let(:not_found_code) { 404 }
|
10
|
+
|
11
|
+
describe ".perform" do
|
12
|
+
|
13
|
+
it "should initialize new Object and perform a request" do
|
14
|
+
request = MiniTest::Mock.new
|
15
|
+
request.expect :perform, {}
|
16
|
+
Drawbridge::Request.expects(:new).with(uri, query, default_timeout).returns(request)
|
17
|
+
Drawbridge::Request.perform(uri, query)
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "#perform" do
|
23
|
+
|
24
|
+
let(:request) { Drawbridge::Request.new uri, query, default_timeout }
|
25
|
+
|
26
|
+
it "should only make one request" do
|
27
|
+
request.expects(:get_response).once.returns({})
|
28
|
+
request.expects(:handle_response).once.returns({})
|
29
|
+
request.perform
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "sucess" do
|
33
|
+
|
34
|
+
before do
|
35
|
+
mock_curb = MiniTest::Mock.new
|
36
|
+
mock_curb.expect :response_code, success_code
|
37
|
+
mock_curb.expect :body_str, "{\"foo\":\"bar'\t\"}"
|
38
|
+
Curl::Easy.expects(:perform).returns(mock_curb)
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should return json parsed data" do
|
42
|
+
results = request.perform
|
43
|
+
results['foo'].must_equal 'bar''
|
44
|
+
end
|
45
|
+
|
46
|
+
it "does not encode single quotes when skipped" do
|
47
|
+
Drawbridge.config.skip_single_quote_encoding = true
|
48
|
+
results = request.perform
|
49
|
+
results['foo'].must_equal "bar'"
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "unsucess" do
|
55
|
+
let(:mock_curb) { MiniTest::Mock.new }
|
56
|
+
|
57
|
+
it "should return default json" do
|
58
|
+
mock_curb.expect :response_code, not_found_code
|
59
|
+
mock_curb.expect :body_str, ""
|
60
|
+
mock_curb.expect :nil?, true
|
61
|
+
Curl::Easy.expects(:perform).returns(mock_curb)
|
62
|
+
request.perform.must_equal Drawbridge::Request::ResultsError
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should throw RequestError when making HTTP request" do
|
66
|
+
Curl::Easy.expects(:perform).raises(StandardError)
|
67
|
+
lambda{ request.send(:get_response) }.must_raise Drawbridge::Request::RequestError
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'should throw Curl::Err::TimeoutError when request times out' do
|
71
|
+
Curl::Easy.expects(:perform).raises(Curl::Err::TimeoutError)
|
72
|
+
lambda { request.send(:get_response) }.must_raise Curl::Err::TimeoutError
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should throw Oj::ParseError" do
|
76
|
+
mock_curb.expect :response_code, success_code
|
77
|
+
mock_curb.expect :body_str, "!@!@#@NoData|*}"
|
78
|
+
lambda{ request.send(:handle_response, mock_curb) }.must_raise Drawbridge::Request::RequestError
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
data/spec/result_spec.rb
ADDED
@@ -0,0 +1,388 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe Drawbridge::Result do
|
4
|
+
|
5
|
+
describe "aggregated results" do
|
6
|
+
let(:result) { Drawbridge::Result.new(aggregate_result_params) }
|
7
|
+
|
8
|
+
describe 'refinements' do
|
9
|
+
it "should not be empty" do
|
10
|
+
result.refinements.wont_be_empty
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should include dimensionid" do
|
14
|
+
result.refinements.first['dimensionid'].must_equal 5885
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should be downcased" do
|
18
|
+
result.refinements.first['dimensionid'].wont_be_nil
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should downcase inner elements" do
|
22
|
+
result.refinements[2]['dimensionvalues'].first['dimvaluename'].wont_be_nil
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "#meta_info" do
|
27
|
+
it "should not be empty" do
|
28
|
+
result.meta_info.wont_be_empty
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should include pagenumber" do
|
32
|
+
result.meta_info['pagenumber'].must_equal 1
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "#records" do
|
37
|
+
it "should not be empty" do
|
38
|
+
result.records.wont_be_empty
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should access property" do
|
42
|
+
result.records.first['endeca_id'].must_equal '000001'
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should include DerivedProperties in a record" do
|
46
|
+
result.records.first['bed_high'].must_equal '2'
|
47
|
+
end
|
48
|
+
|
49
|
+
describe 'geocode' do
|
50
|
+
it "should convert miles" do
|
51
|
+
result.records.first['miles_to_geocode'].must_equal "9.3"
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should convert kilometers" do
|
55
|
+
result.records.first['kilometers_to_geocode'].must_equal "14.9669"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'should include matched_on' do
|
60
|
+
result.records.first['matched_on'].must_equal({'showapartment' => '1'})
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe "#breadcrumbs" do
|
65
|
+
let(:breadcrumbs) { result.breadcrumbs.first }
|
66
|
+
|
67
|
+
it "should not be empty" do
|
68
|
+
breadcrumbs.wont_be_empty
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should include DimensionName" do
|
72
|
+
breadcrumbs['dimensionname'].must_equal '_source'
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should include DimensionName" do
|
76
|
+
breadcrumbs['dimensionname'].must_equal '_source'
|
77
|
+
end
|
78
|
+
|
79
|
+
describe "DimensionValues" do
|
80
|
+
let(:dim_values) { breadcrumbs['dimensionvalues'].first }
|
81
|
+
|
82
|
+
it "should have DimValueName" do
|
83
|
+
dim_values['dimvaluename'].must_equal 'APTGUIDE'
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should have DimValueID" do
|
87
|
+
dim_values['dimvalueid'].must_equal 5875
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe "#to_stats_hash" do
|
93
|
+
let(:hash) { result.to_stats_hash }
|
94
|
+
|
95
|
+
it "should have meta_info" do
|
96
|
+
hash[:meta_info].wont_be_empty
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should have breadcrumbs" do
|
100
|
+
hash[:breadcrumbs].wont_be_empty
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should have refinements" do
|
104
|
+
hash[:refinements].wont_be_empty
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
|
110
|
+
describe "non-aggregated results" do
|
111
|
+
|
112
|
+
let(:result) { Drawbridge::Result.new(no_aggregate_result_params) }
|
113
|
+
|
114
|
+
describe 'refinements' do
|
115
|
+
it "should not be empty" do
|
116
|
+
result.refinements.wont_be_empty
|
117
|
+
end
|
118
|
+
|
119
|
+
it "should include dimensionid" do
|
120
|
+
result.refinements.first['dimensionid'].must_equal 5885
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
describe "meta_info" do
|
125
|
+
it "should not be empty" do
|
126
|
+
result.meta_info.wont_be_empty
|
127
|
+
end
|
128
|
+
|
129
|
+
it "should include pagenumber" do
|
130
|
+
result.meta_info['pagenumber'].must_equal 1
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'should include matched_on' do
|
134
|
+
result.records.first['matched_on'].must_equal nil
|
135
|
+
end
|
136
|
+
|
137
|
+
it "should be downcased" do
|
138
|
+
result.meta_info['pagenumber'].must_equal 1
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
describe "records" do
|
143
|
+
it "should not be empty" do
|
144
|
+
result.records.wont_be_empty
|
145
|
+
end
|
146
|
+
|
147
|
+
it "should asseess property" do
|
148
|
+
result.records.first['endeca_id'].must_equal '000001'
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
describe "empty results" do
|
153
|
+
it "should not throw an exception" do
|
154
|
+
result = Drawbridge::Result.new({})
|
155
|
+
result.records.must_equal []
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
describe "Endeca Error" do
|
162
|
+
{ 404 => "error_result_404", 500 => "error_result_500" }.each do |status, responze|
|
163
|
+
describe "STATUS #{status}" do
|
164
|
+
let(:result) { Drawbridge::Result.new(send(responze)) }
|
165
|
+
|
166
|
+
it "should have Breadcrumbs" do
|
167
|
+
result.breadcrumbs.must_equal []
|
168
|
+
end
|
169
|
+
|
170
|
+
it "should have MetaInfo" do
|
171
|
+
result.meta_info.must_equal({})
|
172
|
+
end
|
173
|
+
|
174
|
+
it "should have Refinements" do
|
175
|
+
result.refinements.must_equal []
|
176
|
+
end
|
177
|
+
|
178
|
+
it "should have status" do
|
179
|
+
result.status.must_equal status
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
describe '#parse_matched_on' do
|
186
|
+
let(:result) { Drawbridge::Result.new({}) }
|
187
|
+
let(:record) {
|
188
|
+
{ 'DGraph.WhyDidItMatch' => ["City: Chapel Hill",
|
189
|
+
"communitystatename: North Carolina"] }
|
190
|
+
}
|
191
|
+
|
192
|
+
it 'hashifies multi-item array of DGraph.WhyDidItMatch results' do
|
193
|
+
expected = { 'City' => 'Chapel Hill',
|
194
|
+
'communitystatename' => 'North Carolina' }
|
195
|
+
result.send(:parse_matched_on, record).must_equal expected
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
private
|
200
|
+
|
201
|
+
|
202
|
+
def error_result_500
|
203
|
+
{
|
204
|
+
"methodResponse" => {
|
205
|
+
"fault" => {
|
206
|
+
"value" => {
|
207
|
+
"faultCode" => "-1",
|
208
|
+
"faultString" => "Error establishing connection to retrieve Navigation \
|
209
|
+
Engine request 'http://localhost:15400/graph?node=5875+5922+5966&select=\
|
210
|
+
agappointmentactive|attuverse|avgoverallrating|bathscat|bedbathleads|\
|
211
|
+
bedbathleadsreq|bold|brighthouse|charter|communityvideo|communityvideourl|\
|
212
|
+
comvideoheight|comvideowidth|coupon|coupontext|defaulttreatment|directv|\
|
213
|
+
emercialurl|endeca_id|floorplans|fpoptout|geocode|hashdfp|hashdphotos|hdtour\
|
214
|
+
|hdtoururl|hdtoururlmobile|hdvideo|hdvideourl|hidecurrentrentspecialsreq|\
|
215
|
+
iscollege|iscorporate|isincome|isluxury|ismilitary|ispet|issenior|\
|
216
|
+
largecustomcoupon|latitude|leadconfirmemail|leadmovedate|leadmovedatecal|\
|
217
|
+
leadmovedatecalreq|leadmovedatereq|leadmovereason|leadmovereasonreq|\
|
218
|
+
leadphonerequired|leadpricerange|leadpricerangereq|listingbedhigh|listingbedlow|\
|
219
|
+
listingid|listingpoints|listingpricehigh|listingpricelow|listingseopath|\
|
220
|
+
listingtier|livechat|longitude|mgtcodescription|mgtcoid|mktratingson|\
|
221
|
+
neighborhoods|numratings|officehours|overallratings|photoplus|photos|\
|
222
|
+
propertycity|propertyname|propertystatelong|propertyzip|ratings|semtollfree|\
|
223
|
+
showapartment|sortpricehigh|sortpricelow|sources|telcoadcode|timewarner|tour|\
|
224
|
+
tourend|tourheight|tourstart|toururl|tourwidth|twonameleads|verizon|webtollfree|\
|
225
|
+
xfinity|xfinityprefix|zipcode&group=5948+5923+5974+23+3+24+5951+4+22+5885+8+5967+\
|
226
|
+
25&sort=searchonly|asc||isapartment|desc||pri_isnewyork|desc||sort_isnewyork|desc|\
|
227
|
+
|geocode(40.7204,-73.9946)|asc&groupby=listingid&offset=0&nbins=20&allbins=1&attrs=\
|
228
|
+
showapartment|1&pred=geocode%7cGCLT+40.7204%2c-73.9946+16.093470878864444&\
|
229
|
+
irversion=640'. Connection refused"
|
230
|
+
}
|
231
|
+
}
|
232
|
+
}
|
233
|
+
}
|
234
|
+
end
|
235
|
+
|
236
|
+
def error_result_404
|
237
|
+
{
|
238
|
+
"methodResponse" => {
|
239
|
+
"fault" => {
|
240
|
+
"value" => {
|
241
|
+
"faultCode" => "-1",
|
242
|
+
"faultString" => "HTTP Error 404 - Navigation Engine not able to process request \
|
243
|
+
'http://localhost:15400/graph?node=0&groupby=somethingwrong&offset=0&nbins=10&allbins=1&irversion=640'."
|
244
|
+
}
|
245
|
+
}
|
246
|
+
}
|
247
|
+
}
|
248
|
+
end
|
249
|
+
|
250
|
+
def aggregate_result_params
|
251
|
+
{
|
252
|
+
"MetaInfo"=>{
|
253
|
+
"PageNumber"=>1
|
254
|
+
},
|
255
|
+
"Breadcrumbs" => [
|
256
|
+
{
|
257
|
+
"DimensionName" => "_source",
|
258
|
+
"DimensionValues" => [
|
259
|
+
{
|
260
|
+
"DimValueName" => "APTGUIDE",
|
261
|
+
"DimValueID" => 5875
|
262
|
+
}
|
263
|
+
],
|
264
|
+
"Type" => "Navigation"
|
265
|
+
}
|
266
|
+
],
|
267
|
+
"AggrRecords"=>[
|
268
|
+
{
|
269
|
+
"Records"=>[
|
270
|
+
{
|
271
|
+
"RecordSpec"=>"000001",
|
272
|
+
"Dimensions"=>{
|
273
|
+
"propertyzip"=>["99689"],
|
274
|
+
"propertycity"=>["Yakutat"]
|
275
|
+
},
|
276
|
+
"Properties"=>{
|
277
|
+
"leadphonerequired"=>"1",
|
278
|
+
"endeca_id"=>"000001",
|
279
|
+
"miles_to_geocode(40.720400,-73.994600)" => "9.3",
|
280
|
+
"kilometers_to_geocode(40.720400,-73.994600)" => "14.9669",
|
281
|
+
"DGraph.WhyDidItMatch" => "showapartment: 1"
|
282
|
+
}
|
283
|
+
}
|
284
|
+
],
|
285
|
+
"RecordCount"=>3,
|
286
|
+
"DerivedProperties"=>{
|
287
|
+
"bed_high"=>"2",
|
288
|
+
"bed_low"=>"1"
|
289
|
+
}
|
290
|
+
},
|
291
|
+
{
|
292
|
+
"Records"=>[
|
293
|
+
{
|
294
|
+
"RecordSpec"=>"000002",
|
295
|
+
"Dimensions"=>{
|
296
|
+
"propertyzip"=>["99689"],
|
297
|
+
"propertycity"=>["Yakutat"]
|
298
|
+
},
|
299
|
+
"Properties"=>{
|
300
|
+
"leadphonerequired"=>"1",
|
301
|
+
"endeca_id"=>"000002"
|
302
|
+
}
|
303
|
+
}
|
304
|
+
],
|
305
|
+
"RecordCount"=>3,
|
306
|
+
"DerivedProperties"=>{
|
307
|
+
"bed_high"=>"2",
|
308
|
+
"bed_low"=>"1"
|
309
|
+
}
|
310
|
+
}
|
311
|
+
],
|
312
|
+
"Refinements"=>[
|
313
|
+
{
|
314
|
+
"DimensionID"=>5885,
|
315
|
+
"DimensionName"=>"price_range"
|
316
|
+
},
|
317
|
+
{
|
318
|
+
"DimensionID"=>3,
|
319
|
+
"DimensionName"=>"bedrooms"
|
320
|
+
},
|
321
|
+
{
|
322
|
+
"DimensionID" => 5974,
|
323
|
+
"DimensionName" => "_telco",
|
324
|
+
"DimensionValues" =>
|
325
|
+
[
|
326
|
+
{
|
327
|
+
"DimValueName" => "Time Warner Cable",
|
328
|
+
"DimValueProperties" => {"DGraph.AggrBins" => "10","sortname" => ["Time Warner"],"sortfield" => ["timewarner"]},
|
329
|
+
"NumberofRecords" => "332",
|
330
|
+
"DimValueID" => 5978
|
331
|
+
},
|
332
|
+
{
|
333
|
+
"DimValueName" => "Verizon FiOS",
|
334
|
+
"DimValueProperties" => {"DGraph.AggrBins" => "33","sortbar" => ["vzn_sort_bar"],"sortname" => ["Verizon"],"sortfield" => ["verizon"]},
|
335
|
+
"NumberofRecords" => "627",
|
336
|
+
"DimValueID" => 5976
|
337
|
+
}
|
338
|
+
]
|
339
|
+
}
|
340
|
+
]
|
341
|
+
}
|
342
|
+
end
|
343
|
+
|
344
|
+
def no_aggregate_result_params
|
345
|
+
{
|
346
|
+
"MetaInfo"=>{
|
347
|
+
"PageNumber"=>1
|
348
|
+
},
|
349
|
+
"Records"=>[
|
350
|
+
{
|
351
|
+
"RecordSpec"=>"000001",
|
352
|
+
"Dimensions"=>{
|
353
|
+
"propertyzip"=>["99689"],
|
354
|
+
"propertycity"=>["Yakutat"]
|
355
|
+
},
|
356
|
+
"Properties"=>{
|
357
|
+
"leadphonerequired"=>"1",
|
358
|
+
"endeca_id"=>"000001",
|
359
|
+
"miles_to_geocode(40.720400,-73.994600)" => "9.3",
|
360
|
+
"kilometers_to_geocode(40.720400,-73.994600)" => "14.9669"
|
361
|
+
}
|
362
|
+
},
|
363
|
+
{
|
364
|
+
"RecordSpec"=>"000002",
|
365
|
+
"Dimensions"=>{
|
366
|
+
"propertyzip"=>["99689"],
|
367
|
+
"propertycity"=>["Yakutat"]
|
368
|
+
},
|
369
|
+
"Properties"=>{
|
370
|
+
"leadphonerequired"=>"1",
|
371
|
+
"endeca_id"=>"000002"
|
372
|
+
}
|
373
|
+
}
|
374
|
+
],
|
375
|
+
"Refinements"=>[
|
376
|
+
{
|
377
|
+
"DimensionID"=>5885,
|
378
|
+
"DimensionName"=>"price_range"
|
379
|
+
},
|
380
|
+
{
|
381
|
+
"DimensionID"=>3,
|
382
|
+
"DimensionName"=>"bedrooms"
|
383
|
+
}
|
384
|
+
]
|
385
|
+
}
|
386
|
+
end
|
387
|
+
|
388
|
+
end
|