lonely_coder 0.1.4 → 0.1.5

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/CHANGELOG CHANGED
@@ -1,3 +1,5 @@
1
+ 0.1.5 (April 04, 2012)
2
+ * Added ethnicity filter
1
3
  0.1.4 (March 27, 2012)
2
4
  * more consistent search results when paginating by using OKCupid server timestamps
3
5
  * Search#load_next_page returns boolean to deal with cases where pagination doesn't load new results
data/README.mdown CHANGED
@@ -20,8 +20,7 @@ Lonely coder seeks nice boy
20
20
  :min_age => 25,
21
21
  :max_age => 35, # just someone around my age, yo
22
22
  :gentation => 'Guys who like guys', # don't hate
23
- :order_by => 'Match %', # I want us to get along
24
- :match_limit => 80, # let's make it last
23
+ :order_by => 'Match %', # I want us to get along, let's make it last
25
24
  :last_login => 'last month',
26
25
  :location => maybe_here
27
26
  :radius => 25, # acceptable values are 25, 50, 100, 250, 500, nil
@@ -0,0 +1,13 @@
1
+ class OKCupid
2
+ class AgeFilter < Filter
3
+ def lookup(value)
4
+ "#{value[0]},#{value[1]}"
5
+ end
6
+ end
7
+
8
+ class Search
9
+ def add_age_option(value)
10
+ @filters << AgeFilter.new('age', value)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,14 @@
1
+ class OKCupid
2
+ class EthnicityFilter < Filter
3
+ def lookup(values)
4
+ # lookup the race values and sum them. I think OKC is doing some kind of base2 math on them
5
+ values.collect {|v| MagicNumbers::Ethnicity[v.downcase]}.inject(0, :+)
6
+ end
7
+ end
8
+
9
+ class Search
10
+ def add_ethnicity_option(values)
11
+ @filters << EthnicityFilter.new('ethnicity', values)
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,74 @@
1
+ class OKCupid
2
+ # Filter instances are used to build the query parameters for a search on OKCupid.
3
+ # OKCupid has specific coded values for many search values, you should check the magic_constants file
4
+ # for a list. Not all of them have been implemented yet.
5
+ #
6
+ # Adding a Filter takes one of three forms:
7
+ # 1) implementing a add_<filter_name>_option method on Search
8
+ # that pushes a new named Filter to the @filters array for unmamed query parts
9
+ #
10
+ # 2) Subclassing Filter for filters that have atypical parameterization behavior.
11
+ # where you'll implement a add_<filter_name>_option method on Search
12
+ # and provide a custom class overriding `lookup` or `to_param` to create
13
+ # a correct url query part.
14
+ #
15
+ # 3) Creating a new class to handle query parameters that are specifically named
16
+ # These are refered to as "Parameters" to contrast them with "Filters" which
17
+ # are parameterized in the "filterN=code,value" pattern (e.g. filter4=22,7).
18
+ # Parameters are not numbered and have specific names, e.g. "loc_id=1234567"
19
+ # You'll also implement a add_<filter_name>_option that adds an instance of this
20
+ # class to the @parameters array (not the @filters array).
21
+ #
22
+ # See the included Filter and Parameter classes for ideas on how to structure these objects.
23
+ #
24
+ # OKCupid's query system is a bit obtuse and the details aren't published anywhere.
25
+ # If you're implementing a new filter, you may need to spend some time figuring out
26
+ # what data they expect to receive and the kinds of results it will return.
27
+ class Filter
28
+ class NoSuchFilter < StandardError; end
29
+ class BadValue < StandardError; end
30
+
31
+ attr_reader :name, :value, :code
32
+
33
+ def initialize(name, value)
34
+ @code = MagicNumbers::Filters[name.to_s]
35
+ raise(NoSuchFilter, name) unless @code
36
+
37
+ @name = name.to_s
38
+ @value = value
39
+ @encoded_value = lookup(@value)
40
+ unless @encoded_value
41
+ raise(BadValue, "#{@value.inspect} is not a possible value for #{@name}. Try one of #{allowed_values.map(&:inspect).join(', ')}")
42
+ end
43
+ end
44
+
45
+ def allowed_values
46
+ MagicNumbers.const_get(@name.camelize).keys
47
+ end
48
+
49
+ def lookup(value)
50
+ MagicNumbers.const_get(@name.camelize)[value.downcase]
51
+ end
52
+
53
+ def to_param(n)
54
+ "filter#{n}=#{@code},#{@encoded_value}"
55
+ end
56
+ end
57
+
58
+ # All filters that follow the base Filter pattern are exposed here through a
59
+ # add_<filter_name>_option method. Custom filters and parameters are defined
60
+ # in their own files and include the appropriate add_<option_name>_option method.
61
+ class Search
62
+ def add_relationship_status_option(value)
63
+ @filters << Filter.new('relationship_status', value)
64
+ end
65
+
66
+ def add_gentation_option(value)
67
+ @filters << Filter.new('gentation', value)
68
+ end
69
+
70
+ def add_last_login_option(value)
71
+ @filters << Filter.new('last_login', value)
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,25 @@
1
+ class OKCupid
2
+ class LocationParameter
3
+ def initialize(value)
4
+ @value = value
5
+ end
6
+
7
+ def to_param
8
+ if @value.is_a?(String)
9
+ if @value.downcase == 'near me'
10
+ "locid=0"
11
+ else
12
+ "locid=#{Search.location_id_for(@value)}&lquery=#{URI.escape(@value)}"
13
+ end
14
+ else
15
+ "locid=#{@value}"
16
+ end
17
+ end
18
+ end
19
+
20
+ class Search
21
+ def add_location_option(value)
22
+ @parameters << LocationParameter.new(value)
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,19 @@
1
+ class OKCupid
2
+ class OrderByParameter
3
+ def initialize(value)
4
+ @value = value
5
+ @encoded_value = MagicNumbers::OrderBy[value.downcase]
6
+ end
7
+
8
+ def to_param
9
+ "matchOrderBy=#{@encoded_value}"
10
+ end
11
+ end
12
+
13
+ # Reopen Search to accept order_by filters
14
+ class Search
15
+ def add_order_by_option(value)
16
+ @parameters << OrderByParameter.new(value)
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,33 @@
1
+ class OKCupid
2
+ # used to create the pagination part of a search url:
3
+ # low=1&count=10&ajax_load=1
4
+ # where low is the start value
5
+ # count is the number of items per page
6
+ class Paginator
7
+ attr_reader :page, :per_page
8
+
9
+ def initialize(options)
10
+ @per_page = options[:per_page]
11
+ @page = options[:page]
12
+ end
13
+
14
+ def low
15
+ @low = ((@page - 1) * @per_page) + 1
16
+ end
17
+
18
+ def next
19
+ @page +=1
20
+ self
21
+ end
22
+
23
+ def to_param
24
+ "low=#{low}&count=#{@per_page}"
25
+ end
26
+ end
27
+
28
+ class Search
29
+ def add_pagination_option(value)
30
+ @parameters << @pagination = Paginator.new(value)
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,18 @@
1
+ class OKCupid
2
+ class RadiusFilter < Filter
3
+ def lookup(value)
4
+ value.nil? ? '' : value
5
+ end
6
+
7
+ def to_param(n)
8
+ return nil if @encoded_value === ''
9
+ super
10
+ end
11
+ end
12
+
13
+ class Search
14
+ def add_radius_option(value)
15
+ @filters << RadiusFilter.new('radius', value)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,13 @@
1
+ class OKCupid
2
+ class RequirePhotoFilter < Filter
3
+ def lookup(value)
4
+ value ? 1 : 0
5
+ end
6
+ end
7
+
8
+ class Search
9
+ def add_require_photo_option(value)
10
+ @filters << RequirePhotoFilter.new('require_photo', value)
11
+ end
12
+ end
13
+ end
@@ -1,15 +1,65 @@
1
1
  require 'uri'
