ajax-datatables-rails 0.3.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +26 -0
  3. data/.gitignore +20 -0
  4. data/.rspec +1 -0
  5. data/.rubocop.yml +1157 -0
  6. data/.travis.yml +68 -0
  7. data/Appraisals +34 -0
  8. data/Gemfile +5 -1
  9. data/LICENSE +17 -18
  10. data/README.md +239 -239
  11. data/Rakefile +1 -1
  12. data/ajax-datatables-rails.gemspec +31 -24
  13. data/gemfiles/rails_4.0.13.gemfile +14 -0
  14. data/gemfiles/rails_4.1.15.gemfile +14 -0
  15. data/gemfiles/rails_4.2.8.gemfile +13 -0
  16. data/gemfiles/rails_5.0.3.gemfile +13 -0
  17. data/gemfiles/rails_5.1.1.gemfile +13 -0
  18. data/lib/ajax-datatables-rails.rb +9 -8
  19. data/lib/ajax-datatables-rails/base.rb +80 -156
  20. data/lib/ajax-datatables-rails/config.rb +8 -5
  21. data/lib/ajax-datatables-rails/datatable/column.rb +169 -0
  22. data/lib/ajax-datatables-rails/datatable/column_date_filter.rb +41 -0
  23. data/lib/ajax-datatables-rails/datatable/datatable.rb +79 -0
  24. data/lib/ajax-datatables-rails/datatable/simple_order.rb +31 -0
  25. data/lib/ajax-datatables-rails/datatable/simple_search.rb +18 -0
  26. data/lib/ajax-datatables-rails/orm/active_record.rb +52 -0
  27. data/lib/ajax-datatables-rails/version.rb +1 -1
  28. data/lib/generators/datatable/templates/ajax_datatables_rails_config.rb +3 -3
  29. data/lib/generators/rails/datatable_generator.rb +7 -19
  30. data/lib/generators/rails/templates/datatable.rb +26 -14
  31. data/spec/ajax-datatables-rails/base_spec.rb +190 -0
  32. data/spec/ajax-datatables-rails/configuration_spec.rb +43 -0
  33. data/spec/ajax-datatables-rails/datatable/column_spec.rb +109 -0
  34. data/spec/ajax-datatables-rails/datatable/datatable_spec.rb +87 -0
  35. data/spec/ajax-datatables-rails/datatable/simple_order_spec.rb +13 -0
  36. data/spec/ajax-datatables-rails/datatable/simple_search_spec.rb +17 -0
  37. data/spec/ajax-datatables-rails/extended_spec.rb +20 -0
  38. data/spec/ajax-datatables-rails/orm/active_record_filter_records_spec.rb +439 -0
  39. data/spec/ajax-datatables-rails/orm/active_record_paginate_records_spec.rb +66 -0
  40. data/spec/ajax-datatables-rails/orm/active_record_sort_records_spec.rb +34 -0
  41. data/spec/ajax-datatables-rails/orm/active_record_spec.rb +25 -0
  42. data/spec/factories/user.rb +9 -0
  43. data/spec/install_oracle.sh +12 -0
  44. data/spec/spec_helper.rb +75 -3
  45. data/spec/support/schema.rb +14 -0
  46. data/spec/support/test_helpers.rb +174 -0
  47. data/spec/support/test_models.rb +2 -0
  48. metadata +169 -37
  49. data/lib/ajax-datatables-rails/extensions/kaminari.rb +0 -12
  50. data/lib/ajax-datatables-rails/extensions/simple_paginator.rb +0 -12
  51. data/lib/ajax-datatables-rails/extensions/will_paginate.rb +0 -12
  52. data/lib/ajax-datatables-rails/models.rb +0 -6
  53. data/spec/ajax-datatables-rails/ajax_datatables_rails_spec.rb +0 -351
  54. data/spec/ajax-datatables-rails/kaminari_spec.rb +0 -35
  55. data/spec/ajax-datatables-rails/models_spec.rb +0 -10
  56. data/spec/ajax-datatables-rails/simple_paginator_spec.rb +0 -32
  57. data/spec/ajax-datatables-rails/will_paginate_spec.rb +0 -28
  58. data/spec/schema.rb +0 -35
  59. data/spec/test_models.rb +0 -21
@@ -1,29 +1,41 @@
1
- class <%= @datatable_name %>Datatable < AjaxDatatablesRails::Base
1
+ class <%= datatable_name %> < AjaxDatatablesRails::Base
2
2
 
