• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

pulibrary / pdc_describe / 6b3b369b-d551-44b6-b079-2c4c0c73ff1a

12 Jul 2024 01:56PM UTC coverage: 95.856% (-0.02%) from 95.872%
6b3b369b-d551-44b6-b079-2c4c0c73ff1a

Pull #1848

circleci

jrgriffiniii
wip
Pull Request #1848: Ensuring that at least one file upload is provided for draft Works

3 of 3 new or added lines in 1 file covered. (100.0%)

1 existing line in 1 file now uncovered.

3285 of 3427 relevant lines covered (95.86%)

216.89 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

88.57
/app/controllers/works_wizard_controller.rb
1
# frozen_string_literal: true
2

3
require "nokogiri"
1✔
4
require "open-uri"
1✔
5

6
# Controller to handle wizard Mode when editing an work
7
#
8
# The wizard flow is shown in the [mermaid diagram here](https://github.com/pulibrary/pdc_describe/blob/main/docs/wizard_flow.md).
9

10
class WorksWizardController < ApplicationController
1✔
11
  include ERB::Util
1✔
12
  around_action :rescue_aasm_error, only: [:validate, :new_submission_save]
1✔
13

14
  before_action :load_work, only: [:edit_wizard, :update_wizard, :attachment_select, :attachment_selected,
1✔
15
                                   :file_upload, :file_uploaded, :file_other, :review, :validate,
16
                                   :readme_select, :readme_uploaded, :readme_uploaded_payload]
17

18
  # GET /works/1/edit-wizard
19
  def edit_wizard
1✔
20
    @wizard_mode = true
33✔
21
    if validate_modification_permissions(work: @work,
33✔
22
                                         uneditable_message: "Can not edit work: #{@work.id} is not editable by #{current_user.uid}",
23
                                         current_state_message: "Can not edit work: #{@work.id} is not editable in current state by #{current_user.uid}")
24

25
      prepare_decorators_for_work_form(@work)
32✔
26
    end
27
  end
28

29
  # PATCH /works/1/update-wizard
30
  def update_wizard
1✔
31
    edit_helper(:edit_wizard, work_update_additional_path(@work))
18✔
32
  end
33

34
  # Prompt to select how to submit their files
35
  # GET /works/1/attachment_select
36
  def attachment_select; end
1✔
37

38
  # User selected a specific way to submit their files
39
  # POST /works/1/attachment_selected
40
  def attachment_selected
1✔
41
    @work.files_location = params["attachment_type"]
21✔
42
    @work.save!
21✔
43

44
    # create a directory for the work if the curator will need to move files by hand
45
    @work.s3_query_service.create_directory if @work.files_location != "file_upload"
21✔
46

47
    if params[:save_only] == "true"
21✔
48
      render :attachment_select
4✔
49
    else
50
      redirect_to file_location_url
17✔
51
    end
52
  end
53

54
  # Allow user to upload files directly
55
  # GET /works/1/file_upload
56
  def file_upload
1✔
57
    @work_decorator = WorkDecorator.new(@work, current_user)
12✔
58
  end
59

60
  # POST /works/1/upload-files-wizard (called via Uppy)
61
  def upload_files
1✔
62
    @work = Work.find(params[:id])
×
63
    upload_service = WorkUploadsEditService.new(@work, current_user)
×
64
    upload_service.update_precurated_file_list(params["files"], [])
×
65
  end
66

67
  # POST /works/1/file_upload
68
  def file_uploaded
1✔
69
    upload_service = WorkUploadsEditService.new(@work, current_user)
14✔
70
    # By the time we hit this endpoint files have been uploaded by Uppy submmitting POST requests
71
    # to /works/1/upload-files-wizard therefore we only need to delete files here and update the upload snapshot.
72
    @work = upload_service.snapshot_uppy_and_delete_files(deleted_files_param)
14✔
73

74
    prepare_decorators_for_work_form(@work)
13✔
75
    if params[:save_only] == "true"
13✔
76
      render :file_upload
2✔
77
    else
78
      redirect_to(work_review_path)
11✔
79
    end
80
  rescue => ex
81
    # Notice that we log the URL (rather than @work.doi) because sometimes we are getting a nil @work.
82
    # The URL will include the ID and might help us troubleshoot the issue further if it happens again.
83
    # See https://github.com/pulibrary/pdc_describe/issues/1801
84
    error_message = "Failed to update work snapshot, URL: #{request.url}: #{ex}"
1✔
85
    Rails.logger.error(error_message)
1✔
86
    Honeybadger.notify(error_message)
1✔
87
    flash[:notice] = "Failed to update work snapshot, work: #{@work&.doi}: #{ex}. Please contact rdss@princeton.edu for assistance."
1✔
88

89
    redirect_to work_file_upload_path(@work)
1✔
90
  end
91

92
  # Allow user to indicate where their files are located in the WWW
93
  # GET /works/1/file_other
94
  def file_other; end
1✔
95

