rexport 1.0.2 → 1.2.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7bc0f21f26d12d42e97f2a1fd8a0c9228becce29b46ed07327ca8fd5369b9deb
4
- data.tar.gz: 98d65ab17ade5855ec9ef73ad220239c2f99aeb64329cc133b29c04f40f540b2
3
+ metadata.gz: 8cf8cb2fe8850f491ab8eb8a92d0034d1447babd6a4a79457acea80fcbec94fc
4
+ data.tar.gz: 2e646631a4c3673359f31bd222c43c32ed6fcb20813f7f6ac34d633005899628
5
5
  SHA512:
6
- metadata.gz: 5da93e49137f2f965206a014bcf21dadb52d47b76adf83135cffb4f0406a1e3ffbc9c99dbcbaffdb8f3f0b5785dc74495c37cb7dc300c9631c8fd8cd18072436
7
- data.tar.gz: 6f5a80568333c860813ed938b027f1d79e6a70cec53024e888eaa58044db638c359db5967f868377fa211c782673a1adeabd83d7ff59501362c3f296ad4cb6dc
6
+ metadata.gz: '08d2fd739cf9775d22295a57ba4ffd934da63079339f0b697ff923ecba958b2bf5c007987a5ade00756b56a758672d37b23482dc9151dbb610157be181761521'
7
+ data.tar.gz: '0359913d6d17b4303518284a54a5da8428a1c0b3ce871766fa117a37c063f5d739aa812a08e495689867502ca63be23e719405211eb2ea35b2c046dae006c6e7'
@@ -1,8 +1,8 @@
1
- <tr id="<%= dom_id(export_item) %>" class="<%= cycle('odd','even') %> <%= @export.modifiable? ? 'handle' : '' %>">
1
+ <%= tag.tr(id: dom_id(export_item), class: "handle") do %>
2
2
  <td class="row_title"><%= export_item.name %></td>
3
3
  <td><%= export_item.rexport_field %></td>
4
4
  <td class="table_icons">
5
- <%= link_to(image_tag('icon_edit.gif'), edit_export_item_path(export_item)) if @export.modifiable? %>
6
- <%= link_to_delete(export_item, text: false) if @export.modifiable? %>
5
+ <%= link_to(image_tag('icon_edit.gif'), edit_export_item_path(export_item)) %>
6
+ <%= link_to_delete(export_item, text: false) %>
7
7
  </td>
8
- </tr>
8
+ <% end %>
@@ -2,7 +2,7 @@
2
2
  <div id="custom_export_options">
3
3
  <h4>Options</h4>
4
4
  <ul>
5
- <li><%= link_to("#{image_tag('icon_edit.gif')} Edit".html_safe, edit_export_path(@export)) if @export.modifiable? %></li>
5
+ <li><%= link_to("#{image_tag('icon_edit.gif')} Edit".html_safe, edit_export_path(@export)) %></li>
6
6
  <li><%= link_to "#{image_tag('icon_export.png')} Export".html_safe, export_path(@export, format: :csv) %></li>
7
7
  <li><%= link_to "#{image_tag('icon_copy.png')} Copy".html_safe, exports_path(:original_export_id => @export.id), method: :post %></li>
8
8
  </ul>
@@ -29,12 +29,12 @@
29
29
  <th class='action_icons'>&nbsp;</th>
30
30
  </tr>
31
31
  </thead>
32
- <%= content_tag :tbody, {id: 'export_items'}.merge(@export.modifiable? ? {class: 'sortable', 'data-url' => export_item_sorting_path} : {}) do %>
32
+ <%= tag.tbody(id: 'export_items', class: 'sortable', 'data-url' => export_item_sorting_path) do %>
33
33
  <%= render partial: @export.export_items.ordered %>
34
34
  <% end %>
35
35
  </table>
36
36
 
37
- <%= content_tag(:p, 'Drag and drop the rows in the table above to re-order the export data left to right in the output (see sample below).', class: 'instructions') if @export.modifiable? %>
37
+ <%= tag.p('Drag and drop the rows in the table above to re-order the export data left to right in the output (see sample below).', class: 'instructions') %>
38
38
 
39
39
  <%= render(partial: 'filters') unless @export.export_filters.blank? %>
40
40
 
@@ -25,8 +25,8 @@
25
25
  <td class="table_icons">
26
26
  <%= link_to_export export_path(export, format: :csv), text: false %>
