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

pulibrary / tigerdata-app / 0716167f-ab73-4e8b-922e-160b009f1109

04 Jun 2025 06:59PM UTC coverage: 85.904% (+0.1%) from 85.795%
0716167f-ab73-4e8b-922e-160b009f1109

push

circleci

web-flow
Refactoring ProjectXmlPresenter to ensure that certain XML Elements are not created when they are empty (#1515)

* Refactoring ProjectXmlPresenter to improve parsing for certain Project metadata values; Ensuring that certain XML elements cannot be created with empty content (these would otherwise invalidate the XML Document)

* Introducing some additional refactoring steps for the ProjectXmlPresenter

4 of 4 branches covered (100.0%)

149 of 156 new or added lines in 6 files covered. (95.51%)

1 existing line in 1 file now uncovered.

2968 of 3455 relevant lines covered (85.9%)

583.47 hits per line

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

94.69
/app/presenters/project_xml_presenter.rb
1
# frozen_string_literal: true
2

3
# rubocop:disable Metrics/ClassLength
4
class ProjectXmlPresenter
1✔
5
  attr_reader :project, :project_metadata
1✔
6

7
  # Delegate methods to the project and project_metadata objects
8
  delegate(
1✔
9
    "id",
10
    "in_mediaflux?",
11
    "mediaflux_id",
12
    "pending?",
13
    "title",
14
    to: :project
15
  )
16

17
  delegate(
1✔
18
    "approval_note",
19
    "description",
20
    "data_manager",
21
    "data_sponsor",
22
    "data_user_read_only",
23
    "data_user_read_write",
24
    "departments",
25
    "project_id",
26
    "project_purpose",
27
    "storage_capacity",
28
    "storage_performance_expectations",
29
    "created_by",
30
    "created_on",
31
    "updated_by",
32
    "updated_on",
33
    "schema_version",
34
    to: :project_metadata
35
  )
36

37
  # @param project [Project] The project for the presenter
38
  def initialize(project)
1✔
39
    @project = project
40✔
40
    @project_metadata = @project.metadata_model
40✔
41
  end
42

43
  # @return [Nokogiri::XML::Document] The XML document
44
  delegate :document, to: :build
1✔
45

46
  # @return [Boolean] Whether the request for a Globus mount is approved
47
  def globus_enable_approved?
1✔
48
    globus_request = project_metadata.globus_request
123✔
49
    globus_request[:approved] || false
123✔
50
  end
51

52
  # @return [String] Whether the request for a Globus mount is approved
53
  def globus_enable_approved
1✔
54
    if globus_enable_approved?
122✔
NEW
55
      "true"
×
56
    else
57
      "false"
122✔
58
    end
59
  end
60

61
  # @return [Boolean] Whether there is a request for a Globus mount
62
  def globus_enable_requested?
1✔
63
    globus_request = project_metadata.globus_request
41✔
64
    globus_request.present?
41✔
65
  end
66

67
  # @return [String] Whether the request for a Globus mount is requested
68
  def globus_enable_requested
1✔
69
    if globus_enable_requested?
41✔
70
      "true"
41✔
71
    else
NEW
72
      "false"
×
73
    end
74
  end
75

76
  # @return [Boolean] Whether the request for the SMB mount is approved
77
  def smb_enable_approved?
1✔
78
    smb_request = project_metadata.smb_request
123✔
79
    smb_request[:approved] || false
123✔
80
  end
81

82
  # @return [String] Whether the request for the SMB mount is approved
83
  def smb_enable_approved
1✔
84
    if smb_enable_approved?
80✔
NEW
85
      "true"
×
86
    else
87
      "false"
80✔
88
    end
89
  end
90

91
  # @return [Boolean] Whether there is a request for SMB mount
92
  def smb_enable_requested?
1✔
93
    smb_request = project_metadata.smb_request
41✔
94
    smb_request.present?
41✔
95
  end
96

97
  # @return [String] Whether the request for the SMB mount is requested
98
  def smb_enable_requested
1✔
99
    if smb_enable_requested?
40✔
100
      "true"
40✔
101
    else
NEW
102
      "false"
×
103
    end
104
  end
105

106
  # @return [String] The project status (mapped to values specified by the TigerData XML schema)
107
  # NOTE: Valid values are one of: 'AdminReview', 'Approved', 'Active', 'Retired', 'Published'
108
  def status
1✔
109
    project_status = project.status
40✔
110
    return if project_status.nil?
40✔
111

112
    return "AdminReview" if project_status == Project::PENDING_STATUS
40✔
113

114
    project_status.capitalize
4✔
115
  end
116

117
  # @return [ProvenanceEvent] The first project submission event
118
  def submission
1✔
119
    @submission ||= project.provenance_events.find_by(event_type: ProvenanceEvent::SUBMISSION_EVENT_TYPE)
196✔
120
  end
121

122
  # @return [Array<ProvenanceEvent>] The project submission events
123
  def submissions
1✔
124
    [submission]
40✔
125
  end
126

127
  # @return [String] The user ID of the user who requested the project
128
  def requested_by
1✔
129
    return if submission.nil?
41✔
130

131
    submission.event_person
37✔
132
  end
133

134
  # @return [String] The date and time of the request
135
  def request_date_time
1✔
136
    return if submission.nil?
41✔
137

138
    value = submission.created_at
37✔
139
    value.strftime("%Y-%m-%dT%H:%M:%S%:z")
37✔
140
  end
141

142
  # @return [String] The user ID of the user who approved the project
143
  def approved_by
1✔
144
    return if approval_note.nil?
41✔
145

146
    approval_note[:note_by]
3✔
147
  end
148

149
  # @return [String] The date and time of the approval
150
  def approval_date_time
1✔
151
    return nil if approval_note.nil?
41✔
152

153
    approval_note[:note_date_time]
3✔
154
  end
155

156
  # @return [String] Whether or not the project data use agreement
157
  def data_use_agreement?
1✔
158
    project_metadata.data_use_agreement.present?
41✔
159
  end
160

161
  # @return [String] The project resource type
162
  def project_resource_type
1✔
163
    project_metadata.resource_type
41✔
164
  end
165

166
  # @return [Boolean] Whether the project is provisional
167
  def provisional_project?
1✔
168
    project_metadata.provisional
41✔
169
  end
170

171
  # @return [String] Whether or not the project is associated with HPC
172
  delegate :hpc, to: :project_metadata
1✔
173

174
  # @return [String] The project visibility
175
  delegate :project_visibility, to: :project_metadata
1✔
176

177
  # @return [Boolean] Whether the project directory request is approved
178
  def project_directory_approved?
1✔
179
    expectations = storage_performance_expectations
40✔
180
    expectations[:approved] || false
40✔
181
  end
182

183
  # @return [Boolean] Whether the project storage capacity request is approved
184
  def storage_capacity_approved?
1✔
185
    storage_capacity_size = storage_capacity["size"] || {}
40✔
186
    return false unless storage_capacity_size.key?(:approved)
40✔
187

188
    approved_size = storage_capacity_size[:approved] || 0
2✔
189
    approved_size > 0
2✔
190
  end
191

192
  # @return [Boolean] Whether the project storage request is approved
193
  def storage_performance_requested?
1✔
194
    requested = storage_performance_expectations[:requested]
40✔
195
    requested.present?
40✔
196
  end
197

198
  # @return [Array<String>] The project directory paths
199
  def project_directory
1✔
200
    [project.project_directory]
122✔
201
  end
202

203
  # @param index [Integer] The index of the project directory
204
  # @return [String] The project directory path
205
  def project_directory_path(index)
1✔
206
    entry = project_directory[index]
40✔
207
    entry
40✔
208
  end
209

210
  # @param index [Integer] The index of the project directory
211
  # @return [String] The protocol for the project directory
212
  def project_directory_protocol(index)
1✔
213
    entry = project_directory[index]
40✔
214
    segments = entry.split("://")
40✔
215

216
    if segments.length > 1
40✔
217
      value = segments[0]
×
218
      value.upcase
×
219
    else
220
      ProjectMetadata.default_directory_protocol
40✔
221
    end
222
  end
223

224
  # @param index [Integer] The index of the department code to retrieve
225
  # @return [String] The department code for departments associated with the project
226
  def department(index)
1✔
227
    value = departments[index]
43✔
228
    if value.length < 6
43✔
229
      value = value.rjust(6, "0")
43✔
230
    end
231
    value
43✔
232
  end
233

234
  # @return [String] The department code for the project
235
  def department_code(index)
1✔
236
    departments[index]
43✔
237
  end
238

239
  # @return [String] The requested project storage capacity
240
  def requested_storage
1✔
241
    storage_performance_expectations[:requested] || nil
41✔
242
  end
243

244
  private
1✔
245

246
    def xml_builder_config
1✔
247
      Rails.configuration.xml_builder
80✔
248
    end
249

250
    def presenter_builder_config
1✔
251
      xml_builder_config[:project] || {}
80✔
252
    end
253

254
    def find_builder_args(key)
1✔
255
      raise "No builder config for #{key}" unless presenter_builder_config.key?(key)
40✔
256

257
      values = presenter_builder_config[key]
40✔
258
      values[:presenter] = self
40✔
259
      values
40✔
260
    end
261

262
    def builder
1✔
263
      @builder ||= begin
40✔
264
                     builder_args = find_builder_args(:resource)
40✔
265
                     XmlTreeBuilder.new(**builder_args)
40✔
266
                   end
267
    end
268

269
    delegate :build, to: :builder
1✔
270
end
271
# rubocop:enable Metrics/ClassLength
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