brainstem 1.1.1 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +81 -4
  3. data/Gemfile.lock +9 -9
  4. data/README.md +134 -37
  5. data/brainstem.gemspec +1 -1
  6. data/lib/brainstem/api_docs/endpoint.rb +40 -18
  7. data/lib/brainstem/api_docs/formatters/markdown/endpoint_formatter.rb +27 -22
  8. data/lib/brainstem/api_docs/formatters/markdown/helper.rb +9 -0
  9. data/lib/brainstem/api_docs/formatters/markdown/presenter_formatter.rb +14 -6
  10. data/lib/brainstem/api_docs/presenter.rb +3 -7
  11. data/lib/brainstem/concerns/controller_dsl.rb +138 -14
  12. data/lib/brainstem/concerns/presenter_dsl.rb +39 -6
  13. data/lib/brainstem/dsl/array_block_field.rb +25 -0
  14. data/lib/brainstem/dsl/block_field.rb +69 -0
  15. data/lib/brainstem/dsl/configuration.rb +13 -5
  16. data/lib/brainstem/dsl/field.rb +15 -1
  17. data/lib/brainstem/dsl/fields_block.rb +20 -2
  18. data/lib/brainstem/dsl/hash_block_field.rb +30 -0
  19. data/lib/brainstem/presenter.rb +10 -6
  20. data/lib/brainstem/presenter_validator.rb +20 -11
  21. data/lib/brainstem/version.rb +1 -1
  22. data/spec/brainstem/api_docs/endpoint_spec.rb +347 -14
  23. data/spec/brainstem/api_docs/formatters/markdown/endpoint_formatter_spec.rb +106 -13
  24. data/spec/brainstem/api_docs/formatters/markdown/helper_spec.rb +19 -0
  25. data/spec/brainstem/api_docs/formatters/markdown/presenter_formatter_spec.rb +150 -37
  26. data/spec/brainstem/api_docs/presenter_spec.rb +85 -18
  27. data/spec/brainstem/concerns/controller_dsl_spec.rb +615 -31
  28. data/spec/brainstem/concerns/inheritable_configuration_spec.rb +32 -9
  29. data/spec/brainstem/concerns/presenter_dsl_spec.rb +99 -25
  30. data/spec/brainstem/dsl/array_block_field_spec.rb +43 -0
  31. data/spec/brainstem/dsl/block_field_spec.rb +188 -0
  32. data/spec/brainstem/dsl/field_spec.rb +86 -20
  33. data/spec/brainstem/dsl/hash_block_field_spec.rb +166 -0
  34. data/spec/brainstem/presenter_collection_spec.rb +24 -24
  35. data/spec/brainstem/presenter_spec.rb +233 -9
  36. data/spec/brainstem/query_strategies/filter_and_search_spec.rb +1 -1
  37. data/spec/spec_helpers/presenters.rb +8 -0
  38. data/spec/spec_helpers/schema.rb +13 -0
  39. metadata +15 -6
@@ -52,14 +52,35 @@ describe Brainstem::DSL::Field do
52
52
  describe '#run_on' do
53
53
  let(:context) { { } }
54
54
 
55
+ it 'calls `evaluate_value_on`' do
56
+ mock(field).evaluate_value_on.with(model, context, anything)
57
+
58
+ field.run_on(model, context)
59
+ end
60
+
61
+ context 'when helper instance is specified' do
62
+ let(:helper_instance) { Object.new }
63
+
64
+ it 'calls `evaluate_value_on` with the given helper instance' do
65
+ mock(field).evaluate_value_on.with(model, context, helper_instance)
66
+
67
+ field.run_on(model, context, helper_instance)
68
+ end
69
+ end
70
+ end
71
+
72
+ describe '#evaluate_value_on' do
73
+ let(:context) { { } }
74
+ let(:helper_instance) { Object.new }
75
+
55
76
  context 'on :dynamic fields' do
56
77
  let(:options) { { dynamic: lambda { some_instance_method } } }
57
78
 
58
79
  it 'calls the :dynamic lambda in the context of the given instance' do
59
80
  do_not_allow(model).title
