ansr 0.0.1 → 0.0.3
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.
- checksums.yaml +15 -0
- data/README.md +35 -0
- data/ansr.gemspec +2 -1
- data/ansr_blacklight/Gemfile +3 -0
- data/ansr_blacklight/README.md +37 -0
- data/ansr_blacklight/ansr_blacklight.gemspec +28 -0
- data/ansr_blacklight/lib/ansr_blacklight.rb +57 -0
- data/ansr_blacklight/lib/ansr_blacklight/arel.rb +6 -0
- data/ansr_blacklight/lib/ansr_blacklight/arel/big_table.rb +57 -0
- data/ansr_blacklight/lib/ansr_blacklight/arel/visitors.rb +6 -0
- data/ansr_blacklight/lib/ansr_blacklight/arel/visitors/query_builder.rb +217 -0
- data/ansr_blacklight/lib/ansr_blacklight/arel/visitors/to_no_sql.rb +14 -0
- data/ansr_blacklight/lib/ansr_blacklight/base.rb +21 -0
- data/ansr_blacklight/lib/ansr_blacklight/connection_adapters/no_sql_adapter.rb +38 -0
- data/ansr_blacklight/lib/ansr_blacklight/model/querying.rb +29 -0
- data/ansr_blacklight/lib/ansr_blacklight/relation.rb +50 -0
- data/ansr_blacklight/lib/ansr_blacklight/relation/solr_projection_methods.rb +55 -0
- data/ansr_blacklight/lib/ansr_blacklight/request_builders.rb +141 -0
- data/ansr_blacklight/lib/ansr_blacklight/solr.rb +4 -0
- data/ansr_blacklight/lib/ansr_blacklight/solr/request.rb +46 -0
- data/ansr_blacklight/lib/ansr_blacklight/solr/response.rb +94 -0
- data/ansr_blacklight/lib/ansr_blacklight/solr/response/group.rb +32 -0
- data/ansr_blacklight/lib/ansr_blacklight/solr/response/group_response.rb +50 -0
- data/ansr_blacklight/lib/ansr_blacklight/solr/response/more_like_this.rb +14 -0
- data/ansr_blacklight/lib/ansr_blacklight/solr/response/pagination_methods.rb +35 -0
- data/ansr_blacklight/lib/ansr_blacklight/solr/response/spelling.rb +92 -0
- data/ansr_blacklight/spec/fixtures/config.yml +0 -0
- data/ansr_blacklight/spec/lib/loaded_relation_spec.rb +223 -0
- data/ansr_blacklight/spec/lib/queryable_relation_spec.rb +133 -0
- data/ansr_blacklight/spec/lib/relation/faceting_spec.rb +475 -0
- data/ansr_blacklight/spec/lib/relation/grouping_spec.rb +159 -0
- data/ansr_blacklight/spec/spec_helper.rb +72 -0
- data/ansr_dpla/Gemfile +3 -0
- data/ansr_dpla/Gemfile.lock +138 -0
- data/ansr_dpla/README.md +2 -2
- data/ansr_dpla/ansr_dpla.gemspec +2 -2
- data/ansr_dpla/lib/ansr_dpla.rb +3 -0
- data/ansr_dpla/lib/ansr_dpla/api.rb +3 -3
- data/ansr_dpla/lib/ansr_dpla/arel.rb +1 -2
- data/ansr_dpla/lib/ansr_dpla/arel/big_table.rb +4 -0
- data/ansr_dpla/lib/ansr_dpla/arel/visitors.rb +6 -0
- data/ansr_dpla/lib/ansr_dpla/arel/visitors/query_builder.rb +188 -0
- data/ansr_dpla/lib/ansr_dpla/arel/visitors/to_no_sql.rb +9 -0
- data/ansr_dpla/lib/ansr_dpla/connection_adapters/no_sql_adapter.rb +58 -0
- data/ansr_dpla/lib/ansr_dpla/model/base.rb +7 -0
- data/ansr_dpla/lib/ansr_dpla/model/querying.rb +6 -10
- data/ansr_dpla/lib/ansr_dpla/relation.rb +61 -0
- data/ansr_dpla/lib/ansr_dpla/request.rb +5 -0
- data/ansr_dpla/spec/lib/api_spec.rb +8 -5
- data/ansr_dpla/spec/lib/item_spec.rb +2 -2
- data/ansr_dpla/spec/lib/relation/facet_spec.rb +27 -19
- data/ansr_dpla/spec/lib/relation/select_spec.rb +10 -8
- data/ansr_dpla/spec/lib/relation/where_spec.rb +1 -1
- data/ansr_dpla/spec/lib/relation_spec.rb +31 -29
- data/ansr_dpla/test/system.rb +4 -2
- data/lib/ansr.rb +7 -0
- data/lib/ansr/arel.rb +3 -0
- data/lib/ansr/arel/big_table.rb +43 -3
- data/lib/ansr/arel/configured_field.rb +19 -0
- data/lib/ansr/arel/nodes.rb +41 -0
- data/lib/ansr/arel/visitors.rb +7 -0
- data/lib/ansr/arel/visitors/context.rb +13 -0
- data/lib/ansr/arel/visitors/query_builder.rb +47 -0
- data/lib/ansr/arel/visitors/to_no_sql.rb +41 -0
- data/lib/ansr/base.rb +29 -1
- data/lib/ansr/configurable.rb +6 -12
- data/lib/ansr/connection_adapters.rb +5 -0
- data/lib/ansr/connection_adapters/no_sql_adapter.rb +80 -0
- data/lib/ansr/dummy_associations.rb +105 -0
- data/lib/ansr/facets.rb +103 -0
- data/lib/ansr/model.rb +17 -107
- data/lib/ansr/model/connection_handler.rb +6 -0
- data/lib/ansr/relation.rb +40 -23
- data/lib/ansr/relation/group.rb +31 -0
- data/lib/ansr/relation/predicate_builder.rb +106 -0
- data/lib/ansr/relation/query_methods.rb +192 -45
- data/lib/ansr/sanitization.rb +5 -18
- data/lib/ansr/utils.rb +89 -0
- data/lib/ansr/version.rb +1 -1
- metadata +73 -25
- data/ansr_dpla/lib/ansr_dpla/arel/connection.rb +0 -81
- data/ansr_dpla/lib/ansr_dpla/arel/query_builder.rb +0 -131
- data/lib/ansr/model/connection.rb +0 -103
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
module Ansr::Dpla::Arel::Visitors
|
|
2
|
+
class QueryBuilder < Ansr::Arel::Visitors::QueryBuilder
|
|
3
|
+
attr_reader :query_opts
|
|
4
|
+
|
|
5
|
+
def initialize(table, query_opts=nil)
|
|
6
|
+
super(table)
|
|
7
|
+
@query_opts = query_opts ||= Ansr::Dpla::Request.new
|
|
8
|
+
@query_opts.path = table.name
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# determines whether multiple values should accumulate or overwrite in merges
|
|
12
|
+
def multiple?(field_key)
|
|
13
|
+
true
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def visit_String o, a
|
|
17
|
+
case a
|
|
18
|
+
when Ansr::Arel::Visitors::From
|
|
19
|
+
query_opts.path = o
|
|
20
|
+
when Ansr::Arel::Visitors::Facet
|
|
21
|
+
filter_field(o.to_sym)
|
|
22
|
+
when Ansr::Arel::Visitors::Order
|
|
23
|
+
order(o)
|
|
24
|
+
else
|
|
25
|
+
raise "visited String \"#{o}\" with #{a.to_s}"
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def visit_Arel_SqlLiteral(n, attribute)
|
|
30
|
+
select_val = n.to_s.split(" AS ")
|
|
31
|
+
case attribute
|
|
32
|
+
when Ansr::Arel::Visitors::Order
|
|
33
|
+
order(n.to_s)
|
|
34
|
+
when Ansr::Arel::Visitors::Facet
|
|
35
|
+
filter_field(select_val[0].to_sym)
|
|
36
|
+
else
|
|
37
|
+
field(select_val[0].to_sym)
|
|
38
|
+
if select_val[1]
|
|
39
|
+
query_opts.aliases ||= {}
|
|
40
|
+
query_opts.aliases[select_val[0]] = select_val[1]
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def visit_Ansr_Arel_Nodes_Filter(object, attribute)
|
|
46
|
+
expr = object.expr
|
|
47
|
+
case expr
|
|
48
|
+
when ::Arel::SqlLiteral
|
|
49
|
+
visit expr, Ansr::Arel::Visitors::Filter.new(attribute) if object.select
|
|
50
|
+
when ::Arel::Attributes::Attribute
|
|
51
|
+
name = object.expr.name
|
|
52
|
+
name = "#{expr.relation.name}.#{name}" if expr.relation.name.to_s != table.name.to_s
|
|
53
|
+
visit name, Ansr::Arel::Visitors::Filter.new(attribute) if object.select
|
|
54
|
+
else
|
|
55
|
+
raise "Unexpected filter expression type #{object.expr.class}"
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def visit_Ansr_Arel_Nodes_Facet(object, attribute)
|
|
60
|
+
expr = object.expr
|
|
61
|
+
case expr
|
|
62
|
+
when ::Arel::SqlLiteral
|
|
63
|
+
visit expr, Ansr::Arel::Visitors::Facet.new(attribute)
|
|
64
|
+
when ::Arel::Attributes::Attribute
|
|
65
|
+
name = object.expr.name
|
|
66
|
+
name = "#{expr.relation.name}.#{name}" if expr.relation.name.to_s != table.name.to_s
|
|
67
|
+
visit name, Ansr::Arel::Visitors::Facet.new(attribute) if object.select
|
|
68
|
+
else
|
|
69
|
+
raise "Unexpected filter expression type #{object.expr.class}"
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def projections
|
|
74
|
+
query_opts[:fields] || []
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def filter_projections
|
|
78
|
+
query_opts[:facets] || []
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def field(field_name)
|
|
83
|
+
return unless field_name
|
|
84
|
+
old = query_opts[:fields] ? Array(query_opts[:fields]) : []
|
|
85
|
+
field_names = (old + Array(field_name)).uniq
|
|
86
|
+
if field_names[0]
|
|
87
|
+
query_opts[:fields] = field_names[1] ? field_names : field_names[0]
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def filter_field(field_name)
|
|
92
|
+
return unless field_name
|
|
93
|
+
field_name = Array(field_name)
|
|
94
|
+
field_name.each {|fn| raise "#{fn} is not a facetable field" unless table.facets.include? fn.to_sym}
|
|
95
|
+
old = query_opts[:facets] ? Array(query_opts[:facets]) : []
|
|
96
|
+
field_names = (old + Array(field_name)).uniq
|
|
97
|
+
if field_names[0]
|
|
98
|
+
query_opts[:facets] = field_names[1] ? field_names : field_names[0]
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def add_where_clause(attr_node, val)
|
|
103
|
+
field_key = field_key_from_node(attr_node)
|
|
104
|
+
if query_opts[field_key]
|
|
105
|
+
query_opts[field_key] = Array(query_opts[field_key]) << val
|
|
106
|
+
else
|
|
107
|
+
query_opts[field_key] = val
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# the DPLA API makes no distinction between filter and normal queries
|
|
112
|
+
def visit_Arel_Nodes_Equality(object, attribute)
|
|
113
|
+
add_where_clause(object.left, object.right)
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def visit_Arel_Nodes_NotEqual(object, attribute)
|
|
117
|
+
add_where_clause(object.left, "NOT " + object.right)
|
|
118
|
+
end
|
|
119
|
+
def visit_Arel_Nodes_Or(object, attribute)
|
|
120
|
+
add_where_clause(object.left, "OR " + object.right)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def visit_Arel_Nodes_Grouping(object, attribute)
|
|
124
|
+
visit object.expr, attribute
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def visit_Arel_Nodes_Ordering(object, attribute)
|
|
128
|
+
if query_opts[:sort_by]
|
|
129
|
+
query_opts[:sort_by] = Array[query_opts[:sort_by]] << object.expr.name
|
|
130
|
+
else
|
|
131
|
+
query_opts[:sort_by] = object.expr.name
|
|
132
|
+
end
|
|
133
|
+
direction = :asc if (::Arel::Nodes::Ascending === object and direction)
|
|
134
|
+
direction = :desc if (::Arel::Nodes::Descending === object)
|
|
135
|
+
query_opts[:sort_order] = direction if direction
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def order(*arel_nodes)
|
|
139
|
+
direction = nil
|
|
140
|
+
nodes = []
|
|
141
|
+
arel_nodes.inject(nodes) do |c, n|
|
|
142
|
+
if ::Arel::Nodes::Ordering === n
|
|
143
|
+
c << n
|
|
144
|
+
elsif n.is_a? String
|
|
145
|
+
_ns = n.split(',')
|
|
146
|
+
_ns.each do |_n|
|
|
147
|
+
_p = _n.split(/\s+/)
|
|
148
|
+
if (_p[1])
|
|
149
|
+
_p[1] = _p[1].downcase.to_sym
|
|
150
|
+
else
|
|
151
|
+
_p[1] = :asc
|
|
152
|
+
end
|
|
153
|
+
c << table[_p[0].to_sym].send(_p[1])
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
c
|
|
157
|
+
end
|
|
158
|
+
nodes.each do |node|
|
|
159
|
+
if ::Arel::Nodes::Ordering === node
|
|
160
|
+
if query_opts[:sort_by]
|
|
161
|
+
query_opts[:sort_by] = Array[query_opts[:sort_by]] << node.expr.name
|
|
162
|
+
else
|
|
163
|
+
query_opts[:sort_by] = node.expr.name
|
|
164
|
+
end
|
|
165
|
+
direction = :asc if (::Arel::Nodes::Ascending === node and direction)
|
|
166
|
+
direction = :desc if (::Arel::Nodes::Descending === node)
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
query_opts[:sort_order] = direction if direction
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
def visit_Arel_Nodes_Limit(object, attribute)
|
|
173
|
+
value = object.expr
|
|
174
|
+
if value and (value = value.to_i)
|
|
175
|
+
raise "Page size cannot be > 500 (#{value}" if value > 500
|
|
176
|
+
query_opts[:page_size] = value
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def visit_Arel_Nodes_Offset(object, attribute)
|
|
181
|
+
value = object.expr
|
|
182
|
+
if value
|
|
183
|
+
query_opts[:page] = (value.to_i / (query_opts[:page_size] || Ansr::Relation::DEFAULT_PAGE_SIZE)) + 1
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
end
|
|
188
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
module Ansr::Dpla
|
|
2
|
+
module ConnectionAdapters
|
|
3
|
+
class NoSqlAdapter < Ansr::ConnectionAdapters::NoSqlAdapter
|
|
4
|
+
|
|
5
|
+
def self.connection_for(klass)
|
|
6
|
+
klass.api
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def initialize(klass, logger = nil, pool = nil) #:nodoc:
|
|
10
|
+
super(klass, klass.api, logger, pool)
|
|
11
|
+
@visitor = Ansr::Dpla::Arel::Visitors::ToNoSql.new(@table)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def to_sql(*args)
|
|
15
|
+
to_nosql(*args)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def execute(query, name='ANSR-DPLA')
|
|
19
|
+
method = query.path
|
|
20
|
+
query = query.to_h if Ansr::Dpla::Request === query
|
|
21
|
+
query = query.dup
|
|
22
|
+
aliases = query.delete(:aliases)
|
|
23
|
+
json = @connection.send(method, query)
|
|
24
|
+
json = json.length > 0 ? JSON.load(json) : {'docs' => [], 'facets' => []}
|
|
25
|
+
if json['docs'] and aliases
|
|
26
|
+
json['docs'].each do |doc|
|
|
27
|
+
aliases.each do |k,v|
|
|
28
|
+
if doc[k]
|
|
29
|
+
old = doc.delete(k)
|
|
30
|
+
if old and doc[v]
|
|
31
|
+
doc[v] = Array(doc[v]) if doc[v]
|
|
32
|
+
Array(old).each {|ov| doc[v] << ov}
|
|
33
|
+
else
|
|
34
|
+
doc[v] = old
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
json
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def table_exists?(table_name)
|
|
44
|
+
['Collection', 'Item'].include? table_name
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def sanitize_limit(limit_value)
|
|
48
|
+
if (0..500) === limit_value.to_s.to_i
|
|
49
|
+
limit_value
|
|
50
|
+
else
|
|
51
|
+
Ansr::Relation::DEFAULT_PAGE_SIZE
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
end
|
|
@@ -6,6 +6,13 @@ module Ansr::Dpla
|
|
|
6
6
|
|
|
7
7
|
include Querying
|
|
8
8
|
|
|
9
|
+
def self.inherited(subclass)
|
|
10
|
+
super(subclass)
|
|
11
|
+
subclass.configure do |config|
|
|
12
|
+
config[:table_class] = Ansr::Dpla::Arel::BigTable
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
9
16
|
def assign_nested_parameter_attributes(pairs)
|
|
10
17
|
pairs.each do |k, v|
|
|
11
18
|
v = PseudoAssociate.new(v) if Hash === v
|
|
@@ -5,10 +5,14 @@ module Ansr::Dpla
|
|
|
5
5
|
extend ActiveSupport::Concern
|
|
6
6
|
|
|
7
7
|
module ClassMethods
|
|
8
|
+
def build_default_scope
|
|
9
|
+
Ansr::Dpla::Relation.new(model(), table())
|
|
10
|
+
end
|
|
11
|
+
|
|
8
12
|
def api
|
|
9
13
|
@api ||= begin
|
|
10
14
|
a = (config[:api] || Ansr::Dpla::Api).new
|
|
11
|
-
a.config(self.config)
|
|
15
|
+
a.config{|x| x.merge!(self.config)}
|
|
12
16
|
a
|
|
13
17
|
end
|
|
14
18
|
end
|
|
@@ -17,16 +21,8 @@ module Ansr::Dpla
|
|
|
17
21
|
@api = api
|
|
18
22
|
end
|
|
19
23
|
|
|
20
|
-
def table
|
|
21
|
-
@big_table ||= Ansr::Dpla::Arel::BigTable.new(model(), {:config => config()})
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def table=(val)
|
|
25
|
-
@big_table = val
|
|
26
|
-
end
|
|
27
|
-
|
|
28
24
|
def connection_handler
|
|
29
|
-
@connection_handler ||= Ansr::Model::ConnectionHandler.new(Ansr::Dpla::
|
|
25
|
+
@connection_handler ||= Ansr::Model::ConnectionHandler.new(Ansr::Dpla::ConnectionAdapters::NoSqlAdapter)
|
|
30
26
|
end
|
|
31
27
|
|
|
32
28
|
def references
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
require 'yaml'
|
|
2
|
+
require 'blacklight'
|
|
3
|
+
module Ansr::Dpla
|
|
4
|
+
class Relation < ::Ansr::Relation
|
|
5
|
+
|
|
6
|
+
def initialize(klass, table, values = {})
|
|
7
|
+
raise "Cannot search nil model" if klass.nil?
|
|
8
|
+
super(klass, table, values)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def facet_values=(values)
|
|
12
|
+
values.each {|value| raise "#{value.expr.name.to_sym} is not facetable" unless table.facets.include? value.expr.name.to_sym}
|
|
13
|
+
super
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def empty?
|
|
17
|
+
count == 0
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def many?
|
|
21
|
+
count > 1
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def offset!(value)
|
|
25
|
+
page_size = self.limit_value || default_limit_value
|
|
26
|
+
if (value.to_i % page_size.to_i) != 0
|
|
27
|
+
raise "Bad offset #{value} for page size #{page_size}"
|
|
28
|
+
end
|
|
29
|
+
self.offset_value=value
|
|
30
|
+
self
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def count
|
|
34
|
+
self.load
|
|
35
|
+
@response['count']
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def filters_from(response)
|
|
39
|
+
f = {}
|
|
40
|
+
(response['facets'] || {}).inject(f) do |h,(k,v)|
|
|
41
|
+
|
|
42
|
+
if v['total'] != 0
|
|
43
|
+
items = v['terms'].collect do |term|
|
|
44
|
+
Blacklight::SolrResponse::Facets::FacetItem.new(:value => term['term'], :hits => term['count'])
|
|
45
|
+
end
|
|
46
|
+
options = {:sort => 'asc', :offset => 0}
|
|
47
|
+
h[k] = Blacklight::SolrResponse::Facets::FacetField.new k, items, options
|
|
48
|
+
end
|
|
49
|
+
h
|
|
50
|
+
end
|
|
51
|
+
f
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def docs_from(response)
|
|
55
|
+
response['docs']
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
end
|
|
@@ -9,18 +9,21 @@ describe Ansr::Dpla::Api do
|
|
|
9
9
|
|
|
10
10
|
it "should be configurable with a Hash" do
|
|
11
11
|
config_fixture = {:api_key => :foo, :url => :bar}
|
|
12
|
-
@test.config(config_fixture)
|
|
12
|
+
@test.config{|x| x.merge!(config_fixture)}
|
|
13
13
|
expect(@test.url).to eql(:bar)
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
it "should be configurable with a path to a yaml" do
|
|
17
|
-
|
|
17
|
+
open(fixture_path('dpla.yml')) do |blob|
|
|
18
|
+
config = YAML.load(blob)
|
|
19
|
+
@test.config{|x| x.merge!(config)}
|
|
20
|
+
end
|
|
18
21
|
expect(@test.url).to eql('http://fake.dp.la/v0/')
|
|
19
22
|
end
|
|
20
23
|
|
|
21
24
|
it "should raise an error of the config doesn't have required fields" do
|
|
22
|
-
expect { Ansr::Dpla::Api.new.config(
|
|
23
|
-
Ansr::Dpla::Api.new.config({:url => :foo, :api_key => :foo})
|
|
25
|
+
expect { Ansr::Dpla::Api.new.config{|x| x.merge!(:url => :foo)}}.to raise_error
|
|
26
|
+
Ansr::Dpla::Api.new.config {|x| x.merge!({:url => :foo, :api_key => :foo})}
|
|
24
27
|
end
|
|
25
28
|
|
|
26
29
|
end
|
|
@@ -28,7 +31,7 @@ describe Ansr::Dpla::Api do
|
|
|
28
31
|
describe '#path_for' do
|
|
29
32
|
before do
|
|
30
33
|
@test = Ansr::Dpla::Api.new
|
|
31
|
-
@test.config(
|
|
34
|
+
@test.config{|x| x.merge!(:api_key => :testing)}
|
|
32
35
|
end
|
|
33
36
|
|
|
34
37
|
|
|
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
|
3
3
|
describe Item do
|
|
4
4
|
describe '.configure' do
|
|
5
5
|
it "should store the configured Api class" do
|
|
6
|
-
Item.configure(
|
|
6
|
+
Item.configure {|x| x.merge!(:api=>Ansr::Dpla::TestApi, :api_key => :dummy)}
|
|
7
7
|
expect(Item.api).to be_a Ansr::Dpla::TestApi
|
|
8
8
|
end
|
|
9
9
|
end
|
|
@@ -25,7 +25,7 @@ describe Item do
|
|
|
25
25
|
|
|
26
26
|
describe '.where' do
|
|
27
27
|
before do
|
|
28
|
-
Item.configure({:api=>Ansr::Dpla::TestApi, :api_key => :dummy})
|
|
28
|
+
Item.configure{|x| x.merge!({:api=>Ansr::Dpla::TestApi, :api_key => :dummy})}
|
|
29
29
|
end
|
|
30
30
|
it 'should return a Relation when there is query information' do
|
|
31
31
|
expect(Item.where({:q=>'kittens'})).to be_a Ansr::Relation
|
|
@@ -1,47 +1,55 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
|
|
3
|
-
describe Ansr::Relation do
|
|
3
|
+
describe Ansr::Dpla::Relation do
|
|
4
4
|
before do
|
|
5
5
|
@kittens = read_fixture('kittens.jsonld')
|
|
6
6
|
@faceted = read_fixture('kittens_faceted.jsonld')
|
|
7
7
|
@empty = read_fixture('empty.jsonld')
|
|
8
8
|
@mock_api = double('api')
|
|
9
|
-
Item.config
|
|
9
|
+
Item.config{ |x| x[:api_key] = :foo}
|
|
10
10
|
Item.engine.api= @mock_api
|
|
11
11
|
end
|
|
12
|
+
|
|
13
|
+
subject { Ansr::Dpla::Relation.new(Item, Item.table) }
|
|
12
14
|
describe '#filter' do
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
describe "do a single field, single value filter" do
|
|
16
|
+
it "with facet" do
|
|
17
|
+
test = subject.filter(:object=>'kittens').facet(:object)
|
|
18
|
+
@mock_api.should_receive(:items).with(:object => 'kittens', :facets => :object).and_return('')
|
|
19
|
+
test.load
|
|
20
|
+
end
|
|
21
|
+
it "without facet" do
|
|
22
|
+
test = subject.filter(:object=>'kittens')
|
|
23
|
+
@mock_api.should_receive(:items).with(:object => 'kittens').and_return('')
|
|
24
|
+
test.load
|
|
25
|
+
end
|
|
17
26
|
end
|
|
18
27
|
it "do a single field, multiple value filter" do
|
|
19
|
-
test =
|
|
28
|
+
test = subject.filter(:object=>['kittens', 'cats']).facet(:object)
|
|
20
29
|
@mock_api.should_receive(:items).with(:object => ['kittens','cats'], :facets => :object).and_return('')
|
|
21
30
|
test.load
|
|
22
31
|
end
|
|
23
32
|
it "do merge single field, multiple value filters" do
|
|
24
|
-
test =
|
|
25
|
-
@mock_api.should_receive(:items).with(:"provider.name" => ['kittens','cats'], :facets => :"provider.name").and_return('')
|
|
33
|
+
test = subject.filter(:"provider.name"=>'kittens').filter(:"provider.name"=>'cats').facet(:"provider.name")
|
|
34
|
+
@mock_api.should_receive(:items).with(hash_including(:"provider.name" => ['kittens','cats'], :facets => :"provider.name")).and_return('')
|
|
26
35
|
test.load
|
|
27
36
|
end
|
|
28
37
|
it "do a multiple field, single value filter" do
|
|
29
|
-
test =
|
|
30
|
-
@mock_api.should_receive(:items).with(:object => 'kittens', :isShownAt=>'bears', :facets => [:object, :isShownAt]).and_return('')
|
|
38
|
+
test = subject.filter(:object=>'kittens',:isShownAt=>'bears').facet([:object, :isShownAt])
|
|
39
|
+
@mock_api.should_receive(:items).with(hash_including(:object => 'kittens', :isShownAt=>'bears', :facets => [:object, :isShownAt])).and_return('')
|
|
31
40
|
test.load
|
|
32
41
|
end
|
|
33
42
|
it "should keep scope distinct from spawned Relations" do
|
|
34
|
-
test =
|
|
43
|
+
test = subject.filter(:"provider.name"=>'kittens').facet(:"provider.name")
|
|
35
44
|
test.where(:q=>'cats')
|
|
36
45
|
@mock_api.should_receive(:items).with(:"provider.name" => 'kittens', :facets => :"provider.name").and_return('')
|
|
37
46
|
test.load
|
|
38
47
|
end
|
|
39
|
-
it "should raise an error if the requested field is not a
|
|
40
|
-
|
|
41
|
-
expect {test.filter(:foo=>'kittens')}.to raise_error
|
|
48
|
+
it "should raise an error if the requested field is not a facetable field" do
|
|
49
|
+
expect {subject.facet(:foo)}.to raise_error
|
|
42
50
|
end
|
|
43
|
-
it "should
|
|
44
|
-
test =
|
|
51
|
+
it "should facet without a filter" do
|
|
52
|
+
test = subject.facet(:object)
|
|
45
53
|
@mock_api.should_receive(:items).with(:facets => :object).and_return('')
|
|
46
54
|
test.load
|
|
47
55
|
end
|
|
@@ -52,7 +60,7 @@ describe Ansr::Relation do
|
|
|
52
60
|
# Blacklight::SolrResponse::Facets::FacetItem.new(:value => s, :hits => v)
|
|
53
61
|
# options = {:sort => 'asc', :offset => 0}
|
|
54
62
|
# Blacklight::SolrResponse::Facets::FacetField.new name, items, options
|
|
55
|
-
test =
|
|
63
|
+
test = subject.where(:q=>'kittens')
|
|
56
64
|
@mock_api.should_receive(:items).with(:q => 'kittens').and_return(@faceted)
|
|
57
65
|
test.load
|
|
58
66
|
fkey = test.filters.keys.first
|
|
@@ -61,7 +69,7 @@ describe Ansr::Relation do
|
|
|
61
69
|
facet.items
|
|
62
70
|
end
|
|
63
71
|
it 'should dispatch a query with no docs requested if not loaded' do
|
|
64
|
-
test =
|
|
72
|
+
test = subject.where(:q=>'kittens')
|
|
65
73
|
@mock_api.should_receive(:items).with(:q => 'kittens', :page_size=>0).once.and_return(@faceted)
|
|
66
74
|
fkey = test.filters.keys.first
|
|
67
75
|
facet = test.filters[fkey]
|