2
+ require 'set'
3
+
4
+ require 'lonely_coder/search/magic_constants'
5
+ require 'lonely_coder/search/search_pagination_parser'
6
+ require 'lonely_coder/search/options/filter'
7
+
8
+ # these are the included filters. See Filter class documentation for adding your own.
9
+ require 'lonely_coder/search/options/age'
10
+ require 'lonely_coder/search/options/ethnicity'
11
+ require 'lonely_coder/search/options/order_by'
12
+ require 'lonely_coder/search/options/location'
13
+ require 'lonely_coder/search/options/paginator'
14
+ require 'lonely_coder/search/options/radius'
15
+ require 'lonely_coder/search/options/require_photo'
2
16
 
3
17
  class OKCupid
18
+ # Creates a new Search with the passed options to act as query parameters.
19
+ # A search will not trigger a query to OKCupid until `results` is called.
20
+ #
21
+ # @param [Hash] options a list of options for the search
22
+ # @option options [Integer] :min_age (18) Minimum age to search for.
23
+ # @option options [Integer] :max_age (99) Maximum age to search for.
24
+ # @option options [String] :gentation Gentation is OKCupid's portmanteau for 'gender and orientation'.
25
+ # Acceptable values are:
26
+ # "girls who like guys", "guys who like girls", "girls who like girls",
27
+ # "guys who like guys", "both who like bi guys", "both who like bi girls",
28
+ # "straight girls only", "straight guys only", "gay girls only",
29
+ # "gay guys only", "bi girls only", "bi guys only", "everybody"
30
+ # this option is required.
31
+ #
32
+ # @option options [String] :order_by ('match %') The sort order of the search results.
33
+ # Acceptable values are 'match %','friend %', 'enemy %',
34
+ # 'special blend', 'join', and 'last login'.
35
+ #
36
+ # @option options [Integer] :radius (25) The search radius, in miles.
37
+ # Acceptable values are 25, 50, 100, 250, 500.
38
+ # You must also specific a :location option.
39
+ # @option options [Integer, String] :location ('near me'). A specific search location.
40
+ # Acceptable values are 'near me', 'anywhere', a "City, State" pair
41
+ # (e.g. 'Chicago, Illinois') or OKCupid location id which can be
42
+ # obtained with Search#location_id_for("City, State").
43
+ # If specifiying a location other than 'near me' or 'anywhere'
44
+ # you may also provide a :radius option
45
+ #
46
+ # @option options [true, false] :require_photo (true). Search for profiles that have photos
47
+ # @option options [String] :relationship_status ('single'). Acceptable values are 'single', 'not single', 'any'
48
+ # @return [Search] A Search without results loaded. To trigger a query against OKCupid call `results`
4
49
  def search(options={})
