ajax-datatables-rails 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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