ajax-datatables-rails 0.3.1 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. checksums.yaml +5 -5
  2. data/.codeclimate.yml +8 -0
  3. data/.github/workflows/ci.yml +128 -0
  4. data/.gitignore +23 -0
  5. data/.rspec +1 -0
  6. data/.rubocop.yml +58 -0
  7. data/Appraisals +28 -0
  8. data/CHANGELOG.md +102 -7
  9. data/Gemfile +4 -1
  10. data/Guardfile +16 -0
  11. data/LICENSE +17 -18
  12. data/README.md +595 -404
  13. data/Rakefile +4 -2
  14. data/ajax-datatables-rails.gemspec +41 -25
  15. data/appraisal.yml +56 -0
  16. data/bin/_guard-core +29 -0
  17. data/bin/appraisal +29 -0
  18. data/bin/bundle +114 -0
  19. data/bin/guard +29 -0
  20. data/bin/rackup +27 -0
  21. data/bin/rake +29 -0
  22. data/bin/rspec +29 -0
  23. data/bin/rubocop +29 -0
  24. data/config.ru +7 -0
  25. data/doc/migrate.md +97 -0
  26. data/doc/webpack.md +55 -0
  27. data/gemfiles/rails_5.2.8.gemfile +21 -0
  28. data/gemfiles/rails_6.0.6.gemfile +21 -0
  29. data/gemfiles/rails_6.1.7.gemfile +21 -0
  30. data/gemfiles/rails_7.0.4.gemfile +21 -0
  31. data/lib/ajax-datatables-rails/active_record.rb +7 -0
  32. data/lib/ajax-datatables-rails/base.rb +114 -149
  33. data/lib/ajax-datatables-rails/datatable/column/date_filter.rb +68 -0
  34. data/lib/ajax-datatables-rails/datatable/column/order.rb +29 -0
  35. data/lib/ajax-datatables-rails/datatable/column/search.rb +125 -0
  36. data/lib/ajax-datatables-rails/datatable/column.rb +123 -0
  37. data/lib/ajax-datatables-rails/datatable/datatable.rb +91 -0
  38. data/lib/ajax-datatables-rails/datatable/simple_order.rb +59 -0
  39. data/lib/ajax-datatables-rails/datatable/simple_search.rb +23 -0
  40. data/lib/ajax-datatables-rails/datatable.rb +6 -0
  41. data/lib/ajax-datatables-rails/error.rb +9 -0
  42. data/lib/ajax-datatables-rails/orm/active_record.rb +60 -0
  43. data/lib/ajax-datatables-rails/orm.rb +6 -0
  44. data/lib/ajax-datatables-rails/version.rb +15 -1
  45. data/lib/ajax-datatables-rails.rb +11 -7
  46. data/lib/generators/rails/datatable_generator.rb +11 -22
  47. data/lib/generators/rails/templates/datatable.rb +13 -15
  48. data/spec/ajax-datatables-rails/base_spec.rb +223 -0
  49. data/spec/ajax-datatables-rails/datatable/column_spec.rb +222 -0
  50. data/spec/ajax-datatables-rails/datatable/datatable_spec.rb +127 -0
  51. data/spec/ajax-datatables-rails/datatable/simple_order_spec.rb +62 -0
  52. data/spec/ajax-datatables-rails/datatable/simple_search_spec.rb +19 -0
  53. data/spec/ajax-datatables-rails/orm/active_record_filter_records_spec.rb +639 -0
  54. data/spec/ajax-datatables-rails/orm/active_record_paginate_records_spec.rb +67 -0
  55. data/spec/ajax-datatables-rails/orm/active_record_sort_records_spec.rb +80 -0
  56. data/spec/dummy/app/assets/config/manifest.js +0 -0
  57. data/spec/dummy/config/database.yml +25 -0
  58. data/spec/dummy/config/routes.rb +5 -0
  59. data/spec/dummy/config/storage.yml +3 -0
  60. data/spec/dummy/db/schema.rb +13 -0
  61. data/spec/dummy/log/.gitignore +1 -0
  62. data/spec/dummy/public/favicon.ico +0 -0
  63. data/spec/factories/user.rb +11 -0
  64. data/spec/install_oracle.sh +18 -0
  65. data/spec/spec_helper.rb +85 -6
  66. data/spec/support/datatables/complex_datatable.rb +33 -0
  67. data/spec/support/datatables/complex_datatable_array.rb +16 -0
  68. data/spec/support/datatables/datatable_cond_date.rb +7 -0
  69. data/spec/support/datatables/datatable_cond_numeric.rb +53 -0
  70. data/spec/support/datatables/datatable_cond_proc.rb +13 -0
  71. data/spec/support/datatables/datatable_cond_string.rb +43 -0
  72. data/spec/support/datatables/datatable_cond_unknown.rb +7 -0
  73. data/spec/support/datatables/datatable_custom_column.rb +17 -0
  74. data/spec/support/datatables/datatable_order_nulls_last.rb +7 -0
  75. data/spec/support/helpers/params.rb +80 -0
  76. data/spec/support/models/user.rb +7 -0
  77. metadata +249 -48
  78. data/lib/ajax-datatables-rails/config.rb +0 -25
  79. data/lib/ajax-datatables-rails/extensions/kaminari.rb +0 -12
  80. data/lib/ajax-datatables-rails/extensions/simple_paginator.rb +0 -12
  81. data/lib/ajax-datatables-rails/extensions/will_paginate.rb +0 -12
  82. data/lib/ajax-datatables-rails/models.rb +0 -6
  83. data/lib/generators/datatable/config_generator.rb +0 -17
  84. data/lib/generators/datatable/templates/ajax_datatables_rails_config.rb +0 -7
  85. data/spec/ajax-datatables-rails/ajax_datatables_rails_spec.rb +0 -351
  86. data/spec/ajax-datatables-rails/kaminari_spec.rb +0 -35
  87. data/spec/ajax-datatables-rails/models_spec.rb +0 -10
  88. data/spec/ajax-datatables-rails/simple_paginator_spec.rb +0 -32
  89. data/spec/ajax-datatables-rails/will_paginate_spec.rb +0 -28
  90. data/spec/schema.rb +0 -35
  91. data/spec/test_models.rb +0 -21
