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

pulibrary / pdc_describe / 35525209-8c8b-426d-b992-849111d800ff

02 Jun 2026 07:47PM UTC coverage: 41.528% (-54.0%) from 95.52%
35525209-8c8b-426d-b992-849111d800ff

Pull #2324

circleci

carolyncole
Updating code to allow for multiple WorkActivity classes based on the transition
Pull Request #2324: Updating code to allow for multiple WorkActivity classes based on the…

35 of 87 new or added lines in 6 files covered. (40.23%)

2096 existing lines in 79 files now uncovered.

1647 of 3966 relevant lines covered (41.53%)

4.81 hits per line

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

28.97
/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✔
UNCOV
20
    @wizard_mode = true
×
UNCOV
21
    if validate_modification_permissions(work: @work,
×
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

UNCOV
25
      prepare_decorators_for_work_form(@work)
×
26
    end
27
  end
28

29
  # PATCH /works/1/update-wizard
30
  def update_wizard
1✔
UNCOV
31
    edit_helper(:edit_wizard, work_update_additional_path(@work))
×
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✔
UNCOV
41
    @work.files_location = params["attachment_type"]
×
UNCOV
42
    @work.save!
×
43

UNCOV
44
    if params[:save_only] == "true"
×
UNCOV
45
      render :attachment_select
×
46
    else
UNCOV
47
      redirect_to file_location_url
×
48
    end
49
  end
50

51
  # Allow user to upload files directly
52
  # GET /works/1/file_upload
53
  def file_upload
1✔
UNCOV
54
    @work_decorator = WorkDecorator.new(@work, current_user)
×
55
  end
56

57
  # POST /works/1/upload-files-wizard (called via Uppy)
58
  def upload_files
1✔
59
    @work = Work.find(params[:id])
×
60
    upload_service = WorkUploadsEditService.new(@work, current_user)
×
61
    upload_service.update_precurated_file_list(params["files"], [])
×
62
    render plain: params["files"].map(&:original_filename).join(",")
×
63
  end
64

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

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

UNCOV
87
    redirect_to work_file_upload_path(@work)
×
88
  end
89

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

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

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

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

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

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

141
  def files_param
1✔
UNCOV
142
    params["files"]
×
143
  end
144

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

UNCOV
151
    readme_file = files_param.first
×
UNCOV
152
    readme = Readme.new(@work, current_user)
×
153

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

163
  def file_location_url
1✔
UNCOV
164
    WorkMetadataService.file_location_url(@work)
×
165
  end
166
  helper_method :file_location_url
1✔
167

168
  private
1✔
169

170
    # rubocop:disable Metrics/MethodLength
171
    def edit_helper(view_name, redirect_url)
1✔
UNCOV
172
      if validate_modification_permissions(work: @work,
×
173
                                           uneditable_message: "Can not update work: #{@work.id} is not editable by #{current_user.uid}",
174
                                           current_state_message: "Can not update work: #{@work.id} is not editable in current state by #{current_user.uid}")
UNCOV
175
        prepare_decorators_for_work_form(@work)
×
UNCOV
176
        check_for_stale_update(@work, params)
×
UNCOV
177
        if WorkCompareService.update_work(work: @work, update_params:, current_user:)
×
UNCOV
178
          if params[:save_only] == "true"
×
179
            # Make sure we render the updated data
UNCOV
180
            prepare_decorators_for_work_form(@work)
×
UNCOV
181
            render view_name
×
182
          else
UNCOV
183
            redirect_to redirect_url
×
184
          end
185
        else
186
          # return 200 so the loadbalancer doesn't capture the error
UNCOV
187
          render view_name
×
188
        end
189
      end
190
    end
191
    # rubocop:enable Metrics/MethodLength
192

193
    def load_work
1✔
UNCOV
194
      @work = Work.find(params[:id])
×
195
    end
196

197
    # @note No testing coverage but not a route, not called
198
    def patch_params
1✔
199
      return {} unless params.key?(:patch)
×
200

201
      params[:patch]
×
202
    end
203

204
    # @note No testing coverage but not a route, not called
205
    def pre_curation_uploads_param
1✔
206
      return if patch_params.nil?
×
207

208
      patch_params[:pre_curation_uploads]
×
209
    end
210

211
    def deleted_files_param
1✔
UNCOV
212
      deleted_count = (params.dig("work", "deleted_files_count") || "0").to_i
×
UNCOV
213
      (1..deleted_count).map { |i| params.dig("work", "deleted_file_#{i}") }.select(&:present?)
×
214
    end
215

216
    # @note No testing coverage but not a route, not called
217
    def readme_file_param
1✔
218
      return if patch_params.nil?
×
219

220
      patch_params[:readme_file]
×
221
    end
222

223
    def rescue_aasm_error
1✔
UNCOV
224
      super
×
225
    rescue StandardError => generic_error
226
      redirect_to root_url, notice: "We apologize, an error was encountered: #{generic_error.message}. Please contact the PDC Describe administrators."
×
227
    end
228

229
    def redirect_aasm_error(transition_error_message)
1✔
UNCOV
230
      if @work.persisted?
×
UNCOV
231
        redirect_to edit_work_wizard_path(id: @work.id), notice: transition_error_message, params:
×
232
      else
233
        redirect_to work_create_new_submission_path(@work), notice: transition_error_message, params:
×
234
      end
235
    end
236
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

© 2026 Coveralls, Inc