96
  # GET /works/1/review
97
  # POST /works/1/review
98
  def review
1✔
99
    if request.method == "POST" || request.method == "PATCH"
23✔
100
      @work.location_notes = params["location_notes"]
11✔
101
      @work.save!
11✔
102
      if params[:save_only] == "true"
11✔
103
        render :file_other
2✔
104
      end
105
    end
106
  end
107

108
  # Validates that the work is ready to be approved
109
  # POST /works/1/validate-wizard
110
  # PATCH /works/1/validate-wizard
111
  def validate
1✔
112
    @work.submission_notes = params["submission_notes"]
20✔
113

114
    if params[:save_only] == "true"
20✔
115
      @work.save
2✔
116
      render :review
2✔
117
    else
118
      @work.complete_submission!(current_user)
18✔
UNCOV
119
      redirect_to work_complete_path(@work.id)
×
120
    end
121
  end
122

123
  # Show the user the form to select a readme
124
  # GET /works/1/readme_select
125
  def readme_select
1✔
126
    readme = Readme.new(@work, current_user)
22✔
127
    @readme = readme.file_name
22✔
128
  end
129

130
  # Hit when the user clicks "Save" or "Next" on the README upload process.
131
  # Notice that this does not really uploads the file, that happens in readme_uploaded_payload.
132
  # PATCH /works/1/readme_uploaded
133
  def readme_uploaded
1✔
134
    readme = Readme.new(@work, current_user)
20✔
135
    if params[:save_only] == "true"
20✔
136
      @readme = readme.file_name
2✔
137
      render :readme_select
2✔
138
    else
139
      redirect_to work_attachment_select_url(@work)
18✔
140
    end
141
  end
142

143
  def files_param
1✔
144
    params["files"]
6✔
145
  end
146

147
  # Uploads the README file, called by Uppy.
148
  # POST /works/1/readme-uploaded-payload
149
  def readme_uploaded_payload
1✔
150
    raise StandardError("Only one README file can be uploaded.") if files_param.empty?
2✔
151
    raise StandardError("Only one README file can be uploaded.") if files_param.length > 1
2✔
152

153
    readme_file = files_param.first
2✔
154
    readme = Readme.new(@work, current_user)
2✔
155

156
    readme_error = readme.attach(readme_file)
2✔
157
    if readme_error.nil?
2✔
158
      render plain: readme.file_name
1✔
159
    else
160
      # Tell Uppy there was an error uploading the README
161
      render plain: readme.file_name, status: :internal_server_error
1✔
162
    end
163
  end
164

165
  def file_location_url
1✔
166
    WorkMetadataService.file_location_url(@work)
38✔
167
  end
168
  helper_method :file_location_url
1✔
169

170
  private
1✔
171

172
    def edit_helper(view_name, redirect_url)
1✔
173
      if validate_modification_permissions(work: @work,
34✔
174
                                           uneditable_message: "Can not update work: #{@work.id} is not editable by #{current_user.uid}",
175
                                           current_state_message: "Can not update work: #{@work.id} is not editable in current state by #{current_user.uid}")
176
        prepare_decorators_for_work_form(@work)
34✔
177
        if WorkCompareService.update_work(work: @work, update_params:, current_user:)
34✔
178
          if params[:save_only] == "true"
33✔
179
            render view_name
3✔
180
          else
181
            redirect_to redirect_url
30✔
182
          end
183
        else
184
          render view_name, status: :unprocessable_entity
1✔
185
        end
186
      end
187
    end
188

189
    def load_work
1✔
190
      @work = Work.find(params[:id])
249✔
191
    end
192

193
    def patch_params
1✔
194
      return {} unless params.key?(:patch)
×
195

196
      params[:patch]
×
197
    end
198

199
    def pre_curation_uploads_param
1✔
200
      return if patch_params.nil?
×
201

202
      patch_params[:pre_curation_uploads]
×
203
    end
204

205
    def deleted_files_param
1✔
206
      deleted_count = (params.dig("work", "deleted_files_count") || "0").to_i
14✔
207
      (1..deleted_count).map { |i| params.dig("work", "deleted_file_#{i}") }.select(&:present?)
17✔
208
    end
209

210
    def readme_file_param
1✔
211
      return if patch_params.nil?
×
212

213
      patch_params[:readme_file]
×
214
    end
215

216
    def rescue_aasm_error
1✔
217
      super
20✔
218
    rescue StandardError => generic_error
219
      redirect_to root_url, notice: "We apologize, an error was encountered: #{generic_error.message}. Please contact the PDC Describe administrators."
×
220
    end
221

222
    def redirect_aasm_error(transition_error_message)
1✔
223
      if @work.persisted?
18✔
224
        redirect_to edit_work_wizard_path(id: @work.id), notice: transition_error_message, params:
18✔
225
      else
226
        redirect_to work_create_new_submission_path(@work), notice: transition_error_message, params:
×
227
      end
228
    end
229
end
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc