Project

General

Profile

Feature #31472 » 31472-add-file-upload-v3.patch

Yuichi HARADA, 2021-03-12 08:26

View differences:

app/controllers/documents_controller.rb
75 75
    @document.safe_attributes = params[:document]
76 76
    if @document.save
77 77
      flash[:notice] = l(:notice_successful_update)
78
      redirect_to document_path(@document)
78
      add_attachment
79 79
    else
80 80
      render :action => 'edit'
81 81
    end
app/models/document.rb
40 40
  )
41 41
  acts_as_activity_provider :scope => proc {preload(:project)}
42 42

  
43
  attr_writer :deleted_attachment_ids
44

  
43 45
  validates_presence_of :project, :title, :category
44 46
  validates_length_of :title, :maximum => 255
45 47

  
48
  after_save :delete_selected_attachments
46 49
  after_create_commit :send_notification
47 50

  
48 51
  scope :visible, (lambda do |*args|
......
51 54
  end)
52 55

  
53 56
  safe_attributes 'category_id', 'title', 'description', 'custom_fields', 'custom_field_values'
57
  safe_attributes(
58
    'deleted_attachment_ids',
59
    :if => lambda {|document, user| document.attachments_deletable?(user)}
60
  )
54 61

  
55 62
  def visible?(user=User.current)
56 63
    !user.nil? && user.allowed_to?(:view_documents, project)
......
75 82
    project.notified_users.reject {|user| !visible?(user)}
76 83
  end
77 84

  
85
  def deleted_attachment_ids
86
    Array(@deleted_attachment_ids).map(&:to_i)
87
  end
88

  
78 89
  private
79 90

  
91
  def delete_selected_attachments
92
    if deleted_attachment_ids.present?
93
      objects = attachments.where(:id => deleted_attachment_ids)
94
      attachments.delete(objects)
95
    end
96
  end
97

  
80 98
  def send_notification
81 99
    if Setting.notified_events.include?('document_added')
82 100
      Mailer.deliver_document_added(self, User.current)
app/views/documents/_form.html.erb
12 12
<% @document.custom_field_values.each do |value| %>
13 13
  <p><%= custom_field_tag_with_label :document, value %></p>
14 14
<% end %>
15
</div>
16 15

  
17 16
<%= wikitoolbar_for 'document_description' %>
18 17

  
19
<% if @document.new_record? %>
20
<div class="box tabular">
21
<p><label><%=l(:label_attachment_plural)%></label><%= render :partial => 'attachments/form', :locals => {:container => @document} %></p>
18
<fieldset>
19
<legend><%=l(:label_attachment_plural)%></legend>
20
<% if @document.attachments.any? && @document.safe_attribute?('deleted_attachment_ids') %>
21
<div class="contextual"><%= link_to l(:label_edit_attachments), '#', :onclick => "$('#existing-attachments').toggle(); return false;" %></div>
22
<div id="existing-attachments" style="<%= 'display:none;' if @document.deleted_attachment_ids.blank? %>">
23
  <% @document.attachments.each do |attachment| %>
24
  <span class="existing-attachment">
25
    <%= text_field_tag '', attachment.filename, :class => "icon icon-attachment filename", :disabled => true %>
26
    <label class='inline'>
27
      <%= check_box_tag 'document[deleted_attachment_ids][]',
28
                        attachment.id,
29
                        @document.deleted_attachment_ids.include?(attachment.id),
30
                        :id => nil, :class => "deleted_attachment" %>&nbsp;<%= l(:button_delete) %>
31
    </label>
32
  </span>
33
  <% end %>
34
  <hr />
22 35
</div>
23 36
<% end %>
37
<div id="new-attachments" style="display:inline-block;">
38
  <%= render :partial => 'attachments/form', :locals => {:container => @document} %>
39
</div>
40
</fieldset>
41
</div>
test/functional/documents_controller_test.rb
224 224
  end
225 225

  
226 226
  def test_update
227
    set_tmp_attachments_directory
227 228
    @request.session[:user_id] = 2
228
    put(
229
      :update,
230
      :params => {
231
        :id => 1,
232
        :document => {
233
          :title => 'test_update'
229
    assert_difference 'Attachment.count' do
230
      put(
231
        :update,
232
        :params => {
233
          :id => 1,
234
          :document => {
235
            :title => 'test_update'
236
          },
237
          :attachments => {
238
            '1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}
239
          }
234 240
        }
235
      }
236
    )
241
      )
242
    end
237 243
    assert_redirected_to '/documents/1'
238 244
    document = Document.find(1)
239 245
    assert_equal 'test_update', document.title
240 246
  end
241 247

  
242 248
  def test_update_with_failure
249
    set_tmp_attachments_directory
243 250
    @request.session[:user_id] = 2
244
    put(
245
      :update,
246
      :params => {
247
        :id => 1,
248
        :document => {
249
          :title => ''
251
    assert_no_difference 'Attachment.count' do
252
      put(
253
        :update,
254
        :params => {
255
          :id => 1,
256
          :document => {
257
            :title => ''
258
          },
259
          :attachments => {
260
            '1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}
261
          }
250 262
        }
251
      }
252
    )
263
      )
264
    end
253 265
    assert_response :success
254 266
    assert_select_error /title cannot be blank/i
255 267
  end
256 268

  
269
  def test_update_with_deleted_attachment_ids
270
    set_tmp_attachments_directory
271
    @request.session[:user_id] = 2
272
    document = Document.find(1)
273
    attachment = document.attachments.first
274
    assert_difference 'Attachment.count', -1 do
275
      put(
276
        :update,
277
        :params => {
278
          :id => 1,
279
          :document => {
280
            :title => 'test_update',
281
            :deleted_attachment_ids => [attachment.id]
282
          }
283
        }
284
      )
285
    end
286
    document.reload
287
    assert_not_includes document.attachments, attachment
288
  end
289

  
290
  def test_update_with_deleted_attachment_ids_and_failure_should_preserve_selected_attachments
291
    set_tmp_attachments_directory
292
    @request.session[:user_id] = 2
293
    document = Document.find(1)
294
    attachment = document.attachments.first
295
    assert_no_difference 'Attachment.count' do
296
      put(
297
        :update,
298
        :params => {
299
          :id => 1,
300
          :document => {
301
            :title => '',
302
            :deleted_attachment_ids => [attachment.id]
303
          }
304
        }
305
      )
306
    end
307
    document.reload
308
    assert_includes document.attachments, attachment
309
  end
310

  
257 311
  def test_destroy
258 312
    set_tmp_attachments_directory
259 313
    @request.session[:user_id] = 2
(4-4/4)