5
50
  Search.new(options, @browser)
6
51
  end
7
52
 
53
+ # The OKCupid search object. Stores filters and query options and a results set. Correct useage is to obtain
54
+ # and instance of this class by using OKCupid#search(options).
55
+ # @see OKCupid#search
8
56
  class Search
9
57
  class FilterError < StandardError; end
10
58
 
11
59
  attr_reader :filters
12
60
 
61
+ # @param [String] A string query for a city and state pair, e.g. 'Little Rock, Arkansas'
62
+ # @return [Integer] The OKCupid location id for the query
13
63
  def self.location_id_for(query)
14
64
  uri = URI("http://www.okcupid.com/locquery?func=query&query=#{URI.encode(query)}")
15
65
  JSON.parse(Net::HTTP.get(uri))['results'][0]['locid'].to_s
@@ -24,62 +74,29 @@ class OKCupid
24
74
  def parse(options)
25
75
  check_for_required_options(options)
26
76
 
77
+ # :age appears as two options when creating a search
78
+ # but is combined into one for paramterizing.
27
79
  options[:age] = combine_ages(options)
28
80
 
29
-
81
+ # filters appear in the query string as filterN=code,value
82
+ # e.g. filter4=11,75
30
83
  @filters = []
84
+
85
+ # parameters appear in the query string as named query parameters
86
+ # e.g. loc_id=1234567
31
87
  @parameters = []
32
88
 
89
+
33
90
  options.each do |name,value|
34
91
  self.send("add_#{name}_option", value)
35
92
  end
36
93
 
37
94
  # OKC needs an initial time key of 1 to represent "waaaay in the past"
38
95
  # futures searches will use the OKC server value returned from the first
39
- # results set
96
+ # results set.
40
97
  @timekey = 1
41
98
  end
42
99
 
