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 +4 -4
- data/app/views/export_items/_export_item.html.erb +4 -4
- data/app/views/exports/_show.html.erb +3 -3
- data/app/views/exports/index.html.erb +2 -2
- data/lib/rexport/data_fields.rb +1 -86
- data/lib/rexport/export_items_controller_methods.rb +1 -1
- data/lib/rexport/export_methods.rb +19 -20
- data/lib/rexport/exports_controller_methods.rb +1 -1
- data/lib/rexport/rexport_model.rb +89 -4
- data/lib/rexport/version.rb +1 -1
- data/test/factories.rb +20 -0
- data/test/test_helper.rb +11 -10
- data/test/unit/data_fields_test.rb +0 -84
- data/test/unit/export_methods_test.rb +7 -4
- data/test/unit/rexport_model_test.rb +115 -13
- metadata +20 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8cf8cb2fe8850f491ab8eb8a92d0034d1447babd6a4a79457acea80fcbec94fc
|
4
|
+
data.tar.gz: 2e646631a4c3673359f31bd222c43c32ed6fcb20813f7f6ac34d633005899628
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '08d2fd739cf9775d22295a57ba4ffd934da63079339f0b697ff923ecba958b2bf5c007987a5ade00756b56a758672d37b23482dc9151dbb610157be181761521'
|
7
|
+
data.tar.gz: '0359913d6d17b4303518284a54a5da8428a1c0b3ce871766fa117a37c063f5d739aa812a08e495689867502ca63be23e719405211eb2ea35b2c046dae006c6e7'
|
@@ -1,8 +1,8 @@
|
|
1
|
-
|
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))
|
6
|
-
<%= link_to_delete(export_item, text: false)
|
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
|
-
|
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))
|
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'> </th>
|
30
30
|
</tr>
|
31
31
|
</thead>
|
32
|
-
<%=
|
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
|
-
<%=
|
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')
|
29
|
-
<%= link_to_delete(export, text: false)
|
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 %>
|
data/lib/rexport/data_fields.rb
CHANGED
@@ -3,97 +3,12 @@ module Rexport #:nodoc:
|
|
3
3
|
extend ActiveSupport::Concern
|
4
4
|
|
5
5
|
module ClassMethods
|
6
|
-
# Returns
|
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
|
@@ -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(
|
140
|
-
return unless
|
141
|
-
|
142
|
-
get_associations(
|
143
|
-
# prevent infinite loop by checking if this class is already in the
|
144
|
-
|
145
|
-
|
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
|
149
|
+
return results
|
149
150
|
end
|
150
151
|
|
151
|
-
def get_associations(
|
152
|
+
def get_associations(model)
|
152
153
|
%i(belongs_to has_one).map do |type|
|
153
|
-
|
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 ||=
|
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
|
-
|
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
|
@@ -2,13 +2,18 @@ module Rexport #:nodoc:
|
|
2
2
|
class RexportModel
|
3
3
|
attr_accessor :klass, :path
|
4
4
|
|
5
|
-
def initialize(klass, path
|
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
|
-
|
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
|
-
|
20
|
-
|
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
|
data/lib/rexport/version.rb
CHANGED
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
|
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
|
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
|
5
|
-
|
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
|
-
|
8
|
-
|
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
|
-
|
11
|
-
assert_equal
|
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
|
-
|
16
|
-
|
17
|
-
|
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
|
-
|
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.
|
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:
|
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:
|
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:
|
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: '
|
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: '
|
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.
|
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.
|
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.
|
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.
|
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.
|
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/
|
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/
|
147
|
+
- test/unit/export_filter_methods_test.rb
|
149
148
|
- test/unit/export_item_methods_test.rb
|
150
|
-
- test/
|
151
|
-
- test/
|
149
|
+
- test/unit/export_methods_test.rb
|
150
|
+
- test/unit/rexport_model_test.rb
|
151
|
+
- test/unit/tree_node_test.rb
|