3
- def sortable_columns
3
+ def view_columns
4
4
  # Declare strings in this format: ModelName.column_name
5
- @sortable_columns ||= []
5
+ # or in aliased_join_table.column_name format
6
+ @view_columns ||= {
7
+ # id: { source: "User.id", cond: :eq },
8
+ # name: { source: "User.name", cond: :like }
9
+ }
6
10
  end
7
11
 
8
- def searchable_columns
9
- # Declare strings in this format: ModelName.column_name
10
- @searchable_columns ||= []
11
- end
12
-
13
- private
14
-
15
12
  def data
16
13
  records.map do |record|
17
- [
18
- # comma separated list of the values for each cell of a table row
19
- # example: record.attribute,
20
- ]
14
+ {
15
+ # example:
16
+ # id: record.id,
17
+ # name: record.name
18
+ }
21
19
  end
22
20
  end
23
21
 
22
+ private
23
+
24
24
  def get_raw_records
25
25
  # insert query here
26
26
  end
27
27
 
28
+ # ==== These methods represent the basic operations to perform on records
29
+ # and feel free to override them
30
+
31
+ # def filter_records(records)
32
+ # end
33
+
34
+ # def sort_records(records)
35
+ # end
36
+
37
+ # def paginate_records(records)
38
+ # end
39
+
28
40
  # ==== Insert 'presenter'-like methods below if necessary
29
41
  end