43
- def add_order_by_option(value)
44
- @parameters << OrderByParameter.new(value)
45
- end
46
-
47
- def add_last_login_option(value)
48
- @filters << Filter.new('last_login', value)
49
- end
50
-
51
- def add_location_option(value)
52
- @parameters << LocationParameter.new(value)
53
- end
54
-
55
- def add_radius_option(value)
56
- @filters << RadiusFilter.new('radius', value)
57
- end
58
-
59
- def add_require_photo_option(value)
60
- @filters << RequirePhotoFilter.new('require_photo', value)
61
- end
62
-
63
- def add_relationship_status_option(value)
64
- @filters << Filter.new('relationship_status', value)
65
- end
66
-
67
- def add_gentation_option(value)
68
- @filters << Filter.new('gentation', value)
69
- end
70
-
71
- def add_age_option(value)
72
- @filters << AgeFilter.new('age', value)
73
- end
74
-
75
- def add_pagination_option(value)
76
- @parameters << @pagination = Paginator.new(value)
77
- end
78
-
79
- def add_match_limit_option(value)
80
- # TODO.
81
- end
82
-
83
100
  def check_for_required_options(options)
84
101
  raise(FilterError, 'gentation is a required option') unless options.has_key?(:gentation)
85
102
  end
@@ -89,30 +106,19 @@ class OKCupid
89
106
  options[:age] = age
90
107
  end
91
108
 
92
- # Default values for search:
93
- # match_limit 80
94
- # min_age 18
95
- # max_age 99
96
- # order_by 'match %'
97
- # last_login 'last month'
98
- # location 'Near me'
99
- # to search 'anywhere', use 'Near me' and omit a radius
100
- # radius 25
101
- # require_photo true
102
- # relationship_status 'single'
109
+ #
103
110
  def defaults
104
111
  {
105
112
  :pagination => {
106
113
  :page => 1,
107
114
  :per_page => 10
108
115
  },
109
- :match_limit => 80,
110
116
  :min_age => 18,
111
117
  :max_age => 99,
112
118
  :order_by => 'Match %',
113
119
  :last_login => 'last month',
114
120
  :location => 'Near me',
115
- :radius => 25, # acceptable values are 25, 50, 100, 250, 500, nil
121
+ :radius => 25,
116
122
  :require_photo => true,
117
123
  :relationship_status => 'single'
118
124
  }
@@ -124,10 +130,13 @@ class OKCupid
124
130
  # the first results request has to receive a full HTML page.
125
131
  # subseqent calls can make json requests
126
132
  page = @browser.get(url)
133
+
134
+ # Stores the OKCupid server timestamp. Without this, pagination returns
135
+ # inconsistent results.
127
136
  @timekey = page.search('script')[0].text.match(/CurrentGMT = new Date\(([\d]+)\*[\d]+\)/).captures[0]
128
137
 
129
- # OKCupid will return previous profiles if there aren't enough
130
- # profiles to fill a query, so we stop that with a set.
138
+ # OKCupid may return previously found profiles if there aren't enough
139
+ # to fill a query or pagination, so we stop that with a set.
131
140
  @results = Set.new
132
141
  @results += page.search('.match_row').collect do |node|
133
142
  OKCupid::Profile.from_search_result(node)
@@ -143,24 +152,25 @@ class OKCupid
143
152
  # update_prefs=1
144
153
  # using_saved_search=0
145
154
  # mygender=m
155
+ #
146
156
  # no idea what the following parameters do, but without them, the search
147
157
  # behaves erratically
148
158
  # &custom_search=0
149
159
  #
150
- # OKCupid timestamps searches for pagniation. The first search gets a timestamp
160
+ # OKCupid timestamps searches for pagination. The first search gets a timestamp
151
161
  # of 1 (e.g. 1 second into the epoch) and future searches are stamped with
152
162
  # some server cache value. If that server value isn't submitted, the results
153
163
  # for pagniation don't quite match what you'd expect: you'll get duplicates,
154
164
  # or lower numbers than expected.
155
165
  # &timekey=1
156
-
157
166
  def magic_params_not_truly_understood
158
167
  "timekey=#{@timekey}&custom_search=0"
159
168
  end
160
169
 
