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

pulibrary / tigerdata-app / fa5427d1-c616-4db4-8869-6c67d0eea350

23 Jun 2025 06:40PM UTC coverage: 71.937% (-0.2%) from 72.107%
fa5427d1-c616-4db4-8869-6c67d0eea350

Pull #1533

circleci

jrgriffiniii
Introducing some additional refactoring steps for the ProjectXmlPresenter; Implements a route for retrieving the Mediaflux XML document for project metadata
Pull Request #1533: Implements a route for retrieving the Mediaflux XML document for project metadata

4 of 18 branches covered (22.22%)

4 of 15 new or added lines in 3 files covered. (26.67%)

18 existing lines in 2 files now uncovered.

2994 of 4162 relevant lines covered (71.94%)

485.82 hits per line

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

81.28
/app/controllers/projects_controller.rb
1
# frozen_string_literal: true
2
class ProjectsController < ApplicationController
1✔
3

4
  before_action :set_breadcrumbs
1✔
5

6
  def new
1✔
7
    add_breadcrumb("New Project Request")
16✔
8
    return build_new_project if current_user.eligible_sponsor?
16✔
9

10
    redirect_to dashboard_path
2✔
11
  end
12

13
  def project_params
1✔
UNCOV
14
    params.dup
×
15
  end
16

17
  def create
1✔
18
    metadata_params = params.dup
12✔
19
    metadata_params[:status] = Project::PENDING_STATUS
12✔
20
    metadata_params[:created_by] = current_user.uid
12✔
21
    metadata_params[:created_on] = Time.current.in_time_zone("America/New_York").iso8601
12✔
22
    project_metadata = ProjectMetadata.new_from_params(metadata_params)
12✔
23

24
    build_new_project # calling private method to build a new project and set a class variable @project
12✔
25
    project.create!(initial_metadata: project_metadata, user: current_user)
12✔
26
    if project.metadata_model.project_id != nil
12✔
27
      begin
28
        mailer = TigerdataMailer.with(project_id: project.id)
12✔
29
        message_delivery = mailer.project_creation
12✔
30
        message_delivery.deliver_later
12✔
31

32
        redirect_to project_confirmation_path(project)
11✔
33
      rescue StandardError => mailer_error
34
        raise(TigerData::MailerError, mailer_error)
2✔
35
      end
36
    else
UNCOV
37
      render :new
×
38
    end
39
  rescue TigerData::MailerError => mailer_error
40
    logger_message = "Error encountered creating the project #{project.id} as user #{current_user.email}"
2✔
41
    Rails.logger.error(logger_message)
2✔
42
    honeybadger_context = {
43
      current_user_email: current_user.email,
2✔
44
      project_id: project.id,
45
      project_metadata: project.metadata
46
    }
47
    Honeybadger.notify(mailer_error, context: honeybadger_context)
2✔
48

49
    error_message = "We are sorry, while the project was successfully created, an error was encountered which prevents the delivery of an e-mail message confirming this. Please know that this error has been logged, and shall be reviewed by members of RDSS."
2✔
50
    flash[:notice] = error_message
2✔
51

52
    render :new
2✔
53
  rescue StandardError => error
UNCOV
54
    logger_message = if project.persisted?
×
55
                      "Error encountered creating the project #{project.id} as user #{current_user.email}"
×
56
                     else
UNCOV
57
                      "Error encountered creating the project #{metadata_params[:title]} as user #{current_user.email}"
×
58
                     end
UNCOV
59
    Rails.logger.error(logger_message)
×
60
    honeybadger_context = {
UNCOV
61
      current_user_email: current_user.email,
×
62
      project_id: project.id,
63
      project_metadata: project.metadata
64
    }
UNCOV
65
    Honeybadger.notify(error, context: honeybadger_context)
×
66

UNCOV
67
    error_message = "We are sorry, the project was not successfully created, and an error was encountered which prevents the delivery of an e-mail message confirming this. Please know that this error has been logged, and shall be reviewed by members of RDSS promptly."
×
68

UNCOV
69
    flash[:notice] = error_message
×
70
    render :new
×
71
  end
72

73
  def details
1✔
74
    return if project.blank?
33✔
75

76
    add_breadcrumb(project.title, project_path)
32✔
77
    add_breadcrumb("Details")
32✔
78

79
    @departments = project.departments.join(", ")
32✔
80
    @project_metadata = project.metadata_model
32✔
81

82
    @data_sponsor = User.find_by(uid: @project_metadata.data_sponsor)
32✔
83
    @data_manager = User.find_by(uid: @project_metadata.data_manager)
32✔
84

85
    read_only_uids = @project_metadata.ro_users
32✔
86
    data_read_only_users = read_only_uids.map { |uid| ReadOnlyUser.find_by(uid:) }.reject(&:blank?)
48✔
87

88
    read_write_uids = @project_metadata.rw_users
32✔
89
    data_read_write_users = read_write_uids.map { |uid| User.find_by(uid:) }.reject(&:blank?)
44✔
90

91
    unsorted_data_users = data_read_only_users + data_read_write_users
32✔
92
    sorted_data_users = unsorted_data_users.sort_by { |u| u.family_name || u.uid }
60✔
93
    @data_users = sorted_data_users.uniq { |u| u.uid }
52✔
94
    user_model_names = @data_users.map(&:display_name_safe)
32✔
95
    @data_user_names = user_model_names.join(", ")
32✔
96

97
    @provenance_events = project.provenance_events.where.not(event_type: ProvenanceEvent::STATUS_UPDATE_EVENT_TYPE)
32✔
98

99
    @project_eligible_to_edit = true if project.status == Project::APPROVED_STATUS && eligible_editor?
32✔
100

101
    @project_metadata = @project.metadata
32✔
102
    @project_id = @project_metadata[:project_id] || {}
32✔
103
    @storage_capacity = @project_metadata[:storage_capacity]
32✔
104
    @size = @storage_capacity[:size]
32✔
105
    @unit = @storage_capacity[:unit]
32✔
106

107
    @requested_size = @size[:requested]
32✔
108
    @requested_unit = @unit[:requested]
32✔
109

110
    @approved_size = @size[:approved]
32✔
111
    @approved_unit = @unit[:approved]
32✔
112

113
    @storage_expectations = @project_metadata[:storage_performance_expectations]
32✔
114
    @requested_storage_expectations = @storage_expectations[:requested]
32✔
115
    @approved_storage_expectations = @storage_expectations[:approved]
32✔
116

117
    @project_purpose = @project_metadata[:project_purpose]
32✔
118

119

120
    @project_session = "details"
32✔
121

122

123
    respond_to do |format|
32✔
124
      format.html do
32✔
125
        @project = ProjectShowPresenter.new(project)
29✔
126
      end
127
      format.json do
32✔
128
        render json: project.to_json
2✔
129
      end
130
      format.xml do
32✔
131
        render xml: project.to_xml
1✔
132
      end
133
    end
134
  end
135

136
  def edit
1✔
137
    add_breadcrumb(project.title, project_path)
16✔
138
    add_breadcrumb("Edit")
16✔
139
    project
16✔
140
    if project.metadata_model.status != Project::APPROVED_STATUS
16✔
141
      flash[:notice] = "Pending projects can not be edited."
1✔
142
      redirect_to project
1✔
143
    elsif project.metadata_model.status == Project::APPROVED_STATUS && !eligible_editor? #check if the current user is a sponsor or a manager
15✔
144
      flash[:notice] = "Only data sponsors and data managers can revise this project."
2✔
145
      redirect_to project
2✔
146
    end
147
  end
148

149
  def update
1✔
150
    @project = Project.find(params[:id])
8✔
151
    #Approve action
152
    if params.key?("mediaflux_id")
8✔
153
      @project.metadata_model.update_with_params(params, current_user)
2✔
154
      @project.approve!(mediaflux_id: params["mediaflux_id"],current_user:)
2✔
155
    end
156

157
    #Edit action
158
    if params.key?("title")
8✔
159
      @project.metadata_model.status = @project.metadata_model.status || Project::PENDING_STATUS
6✔
160
      @project.metadata_model.update_with_params(params, current_user)
6✔
161
    end
162

163
    # @todo ProjectMetadata should be refactored to implement ProjectMetadata.valid?(updated_metadata)
164
    if project.save and params.key?("mediaflux_id")
8✔
165
      redirect_to project_approval_received_path(@project)
2✔
166
    elsif project.save and params.key?("title")
6✔
167
      redirect_to project_revision_confirmation_path(@project)
6✔
168
    else
UNCOV
169
      render :edit
×
170
    end
171
  end
172

173
  def index
1✔
174
    if current_user.eligible_sysadmin?
5✔
175
      @projects = Project.all
1✔
176
    else
177
      flash[:alert] = I18n.t(:access_denied)
4✔
178
      redirect_to dashboard_path
4✔
179
    end
180
  end
181

182
  def confirmation; end
1✔
183
  def revision_confirmation; end
1✔
184

185
  def show
1✔
186
    
187
    return if project.blank?
37✔
188
    add_breadcrumb(project.title, project_path)
36✔
189
    add_breadcrumb("Contents")
36✔
190

191
    @latest_completed_download = current_user.user_requests.where(project_id: @project.id, state: "completed").order(:completion_time).last
36✔
192
    @storage_usage = project.storage_usage(session_id: current_user.mediaflux_session)
36✔
193
    @storage_capacity = project.storage_capacity(session_id: current_user.mediaflux_session)
32✔
194

195
    @num_files = project.asset_count(session_id: current_user.mediaflux_session)
32✔
196

197
    @file_list = project.file_list(session_id: current_user.mediaflux_session, size: 100)
32✔
198
    @files = @file_list[:files]
32✔
199
    @files.sort_by!(&:path)
32✔
200
    @project = ProjectShowPresenter.new(project)
32✔
201

202
    @project_session = "content"
32✔
203
    respond_to do |format| 
32✔
204
      format.html { render }
62✔
205
      format.xml { render xml: @project.to_xml } 
34✔
206
    end 
207
  end
208

209
  # GET "projects/:id/:id-mf"
210
  #
211
  # This action is used to render the mediaflux metadata for a project.
212
  def show_mediaflux
1✔
NEW
213
    project_id = params[:id]
×
NEW
214
    project = Project.find(project_id)
×
215

NEW
216
    respond_to do |format|
×
NEW
217
      format.xml do
×
NEW
218
        render xml: project.mediaflux_meta_xml
×
219
      end
220
    end
221
  end
222

223
  def project_job_service
1✔
224
    @project_job_service ||= ProjectJobService.new(project:)
1✔
225
  end
226

227
  def list_contents
1✔
228
    return if project.blank?
2✔
229

230
    project_job_service.list_contents_job(user: current_user)
1✔
231

232
    json_response = {
233
      message: "File list for \"#{project.title}\" is being generated in the background. A link to the downloadable file list will be available in the \"Recent Activity\" section of your dashboard when it is available. You may safely navigate away from this page or close this tab."
1✔
234
    }
235
    render json: json_response
1✔
236
  rescue => ex
UNCOV
237
    message = "Error producing document list (project id: #{project&.id}): #{ex.message}"
×
238
    Rails.logger.error(message)
×
239
    Honeybadger.notify(message)
×
240
    render json: { message: "Document list could not be generated." }
×
241
  end
242

243
  def file_list_download
1✔
UNCOV
244
    job_id = params[:job_id]
×
245
    user_request = FileInventoryRequest.where(job_id:job_id).first
×
246
    if user_request.nil?
×
247
      # TODO: handle error
UNCOV
248
      redirect_to "/"
×
249
    else
UNCOV
250
      filename = user_request.output_file
×
251
      send_data File.read(filename), type: "text/plain", filename: "filelist.csv", disposition: "attachment"
×
252
    end
253
  end
254

255
  def approve
1✔
256
    if current_user.eligible_sysadmin?
7✔
257
      add_breadcrumb(project.title, project_path)
4✔
258
      add_breadcrumb("Approval Settings", project_approve_path)
4✔
259
      add_breadcrumb("Edit")
4✔
260
      project
4✔
261
      @departments = project.departments.join(", ")
4✔
262
      @project_metadata = project.metadata
4✔
263
      sponsor_uid = @project_metadata[:data_sponsor]
4✔
264
      @data_sponsor = User.find_by(uid: sponsor_uid)
4✔
265
      @provenance_events = project.provenance_events.where.not(event_type: ProvenanceEvent::STATUS_UPDATE_EVENT_TYPE)
4✔
266

267
      @title = @project_metadata["title"]
4✔
268
    else redirect_to dashboard_path
3✔
269
    end
270
  end
271

272
  def create_script
1✔
UNCOV
273
    project_id = params[:id]
×
274
    project = Project.find(project_id)
×
275
    service = MediafluxScriptFactory.new(project: project)
×
276
    respond_to do |format|
×
277
      format.json { render json: {script: service.aterm_script} }
×
278
    end
279
  end
280

281
  private
1✔
282

283
    def build_new_project
1✔
284
      @project ||= Project.new
26✔
285
    end
286

287
    def project
1✔
288
      @project ||= begin
619✔
289
        project = Project.find(params[:id])
90✔
290
        if project.user_has_access?(user: current_user)
90✔
291
          project
87✔
292
        else
293
          flash[:alert] = I18n.t(:access_denied)
3✔
294
          redirect_to dashboard_path
3✔
295
          nil
3✔
296
        end
297
      end
298
    end
299

300
    def eligible_editor?
1✔
301
      return true if current_user.eligible_sponsor? or current_user.eligible_manager?
22✔
302
    end
303

304
    def shared_file_location(filename)
1✔
UNCOV
305
      raise "Shared location is not configured" if Rails.configuration.mediaflux["shared_files_location"].blank?
×
306
      location = Pathname.new(Rails.configuration.mediaflux["shared_files_location"])
×
307
      location.join(filename).to_s
×
308
    end
309

310
    def set_breadcrumbs
1✔
311
      add_breadcrumb("Dashboard",dashboard_path)
149✔
312
    end
313
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