60
- instance = Object.new
61
- mock(instance).some_instance_method
62
- field.run_on(model, context, instance)
81
+ mock(helper_instance).some_instance_method
82
+
83
+ field.evaluate_value_on(model, context, helper_instance)
63
84
  end
64
85
  end
65
86
 
@@ -79,22 +100,22 @@ describe Brainstem::DSL::Field do
79
100
  context 'The first model is ran' do
80
101
  it 'builds lookup cache and returns the value for the first model' do
81
102
  expect(context[:lookup][:fields][name.to_s]).to eq(nil)
82
- instance = Object.new
83
- mock(instance).some_instance_method
84
- expect(field.run_on(first_model, context, instance)).to eq("Ben's Project")
103
+ mock(helper_instance).some_instance_method
104
+
105
+ expect(field.evaluate_value_on(first_model, context, helper_instance)).to eq("Ben's Project")
85
106
  expect(context[:lookup][:fields][name.to_s]).to eq({ first_model.id => "Ben's Project", second_model.id => "Nate's Project" })
86
107
  end
87
108
  end
88
109
 
89
110
  context 'The second model is ran after the first' do
90
111
  it 'returns the value from the lookup cache and does not run the lookup' do
91
- instance = Object.new
92
- mock(instance).some_instance_method
93
- field.run_on(first_model, context, instance)
112
+ mock(helper_instance).some_instance_method
113
+
114
+ field.evaluate_value_on(first_model, context, helper_instance)
94
115
  expect(context[:lookup][:fields][name.to_s]).to eq({ first_model.id => "Ben's Project", second_model.id => "Nate's Project" })
95
116
 
96
- mock(instance).some_instance_method.never
97
- expect(field.run_on(second_model, context, instance)).to eq("Nate's Project")
117
+ mock(helper_instance).some_instance_method.never
118
+ expect(field.evaluate_value_on(second_model, context, helper_instance)).to eq("Nate's Project")
98
119
  end
99
120
  end
100
121
 
@@ -104,7 +125,7 @@ describe Brainstem::DSL::Field do
104
125
 
105
126
  it 'should raise error explaining the default lookup fetch relies on [] to access the model\'s value from the lookup' do
106
127
  expect {
107
- field.run_on(first_model, context)
128
+ field.evaluate_value_on(first_model, context)
108
129
  }.to raise_error(StandardError, 'Brainstem expects the return result of the `lookup` to be a Hash since it must respond to [] in order to access the model\'s assocation(s). Default: lookup_fetch: lambda { |lookup, model| lookup[model.id] }`')
109
130
  end
110
131
  end
@@ -119,10 +140,10 @@ describe Brainstem::DSL::Field do
119
140
  }
120
141
 
121
142
  it 'does not use the dynamic lambda' do
122
- instance = Object.new
123
- mock(instance).dynamic_instance_method.never
124
- mock(instance).lookup_instance_method
125
- expect(field.run_on(first_model, context, instance)).to eq "Ben's Project"
143
+ mock(helper_instance).dynamic_instance_method.never
144
+ mock(helper_instance).lookup_instance_method
145
+
146
+ expect(field.evaluate_value_on(first_model, context, helper_instance)).to eq "Ben's Project"
126
147
  end
127
148
  end
128
149
 
@@ -137,9 +158,9 @@ describe Brainstem::DSL::Field do
137
158
  it 'returns the value from the lookup using the lookup_fetch lambda' do
138
159
  context[:lookup][:fields][name.to_s] = {}
139
160
  context[:lookup][:fields][name.to_s][first_model.id] = "Ben's stubbed out Project"
140
- instance = Object.new
141
- mock(instance).some_instance_method
142
- expect(field.run_on(first_model, context, instance)).to eq("Ben's stubbed out Project")
161
+ mock(helper_instance).some_instance_method
162
+
163
+ expect(field.evaluate_value_on(first_model, context, helper_instance)).to eq("Ben's stubbed out Project")
143
164
  end
144
165
  end
145
166
  end
@@ -148,7 +169,52 @@ describe Brainstem::DSL::Field do
148
169
  it 'calls method_name on the model' do
149
170
  mock(model).foo
150
171
  mock(field).method_name { 'foo' }
151
- field.run_on(model, context)
172
+
173
+ field.evaluate_value_on(model, context)
174
+ end
175
+ end
176
+ end
177
+
178
+ describe '#presentable?' do
179
+ let(:given_context) {
180
+ {
181
+ optional_fields: 'optional field',
182
+ conditionals: 'conditionals',
183
+ helper_instance: 'helper instance',
184
+ conditional_cache: 'conditional cache'
185
+ }
186
+ }
187
+ let(:optioned) { false }
188
+ let(:conditionals_match) { false }
189
+
190
+ before do
191
+ mock(field).optioned?.with(given_context[:optional_fields]) { optioned }
192
+ stub(field).conditionals_match?.with(
193
+ model,
194
+ given_context[:conditionals],
195
+ given_context[:helper_instance],
196
+ given_context[:conditional_cache]
197
+ ) { conditionals_match }
198
+ end
199
+
200
+ it 'calls `optioned?` by passing in the optional fields from the context' do
201
+ expect(field.presentable?(model, given_context)).to be_falsey
202
+ end
203
+
204
+ context 'when field is not optional' do
205
+ let(:optioned) { true }
206
+
207
+ it 'calls `conditionals_match?` with conditionals, helper instance and conditional cache from the context' do
208
+ expect(field.presentable?(model, given_context)).to be_falsey
209
+ end
210
+ end
211
+
212
+ context 'when field is not optional and conditionals match' do
213
+ let(:optioned) { true }
214
+ let(:conditionals_match) { true }
215
+
216
+ it 'returns true' do
217
+ expect(field.presentable?(model, given_context)).to be_truthy
152
218
  end
153
219
  end
154
220
  end