27
27
  <%= link_to_show export, text: false %>
28
- <%= link_to(image_tag('icon_edit.gif'), edit_export_path(export), title: 'Edit') if export.modifiable? %>
29
- <%= link_to_delete(export, text: false) if export.modifiable? %>
28
+ <%= link_to(image_tag('icon_edit.gif'), edit_export_path(export), title: 'Edit') %>
29
+ <%= link_to_delete(export, text: false) %>
30
30
  </td>
31
31
  </tr>
32
32
  <% end %>
@@ -3,97 +3,12 @@ module Rexport #:nodoc:
3
3
  extend ActiveSupport::Concern
4
4
 
5
5
  module ClassMethods
6
- # Returns hash of exportable data items
7
- def rexport_fields
8
- @rexport_fields ||= nil
9
- unless @rexport_fields
10
- @rexport_fields = HashWithIndifferentAccess.new
11
- initialize_rexport_fields
12
- end
13
- @rexport_fields
14
- end
15
-
16
- # Returns sorted array of rexport DataFields
17
- def rexport_fields_array
18
- rexport_fields.values.sort
19
- end
20
-
21
- # Adds a data item to rexport_fields
22
- def add_rexport_field(name, options = {})
23
- rexport_fields[name.to_s] = DataField.new(name, options)
24
- end
25
-
26
- # Adds associated methods to rexport_fields
27
- # :associations - an association or arrary of associations
28
- # :methods - a method or array of methods
29
- # :filter - if true will send type: :association to add_report_field
30
- def add_association_methods(options = {})
31
- options.stringify_keys!
32
- options.assert_valid_keys(%w(associations methods filter))
33
-
34
- methods = options.reverse_merge('methods' => 'name')['methods']
35
- methods = [methods] if methods.kind_of?(String)
36
-
37
- associations = options['associations']
38
- associations = [associations] if associations.kind_of?(String)
39
-
40
- type = options['filter'] ? :association : nil
41
-
42
- associations.each do |association|
43
- methods.each do |method|
44
- add_rexport_field("#{association}_#{method}", method: "#{association}.#{method}", type: type)
45
- end
46
- end
47
- end
48
-
49
- # Removes files from rexport_fields
50
- # useful to remove content columns you don't want included in exports
51
- def remove_rexport_fields(*fields)
52
- fields.flatten.each { |field| rexport_fields.delete(field.to_s) }
53
- end
54
-
55
- # Returns an array of export methods corresponding with field_names
56
- def get_rexport_methods(*field_names)
57
- field_names.flatten.map do |f|
58
- begin
59
- components = f.to_s.split('.')
60
- field_name = components.pop
61
- components.push(get_klass_from_associations(components).get_rexport_method(field_name)) * '.'
62
- rescue NoMethodError
63
- 'undefined_rexport_field'
64
- end
65
- end
66
- end
67
-
68
- # Returns the associated class by following the associations
6
+ # Returns the associated class by following the chain of associations
69
7
  def get_klass_from_associations(*associations)
70
8
  associations.flatten!
71
9
  return self if associations.empty?
72
10
  reflect_on_association(associations.shift.to_sym).klass.get_klass_from_associations(associations)
73
11
  end
74
-
75
- # Returns the export method for a given field_name
76
- def get_rexport_method(field_name)
77
- if rexport_fields[field_name]
78
- rexport_fields[field_name].method
79
- else
80
- raise NoMethodError
81
- end
82
- end
83
-
84
- def reset_column_information
85
- @rexport_fields = nil
86
- super
87
- end
88
-
89
- private
90
-
91
- # Adds content columns rexport_fields, includes callback
92
- # initialize_local_rexport_fields for client defined initialization
93
- def initialize_rexport_fields
94
- content_columns.each { |field| add_rexport_field(field.name, type: field.type) }
95
- initialize_local_rexport_fields if respond_to?(:initialize_local_rexport_fields)
96
- end
97
12
  end
98
13
 
99
14
  # Return an array of formatted export values for the passed methods
@@ -5,7 +5,7 @@ module Rexport
5
5
  end
6
6
 
7
7
  def update
8
- if export_item.update_attributes(export_item_params)
8
+ if export_item.update(export_item_params)
9
9
  redirect_to export_path(export_item.export), notice: 'ExportItem was successfully updated.'
10
10
  else
11
11
  render :edit
@@ -57,6 +57,11 @@ module Rexport #:nodoc:
57
57
  model_class_name.constantize