161
- # returns true if it worked, false if not.
162
- # OKCupid searches will return duplicate results if you attempt to
163
- # page beyond the availble results.
170
+
171
+ # Loads the next page of possible results. Will return `true` if
172
+ # additional results were available or `false` if not
173
+ # @return [true,false]
164
174
  def load_next_page
165
175
  @browser.pluggable_parser.html = SearchPaginationParser
166
176
 
@@ -194,121 +204,4 @@ class OKCupid
194
204
  filters.compact.to_enum(:each_with_index).map {|filter,index| filter.to_param(index+1)}.join('&')
195
205
  end
196
206
  end
197
-
198
- # used to create the pagination part of a search url:
199
- # low=1&count=10&ajax_load=1
200
- # where low is the start value
201
- # count is the number of items per page
202
- class Paginator
203
- attr_reader :page, :per_page
204
-
205
- def initialize(options)
206
- @per_page = options[:per_page]
207
- @page = options[:page]
208
- end
209
-
210
- def low
211
- @low = ((@page - 1) * @per_page) + 1
212
- end
213
-
214
- def next
215
- @page +=1
216
- self
217
- end
218
-
219
- def to_param
220
- "low=#{low}&count=#{@per_page}"
221
- end
222
- end
223
-
224
- class Filter
225
- class NoSuchFilter < StandardError; end
226
- class BadValue < StandardError; end
227
-
228
- attr_reader :name, :value, :code
229
-
230
- def initialize(name, value)
231
- @code = MagicNumbers::Filters[name.to_s]
232
- raise(NoSuchFilter, name) unless @code
233
-
234
- @name = name.to_s
235
- @value = value
236
- @encoded_value = lookup(@value)
237
- unless @encoded_value
238
- raise(BadValue, "#{@value.inspect} is not a possible value for #{@name}. Try one of #{allowed_values.map(&:inspect).join(', ')}")
239
- end
240
- end
241
-
242
- def allowed_values
243
- MagicNumbers.const_get(@name.camelize).keys
244
- end
245
-
246
- def lookup(value)
247
- MagicNumbers.const_get(@name.camelize)[value.downcase]
248
- end
249
-
250
- def to_param(n)
251
- "filter#{n}=#{@code},#{@encoded_value}"
252
- end
253
- end
254
-
255
- class EthnicityFilter < Filter
256
- def lookup(values)
257
- # lookup the race values and sum them. I think OKC is doing some kind of base2 math on them
258
- values.collect {|v| MagicNumbers::Ethnicity[v.downcase]}.inject(0, :+)
259
- end
260
- end
261
-
262
- class LocationParameter
263
- def initialize(value)
264
- @value = value
265
- end
266
-
267
- def to_param
268
- # to do: 'anywhere' needs to remove the radius filter
269
- if @value.is_a?(String)
270
- if @value.downcase == 'near me'
271
- "locid=0"
272
- else
273
- "locid=#{Search.location_id_for(@value)}&lquery=#{URI.escape(@value)}"
274
- end
275
- else
276
- "locid=#{@value}"
277
- end
278
- end
279
- end
280
-
281
- class OrderByParameter
282
- def initialize(value)
283
- @value = value
284
- @encoded_value = MagicNumbers::OrderBy[value.downcase]
285
- end
286
-
287
- def to_param
288
- "matchOrderBy=#{@encoded_value}"
289
- end
290
- end
291
-
292
- class RequirePhotoFilter < Filter
293
- def lookup(value)
294
- value ? 1 : 0
295
- end
296
- end
297
-
298
- class RadiusFilter < Filter
299
- def lookup(value)
300
- value.nil? ? '' : value
301
- end
302
-
303
- def to_param(n)
304
- return nil if @encoded_value === ''
305
- super
306
- end
307
- end
308
-
309
- class AgeFilter < Filter
310
- def lookup(value)
311
- "#{value[0]},#{value[1]}"
312
- end
313
- end
314
207
  end
data/lib/lonely_coder.rb CHANGED
@@ -11,7 +11,7 @@ require 'mechanize'
11
11
 
12
12
  class OKCupid
13
13
  BaseUrl = 'http://www.okcupid.com'
14
- VERSION = '0.1.4'
14
+ VERSION = '0.1.5'
15
15
 