@@ -0,0 +1,166 @@
1
+ require 'spec_helper'
2
+ require 'brainstem/dsl/hash_block_field'
3
+
4
+ describe Brainstem::DSL::HashBlockField do
5
+ let(:name) { :tasks }
6
+ let(:type) { :hash }
7
+ let(:description) { 'the title of this model' }
8
+ let(:options) { { info: description } }
9
+ let(:nested_field) { Brainstem::DSL::HashBlockField.new(name, type, options) }
10
+ let(:model) { Workspace.find(1) }
11
+ let(:lead_user) { model.lead_user }
12
+
13
+ before do
14
+ expect(lead_user).to be_present
15
+ expect(nested_field.configuration.keys).to be_empty
16
+
17
+ # Add sub fields to the hash block field.
18
+ nested_field.configuration[:type] = Brainstem::DSL::Field.new(:type, type, {})
19
+ nested_field.configuration[:formatted_type] = Brainstem::DSL::Field.new(:formatted_type, type,
20
+ dynamic: -> (model) { "Formatted #{model.type}" },
21
+ use_parent_value: true
22
+ )
23
+
24
+ expect(nested_field.configuration.keys).to eq(%w(type formatted_type))
25
+ end
26
+
27
+ describe '#run_on' do
28
+ let(:context) { { } }
29
+ let(:helper_instance) { Object.new }
30
+
31
+ describe 'when none of the sub-fields are presentable' do
32
+ before do
33
+ stub.any_instance_of(Brainstem::DSL::Field).presentable? { false }
34
+ end
35
+
36
+ it 'presents an empty hash' do
37
+ presented_data = nested_field.run_on(model, context)
38
+
39
+ expect(presented_data).to eq({})
40
+ end
41
+ end
42
+
43
+ describe 'when the field is executable' do
44
+ let(:name) { :lead_user }
45
+ let(:options) { { info: description, via: :lead_user } }
46
+
47
+ before do
48
+ expect(nested_field.executable?).to be_truthy
49
+
50
+ expect(nested_field.configuration[:type].options[:use_parent_value]).to be_nil
51
+ expect(nested_field.configuration[:formatted_type].options[:use_parent_value]).to be_truthy
52
+ end
53
+
54
+ it 'returns a hash with the value from the evaluated parent' do
55
+ presented_data = nested_field.run_on(model, context)
56
+
57
+ expect(presented_data['type']).to eq(lead_user.type)
58
+ expect(presented_data['formatted_type']).to eq("Formatted #{lead_user.type}")
59
+ end
60
+
61
+ context 'when the evaluated parent value is blank' do
62
+ before do
63
+ stub(model).lead_user { nil }
64
+ end
65
+
66
+ it 'returns a hash with the value from the evaluated parent' do
67
+ expect(nested_field.run_on(model, context)).to eq({})
68
+ end
69
+ end
70
+
71
+ context 'when the sub field doesn\'t use a parent value' do
72
+ before do
73
+ nested_field.configuration[:secret] = Brainstem::DSL::Field.new(:secret, type,
74
+ via: :secret_info,
75
+ use_parent_value: false
76
+ )
77
+
78
+ expect(nested_field.configuration.keys).to eq(%w(type formatted_type secret))
79
+ expect(nested_field.configuration[:secret].options[:use_parent_value]).to be_falsey
80
+ end
81
+
82
+ it 'returns a hash with the value from itself' do
83
+ presented_data = nested_field.run_on(model, context)
84
+
85
+ expect(presented_data['secret']).to eq(model.secret_info)
86
+ end
87
+
88
+ context 'when the evaluated parent value is blank' do
89
+ before do
90
+ stub(model).lead_user { nil }
91
+ end
92
+
93
+ it 'returns a hash with the value from itself' do
94
+ presented_data = nested_field.run_on(model, context)
95
+
96
+ expect(presented_data['secret']).to eq(model.secret_info)
97
+ end
98
+ end
99
+ end
100
+ end
101
+
102
+ describe 'when the field delegates to its parent' do
103
+ let(:name) { :klass }
104
+
105
+ before do
106
+ expect(nested_field.executable?).to be_falsey
107
+
108
+ expect(nested_field.configuration[:type].options[:use_parent_value]).to be_nil
109
+ expect(nested_field.configuration[:formatted_type].options[:use_parent_value]).to be_truthy
110
+ end
111
+
112
+ it 'returns a hash with the value from its parent' do
113
+ presented_data = nested_field.run_on(model, context)
114
+
115
+ expect(presented_data['type']).to eq(model.type)
116
+ expect(presented_data['formatted_type']).to eq("Formatted #{model.type}")
117
+ end
118
+
119
+ context 'when the sub field doesn\'t use a parent value' do
120
+ before do
121
+ nested_field.configuration[:secret] = Brainstem::DSL::Field.new(:secret, type,
122
+ via: :secret_info,
123
+ use_parent_value: false
124
+ )
125
+
126
+ expect(nested_field.configuration.keys).to eq(%w(type formatted_type secret))
127
+ expect(nested_field.configuration[:secret].options[:use_parent_value]).to be_falsey
128
+ end
129
+
130
+ it 'returns a hash with the value from itself' do
131
+ presented_data = nested_field.run_on(model, context)
132
+
133
+ expect(presented_data['secret']).to eq(model.secret_info)
134
+ end
135
+ end
136
+ end
137
+ end
138
+
139
+ describe '#executable' do
140
+ subject { nested_field.executable? }
141
+
142
+ context 'when dynamic option is specified' do
143
+ let(:options) { { dynamic: -> { [] } } }
144
+
145
+ it { is_expected.to be_truthy }
146
+ end
147
+
148
+ context 'when lookup option is specified' do
149
+ let(:options) { { lookup: -> { [] } } }
150
+
151
+ it { is_expected.to be_truthy }
152
+ end
153
+
154
+ context 'when via option is specified' do
155
+ let(:options) { { via: :foo } }
156
+
157
+ it { is_expected.to be_truthy }
158
+ end
159
+
160
+ context 'when dynamic option is specified' do
161
+ let(:options) { {} }
162
+
163
+ it { is_expected.to be_falsey }
164
+ end
165
+ end
166
+ end
@@ -482,8 +482,8 @@ describe Brainstem::PresenterCollection do
482
482
 
483
483
  describe "filters" do
484
484
  before do