58
58
  end
59
59
 
60
+ # Returns a RexportModel for the current export_model
61
+ def rexport_model
62
+ @rexport_model ||= RexportModel.new(export_model)
63
+ end
64
+
60
65
  # Returns an array of RexportModels including export_model and associated rexport capable models
61
66
  def rexport_models
62
67
  @rexport_models ||= get_rexport_models(export_model)
@@ -117,15 +122,12 @@ module Rexport #:nodoc:
117
122
  end
118
123
  end
119
124
 
120
- def modifiable?
121
- # override to disable edit and destroy links for specific exports
122
- true
123
- end
124
-
125
125
  private
126
126
 
127
127
  def get_records(limit = nil)
128
128
  get_export_values(export_model.where(build_conditions).includes(build_include).limit(limit))
129
+ rescue ActiveRecord::StatementInvalid => e
130
+ [[e.message]]
129
131
  end
130
132
 
131
133
  def seed_records(objects)
@@ -136,21 +138,20 @@ module Rexport #:nodoc:
136
138
  objects.map { |object| object.export(rexport_methods) }
137
139
  end
138
140
 
139
- def get_rexport_models(rexport_model, result = [], path = nil)
140
- return unless rexport_model.respond_to?(:rexport_fields)
141
- result << RexportModel.new(rexport_model, path)
142
- get_associations(rexport_model).each do |associated_model|
143
- # prevent infinite loop by checking if this class is already in the result set
144
- unless result.detect { |model| model.klass == associated_model.klass }
145
- get_rexport_models(associated_model.klass, result, [path, associated_model.name].compact * '.')
146
- end
141
+ def get_rexport_models(model, results = [], path = nil)
142
+ return unless model.include?(Rexport::DataFields)
143
+ results << RexportModel.new(model, path: path)
144
+ get_associations(model).each do |associated_model|
145
+ # prevent infinite loop by checking if this class is already in the results set
146
+ next if results.detect { |result| result.klass == associated_model.klass }
147
+ get_rexport_models(associated_model.klass, results, [path, associated_model.name].compact * '.')
147
148
  end
148
- return result
149
+ return results
149
150
  end
150
151
 
151
- def get_associations(rexport_model)
152
+ def get_associations(model)
152
153
  %i(belongs_to has_one).map do |type|
153
- rexport_model.reflect_on_all_associations(type)
154
+ model.reflect_on_all_associations(type)
154
155
  end.flatten.reject(&:polymorphic?)
155
156
  end
156
157
 
@@ -177,7 +178,7 @@ module Rexport #:nodoc:
177
178
  end
178
179
 
179
180
  def rexport_methods
180
- @rexport_methods ||= export_model.get_rexport_methods(ordered_rexport_fields)
181
+ @rexport_methods ||= rexport_model.get_rexport_methods(ordered_rexport_fields)
181
182
  end
182
183
 
183
184
  def rexport_fields
@@ -199,9 +200,7 @@ module Rexport #:nodoc:
199
200
  end
200
201
  end
201
202
 
202
- position = 0
203
- rexport_fields.each do |rexport_field|
204
- position += 1
203
+ rexport_fields.each.with_index(1) do |rexport_field, position|
205
204
  export_item = export_items.detect { |i| i.rexport_field == rexport_field } || export_items.create(rexport_field: rexport_field)
206
205
  export_item.update_attribute(:position, position) if set_position
207
206
  end
@@ -32,7 +32,7 @@ module Rexport
32
32
  end
33
33
 
34
34
  def update
35
- if export.update_attributes(export_params)
35
+ if export.update(export_params)
36
36
  redirect_to export, notice: 'Export was successfully updated.'
37
37
  else
38
38
  render :edit
@@ -2,13 +2,18 @@ module Rexport #:nodoc:
2
2
  class RexportModel
3
3
  attr_accessor :klass, :path
4
4
 
5
- def initialize(klass, path = nil)
5
+ def initialize(klass, path: nil)
6
6
  self.klass = klass
7
7
  self.path = path.to_s unless path.blank?
8
+ initialize_rexport_fields
9
+ end
10
+
11
+ def rexport_fields
12
+ @rexport_fields ||= HashWithIndifferentAccess.new
8
13
  end
9
14
 
10
15
  def rexport_fields_array
11
- klass.rexport_fields_array
16
+ rexport_fields.values.sort
12
17
  end
13
18
 
14
19
  def field_path(field_name)