@@ -0,0 +1,190 @@
1
+ require 'spec_helper'
2
+
3
+ describe AjaxDatatablesRails::Base do
4
+
5
+ describe 'an instance' do
6
+ let(:view) { double('view', params: sample_params) }
7
+
8
+ it 'requires a view_context' do
9
+ expect { AjaxDatatablesRails::Base.new }.to raise_error ArgumentError
10
+ end
11
+
12
+ it 'accepts an options hash' do
13
+ datatable = AjaxDatatablesRails::Base.new(view, foo: 'bar')
14
+ expect(datatable.options).to eq(foo: 'bar')
15
+ end
16
+ end
17
+
18
+ context 'Public API' do
19
+ let(:view) { double('view', params: sample_params) }
20
+ let(:datatable) { AjaxDatatablesRails::Base.new(view) }
21
+
22
+ describe '#view_columns' do
23
+ it 'raises an error if not defined by the user' do
24
+ expect { datatable.view_columns }.to raise_error AjaxDatatablesRails::NotImplemented
25
+ end
26
+
27
+ context 'child class implements view_columns' do
28
+ it 'expects an array based defining columns' do
29
+ datatable = SampleDatatable.new(view)
30
+ expect(datatable.view_columns).to be_a(Array)
31
+ end
32
+
33
+ it 'expects a hash based defining columns' do
34
+ datatable = ComplexDatatable.new(view)
35
+ expect(datatable.view_columns).to be_a(Hash)
36
+ end
37
+ end
38
+ end
39
+
40
+ describe '#get_raw_records' do
41
+ it 'raises an error if not defined by the user' do
42
+ expect { datatable.get_raw_records }.to raise_error AjaxDatatablesRails::NotImplemented
43
+ end
44
+ end
45
+
46
+ describe '#data' do
47
+ it 'raises an error if not defined by the user' do
48
+ expect { datatable.data }.to raise_error AjaxDatatablesRails::NotImplemented
49
+ end
50
+
51
+ context 'when data is defined as a hash' do
52
+ it 'should return an array of hashes' do
53
+ datatable = ComplexDatatableHash.new(view)
54
+ create_list(:user, 5)
55
+ expect(datatable.data).to be_a(Array)
56
+ expect(datatable.data.size).to eq 5
57
+ item = datatable.data.first
58
+ expect(item).to be_a(Hash)
59
+ end
60
+
61
+ it 'should html escape data' do
62
+ datatable = ComplexDatatableHash.new(view)
63
+ create(:user, first_name: 'Name "><img src=x onerror=alert("first_name")>', last_name: 'Name "><img src=x onerror=alert("last_name")>')
64
+ data = datatable.send(:sanitize, datatable.data)
65
+ item = data.first
66
+ expect(item[:first_name]).to eq 'Name &quot;&gt;&lt;img src=x onerror=alert(&quot;first_name&quot;)&gt;'
67
+ expect(item[:last_name]).to eq 'Name &quot;&gt;&lt;img src=x onerror=alert(&quot;last_name&quot;)&gt;'
68
+ end
69
+ end
70
+
71
+ context 'when data is defined as a array' do
72
+ it 'should return an array of arrays' do
73
+ datatable = ComplexDatatableArray.new(view)
74
+ create_list(:user, 5)
75
+ expect(datatable.data).to be_a(Array)
76
+ expect(datatable.data.size).to eq 5
77
+ item = datatable.data.first
78
+ expect(item).to be_a(Array)
79
+ end
80
+
81
+ it 'should html escape data' do
82
+ datatable = ComplexDatatableArray.new(view)
83
+ create(:user, first_name: 'Name "><img src=x onerror=alert("first_name")>', last_name: 'Name "><img src=x onerror=alert("last_name")>')
84
+ data = datatable.send(:sanitize, datatable.data)
85
+ item = data.first
86
+ expect(item[2]).to eq 'Name &quot;&gt;&lt;img src=x onerror=alert(&quot;first_name&quot;)&gt;'
87
+ expect(item[3]).to eq 'Name &quot;&gt;&lt;img src=x onerror=alert(&quot;last_name&quot;)&gt;'
88
+ end
89
+ end
90
+ end
91
+
92
+ describe '#as_json' do
93
+ it 'should return a hash' do
94
+ datatable = ComplexDatatableHash.new(view)
95
+ create_list(:user, 5)
96
+ data = datatable.as_json
97
+ expect(data[:recordsTotal]).to eq 5
98
+ expect(data[:recordsFiltered]).to eq 5
99
+ expect(data[:data]).to be_a(Array)
100
+ expect(data[:data].size).to eq 5
101
+ end
102
+
103
+ context 'with additional_datas' do
104
+ it 'should return a hash' do
105
+ datatable = ComplexDatatableHash.new(view)
106
+ create_list(:user, 5)
107
+ expect(datatable).to receive(:additional_datas){ { foo: 'bar' } }
108
+ data = datatable.as_json
109
+ expect(data[:recordsTotal]).to eq 5
110
+ expect(data[:recordsFiltered]).to eq 5
111
+ expect(data[:data]).to be_a(Array)
112
+ expect(data[:data].size).to eq 5
113
+ expect(data[:foo]).to eq 'bar'
114
+ end
115
+ end
116
+ end
117
+ end
118
+
119
+
120
+ context 'Private API' do
121
+
122
+ let(:view) { double('view', params: sample_params) }
123
+ let(:datatable) { ComplexDatatable.new(view) }
124
+
125
+ before(:each) do
126
+ allow_any_instance_of(AjaxDatatablesRails::Configuration).to receive(:orm) { nil }
127
+ end
128
+
129
+ describe '#fetch_records' do
130
+ it 'raises an error if it does not include an ORM module' do
131
+ expect { datatable.send(:fetch_records) }.to raise_error NoMethodError
132
+ end
133
+ end
134
+
135
+ describe '#filter_records' do
136
+ it 'raises an error if it does not include an ORM module' do
137
+ expect { datatable.send(:filter_records) }.to raise_error NoMethodError
138
+ end
139
+ end
140
+
141
+ describe '#sort_records' do
142
+ it 'raises an error if it does not include an ORM module' do
143
+ expect { datatable.send(:sort_records) }.to raise_error NoMethodError
144
+ end
145
+ end
146
+
147
+ describe '#paginate_records' do
148
+ it 'raises an error if it does not include an ORM module' do
149
+ expect { datatable.send(:paginate_records) }.to raise_error NoMethodError
150
+ end
151
+ end
152
+
153
+ describe 'helper methods' do
154
+ describe '#offset' do
155
+ it 'defaults to 0' do
156
+ default_view = double('view', params: {})
157
+ datatable = AjaxDatatablesRails::Base.new(default_view)
158
+ expect(datatable.datatable.send(:offset)).to eq(0)
159
+ end
160
+
161
+ it 'matches the value on view params[:start] minus 1' do
162
+ paginated_view = double('view', params: { start: '11' })
163
+ datatable = AjaxDatatablesRails::Base.new(paginated_view)
164
+ expect(datatable.datatable.send(:offset)).to eq(10)
165
+ end
166
+ end
167
+
168
+ describe '#page' do
169
+ it 'calculates page number from params[:start] and #per_page' do
170
+ paginated_view = double('view', params: { start: '11' })
171
+ datatable = AjaxDatatablesRails::Base.new(paginated_view)
172
+ expect(datatable.datatable.send(:page)).to eq(2)
173
+ end
174
+ end
175
+
176
+ describe '#per_page' do
177
+ it 'defaults to 10' do
178
+ datatable = AjaxDatatablesRails::Base.new(view)
179
+ expect(datatable.datatable.send(:per_page)).to eq(10)
180
+ end
181
+
182
+ it 'matches the value on view params[:length]' do
183
+ other_view = double('view', params: { length: 20 })
184
+ datatable = AjaxDatatablesRails::Base.new(other_view)
185
+ expect(datatable.datatable.send(:per_page)).to eq(20)
186
+ end
187
+ end
188
+ end
189
+ end
190
+ end
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+
3
+ describe AjaxDatatablesRails do
4
+ describe 'configurations' do
5
+ context 'configurable from outside' do
6
+ before(:each) do
7
+ AjaxDatatablesRails.configure do |config|
8
+ config.db_adapter = :mysql
9
+ end
10
+ end
11
+
12
+ it 'should have custom value' do
13
+ expect(AjaxDatatablesRails.config.db_adapter).to eq(:mysql)
14
+ end
15
+ end
16
+ end
17
+ end
18
+
19
+ describe AjaxDatatablesRails::Configuration do
20
+ let(:config) { AjaxDatatablesRails::Configuration.new }
21
+
22
+ describe 'default config' do
23
+ it 'default orm should :active_record' do
24
+ expect(config.orm).to eq(:active_record)
25
+ end
26
+
27
+ it 'default db_adapter should :postgresql' do
28
+ expect(config.db_adapter).to eq(:postgresql)
29
+ end
30
+ end
31
+
32
+ describe 'custom config' do
33
+ it 'should accept db_adapter custom value' do
34
+ config.db_adapter = :mysql
35
+ expect(config.db_adapter).to eq(:mysql)
36
+ end
37
+
38
+ it 'accepts a custom orm value' do
39
+ config.orm = :mongoid
40
+ expect(config.orm).to eq(:mongoid)
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,109 @@
1
+ require 'spec_helper'
2
+
3
+ describe AjaxDatatablesRails::Datatable::Column do
4
+
5
+ let(:view) { double('view', params: sample_params) }
6
+ let(:datatable) { ComplexDatatable.new(view) }
7
+
8
+ describe 'username column' do
9
+
10
+ let(:column) { datatable.datatable.columns.first }
11
+
12
+ before do
13
+ datatable.params[:columns] = {'0'=>{'data'=>'username', 'name'=>'', 'searchable'=>'true', 'orderable'=>'true', 'search'=>{'value'=>'searchvalue', 'regex'=>'false'}}}
14
+ end
15
+
16
+ it 'should be orderable' do
17
+ expect(column.orderable?).to eq(true)
18
+ end
19
+
20
+ it 'should be searchable' do
21
+ expect(column.searchable?).to eq(true)
22
+ end
23
+
24
+ it 'should be searched' do
25
+ expect(column.searched?).to eq(true)
26
+ end
27
+
28
+ it 'should have connected to id column' do
29
+ expect(column.data).to eq('username')
30
+ end
31
+
32
+ describe '#search' do
33
+ it 'child class' do
34
+ expect(column.search).to be_a(AjaxDatatablesRails::Datatable::SimpleSearch)
35
+ end
36
+
37
+ it 'should have search value' do
38
+ expect(column.search.value).to eq('searchvalue')
39
+ end
40
+
41
+ it 'should not regex' do
42
+ expect(column.search.regexp?).to eq false
43
+ end
44
+ end
45
+
46
+ describe '#cond' do
47
+ it 'should be :like by default' do
48
+ expect(column.cond).to eq(:like)
49
+ end
50
+ end
51
+
52
+ describe '#source' do
53
+ it 'should be :like by default' do
54
+ expect(column.source).to eq('User.username')
55
+ end
56
+ end
57
+
58
+ describe '#search_query' do
59
+ it 'should buld search query' do
60
+ expect(column.search_query.to_sql).to include('%searchvalue%')
61
+ end
62
+ end
63
+
64
+ describe '#sort_query' do
65
+ it 'should build sort query' do
66
+ expect(column.sort_query).to eq('users.username')
67
+ end
68
+ end
69
+
70
+ describe '#use_regex?' do
71
+ it 'should be true by default' do
72
+ expect(column.use_regex?).to be true
73
+ end
74
+ end
75
+
76
+ describe '#delimiter' do
77
+ it 'should be - by default' do
78
+ expect(column.delimiter).to eq('-')
79
+ end
80
+ end
81
+ end
82
+
83
+ describe 'last_name column' do
84
+ let(:column) { datatable.datatable.columns.last }
85
+
86
+ before do
87
+ datatable.params[:columns] = {'0'=>{'data'=>'last_name', 'name'=>'', 'searchable'=>'true', 'orderable'=>'true', 'search'=>{'value'=>'', 'regex'=>'false'}}}
88
+ end
89
+
90
+ it 'should be orderable' do
91
+ expect(column.orderable?).to eq(true)
92
+ end
93
+
94
+ it 'should be searchable' do
95
+ expect(column.searchable?).to eq(true)
96
+ end
97
+
98
+ it 'should have connected to id column' do
99
+ expect(column.data).to eq('last_name')
100
+ end
101
+
102
+ describe '#formater' do
103
+ it 'should be a proc' do
104
+ expect(column.formater).to be_a(Proc)
105
+ end
106
+ end
107
+ end
108
+
109
+ end
@@ -0,0 +1,87 @@
1
+ require 'spec_helper'
2
+
3
+ describe AjaxDatatablesRails::Datatable::Datatable do
4
+
5
+ let(:view) { double('view', params: sample_params) }
6
+ let(:datatable) { ComplexDatatable.new(view).datatable }
7
+ let(:order_option) { {'0'=>{'column'=>'0', 'dir'=>'asc'}, '1'=>{'column'=>'1', 'dir'=>'desc'}} }
8
+
9
+ describe 'order methods' do
10
+ it 'should be orderable' do
11
+ expect(datatable.orderable?).to eq(true)
12
+ end
13
+
14
+ it 'should not be orderable' do
15
+ datatable.options[:order] = nil
16
+ expect(datatable.orderable?).to eq(false)
17
+ end
18
+
19
+ it 'should have 2 orderable columns' do
20
+ datatable.options[:order] = order_option
21
+ expect(datatable.orders.count).to eq(2)
22
+ end
23
+
24
+ it 'first column ordered by ASC' do
25
+ datatable.options[:order] = order_option
26
+ expect(datatable.orders.first.direction).to eq('ASC')
27
+ end
28
+
29
+ it 'first column ordered by DESC' do
30
+ datatable.options[:order] = order_option
31
+ expect(datatable.orders.last.direction).to eq('DESC')
32
+ end
33
+
34
+ it 'child class' do
35
+ expect(datatable.orders.first).to be_a(AjaxDatatablesRails::Datatable::SimpleOrder)
36
+ end
37
+ end
38
+
39
+ describe 'search methods' do
40
+ it 'should be searchable' do
41
+ datatable.options[:search][:value] = 'atom'
42
+ expect(datatable.searchable?).to eq(true)
43
+ end
44
+
45
+ it 'should not be searchable' do
46
+ datatable.options[:search][:value] = nil
47
+ expect(datatable.searchable?).to eq(false)
48
+ end
49
+
50
+ it 'child class' do
51
+ expect(datatable.search).to be_a(AjaxDatatablesRails::Datatable::SimpleSearch)
52
+ end
53
+ end
54
+
55
+ describe 'columns methods' do
56
+ it 'should have 4 columns' do
57
+ expect(datatable.columns.count).to eq(6)
58
+ end
59
+
60
+ it 'child class' do
61
+ expect(datatable.columns.first).to be_a(AjaxDatatablesRails::Datatable::Column)
62
+ end
63
+ end
64
+
65
+ describe 'option methods' do
66
+ before :each do
67
+ datatable.options[:start] = '50'
68
+ datatable.options[:length] = '15'
69
+ end
70
+
71
+ it 'paginate?' do
72
+ expect(datatable.paginate?).to be(true)
73
+ end
74
+
75
+ it 'offset' do
76
+ expect(datatable.offset).to eq(45)
77
+ end
78
+
79
+ it 'page' do
80
+ expect(datatable.page).to eq(4)
81
+ end
82
+
83
+ it 'per_page' do
84
+ expect(datatable.per_page).to eq(15)
85
+ end
86
+ end
87
+ end