485
- WorkspacePresenter.filter(:owned_by) { |scope, user_id| scope.owned_by(user_id.to_i) }
486
- WorkspacePresenter.filter(:title) { |scope, title| scope.where(:title => title) }
485
+ WorkspacePresenter.filter(:owned_by, :integer) { |scope, user_id| scope.owned_by(user_id.to_i) }
486
+ WorkspacePresenter.filter(:title, :string) { |scope, title| scope.where(:title => title) }
487
487
  end
488
488
 
489
489
  it "limits records to those matching given filters" do
@@ -510,7 +510,7 @@ describe Brainstem::PresenterCollection do
510
510
  it "converts boolean parameters from strings to booleans" do
511
511
  jane_id = jane.id
512
512
  bob_id = bob.id
513
- WorkspacePresenter.filter(:owned_by_bob) { |scope, boolean| boolean ? scope.where(:user_id => bob_id) : scope.where(:user_id => jane_id) }
513
+ WorkspacePresenter.filter(:owned_by_bob, :boolean) { |scope, boolean| boolean ? scope.where(:user_id => bob_id) : scope.where(:user_id => jane_id) }
514
514
  result = @presenter_collection.presenting("workspaces", :params => { :owned_by_bob => "false" }) { Workspace.where(nil) }
515
515
  expect(result['workspaces'].values.find { |workspace| workspace['title'].include?("jane") }).to be
516
516
  expect(result['workspaces'].values.find { |workspace| workspace['title'].include?("bob") }).not_to be
@@ -518,7 +518,7 @@ describe Brainstem::PresenterCollection do
518
518
 
519
519
  it "ensures arguments are strings if they are not arrays" do
520
520
  string = nil
521
- WorkspacePresenter.filter(:owned_by_bob) do |scope, arg|
521
+ WorkspacePresenter.filter(:owned_by_bob, :boolean) do |scope, arg|
522
522
  string = arg
523
523
  scope
524
524
  end
@@ -528,7 +528,7 @@ describe Brainstem::PresenterCollection do
528
528
 
529
529
  it "preserves array arguments" do
530
530
  array = nil
531
- WorkspacePresenter.filter(:owned_by_bob) do |scope, arg|
531
+ WorkspacePresenter.filter(:owned_by_bob, :boolean) do |scope, arg|
532
532
  array = arg
533
533
  scope
534
534
  end
@@ -537,7 +537,7 @@ describe Brainstem::PresenterCollection do
537
537
  end
538
538
 
539
539
  it "allows filters to be called with false as an argument" do
540
- WorkspacePresenter.filter(:nothing) { |scope, bool| bool ? scope.where(:id => nil) : scope }
540
+ WorkspacePresenter.filter(:nothing, :boolean) { |scope, bool| bool ? scope.where(:id => nil) : scope }
541
541
  result = @presenter_collection.presenting("workspaces", :params => { :nothing => "true" }) { Workspace.where(nil) }
542
542
  expect(result['workspaces'].length).to eq(0)
543
543
  result = @presenter_collection.presenting("workspaces", :params => { :nothing => "false" }) { Workspace.where(nil) }
@@ -546,7 +546,7 @@ describe Brainstem::PresenterCollection do
546
546
 
547
547
  it "passes colon separated params through as a string" do
548
548
  a, b = nil, nil
549
- WorkspacePresenter.filter(:between) { |scope, a_and_b|
549
+ WorkspacePresenter.filter(:between, :string) { |scope, a_and_b|
550
550
  a, b = a_and_b.split(':')
551
551
  scope
552
552
  }
@@ -564,7 +564,7 @@ describe Brainstem::PresenterCollection do
564
564
  end
565
565
 
566
566
  called = false
567
- WorkspacePresenter.filter(:something) { |scope, string|
567
+ WorkspacePresenter.filter(:something, :string) { |scope, string|
568
568
  called = true
569
569
  some_method
570
570
  scope
@@ -576,7 +576,7 @@ describe Brainstem::PresenterCollection do
576
576
 
577
577
  context "with defaults" do
578
578
  before do
579
- WorkspacePresenter.filter(:owner, :default => bob.id) { |scope, id| scope.owned_by(id) }
579
+ WorkspacePresenter.filter(:owner, :integer, :default => bob.id) { |scope, id| scope.owned_by(id) }
580
580
  end
581
581
 
582
582
  let(:jane) { User.where(:username => "jane").first }
@@ -587,7 +587,7 @@ describe Brainstem::PresenterCollection do
587
587
  end
588
588
 
589
589
  it "allows falsy defaults" do
590
- WorkspacePresenter.filter(:include_early_workspaces, :default => false) { |scope, bool| bool ? scope : scope.where("id > 3") }
590
+ WorkspacePresenter.filter(:include_early_workspaces, :boolean, :default => false) { |scope, bool| bool ? scope : scope.where("id > 3") }
591
591
  result = @presenter_collection.presenting("workspaces") { Workspace.unscoped }
592
592
  expect(result['workspaces']['2']).not_to be_present
593
593
  result = @presenter_collection.presenting("workspaces", :params => { :include_early_workspaces => "true" }) { Workspace.unscoped }
@@ -595,7 +595,7 @@ describe Brainstem::PresenterCollection do
595
595
  end
596
596
 
597
597
  it "allows defaults to be skipped if :apply_default_filters is false" do
598
- WorkspacePresenter.filter(:include_early_workspaces, :default => false) { |scope, bool| bool ? scope : scope.where("id > 3") }
598
+ WorkspacePresenter.filter(:include_early_workspaces, :boolean, :default => false) { |scope, bool| bool ? scope : scope.where("id > 3") }
599
599
  result = @presenter_collection.presenting("workspaces", :apply_default_filters => true) { Workspace.unscoped }
600
600
  expect(result['workspaces']['2']).not_to be_present
601
601
  result = @presenter_collection.presenting("workspaces", :apply_default_filters => false) { Workspace.unscoped }
@@ -603,7 +603,7 @@ describe Brainstem::PresenterCollection do
603
603
  end
604
604
 
605
605
  it "allows defaults set to false to be skipped if params contain :apply_default_filters with a false value" do
606
- WorkspacePresenter.filter(:include_early_workspaces, :default => false) { |scope, bool| bool ? scope : scope.where("id > 3") }
606
+ WorkspacePresenter.filter(:include_early_workspaces, :boolean, :default => false) { |scope, bool| bool ? scope : scope.where("id > 3") }
607
607
 
608
608
  result = @presenter_collection.presenting("workspaces", :params => { :apply_default_filters => "true" }) { Workspace.unscoped }
609
609
  expect(result['workspaces']['2']).not_to be_present
@@ -613,7 +613,7 @@ describe Brainstem::PresenterCollection do
613
613
  end
614
614
 
615
615
  it "allows defaults set to true to be skipped if params contain :apply_default_filters with a false value" do
616
- WorkspacePresenter.filter(:include_early_workspaces, :default => true) { |scope, bool| bool ? scope : scope.where("id > 3") }
616
+ WorkspacePresenter.filter(:include_early_workspaces, :boolean, :default => true) { |scope, bool| bool ? scope : scope.where("id > 3") }
617
617
 
618
618
  result = @presenter_collection.presenting("workspaces", :params => { :apply_default_filters => "false" }) { Workspace.unscoped }
619
619
  expect(result['workspaces']['2']).to be_present
@@ -626,7 +626,7 @@ describe Brainstem::PresenterCollection do
626
626
  result = @presenter_collection.presenting("workspaces", :params => { :owner => jane.id.to_s }) { Workspace.unscoped }
627
627
  expect(result['workspaces'].keys).to match_array(jane.workspaces.map(&:id).map(&:to_s))
628
628
 
629
- WorkspacePresenter.filter(:include_early_workspaces, :default => true) { |scope, bool| bool ? scope : scope.where("id > 3") }
629
+ WorkspacePresenter.filter(:include_early_workspaces, :boolean, :default => true) { |scope, bool| bool ? scope : scope.where("id > 3") }
630
630
  result = @presenter_collection.presenting("workspaces", :params => { :include_early_workspaces => "false" }) { Workspace.unscoped }
631
631
  expect(result['workspaces']['2']).not_to be_present
632
632
  end
@@ -637,7 +637,7 @@ describe Brainstem::PresenterCollection do
637
637
  let(:jane) { User.where(:username => "jane").first }
638
638
 
639
639
  before do
640
- WorkspacePresenter.filter(:owned_by, :default => bob.id)
640
+ WorkspacePresenter.filter(:owned_by, :boolean, :default => bob.id)
641
641
  end
642
642
 
643
643
  it "calls the named scope with default arguments" do
@@ -651,7 +651,7 @@ describe Brainstem::PresenterCollection do
651
651
  end
652
652
 
653
653
  it "can use filters without lambdas in the presenter or model, but behaves strangely when false is given" do
654
- WorkspacePresenter.filter(:numeric_description)
654
+ WorkspacePresenter.filter(:numeric_description, :boolean)
655
655
 
656
656
  result = @presenter_collection.presenting("workspaces") { Workspace.where(nil) }
657
657
  expect(result['workspaces'].keys).to eq(%w[1 2 3 4])
@@ -668,13 +668,13 @@ describe Brainstem::PresenterCollection do
668
668
 
669
669
  context "with include_params" do
670
670
  it "passes the params into the filter block" do
671
- WorkspacePresenter.filter(:other_filter) { |scope, opt| scope }
672
- WorkspacePresenter.filter(:unused_filter) { |scope, opt| scope }
673
- WorkspacePresenter.filter(:other_filter_with_default, default: true) { |scope, opt| scope }
671
+ WorkspacePresenter.filter(:other_filter, :integer) { |scope, opt| scope }
672
+ WorkspacePresenter.filter(:unused_filter, :string) { |scope, opt| scope }
673
+ WorkspacePresenter.filter(:other_filter_with_default, :boolean, default: true) { |scope, opt| scope }
674
674
 
675
675
  provided_params = nil
676
676
 
677
- WorkspacePresenter.filter :filter_with_param, :include_params => true do |scope, option, params|
677
+ WorkspacePresenter.filter :filter_with_param, :string, :include_params => true do |scope, option, params|
678
678
  provided_params = params
679
679
  scope
680
680
  end
@@ -767,7 +767,7 @@ describe Brainstem::PresenterCollection do
767
767
 
768
768
  describe "passing options to the search block" do
769
769
  it "passes the search method, the search string, includes, order, and paging options" do
770
- WorkspacePresenter.filter(:owned_by) { |scope| scope }
770
+ WorkspacePresenter.filter(:owned_by, :integer) { |scope| scope }
771
771
  search_args = nil
772
772
  WorkspacePresenter.search do |*args|
773
773
  search_args = args
@@ -801,7 +801,7 @@ describe Brainstem::PresenterCollection do
801
801
 
802
802
  describe "filters" do
803
803
  it "passes through the default filters if no filter is requested" do
804
- WorkspacePresenter.filter(:owned_by, :default => true) { |scope| scope }
804
+ WorkspacePresenter.filter(:owned_by, :boolean, :default => true) { |scope| scope }
805
805
  search_options = nil
806
806
  WorkspacePresenter.search do |string, options|
807
807
  search_options = options
@@ -824,7 +824,7 @@ describe Brainstem::PresenterCollection do
824
824
  end
825
825
 
826
826
  it "does not pass through existing non-default filters that are not requested" do
827
- WorkspacePresenter.filter(:owned_by) { |scope| scope }
827
+ WorkspacePresenter.filter(:owned_by, :integer) { |scope| scope }
828
828
  search_options = nil
829
829
  WorkspacePresenter.search do |string, options|
830
830
  search_options = options
@@ -1090,7 +1090,7 @@ describe Brainstem::PresenterCollection do
1090
1090
 
1091
1091
  describe "the count top level key" do
1092
1092
  it "should return the total number of matched records" do
1093
- WorkspacePresenter.filter(:owned_by) { |scope, user_id| scope.owned_by(user_id.to_i) }
1093
+ WorkspacePresenter.filter(:owned_by, :integer) { |scope, user_id| scope.owned_by(user_id.to_i) }
1094
1094
 
1095
1095
  result = @presenter_collection.presenting("workspaces") { Workspace.where(:id => 1) }
1096
1096
  expect(result['count']).to eq(1)