doi_extractor 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +54 -0
  3. data/Capfile +34 -0
  4. data/Gemfile +6 -0
  5. data/README.md +50 -0
  6. data/Rakefile +43 -0
  7. data/bin/doi_extractor +18 -0
  8. data/config/deploy.rb +34 -0
  9. data/config/deploy/production.rb +65 -0
  10. data/doi_extractor.gemspec +29 -0
  11. data/lib/doi_extractor.rb +25 -0
  12. data/lib/doi_extractor/cancel_command.rb +24 -0
  13. data/lib/doi_extractor/command.rb +81 -0
  14. data/lib/doi_extractor/command_line_parser.rb +154 -0
  15. data/lib/doi_extractor/create_command.rb +32 -0
  16. data/lib/doi_extractor/download_command.rb +109 -0
  17. data/lib/doi_extractor/download_location.rb +86 -0
  18. data/lib/doi_extractor/errors.rb +34 -0
  19. data/lib/doi_extractor/ipums_client.rb +159 -0
  20. data/lib/doi_extractor/ipums_uri_builder.rb +51 -0
  21. data/lib/doi_extractor/old_ruby_patch.rb +25 -0
  22. data/lib/doi_extractor/options.rb +132 -0
  23. data/lib/doi_extractor/secrets.rb +18 -0
  24. data/lib/doi_extractor/status_command.rb +62 -0
  25. data/lib/doi_extractor/version.rb +3 -0
  26. data/spec/fixtures/api_creds.yml +2 -0
  27. data/spec/reports/SPEC-DoiExtractor-CancelCommand-when-successful.xml +7 -0
  28. data/spec/reports/SPEC-DoiExtractor-CancelCommand.xml +3 -0
  29. data/spec/reports/SPEC-DoiExtractor-CommandLineParser-with-a-valid-create-command-with-email.xml +14 -0
  30. data/spec/reports/SPEC-DoiExtractor-CommandLineParser-with-a-valid-create-command.xml +9 -0
  31. data/spec/reports/SPEC-DoiExtractor-CommandLineParser-with-a-valid-download-command.xml +9 -0
  32. data/spec/reports/SPEC-DoiExtractor-CommandLineParser-with-a-valid-status-command.xml +9 -0
  33. data/spec/reports/SPEC-DoiExtractor-CommandLineParser-with-an-invalid-command.xml +9 -0
  34. data/spec/reports/SPEC-DoiExtractor-CommandLineParser-with-an-unknown-option.xml +5 -0
  35. data/spec/reports/SPEC-DoiExtractor-CommandLineParser.xml +3 -0
  36. data/spec/reports/SPEC-DoiExtractor-CreateCommand-when-an-existing-extract-is-processing.xml +7 -0
  37. data/spec/reports/SPEC-DoiExtractor-CreateCommand-when-successful.xml +7 -0
  38. data/spec/reports/SPEC-DoiExtractor-CreateCommand.xml +3 -0
  39. data/spec/reports/SPEC-DoiExtractor-DownloadCommand-user-cancels-download.xml +7 -0
  40. data/spec/reports/SPEC-DoiExtractor-DownloadCommand-when-an-extract-is-available-when-force-is-not-set.xml +5 -0
  41. data/spec/reports/SPEC-DoiExtractor-DownloadCommand-when-an-extract-is-available.xml +13 -0
  42. data/spec/reports/SPEC-DoiExtractor-DownloadCommand.xml +3 -0
  43. data/spec/reports/SPEC-DoiExtractor-DownloadLocation.xml +11 -0
  44. data/spec/reports/SPEC-DoiExtractor-IpumsClient.xml +7 -0
  45. data/spec/reports/SPEC-DoiExtractor-IpumsUriBuilder-internal-environment.xml +5 -0
  46. data/spec/reports/SPEC-DoiExtractor-IpumsUriBuilder-live-environment.xml +5 -0
  47. data/spec/reports/SPEC-DoiExtractor-IpumsUriBuilder-local-environment.xml +5 -0
  48. data/spec/reports/SPEC-DoiExtractor-IpumsUriBuilder.xml +3 -0
  49. data/spec/reports/SPEC-DoiExtractor-Options-for-command-with-create-command-with-invalid-doi-version.xml +5 -0
  50. data/spec/reports/SPEC-DoiExtractor-Options-for-command-with-create-command.xml +7 -0
  51. data/spec/reports/SPEC-DoiExtractor-Options-for-command-with-download-command.xml +7 -0
  52. data/spec/reports/SPEC-DoiExtractor-Options-for-command-with-status-command.xml +7 -0
  53. data/spec/reports/SPEC-DoiExtractor-Options-for-command.xml +3 -0
  54. data/spec/reports/SPEC-DoiExtractor-Options-when-setting-path-values.xml +9 -0
  55. data/spec/reports/SPEC-DoiExtractor-Options.xml +5 -0
  56. data/spec/reports/SPEC-DoiExtractor-Secrets.xml +7 -0
  57. data/spec/reports/SPEC-DoiExtractor-StatusCommand.xml +5 -0
  58. data/spec/spec_helper.rb +20 -0
  59. data/spec/support/test_input.rb +36 -0
  60. data/spec/unit/cancel_command_spec.rb +28 -0
  61. data/spec/unit/command_line_parser_spec.rb +68 -0
  62. data/spec/unit/create_command_spec.rb +44 -0
  63. data/spec/unit/download_command_spec.rb +139 -0
  64. data/spec/unit/download_location_spec.rb +71 -0
  65. data/spec/unit/ipums_client_spec.rb +23 -0
  66. data/spec/unit/ipums_uri_builder_spec.rb +26 -0
  67. data/spec/unit/options_spec.rb +86 -0
  68. data/spec/unit/secrets_spec.rb +14 -0
  69. data/spec/unit/status_command_spec.rb +46 -0
  70. metadata +282 -0
@@ -0,0 +1,51 @@
1
+ module DoiExtractor
2
+ class IpumsUriBuilder
3
+
4
+ IpumsConfig = Struct.new(:base_domain, :live_prefix, :action_name)
5
+
6
+ CONFIGS = {
7
+ ahtus: IpumsConfig.new('ahtusdata.org', 'www.'),
8
+ atus: IpumsConfig.new('atusdata.org', 'www.'),
9
+ cps: IpumsConfig.new('cps.ipums.org'),
10
+ dhs: IpumsConfig.new('idhsdata.org', 'www.', 'idhs'),
11
+ highered: IpumsConfig.new('highered.ipums.org'),
12
+ nhis: IpumsConfig.new('nhis.ipums.org'),
13
+ ipumsi: IpumsConfig.new('international.ipums.org', nil, 'international'),
14
+ mtus: IpumsConfig.new('mtusdata.org', 'www.'),
15
+ napp: IpumsConfig.new('nappdata.org', 'www.'),
16
+ usa: IpumsConfig.new('usa.ipums.org'),
17
+ }
18
+
19
+ attr_reader :project, :environment, :config
20
+
21
+ def initialize(project, environment)
22
+ @project = project.to_sym
23
+ @environment = environment.to_sym
24
+ @config = CONFIGS[@project]
25
+ end
26
+
27
+ def protocol
28
+ environment == :local ? 'http' : 'https'
29
+ end
30
+
31
+ def domain
32
+ case environment
33
+ when :local
34
+ 'localhost:3003'
35
+ when :live
36
+ config.live_prefix.to_s + config.base_domain
37
+ else
38
+ environment.to_s + '.' + config.base_domain
39
+ end
40
+ end
41
+
42
+ def path
43
+ (config.action_name || project).to_s + '-action'
44
+ end
45
+
46
+ def url
47
+ "#{protocol}://#{domain}/#{path}"
48
+ end
49
+
50
+ end
51
+ end
@@ -0,0 +1,25 @@
1
+
2
+ if RUBY_VERSION.start_with?('1.9')
3
+
4
+ # Previous to 2.0 ruby doesn't define the index methods on OpenStruct. These are used in the IpumsClient when parsing
5
+ # json into OpenStruct objects.
6
+ class OpenStruct
7
+ def [](key)
8
+ self.send(key.to_sym)
9
+ end
10
+
11
+ def []=(key, value)
12
+ self.send("#{key}=".to_sym, value)
13
+ end
14
+ end
15
+
16
+ # 1.9 doesn't implement the 422 http code
17
+ module Net
18
+ class HTTPUnprocessableEntity < HTTPClientError
19
+ HAS_BODY = true
20
+ end
21
+
22
+ HTTPResponse::CODE_TO_OBJ['422'] = HTTPUnprocessableEntity
23
+ end
24
+
25
+ end
@@ -0,0 +1,132 @@
1
+ module DoiExtractor
2
+ class Options
3
+
4
+ PROJECTS = %w(ahtus atus cps dhs highered nhis ipumsi mtus napp usa)
5
+ ENVIRONMENTS = %w(local demo internal staging live)
6
+ COMMANDS = %w(create download status cancel)
7
+
8
+ OPTIONS = [
9
+ :command,
10
+ :verbose,
11
+ :environment,
12
+ :project,
13
+ :api_uri,
14
+ :api_username,
15
+ :api_password,
16
+ :download_base_path,
17
+ :doi_version,
18
+ :year,
19
+ :email,
20
+ :force,
21
+ :extract_group_id
22
+ ]
23
+
24
+ def self.for_command(cmd, attrs = nil)
25
+ if COMMANDS.include? cmd
26
+ new({command: cmd}.merge(attrs || {}))
27
+ else
28
+ raise 'Invalid Command'
29
+ end
30
+ end
31
+
32
+ attr_reader :errors
33
+ attr_accessor *OPTIONS
34
+
35
+ def initialize(attrs = nil)
36
+ assign_attrs(attrs, OPTIONS)
37
+ end
38
+
39
+ def validate
40
+ @errors = []
41
+
42
+ if environment.nil?
43
+ self.environment = 'live'
44
+ end
45
+
46
+ if !COMMANDS.include?(command)
47
+ errors << 'Invalid Command'
48
+ end
49
+
50
+ if !ENVIRONMENTS.include?(environment)
51
+ errors << 'Invalid Environment'
52
+ end
53
+
54
+ if !PROJECTS.include?(project)
55
+ errors << 'Invalid Project'
56
+ end
57
+
58
+ # if command, env or project are invalid, stop performing further validation
59
+ return if errors.any?
60
+
61
+ self.api_uri = calculate_api_uri if api_uri.nil?
62
+ errors << 'Missing API URI' if self.api_uri.nil?
63
+
64
+ # For demo, internal, and staging envs, use the basic auth creds by default
65
+ if %w(demo internal staging).include?(environment)
66
+ self.api_username ||= 'hcp'
67
+ self.api_password ||= '1234'
68
+ end
69
+
70
+ if command == 'create'
71
+ self.year ||= Time.now.year.to_s
72
+
73
+ if self.year !~ /^\d{4}$/
74
+ errors << 'Year must be a 4 digit year'
75
+ end
76
+
77
+ if m = /[vV]?(\d+\.\d+)/.match(self.doi_version)
78
+ self.doi_version = m[1]
79
+ else
80
+ errors << 'DOI version is required and must match the pattern VX.X'
81
+ end
82
+ end
83
+
84
+ if %w(download status).include?(command)
85
+ self.download_base_path ||= calculate_download_base_path
86
+
87
+ if self.download_base_path.nil? || self.download_base_path.strip.empty?
88
+ errors << 'Unable to determine download base path'
89
+ end
90
+ end
91
+
92
+ if %w(download cancel).include?(command)
93
+ unless self.extract_group_id
94
+ errors << 'Missing extract request group id'
95
+ end
96
+ end
97
+ end
98
+
99
+ def valid?
100
+ validate
101
+ errors.empty?
102
+ end
103
+
104
+ private
105
+
106
+ def calculate_api_uri
107
+ if project && environment
108
+ IpumsUriBuilder.new(project, environment).url
109
+ else
110
+ nil
111
+ end
112
+ end
113
+
114
+ def calculate_download_base_path
115
+ if project && environment
116
+ # "/pkg/ipums/programming/#{project}/#{environment}"
117
+ "/pkg/ipums/programming/doi_extractor/temp_archive/#{project}/#{environment}"
118
+ else
119
+ nil
120
+ end
121
+ end
122
+
123
+ def assign_attrs(attrs, known_keys)
124
+ if attrs
125
+ known_keys.each do |k|
126
+ self.send("#{k}=", attrs[k]) if attrs[k]
127
+ end
128
+ end
129
+ end
130
+ end
131
+ end
132
+
@@ -0,0 +1,18 @@
1
+ module DoiExtractor
2
+ class Secrets
3
+ DEFAULT_API_PATH = '/pkg/mpctools/secrets/api_creds.yml'
4
+ DEFAULT_API_USERNAME = 'terrapop' # 'doi_extractor'
5
+
6
+ attr_reader :api_path, :api_username, :api_password
7
+
8
+ def initialize(overrides = {})
9
+ @api_path = overrides[:api_path] || DEFAULT_API_PATH
10
+ @api_username = overrides[:api_username] || DEFAULT_API_USERNAME
11
+ @api_password = overrides[:api_password] || read_yaml(@api_path)[@api_username]
12
+ end
13
+
14
+ def read_yaml(path)
15
+ YAML.load(ERB.new(IO.read(path)).result)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,62 @@
1
+ module DoiExtractor
2
+ class StatusCommand < Command
3
+
4
+ def _execute
5
+ if options.extract_group_id
6
+ report_group(options.extract_group_id)
7
+ else
8
+ report_recent
9
+ end
10
+ end
11
+
12
+ def report_group(id)
13
+ doi_extract = ipums_client.get_doi_extract(id)
14
+
15
+ unless doi_extract
16
+ fail("no extract for #{id} found")
17
+ end
18
+
19
+ location = DownloadLocation.new(options.download_base_path, doi_extract)
20
+
21
+ say_doi_summary(doi_extract, location)
22
+ say("Extract Requests:")
23
+
24
+ fmt = '%-10s%25s%20s%12s'
25
+
26
+ say(sprintf(fmt.sub('i', 's'), 'ID', 'Status', 'Sample', 'Downloaded'))
27
+ doi_extract.extract_requests.each do |er|
28
+ say(sprintf(fmt, er.id, er.completion_status, er.samples.first.name, location.complete_extract_request?(er)))
29
+ end
30
+
31
+ end
32
+
33
+ def report_recent
34
+ recent = ipums_client.recent_doi_extracts
35
+
36
+ if recent.nil? || recent.empty?
37
+ say("There are no DOI extracts")
38
+ else
39
+ recent.each do |doi|
40
+ location = DownloadLocation.new(options.download_base_path, doi)
41
+ say_doi_summary(doi, location)
42
+ say("\tExtracts: #{doi.extract_requests.count}")
43
+ end
44
+ end
45
+ end
46
+
47
+ def say_doi_summary(doi_extract, location)
48
+ count_hsh = Hash.new { |h, k| h[k] = 0 }
49
+ extract_counts = doi_extract.extract_requests.reduce(count_hsh) { |h, e| h[e.completion_status] += 1; h }
50
+
51
+ say("DOI Extract (ID: #{doi_extract.id})")
52
+ say("\tStatus: #{doi_extract.status}")
53
+ say("\tSubmitted: #{doi_extract.submit_date}")
54
+ say("\tFinished: #{doi_extract.finish_date}")
55
+ say("\tData Available: #{doi_extract.all_data_available}")
56
+ say("\tPath: #{location.path}")
57
+ say("\tExtract Counts: #{extract_counts.map { |k, v| "#{k}: #{v}" }.join(', ')}")
58
+ say("\tDownloaded: #{doi_extract.extract_requests.any? && doi_extract.extract_requests.all? { |er| location.complete_extract_request?(er) }}")
59
+ end
60
+
61
+ end
62
+ end
@@ -0,0 +1,3 @@
1
+ module DoiExtractor
2
+ VERSION = '1.0.5'
3
+ end
@@ -0,0 +1,2 @@
1
+ terrapop: testPassword
2
+ doi_extractor: testPassword
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <testsuite name="DoiExtractor::CancelCommand when successful" tests="2" time="0.01088" failures="0" errors="0" skipped="0" timestamp="2017-09-12T12:47:52-05:00">
3
+ <testcase name="DoiExtractor::CancelCommand when successful makes two API calls" time="0.005551">
4
+ </testcase>
5
+ <testcase name="DoiExtractor::CancelCommand when successful writes to sdtout" time="0.004845">
6
+ </testcase>
7
+ </testsuite>
@@ -0,0 +1,3 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <testsuite name="DoiExtractor::CancelCommand" tests="0" time="0.000107" skipped="0" timestamp="2017-09-12T12:47:52-05:00">
3
+ </testsuite>
@@ -0,0 +1,14 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <testsuite name="DoiExtractor::CommandLineParser with a valid create command with email" tests="4" time="0.009902" failures="0" errors="0" skipped="0" timestamp="2017-09-12T12:47:53-05:00">
3
+ <testcase name="DoiExtractor::CommandLineParser with a valid create command with email should be valid" time="0.002419">
4
+ </testcase>
5
+ <testcase name="DoiExtractor::CommandLineParser with a valid create command with email should contain options" time="0.002116">
6
+ </testcase>
7
+ <testcase name="DoiExtractor::CommandLineParser with a valid create command with email should set options attributes" time="0.002968">
8
+ </testcase>
9
+ <testcase name="DoiExtractor::CommandLineParser with a valid create command with email should set the email option" time="0.00192">
10
+ </testcase>
11
+ <system-out>
12
+ #&lt;DoiExtractor::Options:0x007ff44e85cdd0 @command="create", @environment="live", @project="cps", @errors=[], @api_uri="https://cps.ipums.org/cps-action", @doi_version="1.2", @year="2017", @email="roland@tet.com"&gt;
13
+ </system-out>
14
+ </testsuite>
@@ -0,0 +1,9 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <testsuite name="DoiExtractor::CommandLineParser with a valid create command" tests="3" time="0.010797" failures="0" errors="0" skipped="0" timestamp="2017-09-12T12:47:52-05:00">
3
+ <testcase name="DoiExtractor::CommandLineParser with a valid create command should be valid" time="0.003975">
4
+ </testcase>
5
+ <testcase name="DoiExtractor::CommandLineParser with a valid create command should contain options" time="0.003727">
6
+ </testcase>
7
+ <testcase name="DoiExtractor::CommandLineParser with a valid create command should set options attributes" time="0.002684">
8
+ </testcase>
9
+ </testsuite>
@@ -0,0 +1,9 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <testsuite name="DoiExtractor::CommandLineParser with a valid download command" tests="3" time="0.007531" failures="0" errors="0" skipped="0" timestamp="2017-09-12T12:47:53-05:00">
3
+ <testcase name="DoiExtractor::CommandLineParser with a valid download command should be valid" time="0.00285">
4
+ </testcase>
5
+ <testcase name="DoiExtractor::CommandLineParser with a valid download command should contain options" time="0.00228">
6
+ </testcase>
7
+ <testcase name="DoiExtractor::CommandLineParser with a valid download command should set options attributes" time="0.001983">
8
+ </testcase>
9
+ </testsuite>
@@ -0,0 +1,9 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <testsuite name="DoiExtractor::CommandLineParser with a valid status command" tests="3" time="0.007673" failures="0" errors="0" skipped="0" timestamp="2017-09-12T12:47:53-05:00">
3
+ <testcase name="DoiExtractor::CommandLineParser with a valid status command should be valid" time="0.001887">
4
+ </testcase>
5
+ <testcase name="DoiExtractor::CommandLineParser with a valid status command should contain options" time="0.001957">
6
+ </testcase>
7
+ <testcase name="DoiExtractor::CommandLineParser with a valid status command should set options attributes" time="0.00351">
8
+ </testcase>
9
+ </testsuite>
@@ -0,0 +1,9 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <testsuite name="DoiExtractor::CommandLineParser with an invalid command" tests="3" time="0.013999" failures="0" errors="0" skipped="0" timestamp="2017-09-12T12:47:53-05:00">
3
+ <testcase name="DoiExtractor::CommandLineParser with an invalid command should not be valid" time="0.003411">
4
+ </testcase>
5
+ <testcase name="DoiExtractor::CommandLineParser with an invalid command should have a reasonable error message" time="0.003179">
6
+ </testcase>
7
+ <testcase name="DoiExtractor::CommandLineParser with an invalid command should not have any options" time="0.006824">
8
+ </testcase>
9
+ </testsuite>
@@ -0,0 +1,5 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <testsuite name="DoiExtractor::CommandLineParser with an unknown option" tests="1" time="0.005251" failures="0" errors="0" skipped="0" timestamp="2017-09-12T12:47:53-05:00">
3
+ <testcase name="DoiExtractor::CommandLineParser with an unknown option should not be valid" time="0.00477">
4
+ </testcase>
5
+ </testsuite>
@@ -0,0 +1,3 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <testsuite name="DoiExtractor::CommandLineParser" tests="0" time="6.8e-05" skipped="0" timestamp="2017-09-12T12:47:52-05:00">
3
+ </testsuite>
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <testsuite name="DoiExtractor::CreateCommand when an existing extract is processing" tests="2" time="0.005917" failures="0" errors="0" skipped="0" timestamp="2017-09-12T12:47:53-05:00">
3
+ <testcase name="DoiExtractor::CreateCommand when an existing extract is processing makes 1 API call" time="0.002311">
4
+ </testcase>
5
+ <testcase name="DoiExtractor::CreateCommand when an existing extract is processing raises a CommandFailError" time="0.003323">
6
+ </testcase>
7
+ </testsuite>
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <testsuite name="DoiExtractor::CreateCommand when successful" tests="2" time="0.01331" failures="0" errors="0" skipped="0" timestamp="2017-09-12T12:47:53-05:00">
3
+ <testcase name="DoiExtractor::CreateCommand when successful makes 2 API calls" time="0.008916">
4
+ </testcase>
5
+ <testcase name="DoiExtractor::CreateCommand when successful writes to sdtout" time="0.004134">
6
+ </testcase>
7
+ </testsuite>
@@ -0,0 +1,3 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <testsuite name="DoiExtractor::CreateCommand" tests="0" time="8.4e-05" skipped="0" timestamp="2017-09-12T12:47:53-05:00">
3
+ </testsuite>
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <testsuite name="DoiExtractor::DownloadCommand user cancels download" tests="2" time="0.008309" failures="0" errors="0" skipped="0" timestamp="2017-09-12T12:47:53-05:00">
3
+ <testcase name="DoiExtractor::DownloadCommand user cancels download asks for input" time="0.005059">
4
+ </testcase>
5
+ <testcase name="DoiExtractor::DownloadCommand user cancels download does not create the output path" time="0.002841">
6
+ </testcase>
7
+ </testsuite>
@@ -0,0 +1,5 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <testsuite name="DoiExtractor::DownloadCommand when an extract is available when force is not set" tests="1" time="0.060445" failures="0" errors="0" skipped="0" timestamp="2017-09-12T12:47:53-05:00">
3
+ <testcase name="DoiExtractor::DownloadCommand when an extract is available when force is not set asks for user input" time="0.060068">
4
+ </testcase>
5
+ </testsuite>
@@ -0,0 +1,13 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <testsuite name="DoiExtractor::DownloadCommand when an extract is available" tests="5" time="0.338937" failures="0" errors="0" skipped="0" timestamp="2017-09-12T12:47:53-05:00">
3
+ <testcase name="DoiExtractor::DownloadCommand when an extract is available executes all requests" time="0.081153">
4
+ </testcase>
5
+ <testcase name="DoiExtractor::DownloadCommand when an extract is available packages everything" time="0.069818">
6
+ </testcase>
7
+ <testcase name="DoiExtractor::DownloadCommand when an extract is available adds the citation to the summary file" time="0.064809">
8
+ </testcase>
9
+ <testcase name="DoiExtractor::DownloadCommand when an extract is available cleans up the tmp folder" time="0.060621">
10
+ </testcase>
11
+ <testcase name="DoiExtractor::DownloadCommand when an extract is available does not prompt the user when forced it true" time="0.061706">
12
+ </testcase>
13
+ </testsuite>