@@ -16,8 +21,11 @@ module Rexport #:nodoc:
16
21
  end
17
22
 
18
23
  def collection_from_association(association)
19
- return klass.send("find_#{association}_for_rexport") if klass.respond_to?("find_#{association}_for_rexport")
20
- klass.reflect_on_association(association.to_sym).klass.all
24
+ if klass.respond_to?("find_#{association}_for_rexport")
25
+ klass.public_send("find_#{association}_for_rexport")
26
+ else
27
+ klass.reflect_on_association(association.to_sym).klass.all
28
+ end
21
29
  end
22
30
 
23
31
  def filter_column(field)
@@ -29,5 +37,82 @@ module Rexport #:nodoc:
29
37
  def name
30
38
  klass.name
31
39
  end
40
+
41
+ # Adds a data item to rexport_fields
42
+ def add_rexport_field(name, options = {})
43
+ rexport_fields[name.to_s] = DataField.new(name, options)
44
+ end
45
+
46
+ # Removes files from rexport_fields
47
+ # useful to remove content columns you don't want included in exports
48
+ def remove_rexport_fields(*fields)
49
+ fields.flatten.each { |field| rexport_fields.delete(field.to_s) }
50
+ end
51
+
52
+ # Adds associated methods to rexport_fields
53
+ # :associations - an association or arrary of associations
54
+ # :methods - a method or array of methods
55
+ # :filter - if true will send type: :association to add_report_field
56
+ def add_association_methods(options = {})
57
+ options.stringify_keys!
58
+ options.assert_valid_keys(%w(associations methods filter))
59
+
60
+ methods = options.reverse_merge('methods' => 'name')['methods']
61
+ methods = [methods] if methods.kind_of?(String)
62
+
63
+ associations = options['associations']
64
+ associations = [associations] if associations.kind_of?(String)
65
+
66
+ type = options['filter'] ? :association : nil
67
+
68
+ associations.each do |association|
69
+ methods.each do |method|
70
+ add_rexport_field("#{association}_#{method}", method: "#{association}.#{method}", type: type)
71
+ end
72
+ end
73
+ end
74
+
75
+ # Returns an array of export methods corresponding with field_names
76
+ def get_rexport_methods(*field_names)
77
+ field_names.flatten.map do |f|
78
+ begin
79
+ components = f.to_s.split('.')
80
+ field_name = components.pop
81
+ components.push(get_rexport_model(components).get_rexport_method(field_name)) * '.'
82
+ rescue NoMethodError
83
+ 'undefined_rexport_field'
84
+ end
85
+ end
86
+ end
87
+
88
+ protected
89
+
90
+ # Returns a rexport_model for the associated class by following the chain of associations
91
+ def get_rexport_model(associations)
92
+ associations.empty? ? self : rexport_models[associations.dup]
93
+ end
94
+
95
+ # Memoize rexport_models to avoid initializing rexport_fields multiple times
96
+ def rexport_models
97
+ @rexport_models ||= Hash.new do |hash, key|
98
+ hash[key] = self.class.new(klass.get_klass_from_associations(key))
99
+ end
100
+ end
101
+
102
+ # Returns the export method for a given field_name
103
+ def get_rexport_method(field_name)
104
+ if rexport_fields[field_name]
105
+ rexport_fields[field_name].method
106
+ else
107
+ raise NoMethodError
108
+ end
109
+ end
110
+
111
+ private
112
+
113
+ def initialize_rexport_fields
114
+ klass.content_columns.each { |field| add_rexport_field(field.name, type: field.type) }
115
+ klass.initialize_local_rexport_fields(self) if klass.respond_to?(:initialize_local_rexport_fields)
116
+ end
32
117
  end
33
118
  end
@@ -1,3 +1,3 @@
1
1
  module Rexport
2
- VERSION = '1.0.2'
2
+ VERSION = '1.2.1'
3
3
  end
data/test/factories.rb CHANGED
@@ -54,6 +54,21 @@ module Rexport
54
54
  end
55
55
  end
56
56
 
57
+ factory :invalid_filtered_export, class: 'Export' do
58
+ name { 'Invalid Filtered Enrollment Export' }
59
+ model_class_name { 'Enrollment' }
60
+ export_items do |items|
61
+ %w(grade_export_item status_name_export_item).map do |item|
62
+ items.association(item)
63
+ end
64
+ end
65
+ export_filters do |filters|
66
+ %w(invalid_filter).map do |filter|
67
+ filters.association(filter)
68
+ end
69
+ end
70
+ end
71
+
57
72
  factory :family_name_export_item, class: 'ExportItem' do
