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

pulibrary / tigerdata-app / fee0bd05-a88f-42ea-b6f8-84481fc8ab67

20 May 2025 06:16PM UTC coverage: 85.846% (+0.7%) from 85.126%
fee0bd05-a88f-42ea-b6f8-84481fc8ab67

push

circleci

web-flow
Advancing XML Document generation for Projects (#1493)

* New ProjectXmlPresenter class

* Add Spec for ProjectXmlPresenter

* Beginning to implement the #to_xml method for the class ProjectXmlPresenter

Co-authored-by: Robert-Anthony Lee-Faison <leefaisonr@users.noreply.github.com>

* Implementing support for attributes on the <resource> root node

Co-authored-by: Robert-Anthony Lee-Faison <leefaisonr@users.noreply.github.com>

* Implementing the <title> element as the first child element of <resource>

Co-authored-by: Robert-Anthony Lee-Faison <leefaisonr@users.noreply.github.com>

* add description element

* Refactoring the ProjectXmlPresenter to use separate classes for XML document building

* Integrating a configuration file for building XML representations of Projects

* Ensuring that the <storagePerformance @approved> attribute value is delegated to the ProjectXmlPresenter and defaults to false

Co-authored-by: Robert-Anthony Lee-Faison <leefaisonr@users.noreply.github.com>

* Advancing the validation against the XSD by ensuring that XML elements are properly ordered

Co-authored-by: Robert-Anthony Lee-Faison <leefaisonr@users.noreply.github.com>

* Refactoring by introducing the following:
- Improving the speed for the test suites
- Fixing an order-related bug with the recursive building of XML trees
- Removing empty arguments from the config
- Renaming `message` to `object_method`
- Tracking the W3C XML schema in order to ensure that Nokogiri schema validation works properly
- Enabling the XSD schema document validation test case
- Ensuring that the config YAML file does not contain specify deployment environments
- Extending the test suites in order to advance XSD schema validation

* Ensuring that the XSD schema validation is now passing with default values returned by the Presenter

Co-authored-by: Robert-Anthony Lee-Faison <leefaisonr@users.noreply.github.com>

* Ensuring that the projectDirectoryPath entries have protocols in the upper... (continued)

4 of 4 branches covered (100.0%)

169 of 171 new or added lines in 4 files covered. (98.83%)

2796 of 3257 relevant lines covered (85.85%)

498.46 hits per line

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

97.85
/app/presenters/project_xml_presenter.rb
1
# frozen_string_literal: true
2
class ProjectXmlPresenter
1✔
3
  attr_reader :project, :project_metadata
1✔
4

5
  # Delegate methods to the project and project_metadata objects
6
  delegate "id", "in_mediaflux?", "mediaflux_id", "pending?", "status", "title", to: :project
1✔
7
  delegate(
1✔
8
    "description",
9
    "data_manager", "data_sponsor",
10
    "data_user_read_only", "data_user_read_write",
11
    "departments",
12
    "project_id",
13
    "project_purpose",
14
    "storage_capacity", "storage_performance_expectations",
15
    "created_by", "created_on",
16
    "updated_by", "updated_on",
17
    "approval_note",
18
    "schema_version",
19
    # "submission",
20
    to: :project_metadata
21
  )
22

23
  # @return [String] The default directory protocol
24
  def self.default_directory_protocol
1✔
25
    "NFS"
36✔
26
  end
27

28
  # @return [String] The default project resource type
29
  def self.default_project_resource_type
1✔
30
    "TigerData Project"
37✔
31
  end
32

33
  # @return [String] The default HPC value
34
  def self.default_hpc
1✔
35
    "No"
37✔
36
  end
37

38
  # @return [String] The default project visibility
39
  def self.default_project_visibility
1✔
40
    "Restricted"
36✔
41
  end
42

43
  # @param project [Project] The project for the presenter
44
  def initialize(project)
1✔
45
    @project = project
36✔
46
    @project_metadata = @project.metadata_model
36✔
47
  end
48

49
  # @return [Nokogiri::XML::Document] The XML document
50
  def document
1✔
51
    @document ||= build_xml.document
36✔
52
  end
53

54
  # @return [Boolean] Whether the request for a Globus mount is approved
55
  def globus_enable_approved?
1✔
56
    false
111✔
57
  end
58

59
  # @return [Boolean] Whether there is a request for a Globus mount
60
  def globus_enable_requested?
1✔
61
    false
37✔
62
  end
63

64
  # @return [Boolean] Whether the request for the SMB mount is approved
65
  def smb_enable_approved?
1✔
66
    false
111✔
67
  end
68

69
  # @return [Boolean] Whether there is a request for SMB mount
70
  def smb_enable_requested?
1✔
71
    false
37✔
72
  end
73

74
  # @return [String] The project status
75
  def status
1✔
76
    "Active"
36✔
77
  end
78

79
  # @return [ProvenanceEvent] The first project submission event
80
  def submission
1✔
81
    @submission ||= project.provenance_events.find_by(event_type: ProvenanceEvent::SUBMISSION_EVENT_TYPE)
110✔
82
  end
83

84
  # @return [Array<ProvenanceEvent>] The project submission events
85
  def submissions
1✔
86
    [submission]
36✔
87
  end
88

89
  # @return [String] The user ID of the user who requested the project
90
  def requested_by
1✔
91
    submission.event_person
37✔
92
  end
93

94
  # @return [String] The date and time of the request
95
  def request_date_time
1✔
96
    value = submission.created_at
37✔
97
    value.strftime("%Y-%m-%dT%H:%M:%S%:z")
37✔
98
  end
99

100
  # @return [String] The user ID of the user who approved the project
101
  def approved_by
1✔
102
    "abdc12"
37✔
103
  end
104

105
  # @return [String] The date and time of the approval
106
  def approval_date_time
1✔
107
    "2025-03-28T15:34:11-04:00"
37✔
108
  end
109

110
  # @return [String] Whether or not the project data use agreement
111
  def data_use_agreement?
1✔
112
    false
37✔
113
  end
114

115
  # @return [String] The project resource type
116
  def project_resource_type
1✔
117
    self.class.default_project_resource_type
37✔
118
  end
119

120
  # @return [Boolean] Whether the project is provisional
121
  def provisional_project?
1✔
122
    false
37✔
123
  end
124

125
  # @return [String] Whether or not the project is associated with HPC
126
  def hpc
1✔
127
    self.class.default_hpc
37✔
128
  end
129

130
  # @return [String] The project visibility
131
  def project_visibility
1✔
132
    self.class.default_project_visibility
36✔
133
  end
134

135
  # @return [Boolean] Whether the project directory request is approved
136
  def project_directory_approved?
1✔
137
    false
36✔
138
  end
139

140
  # @return [Boolean] Whether the project storage capacity request is approved
141
  def storage_capacity_approved?
1✔
142
    false
36✔
143
  end
144

145
  # @return [Boolean] Whether the project storage request is approved
146
  def storage_performance_approved?
1✔
147
    false
36✔
148
  end
149

150
  # @return [Array<String>] The project directory paths
151
  def project_directory
1✔
152
    [project_metadata.project_directory]
110✔
153
  end
154

155
  # @param index [Integer] The index of the project directory
156
  # @return [String] The project directory path
157
  def project_directory_path(index)
1✔
158
    entry = project_directory[index]
36✔
159
    entry
36✔
160
  end
161

162
  # @param index [Integer] The index of the project directory
163
  # @return [String] The protocol for the project directory
164
  def project_directory_protocol(index)
1✔
165
    entry = project_directory[index]
36✔
166
    segments = entry.split("://")
36✔
167

168
    if segments.length > 1
36✔
NEW
169
      value = segments[0]
×
NEW
170
      value.upcase
×
171
    else
172
      self.class.default_directory_protocol
36✔
173
    end
174
  end
175

176
  # @param index [Integer] The index of the department code to retrieve
177
  # @return [String] The department code for departments associated with the project
178
  def department(index)
1✔
179
    value = departments[index]
36✔
180
    if value.length < 6
36✔
181
      value = value.rjust(6, "0")
36✔
182
    end
183
    value
36✔
184
  end
185

186
  # @return [String] The department code for the project
187
  def department_code(index)
1✔
188
    departments[index]
36✔
189
  end
190

191
  # @return [String] The requested project storage capacity
192
  def requested_storage
1✔
193
    storage_performance_expectations[:requested] || nil
37✔
194
  end
195

196
  private
1✔
197

198
    def xml_builder_config
1✔
199
      Rails.configuration.xml_builder
72✔
200
    end
201

202
    def presenter_builder_config
1✔
203
      xml_builder_config[:project] || {}
72✔
204
    end
205

206
    def find_builder_args(key)
1✔
207
      raise "No builder config for #{key}" unless presenter_builder_config.key?(key)
36✔
208

209
      values = presenter_builder_config[key]
36✔
210
      values[:presenter] = self
36✔
211
      values
36✔
212
    end
213

214
    def xml_builder
1✔
215
      @xml_builder ||= begin
36✔
216
                         builder_args = find_builder_args(:resource)
36✔
217
                         XmlTreeBuilder.new(**builder_args)
36✔
218
                       end
219
    end
220

221
    def build_xml
1✔
222
      xml_builder.build
36✔
223
    end
224
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