@@ -0,0 +1,223 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe AjaxDatatablesRails::Base do
6
+
7
+ describe 'an instance' do
8
+ it 'requires a hash of params' do
9
+ expect { described_class.new }.to raise_error ArgumentError
10
+ end
11
+
12
+ it 'accepts an options hash' do
13
+ datatable = described_class.new(sample_params, foo: 'bar')
14
+ expect(datatable.options).to eq(foo: 'bar')
15
+ end
16
+ end
17
+
18
+ describe 'User API' do
19
+ describe '#view_columns' do
20
+ context 'when method is not defined by the user' do
21
+ it 'raises an error' do
22
+ datatable = described_class.new(sample_params)
23
+ expect { datatable.view_columns }.to raise_error NotImplementedError
24
+ end
25
+ end
26
+
27
+ context 'child class implements view_columns' do
28
+ it 'expects a hash based defining columns' do
29
+ datatable = ComplexDatatable.new(sample_params)
30
+ expect(datatable.view_columns).to be_a(Hash)
31
+ end
32
+ end
33
+ end
34
+
35
+ describe '#get_raw_records' do
36
+ context 'when method is not defined by the user' do
37
+ it 'raises an error' do
38
+ datatable = described_class.new(sample_params)
39
+ expect { datatable.get_raw_records }.to raise_error NotImplementedError
40
+ end
41
+ end
42
+ end
43
+
44
+ describe '#data' do
45
+ context 'when method is not defined by the user' do
46
+ it 'raises an error' do
47
+ datatable = described_class.new(sample_params)
48
+ expect { datatable.data }.to raise_error NotImplementedError
49
+ end
50
+ end
51
+
52
+ context 'when data is defined as a hash' do
53
+ let(:datatable) { ComplexDatatable.new(sample_params) }
54
+
55
+ it 'returns an array of hashes' do
56
+ create_list(:user, 5)
57
+ expect(datatable.data).to be_a(Array)
58
+ expect(datatable.data.size).to eq 5
59
+ item = datatable.data.first
60
+ expect(item).to be_a(Hash)
61
+ end
62
+
63
+ it 'htmls escape data' do
64
+ create(:user, first_name: 'Name "><img src=x onerror=alert("first_name")>', last_name: 'Name "><img src=x onerror=alert("last_name")>')
65
+ data = datatable.send(:sanitize_data, datatable.data)
66
+ item = data.first
67
+ expect(item[:first_name]).to eq 'Name &quot;&gt;&lt;img src=x onerror=alert(&quot;first_name&quot;)&gt;'
68
+ expect(item[:last_name]).to eq 'Name &quot;&gt;&lt;img src=x onerror=alert(&quot;last_name&quot;)&gt;'
69
+ end
70
+ end
71
+
72
+ context 'when data is defined as a array' do
73
+ let(:datatable) { ComplexDatatableArray.new(sample_params) }
74
+
75
+ it 'returns an array of arrays' do
76
+ create_list(:user, 5)
77
+ expect(datatable.data).to be_a(Array)
78
+ expect(datatable.data.size).to eq 5
79
+ item = datatable.data.first
80
+ expect(item).to be_a(Array)
81
+ end
82
+
83
+ it 'htmls escape data' do
84
+ create(:user, first_name: 'Name "><img src=x onerror=alert("first_name")>', last_name: 'Name "><img src=x onerror=alert("last_name")>')
85
+ data = datatable.send(:sanitize_data, datatable.data)
86
+ item = data.first
87
+ expect(item[2]).to eq 'Name &quot;&gt;&lt;img src=x onerror=alert(&quot;first_name&quot;)&gt;'
88
+ expect(item[3]).to eq 'Name &quot;&gt;&lt;img src=x onerror=alert(&quot;last_name&quot;)&gt;'
89
+ end
90
+ end
91
+ end
92
+ end
93
+
94
+ describe 'ORM API' do
95
+ context 'when ORM is not implemented' do
96
+ let(:datatable) { AjaxDatatablesRails::Base.new(sample_params) }
97
+
98
+ describe '#fetch_records' do
99
+ it 'raises an error if it does not include an ORM module' do
100
+ expect { datatable.fetch_records }.to raise_error NotImplementedError
101
+ end
102
+ end
103
+
104
+ describe '#filter_records' do
105
+ it 'raises an error if it does not include an ORM module' do
106
+ expect { datatable.filter_records([]) }.to raise_error NotImplementedError
107
+ end
108
+ end
109
+
110
+ describe '#sort_records' do
111
+ it 'raises an error if it does not include an ORM module' do
112
+ expect { datatable.sort_records([]) }.to raise_error NotImplementedError
113
+ end
114
+ end
115
+
116
+ describe '#paginate_records' do
117
+ it 'raises an error if it does not include an ORM module' do
118
+ expect { datatable.paginate_records([]) }.to raise_error NotImplementedError
119
+ end
120
+ end
121
+ end
122
+
123
+ context 'when ORM is implemented' do
124
+ describe 'it allows method override' do
125
+ let(:datatable) do
126
+ datatable = Class.new(ComplexDatatable) do
127
+ def filter_records(records)
128
+ raise NotImplementedError.new('FOO')
129
+ end
130
+
131
+ def sort_records(records)
132
+ raise NotImplementedError.new('FOO')
133
+ end
134
+
135
+ def paginate_records(records)
136
+ raise NotImplementedError.new('FOO')
137
+ end
138
+ end
139
+ datatable.new(sample_params)
140
+ end
141
+
142
+ describe '#fetch_records' do
143
+ it 'calls #get_raw_records' do
144
+ expect(datatable).to receive(:get_raw_records) { User.all }
145
+ datatable.fetch_records
146
+ end
147
+
148
+ it 'returns a collection of records' do
149
+ expect(datatable).to receive(:get_raw_records) { User.all }
150
+ expect(datatable.fetch_records).to be_a(ActiveRecord::Relation)
151
+ end
152
+ end
153
+
154
+ describe '#filter_records' do
155
+ it {
156
+ expect { datatable.filter_records([]) }.to raise_error(NotImplementedError).with_message('FOO')
157
+ }
158
+ end
159
+
160
+ describe '#sort_records' do
161
+ it {
162
+ expect { datatable.sort_records([]) }.to raise_error(NotImplementedError).with_message('FOO')
163
+ }
164
+ end
165
+
166
+ describe '#paginate_records' do
167
+ it {
168
+ expect { datatable.paginate_records([]) }.to raise_error(NotImplementedError).with_message('FOO')
169
+ }
170
+ end
171
+ end
172
+ end
173
+ end
174
+
175
+ describe 'JSON format' do
176
+ describe '#as_json' do
177
+ let(:datatable) { ComplexDatatable.new(sample_params) }
178
+
179
+ it 'returns a hash' do
180
+ create_list(:user, 5)
181
+ data = datatable.as_json
182
+ expect(data[:recordsTotal]).to eq 5
183
+ expect(data[:recordsFiltered]).to eq 5
184
+ expect(data[:data]).to be_a(Array)
185
+ expect(data[:data].size).to eq 5
186
+ end
187
+
188
+ context 'with additional_data' do
189
+ it 'returns a hash' do
190
+ create_list(:user, 5)
191
+ expect(datatable).to receive(:additional_data) { { foo: 'bar' } }
192
+ data = datatable.as_json
193
+ expect(data[:recordsTotal]).to eq 5
194
+ expect(data[:recordsFiltered]).to eq 5
195
+ expect(data[:data]).to be_a(Array)
196
+ expect(data[:data].size).to eq 5
197
+ expect(data[:foo]).to eq 'bar'
198
+ end
199
+ end
200
+ end
201
+ end
202
+
203
+ describe 'User helper methods' do
204
+ describe '#column_id' do
205
+ let(:datatable) { ComplexDatatable.new(sample_params) }
206
+
207
+ it 'returns column id from view_columns hash' do
208
+ expect(datatable.column_id(:username)).to eq(0)
209
+ expect(datatable.column_id('username')).to eq(0)
210
+ end
211
+ end
212
+
213
+ describe '#column_data' do
214
+ let(:datatable) { ComplexDatatable.new(sample_params) }
215
+ before { datatable.params[:columns]['0'][:search][:value] = 'doe' }
216
+
217
+ it 'returns column data from params' do
218
+ expect(datatable.column_data(:username)).to eq('doe')
219
+ expect(datatable.column_data('username')).to eq('doe')
220
+ end
221
+ end
222
+ end
223
+ end
@@ -0,0 +1,222 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe AjaxDatatablesRails::Datatable::Column do
6
+
7
+ let(:datatable) { ComplexDatatable.new(sample_params) }
8
+
9
+ describe 'username column' do
10
+
11
+ let(:column) { datatable.datatable.columns.first }
12
+
13
+ before { datatable.params[:columns]['0'][:search][:value] = 'searchvalue' }
14
+
15
+ it 'is orderable' do
16
+ expect(column.orderable?).to eq(true)
17
+ end
18
+
19
+ it 'sorts nulls last' do
20
+ expect(column.nulls_last?).to eq(false)
21
+ end
22
+
23
+ it 'is searchable' do
24
+ expect(column.searchable?).to eq(true)
25
+ end
26
+
27
+ it 'is searched' do
28
+ expect(column.searched?).to eq(true)
29
+ end
30
+
31
+ it 'has connected to id column' do
32
+ expect(column.data).to eq('username')
33
+ end
34
+
35
+ describe '#data' do
36
+ it 'returns the data from params' do
37
+ expect(column.data).to eq 'username'
38
+ end
39
+ end
40
+
41
+ describe '#source' do
42
+ it 'returns the data source from view_column' do
43
+ expect(column.source).to eq 'User.username'
44
+ end
45
+ end
46
+
47
+ describe '#table' do
48
+ context 'with ActiveRecord ORM' do
49
+ it 'returns the corresponding AR table' do
50
+ expect(column.table).to eq User.arel_table
51
+ end
52
+ end
53
+
54
+ context 'with other ORM' do
55
+ it 'returns the corresponding model' do
56
+ expect(User).to receive(:respond_to?).with(:arel_table).and_return(false)
57
+ expect(column.table).to eq User
58
+ end
59
+ end
60
+ end
61
+
62
+ describe '#model' do
63
+ it 'returns the corresponding AR model' do
64
+ expect(column.model).to eq User
65
+ end
66
+ end
67
+
68
+ describe '#field' do
69
+ it 'returns the corresponding field in DB' do
70
+ expect(column.field).to eq :username
71
+ end
72
+ end
73
+
74
+ describe '#custom_field?' do
75
+ it 'returns false if field is bound to an AR field' do
76
+ expect(column.custom_field?).to be false
77
+ end
78
+ end
79
+
80
+ describe '#search' do
81
+ it 'child class' do
82
+ expect(column.search).to be_a(AjaxDatatablesRails::Datatable::SimpleSearch)
83
+ end
84
+
85
+ it 'has search value' do
86
+ expect(column.search.value).to eq('searchvalue')
87
+ end
88
+
89
+ it 'does not regex' do
90
+ expect(column.search.regexp?).to eq false
91
+ end
92
+ end
93
+
94
+ describe '#cond' do
95
+ it 'is :like by default' do
96
+ expect(column.cond).to eq(:like)
97
+ end
98
+ end
99
+
100
+ describe '#source' do
101
+ it 'is :like by default' do
102
+ expect(column.source).to eq('User.username')
103
+ end
104
+ end
105
+
106
+ describe '#search_query' do
107
+ it 'bulds search query' do
108
+ expect(column.search_query.to_sql).to include('%searchvalue%')
109
+ end
110
+ end
111
+
112
+ describe '#sort_query' do
113
+ it 'builds sort query' do
114
+ expect(column.sort_query).to eq('users.username')
115
+ end
116
+ end
117
+
118
+ describe '#use_regex?' do
119
+ it 'is true by default' do
120
+ expect(column.use_regex?).to be true
121
+ end
122
+ end
123
+
124
+ describe '#delimiter' do
125
+ it 'is - by default' do
126
+ expect(column.delimiter).to eq('-')
127
+ end
128
+ end
129
+ end
130
+
131
+ describe '#formatter' do
132
+ let(:datatable) { DatatableWithFormater.new(sample_params) }
133
+ let(:column) { datatable.datatable.columns.find { |c| c.data == 'last_name' } }
134
+
135
+ it 'is a proc' do
136
+ expect(column.formatter).to be_a(Proc)
137
+ end
138
+ end
139
+
140
+ describe '#filter' do
141
+ let(:datatable) { DatatableCondProc.new(sample_params) }
142
+ let(:column) { datatable.datatable.columns.find { |c| c.data == 'username' } }
143
+
144
+ it 'is a proc' do
145
+ config = column.instance_variable_get('@view_column')
146
+ filter = config[:cond]
147
+ expect(filter).to be_a(Proc)
148
+ expect(filter).to receive(:call).with(column, column.formatted_value)
149
+ column.filter
150
+ end
151
+ end
152
+
153
+ describe '#type_cast' do
154
+ let(:column) { datatable.datatable.columns.first }
155
+
156
+ it 'returns VARCHAR if :db_adapter is :pg' do
157
+ expect(datatable).to receive(:db_adapter) { :pg }
158
+ expect(column.send(:type_cast)).to eq('VARCHAR')
159
+ end
160
+
161
+ it 'returns VARCHAR if :db_adapter is :postgre' do
162
+ expect(datatable).to receive(:db_adapter) { :postgre }
163
+ expect(column.send(:type_cast)).to eq('VARCHAR')
164
+ end
165
+
166
+ it 'returns VARCHAR if :db_adapter is :postgresql' do
167
+ expect(datatable).to receive(:db_adapter) { :postgresql }
168
+ expect(column.send(:type_cast)).to eq('VARCHAR')
169
+ end
170
+
171
+ it 'returns VARCHAR2(4000) if :db_adapter is :oracle' do
172
+ expect(datatable).to receive(:db_adapter) { :oracle }
173
+ expect(column.send(:type_cast)).to eq('VARCHAR2(4000)')
174
+ end
175
+
176
+ it 'returns VARCHAR2(4000) if :db_adapter is :oracleenhanced' do
177
+ expect(datatable).to receive(:db_adapter) { :oracleenhanced }
178
+ expect(column.send(:type_cast)).to eq('VARCHAR2(4000)')
179
+ end
180
+
181
+ it 'returns CHAR if :db_adapter is :mysql2' do
182
+ expect(datatable).to receive(:db_adapter) { :mysql2 }
183
+ expect(column.send(:type_cast)).to eq('CHAR')
184
+ end
185
+
186
+ it 'returns CHAR if :db_adapter is :mysql' do
187
+ expect(datatable).to receive(:db_adapter) { :mysql }
188
+ expect(column.send(:type_cast)).to eq('CHAR')
189
+ end
190
+
191
+ it 'returns TEXT if :db_adapter is :sqlite' do
192
+ expect(datatable).to receive(:db_adapter) { :sqlite }
193
+ expect(column.send(:type_cast)).to eq('TEXT')
194
+ end
195
+
196
+ it 'returns TEXT if :db_adapter is :sqlite3' do
197
+ expect(datatable).to receive(:db_adapter) { :sqlite3 }
198
+ expect(column.send(:type_cast)).to eq('TEXT')
199
+ end
200
+
201
+ it 'returns VARCHAR(4000) if :db_adapter is :sqlserver' do
202
+ expect(datatable).to receive(:db_adapter) { :sqlserver }
203
+ expect(column.send(:type_cast)).to eq('VARCHAR(4000)')
204
+ end
205
+ end
206
+
207
+ describe 'when empty column' do
208
+ before { datatable.params[:columns]['0'][:data] = '' }
209
+
210
+ it 'raises error' do
211
+ expect { datatable.to_json }.to raise_error(AjaxDatatablesRails::Error::InvalidSearchColumn).with_message('Unknown column. Check that `data` field is filled on JS side with the column name')
212
+ end
213
+ end
214
+
215
+ describe 'when unknown column' do
216
+ before { datatable.params[:columns]['0'][:data] = 'foo' }
217
+
218
+ it 'raises error' do
219
+ expect { datatable.to_json }.to raise_error(AjaxDatatablesRails::Error::InvalidSearchColumn).with_message("Check that column 'foo' exists in view_columns")
220
+ end
221
+ end
222
+ end
@@ -0,0 +1,127 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe AjaxDatatablesRails::Datatable::Datatable do
6
+
7
+ let(:datatable) { ComplexDatatable.new(sample_params).datatable }
8
+ let(:datatable_json) { ComplexDatatable.new(sample_params_json).datatable }
9
+ let(:order_option) { { '0' => { 'column' => '0', 'dir' => 'asc' }, '1' => { 'column' => '1', 'dir' => 'desc' } } }
10
+ let(:order_option_json) { [{ 'column' => '0', 'dir' => 'asc' }, { 'column' => '1', 'dir' => 'desc' }] }
11
+
12
+ shared_examples 'order methods' do
13
+ it 'is orderable' do
14
+ expect(datatable.orderable?).to eq(true)
15
+ end
16
+
17
+ it 'is not orderable' do
18
+ datatable.options[:order] = nil
19
+ expect(datatable.orderable?).to eq(false)
20
+ end
21
+
22
+ it 'has 2 orderable columns' do
23
+ datatable.options[:order] = order_option
24
+ expect(datatable.orders.count).to eq(2)
25
+ end
26
+
27
+ it 'first column ordered by ASC' do
28
+ datatable.options[:order] = order_option
29
+ expect(datatable.orders.first.direction).to eq('ASC')
30
+ end
31
+
32
+ it 'first column ordered by DESC' do
33
+ datatable.options[:order] = order_option
34
+ expect(datatable.orders.last.direction).to eq('DESC')
35
+ end
36
+
37
+ it 'child class' do
38
+ expect(datatable.orders.first).to be_a(AjaxDatatablesRails::Datatable::SimpleOrder)
39
+ end
40
+ end
41
+
42
+ shared_examples 'columns methods' do
43
+ it 'has 7 columns' do
44
+ expect(datatable.columns.count).to eq(7)
45
+ end
46
+
47
+ it 'child class' do
48
+ expect(datatable.columns.first).to be_a(AjaxDatatablesRails::Datatable::Column)
49
+ end
50
+ end
51
+
52
+ describe 'with query params' do
53
+ it_behaves_like 'order methods'
54
+ it_behaves_like 'columns methods'
55
+ end
56
+
57
+ describe 'with json params' do
58
+ let(:order_option) { order_option_json }
59
+ let(:datatable) { datatable_json }
60
+ it_behaves_like 'order methods'
61
+ it_behaves_like 'columns methods'
62
+ end
63
+
64
+ describe 'search methods' do
65
+ it 'is searchable' do
66
+ datatable.options[:search][:value] = 'atom'
67
+ expect(datatable.searchable?).to eq(true)
68
+ end
69
+
70
+ it 'is not searchable' do
71
+ datatable.options[:search][:value] = nil
72
+ expect(datatable.searchable?).to eq(false)
73
+ end
74
+
75
+ it 'child class' do
76
+ expect(datatable.search).to be_a(AjaxDatatablesRails::Datatable::SimpleSearch)
77
+ end
78
+ end
79
+
80
+ describe 'option methods' do
81
+ describe '#paginate?' do
82
+ it {
83
+ expect(datatable.paginate?).to be(true)
84
+ }
85
+ end
86
+
87
+ describe '#per_page' do
88
+ context 'when params[:length] is missing' do
89
+ it 'defaults to 10' do
90
+ expect(datatable.per_page).to eq(10)
91
+ end
92
+ end
93
+
94
+ context 'when params[:length] is passed' do
95
+ let(:datatable) { ComplexDatatable.new({ length: '20' }).datatable }
96
+
97
+ it 'matches the value on view params[:length]' do
98
+ expect(datatable.per_page).to eq(20)
99
+ end
100
+ end
101
+ end
102
+
103
+ describe '#offset' do
104
+ context 'when params[:start] is missing' do
105
+ it 'defaults to 0' do
106
+ expect(datatable.offset).to eq(0)
107
+ end
108
+ end
109
+
110
+ context 'when params[:start] is passed' do
111
+ let(:datatable) { ComplexDatatable.new({ start: '11' }).datatable }
112
+
113
+ it 'matches the value on view params[:start]' do
114
+ expect(datatable.offset).to eq(11)
115
+ end
116
+ end
117
+ end
118
+
119
+ describe '#page' do
120
+ let(:datatable) { ComplexDatatable.new({ start: '11' }).datatable }
121
+
122
+ it 'calculates page number from params[:start] and #per_page' do
123
+ expect(datatable.page).to eq(2)
124
+ end
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe AjaxDatatablesRails::Datatable::SimpleOrder do
6
+
7
+ let(:parent) { ComplexDatatable.new(sample_params) }
8
+ let(:datatable) { parent.datatable }
9
+ let(:options) { ActiveSupport::HashWithIndifferentAccess.new({ 'column' => '1', 'dir' => 'desc' }) }
10
+ let(:simple_order) { AjaxDatatablesRails::Datatable::SimpleOrder.new(datatable, options) }
11
+
12
+ describe 'option methods' do
13
+ it 'sql query' do
14
+ expect(simple_order.query('firstname')).to eq('firstname DESC')
15
+ end
16
+ end
17
+
18
+ describe 'option methods with nulls last' do
19
+ describe 'using class option' do
20
+ before { parent.nulls_last = true }
21
+ after { parent.nulls_last = false }
22
+
23
+ it 'sql query' do
24
+ skip('unsupported database adapter') if RunningSpec.oracle?
25
+
26
+ expect(simple_order.query('email')).to eq(
27
+ "email DESC #{nulls_last_sql(parent)}"
28
+ )
29
+ end
30
+ end
31
+
32
+ describe 'using column option' do
33
+ let(:parent) { DatatableOrderNullsLast.new(sample_params) }
34
+ let(:sorted_datatable) { parent.datatable }
35
+ let(:nulls_last_order) { AjaxDatatablesRails::Datatable::SimpleOrder.new(sorted_datatable, options) }
36
+
37
+ context 'with postgres database adapter' do
38
+ before { parent.db_adapter = :pg }
39
+
40
+ it 'sql query' do
41
+ expect(nulls_last_order.query('email')).to eq('email DESC NULLS LAST')
42
+ end
43
+ end
44
+
45
+ context 'with sqlite database adapter' do
46
+ before { parent.db_adapter = :sqlite }
47
+
48
+ it 'sql query' do
49
+ expect(nulls_last_order.query('email')).to eq('email DESC IS NULL')
50
+ end
51
+ end
52
+
53
+ context 'with mysql database adapter' do
54
+ before { parent.db_adapter = :mysql }
55
+
56
+ it 'sql query' do
57
+ expect(nulls_last_order.query('email')).to eq('email DESC IS NULL')
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe AjaxDatatablesRails::Datatable::SimpleSearch do
6
+
7
+ let(:options) { ActiveSupport::HashWithIndifferentAccess.new({ 'value' => 'search value', 'regex' => 'true' }) }
8
+ let(:simple_search) { AjaxDatatablesRails::Datatable::SimpleSearch.new(options) }
9
+
10
+ describe 'option methods' do
11
+ it 'regexp?' do
12
+ expect(simple_search.regexp?).to be(true)
13
+ end
14
+
15
+ it 'value' do
16
+ expect(simple_search.value).to eq('search value')
17
+ end
18
+ end
19
+ end