58
73
  position { 1 }
59
74
  name { 'Family Name' }
@@ -86,6 +101,11 @@ module Rexport
86
101
  filter_field { 'status.name' }
87
102
  value { 'active' }
88
103
  end
104
+
105
+ factory :invalid_filter, class: 'ExportFilter' do
106
+ filter_field { 'invalid' }
107
+ value { '1' }
108
+ end
89
109
  end
90
110
  end
91
111
  end
data/test/test_helper.rb CHANGED
@@ -112,10 +112,10 @@ class Enrollment < ActiveRecord::Base
112
112
 
113
113
  private
114
114
 
115
- def Enrollment.initialize_local_rexport_fields
116
- add_rexport_field(:foo_method, method: :foo)
117
- add_rexport_field(:bad_method, method: 'bad_method')
118
- add_association_methods(associations: %w(status ilp_status))
115
+ def self.initialize_local_rexport_fields(rexport_model)
116
+ rexport_model.add_rexport_field(:foo_method, method: :foo)
117
+ rexport_model.add_rexport_field(:bad_method, method: 'bad_method')
118
+ rexport_model.add_association_methods(associations: %w(status ilp_status))
119
119
  end
120
120
  end
121
121
 
@@ -123,6 +123,10 @@ class Student < ActiveRecord::Base
123
123
  include Rexport::DataFields
124
124
  belongs_to :family
125
125
  has_many :enrollments
126
+
127
+ def self.find_family_for_rexport
128
+ Family.order(:name)
129
+ end
126
130
  end
127
131
 
128
132
  class Family < ActiveRecord::Base
@@ -135,8 +139,8 @@ class Family < ActiveRecord::Base
135
139
 
136
140
  private
137
141
 
138
- def Family.initialize_local_rexport_fields
139
- add_rexport_field(:foo_method, method: :foo)
142
+ def self.initialize_local_rexport_fields(rexport_model)
143
+ rexport_model.add_rexport_field(:foo_method, method: :foo)
140
144
  end
141
145
  end
142
146
 
@@ -158,9 +162,6 @@ class ExportFilter < ActiveRecord::Base
158
162
  end
159
163
 
160
164
  class SelfReferentialCheck < ActiveRecord::Base
165
+ include Rexport::DataFields
161
166
  belongs_to :enrollment
162
-
163
- def SelfReferentialCheck.rexport_fields
164
- 'trick get_rexport_models into believing we are exportable'
165
- end
166
167
  end
@@ -3,83 +3,6 @@ require 'test_helper'
3
3
  class DataFieldsTest < ActiveSupport::TestCase
4
4
 
5
5
  class RexportClassMethodsTest < DataFieldsTest
6
- test 'should initialize local rexport fields' do
7
- assert_equal(
8
- %w(active bad_method created_at foo_method grade ilp_status_name status_name updated_at),
9
- Enrollment.rexport_fields.keys.sort
10
- )
11
- end
12
-
13
- test 'should initialize data atributes' do
14
- assert_equal 'grade', Enrollment.rexport_fields[:grade].method
15
- assert_equal :integer, Enrollment.rexport_fields[:grade].type
16
- end
17
-
18
- test 'should initialize method' do
19
- assert_equal 'foo', Enrollment.rexport_fields[:foo_method].method
20
- assert_nil Enrollment.rexport_fields[:foo_method].type
21
- end
22
-
23
- test 'should return sorted data fields array' do
24
- assert_equal(
25
- %w(active bad_method created_at foo_method grade ilp_status_name status_name updated_at),
26
- Enrollment.rexport_fields_array.map(&:name)
27
- )
28
- end
29
-
30
- test 'should add single association method to rexport_fields' do
31
- assert_difference('Enrollment.rexport_fields.length') do
32
- Enrollment.add_association_methods(associations: 'test_association')
33
- end
34
- assert_equal 'test_association_name', Enrollment.rexport_fields[:test_association_name].name
35
- assert_equal 'test_association.name', Enrollment.rexport_fields[:test_association_name].method
36
- end
37
-
38
- test 'should add name methods for multiple associations' do
39
- assert_difference('Enrollment.rexport_fields.length', 3) do
40
- Enrollment.add_association_methods(associations: %w(a b c))
41
- end
42
- end
43
-
44
- test 'should add multiple methods for multiple associations' do
45
- assert_difference('Enrollment.rexport_fields.length', 9) do
46
- Enrollment.add_association_methods(associations: %w(a1 a2 a3), methods: %w(m1 m2 m3))
47
- end
48
- end
49
-
50
- test 'should get rexport methods' do
51
- assert_equal(
52
- ['student.family.foo',
53
- 'student.name',
54
- 'undefined_rexport_field',
55
- 'undefined_rexport_field',
56
- 'status.name',
57
- 'grade'
58
- ],
59
- Enrollment.get_rexport_methods(
60
- 'student.family.foo_method',
61
- 'student.name',
62
- 'student.bad_method',
63
- 'bad_association.test',
64
- 'status_name',
65
- 'grade'
66
- )
67
- )
68
- end
69
-
70
- test 'should remove single rexport field' do
71
- assert Enrollment.rexport_fields[:grade]
72
- assert Enrollment.remove_rexport_fields(:grade)
73
- assert_nil Enrollment.rexport_fields[:grade]
74
- end
75
-
76
- test 'should remove multiple rexport fields' do
77
- fields = %w(grade status_name foo_method)
78
- fields.each { |field| assert(Enrollment.rexport_fields[field]) }
79
- assert Enrollment.remove_rexport_fields(fields)
80
- fields.each { |field| assert_nil(Enrollment.rexport_fields[field]) }
81
- end
82
-
83
6
  test 'should get klass from assocations' do
84
7
  assert_equal Family, Enrollment.get_klass_from_associations('student', 'family')
85
8
  end
@@ -89,13 +12,6 @@ class DataFieldsTest < ActiveSupport::TestCase
89
12
  Enrollment.get_klass_from_associations('not_an_association')
90
13
  end
91
14
  end
92
-
93
- test 'should reset column information with rexport_reset' do
94
- Enrollment.expects(:initialize_rexport_fields).times(2).returns(true)
95
- assert Enrollment.rexport_fields
96
- Enrollment.reset_column_information
97
- assert Enrollment.rexport_fields
98
- end
99
15
  end
100
16
 
101
17
  class RexportInstanceMethodsTest < DataFieldsTest
@@ -42,6 +42,13 @@ class ExportMethodsTest < ActiveSupport::TestCase
42
42
  assert_equal [['1', 'active']], create(:filtered_export).records
43
43
  end
44
44
 
45
+ test 'should return error message for records when export has an invalid filter' do
46
+ assert_equal(
47
+ [["SQLite3::SQLException: no such column: enrollments.invalid"]],
48
+ create(:invalid_filtered_export).records
49
+ )
50
+ end
51
+
45
52
  test 'should call get_records' do
46
53
  export = build(:export)
47
54
  export.expects(:get_records).with(Rexport::SAMPLE_SIZE).returns(true)
@@ -202,10 +209,6 @@ class ExportMethodsTest < ActiveSupport::TestCase
202
209
  end
203
210
  end
204
211
 
205
- test 'should return true for modifiable?' do
206
- assert Export.new.modifiable?
207
- end
208
-
209
212
  private
210
213
 
211
214
  def create_export(fields: {}, filters: {})
@@ -1,35 +1,137 @@
1
1
  require 'test_helper'
2
2
 
3
3
  class RexportModel < ActiveSupport::TestCase
4
- test 'should return correct foreign_key' do
5
- rexport_model = Rexport::RexportModel.new(Enrollment)
4
+ test 'should initialize rexport_fields' do
5
+ assert_equal(
6
+ %w(active bad_method created_at foo_method grade ilp_status_name status_name updated_at),
7
+ rexport_model.rexport_fields.keys.sort
8
+ )
9
+ end
10
+
11
+ test 'should initialize data atributes' do
12
+ assert_equal 'grade', rexport_model.rexport_fields[:grade].method
13
+ assert_equal :integer, rexport_model.rexport_fields[:grade].type
14
+ end
15
+
16
+ test 'should initialize method' do
17
+ assert_equal 'foo', rexport_model.rexport_fields[:foo_method].method
18
+ assert_nil rexport_model.rexport_fields[:foo_method].type
19
+ end
20
+
21
+ test 'should add single association method to rexport_fields' do
22
+ assert_fields_length do |rexport|
23
+ rexport.add_association_methods(associations: 'test_association')
24
+ assert_equal 'test_association_name', rexport.rexport_fields[:test_association_name].name
25
+ assert_equal 'test_association.name', rexport.rexport_fields[:test_association_name].method
26
+ end
27
+ end
28
+
29
+ test 'should add name methods for multiple associations' do
30
+ assert_fields_length(change: 3) do |rexport|
31
+ rexport.add_association_methods(associations: %w(a b c))
32
+ end
33
+ end
34
+
35
+ test 'should add multiple methods for multiple associations' do
36
+ assert_fields_length(change: 9) do |rexport|
37
+ rexport.add_association_methods(associations: %w(a1 a2 a3), methods: %w(m1 m2 m3))
38
+ end
39
+ end
40
+
41
+ test 'should remove single rexport field' do
42
+ rexport_model.tap do |rexport|
43
+ assert rexport.rexport_fields[:grade]
44
+ assert rexport.remove_rexport_fields(:grade)
45
+ assert_nil rexport.rexport_fields[:grade]
46
+ end
47
+ end
48
+
49
+ test 'should remove multiple rexport fields' do
50
+ fields = %w(grade status_name foo_method)
6
51
 
7
- data_field = Enrollment.rexport_fields['status_name']
8
- assert_equal 'status_id', rexport_model.filter_column(data_field)
52
+ rexport_model.tap do |rexport|
53
+ fields.each { |field| assert(rexport.rexport_fields[field]) }
54
+ assert rexport.remove_rexport_fields(fields)
55
+ fields.each { |field| assert_nil(rexport.rexport_fields[field]) }
56
+ end
57
+ end
9
58
 
10
- data_field = Enrollment.rexport_fields['ilp_status_name']
11
- assert_equal 'ilp_status_id', rexport_model.filter_column(data_field)
59
+ test 'should get rexport methods' do
60
+ assert_equal(
61
+ [
62
+ 'student.family.foo',
63
+ 'student.name',
64
+ 'undefined_rexport_field',
65
+ 'undefined_rexport_field',
66
+ 'status.name',
67
+ 'grade'
68
+ ],
69
+ rexport_model.get_rexport_methods(
70
+ 'student.family.foo_method',
71
+ 'student.name',
72
+ 'student.bad_method',
73
+ 'bad_association.test',
74
+ 'status_name',
75
+ 'grade'
76
+ )
77
+ )
78
+ end
79
+
80
+ test 'should use cached rexport_model when getting multiple fields from one model' do
81
+ rexport_model.tap do |rexport|
82
+ assert_equal ['student.name'], rexport.get_rexport_methods('student.name')
83
+ Student.expects(:get_klass_from_associations).times(0)
84
+ assert_equal ['student.date_of_birth'], rexport.get_rexport_methods('student.date_of_birth')
85
+ end
86
+ end
87
+
88
+ test 'should return default foreign_key' do
89
+ assert_equal 'status_id', rexport_model.filter_column(data_field('status_name'))
90
+ end
91
+
92
+ test 'should return custom foreign_key' do
93
+ assert_equal 'ilp_status_id', rexport_model.filter_column(data_field('ilp_status_name'))
12
94
  end
13
95
 
14
96
  test 'should call rexport_fields_array' do
15
- rexport_model = Rexport::RexportModel.new(Enrollment)
16
- Enrollment.expects(:rexport_fields_array).returns(true)
17
- assert rexport_model.rexport_fields_array
97
+ assert_equal(
98
+ %w(active bad_method created_at foo_method grade ilp_status_name status_name updated_at),
99
+ rexport_model.rexport_fields_array.map(&:name)
100
+ )
18
101
  end
19
102
 
20
103
  test 'should return field_path' do
21
- rexport_model = Rexport::RexportModel.new(Enrollment, 'foo')
22
- assert_equal 'foo.bar', rexport_model.field_path('bar')
104
+ assert_equal 'foo.bar', rexport_model(path: 'foo').field_path('bar')
23
105
  end
24
106
 
25
107
  test 'should return collection_from_association' do
26
- rexport_model = Rexport::RexportModel.new(Enrollment)
27
108
  Status.expects(:all).returns(true)
28
109
  assert rexport_model.collection_from_association('status')
29
110
  end
30
111
 
112
+ test 'should return custom find method for collection_from_association' do
113
+ Student.expects(:find_family_for_rexport).returns(true)
114
+ assert rexport_model(model: Student).collection_from_association('family')
115
+ end
116
+
117
+
31
118
  test 'should return class name' do
32
- rexport_model = Rexport::RexportModel.new(Enrollment)
33
119
  assert_equal 'Enrollment', rexport_model.name
34
120
  end
121
+
122
+ private
123
+
124
+ def rexport_model(model: Enrollment, path: nil)
125
+ Rexport::RexportModel.new(model, path: path)
126
+ end
127
+
128
+ def data_field(name)
129
+ rexport_model.rexport_fields[name]
130
+ end
131
+
132
+ def assert_fields_length(rexport: rexport_model, change: 1, &block)
133
+ assert_difference('rexport.rexport_fields.length', change) do
134
+ block.call(rexport)
135
+ end
136
+ end
35
137
  end
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rexport
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron Baldwin
8
8
  - Brightways Learning
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2019-07-09 00:00:00.000000000 Z
12
+ date: 2022-09-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -17,56 +17,56 @@ dependencies:
17
17
  requirements:
18
18
  - - ">="
19
19
  - !ruby/object:Gem::Version
20
- version: 4.0.1
20
+ version: 6.0.3
21
21
  type: :runtime
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
25
  - - ">="
26
26
  - !ruby/object:Gem::Version
27
- version: 4.0.1
27
+ version: 6.0.3
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: factory_bot
30
30
  requirement: !ruby/object:Gem::Requirement
31
31
  requirements:
32
32
  - - "~>"
33
33
  - !ruby/object:Gem::Version
34
- version: '4.7'
34
+ version: '6.2'
35
35
  type: :development
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
39
  - - "~>"
40
40
  - !ruby/object:Gem::Version
41
- version: '4.7'
41
+ version: '6.2'
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: sqlite3
44
44
  requirement: !ruby/object:Gem::Requirement
45
45
  requirements:
46
46
  - - "~>"
47
47
  - !ruby/object:Gem::Version
48
- version: '1.3'
48
+ version: '1.4'
49
49
  type: :development
50
50
  prerelease: false
51
51
  version_requirements: !ruby/object:Gem::Requirement
52
52
  requirements:
53
53
  - - "~>"
54
54
  - !ruby/object:Gem::Version
55
- version: '1.3'
55
+ version: '1.4'
56
56
  - !ruby/object:Gem::Dependency
57
57
  name: mocha
58
58
  requirement: !ruby/object:Gem::Requirement
59
59
  requirements:
60
60
  - - "~>"
61
61
  - !ruby/object:Gem::Version
62
- version: '1.0'
62
+ version: '1.13'
63
63
  type: :development
64
64
  prerelease: false
65
65
  version_requirements: !ruby/object:Gem::Requirement
66
66
  requirements:
67
67
  - - "~>"
68
68
  - !ruby/object:Gem::Version
69
- version: '1.0'
69
+ version: '1.13'
70
70
  description: Rexport integrates into a Rails application making model data available
71
71
  for export into CSV files.
72
72
  email:
@@ -120,7 +120,7 @@ homepage: https://github.com/wwidea/rexport
120
120
  licenses:
121
121
  - MIT
122
122
  metadata: {}
123
- post_install_message:
123
+ post_install_message:
124
124
  rdoc_options: []
125
125
  require_paths:
126
126
  - lib
@@ -135,17 +135,17 @@ required_rubygems_version: !ruby/object:Gem::Requirement
135
135
  - !ruby/object:Gem::Version
136
136
  version: '0'
137
137
  requirements: []
138
- rubygems_version: 3.0.4
139
- signing_key:
138
+ rubygems_version: 3.3.9
139
+ signing_key:
140
140
  specification_version: 4
141
141
  summary: Ruby on Rails gem to manage exports.
142
142
  test_files:
143
- - test/unit/export_methods_test.rb
143
+ - test/factories.rb
144
+ - test/test_helper.rb
144
145
  - test/unit/data_field_test.rb
145
- - test/unit/rexport_model_test.rb
146
- - test/unit/export_filter_methods_test.rb
147
146
  - test/unit/data_fields_test.rb
148
- - test/unit/tree_node_test.rb
147
+ - test/unit/export_filter_methods_test.rb
149
148
  - test/unit/export_item_methods_test.rb
150
- - test/factories.rb
151
- - test/test_helper.rb
149
+ - test/unit/export_methods_test.rb
150
+ - test/unit/rexport_model_test.rb
151
+ - test/unit/tree_node_test.rb