16
16
  def initialize(username=nil, password=nil)
17
17
  @browser = Mechanize.new
@@ -31,9 +31,7 @@ end
31
31
 
32
32
  require 'active_support/core_ext/string/inflections'
33
33
 
34
- require 'lonely_coder/magic_constants'
35
34
  require 'lonely_coder/profile'
36
35
  require 'lonely_coder/search'
37
- require 'lonely_coder/search_pagination_parser'
38
36
  require 'lonely_coder/authentication'
39
37
  require 'lonely_coder/mailbox'
data/lonely_coder.gemspec CHANGED
@@ -1,7 +1,7 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
  Gem::Specification.new do |s|
3
3
  s.name = "lonely_coder"
4
- s.version = '0.1.4'
4
+ s.version = '0.1.5'
5
5
  s.platform = Gem::Platform::RUBY
6
6
  s.authors = ["Trek Glowacki"]
7
7
  s.email = ["trek.glowacki@gmail.com"]
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ describe "EthnicityFilter" do
4
+ it "adds ethnicity as an numbered filter to the query url" do
5
+ @search = OKCupid::Search.new({
6
+ :gentation => 'guys who like guys',
7
+ :ethnicity => ['human']
8
+ })
9
+ @search.url.should match(/filter[\d]=9,512/)
10
+ end
11
+
12
+ it "supports mulitple ethnicity values" do
13
+ @search = OKCupid::Search.new({
14
+ :gentation => 'guys who like guys',
15
+ :ethnicity => ['white', 'black']
16
+ })
17
+ # White + Black
18
+ # 256 + 8
19
+ @search.url.should match(/filter[\d]=9,264/)
20
+ end
21
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lonely_coder
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-03-27 00:00:00.000000000 Z
12
+ date: 2012-04-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: mechanize
@@ -55,11 +55,19 @@ files:
55
55
  - README.mdown
56
56
  - lib/lonely_coder.rb
57
57
  - lib/lonely_coder/authentication.rb
58
- - lib/lonely_coder/magic_constants.rb
59
58
  - lib/lonely_coder/mailbox.rb
60
59
  - lib/lonely_coder/profile.rb
61
60
  - lib/lonely_coder/search.rb
62
- - lib/lonely_coder/search_pagination_parser.rb
61
+ - lib/lonely_coder/search/magic_constants.rb
62
+ - lib/lonely_coder/search/options/age.rb
63
+ - lib/lonely_coder/search/options/ethnicity.rb
64
+ - lib/lonely_coder/search/options/filter.rb
65
+ - lib/lonely_coder/search/options/location.rb
66
+ - lib/lonely_coder/search/options/order_by.rb
67
+ - lib/lonely_coder/search/options/paginator.rb
68
+ - lib/lonely_coder/search/options/radius.rb
69
+ - lib/lonely_coder/search/options/require_photo.rb
70
+ - lib/lonely_coder/search/search_pagination_parser.rb
63
71
  - lonely_coder.gemspec
64
72
  - spec/authentication_spec.rb
65
73
  - spec/cassettes/failed_authentication.yml
@@ -75,6 +83,7 @@ files:
75
83
  - spec/cassettes/search_finding_no_results.yml
76
84
  - spec/cassettes/search_that_includes_a_location.yml
77
85
  - spec/cassettes/successful_authentication.yml
86
+ - spec/ethnicity_filter_spec.rb
78
87
  - spec/helper_spec.rb
79
88
  - spec/location_id_spec.rb
80
89
  - spec/mailbox_spec.rb
@@ -123,6 +132,7 @@ test_files:
123
132
  - spec/cassettes/search_finding_no_results.yml
124
133
  - spec/cassettes/search_that_includes_a_location.yml
125
134
  - spec/cassettes/successful_authentication.yml
135
+ - spec/ethnicity_filter_spec.rb
126
136
  - spec/helper_spec.rb
127
137
  - spec/location_id_spec.rb
128
138
  - spec/mailbox_spec.rb
@@ -131,3 +141,4 @@ test_files:
131
141
  - spec/profile_spec.rb
132
142
  - spec/search_spec.rb
133
143
  - spec/spec_helper.rb
144
+ has_rdoc: