doi_extractor 1.0.5

Sign up to get free protection for your applications and to get access to all the features.
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,3 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <testsuite name="DoiExtractor::DownloadCommand" tests="0" time="0.000123" skipped="0" timestamp="2017-09-12T12:47:53-05:00">
3
+ </testsuite>
@@ -0,0 +1,11 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <testsuite name="DoiExtractor::DownloadLocation" tests="4" time="0.021346" failures="0" errors="0" skipped="0" timestamp="2017-09-12T12:47:53-05:00">
3
+ <testcase name="DoiExtractor::DownloadLocation calculates extract request paths" time="0.000391">
4
+ </testcase>
5
+ <testcase name="DoiExtractor::DownloadLocation can create itself" time="0.000702">
6
+ </testcase>
7
+ <testcase name="DoiExtractor::DownloadLocation creates and clears the tmp path" time="0.000797">
8
+ </testcase>
9
+ <testcase name="DoiExtractor::DownloadLocation packages up downloaded extract files" time="0.018921">
10
+ </testcase>
11
+ </testsuite>
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <testsuite name="DoiExtractor::IpumsClient" tests="2" time="0.005526" failures="0" errors="0" skipped="0" timestamp="2017-09-12T12:47:53-05:00">
3
+ <testcase name="DoiExtractor::IpumsClient handles HTTP 422" time="0.002534">
4
+ </testcase>
5
+ <testcase name="DoiExtractor::IpumsClient handles HTTP 500" time="0.002482">
6
+ </testcase>
7
+ </testsuite>
@@ -0,0 +1,5 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <testsuite name="DoiExtractor::IpumsUriBuilder internal environment" tests="1" time="0.000353" failures="0" errors="0" skipped="0" timestamp="2017-09-12T12:47:53-05:00">
3
+ <testcase name="DoiExtractor::IpumsUriBuilder internal environment builds correct urls" time="0.000117">
4
+ </testcase>
5
+ </testsuite>
@@ -0,0 +1,5 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <testsuite name="DoiExtractor::IpumsUriBuilder live environment" tests="1" time="0.000317" failures="0" errors="0" skipped="0" timestamp="2017-09-12T12:47:53-05:00">
3
+ <testcase name="DoiExtractor::IpumsUriBuilder live environment builds correct urls" time="0.000186">
4
+ </testcase>
5
+ </testsuite>
@@ -0,0 +1,5 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <testsuite name="DoiExtractor::IpumsUriBuilder local environment" tests="1" time="0.000334" failures="0" errors="0" skipped="0" timestamp="2017-09-12T12:47:53-05:00">
3
+ <testcase name="DoiExtractor::IpumsUriBuilder local environment builds correct urls" time="0.000127">
4
+ </testcase>
5
+ </testsuite>
@@ -0,0 +1,3 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <testsuite name="DoiExtractor::IpumsUriBuilder" tests="0" time="6.6e-05" skipped="0" timestamp="2017-09-12T12:47:53-05:00">
3
+ </testsuite>
@@ -0,0 +1,5 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <testsuite name="DoiExtractor::Options.for_command with create command with invalid doi version" tests="1" time="0.000343" failures="0" errors="0" skipped="0" timestamp="2017-09-12T12:47:53-05:00">
3
+ <testcase name="DoiExtractor::Options.for_command with create command with invalid doi version is not valid" time="0.000167">
4
+ </testcase>
5
+ </testsuite>
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <testsuite name="DoiExtractor::Options.for_command with create command" tests="2" time="0.000517" failures="0" errors="0" skipped="0" timestamp="2017-09-12T12:47:53-05:00">
3
+ <testcase name="DoiExtractor::Options.for_command with create command returns the right class" time="0.000158">
4
+ </testcase>
5
+ <testcase name="DoiExtractor::Options.for_command with create command sets the attributes" time="0.000162">
6
+ </testcase>
7
+ </testsuite>
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <testsuite name="DoiExtractor::Options.for_command with download command" tests="2" time="0.000534" failures="0" errors="0" skipped="0" timestamp="2017-09-12T12:47:53-05:00">
3
+ <testcase name="DoiExtractor::Options.for_command with download command returns the right class" time="0.00013">
4
+ </testcase>
5
+ <testcase name="DoiExtractor::Options.for_command with download command sets the attributes" time="0.000134">
6
+ </testcase>
7
+ </testsuite>
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <testsuite name="DoiExtractor::Options.for_command with status command" tests="2" time="0.000515" failures="0" errors="0" skipped="0" timestamp="2017-09-12T12:47:53-05:00">
3
+ <testcase name="DoiExtractor::Options.for_command with status command returns the right class" time="0.000128">
4
+ </testcase>
5
+ <testcase name="DoiExtractor::Options.for_command with status command sets the attributes" time="0.000122">
6
+ </testcase>
7
+ </testsuite>
@@ -0,0 +1,3 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <testsuite name="DoiExtractor::Options.for_command" tests="0" time="5.0e-05" skipped="0" timestamp="2017-09-12T12:47:53-05:00">
3
+ </testsuite>
@@ -0,0 +1,9 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <testsuite name="DoiExtractor::Options when setting path values" tests="3" time="0.000766" failures="0" errors="0" skipped="0" timestamp="2017-09-12T12:47:53-05:00">
3
+ <testcase name="DoiExtractor::Options when setting path values defaults the base path" time="0.000145">
4
+ </testcase>
5
+ <testcase name="DoiExtractor::Options when setting path values allows overriding the base path" time="0.000137">
6
+ </testcase>
7
+ <testcase name="DoiExtractor::Options when setting path values does not allow an empty base path" time="0.000143">
8
+ </testcase>
9
+ </testsuite>
@@ -0,0 +1,5 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <testsuite name="DoiExtractor::Options" tests="1" time="0.000294" failures="0" errors="0" skipped="0" timestamp="2017-09-12T12:47:53-05:00">
3
+ <testcase name="DoiExtractor::Options defaults to basic auth creds on internal env" time="0.000171">
4
+ </testcase>
5
+ </testsuite>
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <testsuite name="DoiExtractor::Secrets" tests="2" time="0.003972" failures="0" errors="0" skipped="0" timestamp="2017-09-12T12:47:53-05:00">
3
+ <testcase name="DoiExtractor::Secrets reads the api password" time="0.003576">
4
+ </testcase>
5
+ <testcase name="DoiExtractor::Secrets overrides correctly" time="0.000128">
6
+ </testcase>
7
+ </testsuite>
@@ -0,0 +1,5 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <testsuite name="DoiExtractor::StatusCommand" tests="1" time="0.004027" failures="0" errors="0" skipped="0" timestamp="2017-09-12T12:47:53-05:00">
3
+ <testcase name="DoiExtractor::StatusCommand generates some output" time="0.003642">
4
+ </testcase>
5
+ </testsuite>
@@ -0,0 +1,20 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'simplecov'
4
+ require 'simplecov-rcov'
5
+
6
+ SimpleCov.formatter = SimpleCov::Formatter::RcovFormatter
7
+ SimpleCov.start do
8
+ add_filter '/spec/'
9
+ add_filter '/vendor/bundle'
10
+ end
11
+
12
+ require 'rspec'
13
+ require 'webmock/rspec'
14
+ require File.expand_path('../../lib/doi_extractor', __FILE__)
15
+
16
+ Dir[File.expand_path('../support/**/*', __FILE__)].each { |f| require f }
17
+
18
+ RSpec.configure do |config|
19
+
20
+ end
@@ -0,0 +1,36 @@
1
+ class TestInput
2
+
3
+ AskAnswer = Struct.new(:question, :answer)
4
+
5
+ attr_reader :answers
6
+ attr_reader :history
7
+
8
+ def initialize(answers = {})
9
+ @answers = answers
10
+ @history = []
11
+ end
12
+
13
+ def add_answer(msg_match, answer)
14
+ answers[msg_match] = answer
15
+ end
16
+
17
+ def asked?(msg)
18
+ history.any? { |h| msg === h.question }
19
+ end
20
+
21
+ def call(msg)
22
+ a = answers.detect do |k, v|
23
+ k === msg
24
+ end
25
+
26
+ value = a ? a[1] : nil
27
+
28
+ if value && value.respond_to?(:call)
29
+ value = value.call
30
+ end
31
+
32
+ history << AskAnswer.new(msg, value)
33
+ value
34
+ end
35
+
36
+ end
@@ -0,0 +1,28 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe DoiExtractor::CancelCommand do
4
+
5
+ let(:options) { DoiExtractor::Options.for_command('cancel', project: 'cps', environment: 'local', api_password: 'abc123', force: true, extract_group_id: 1).tap {|o| o.validate } }
6
+ let(:output) { StringIO.new }
7
+ let(:command) { DoiExtractor::CancelCommand.new(options, output) }
8
+
9
+ let(:get_url) { 'http://localhost:3003/cps-action/api/extracts/v1/extract_request_groups/1' }
10
+ let(:cancel_url) { 'http://localhost:3003/cps-action/api/extracts/v1/extract_request_groups/1/cancel' }
11
+
12
+ context 'when successful' do
13
+
14
+ let!(:get_stub) { stub_request(:get, get_url).to_return(body: '{"id": 1, "status": "submitted"}') }
15
+ let!(:cancel_stub) { stub_request(:post, cancel_url).to_return(body: '{"id": 1, "status": "cancelled"}') }
16
+
17
+ it 'makes two API calls' do
18
+ command.execute
19
+ expect(get_stub).to have_been_requested.times(1)
20
+ expect(cancel_stub).to have_been_requested.times(1)
21
+ end
22
+
23
+ it 'writes to sdtout' do
24
+ command.execute
25
+ expect(output.string).to match /complete/i
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,68 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe DoiExtractor::CommandLineParser do
4
+
5
+ shared_examples 'command_examples' do |name, extra_flags = []|
6
+ let(:parser) { DoiExtractor::CommandLineParser.parse([name] + %w(-p cps -e live) + extra_flags) }
7
+
8
+ it 'should be valid' do
9
+ expect(parser.valid?).to eq true
10
+ end
11
+
12
+ it "should contain options" do
13
+ expect(parser.options).to be_a DoiExtractor::Options
14
+ end
15
+
16
+ it 'should set options attributes' do
17
+ expect(parser.options.command).to eq name
18
+ expect(parser.options.project).to eq 'cps'
19
+ expect(parser.options.environment).to eq 'live'
20
+ end
21
+ end
22
+
23
+ context 'with a valid create command' do
24
+ include_examples 'command_examples', 'create', %w(-v 1.1)
25
+ end
26
+
27
+ context 'with a valid create command with email' do
28
+ include_examples 'command_examples', 'create', %w(-v 1.2 -E roland@tet.com)
29
+
30
+ it 'should set the email option' do
31
+ puts parser.options.inspect
32
+ expect(parser.options.email).to eq 'roland@tet.com'
33
+ end
34
+ end
35
+
36
+ context 'with a valid status command' do
37
+ include_examples 'command_examples', 'status', %w(-i 1)
38
+ end
39
+
40
+ context 'with a valid download command' do
41
+ include_examples 'command_examples', 'download', %w(-i 1)
42
+ end
43
+
44
+ context 'with an invalid command' do
45
+ let(:parser) { DoiExtractor::CommandLineParser.parse(%w(invalid -p cps)) }
46
+
47
+ it 'should not be valid' do
48
+ expect(parser.valid?).to eq false
49
+ end
50
+
51
+ it 'should have a reasonable error message' do
52
+ expect(parser.to_s).to match(/invalid\s+command/i)
53
+ end
54
+
55
+ it 'should not have any options' do
56
+ expect(parser.options).to be_nil
57
+ end
58
+ end
59
+
60
+ context 'with an unknown option' do
61
+ let(:parser) { DoiExtractor::CommandLineParser.parse(%w(status -p cps -e live -x extra))}
62
+
63
+ it 'should not be valid' do
64
+ expect(parser.valid?).to eq false
65
+ end
66
+ end
67
+
68
+ end
@@ -0,0 +1,44 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe DoiExtractor::CreateCommand do
4
+
5
+ let(:options) { DoiExtractor::Options.for_command('create', project: 'cps', environment: 'local', api_password: 'abc123').tap {|o| o.validate } }
6
+ let(:output) { StringIO.new }
7
+ let(:command) { DoiExtractor::CreateCommand.new(options, output) }
8
+
9
+ let(:recent_url) { 'http://localhost:3003/cps-action/api/extracts/v1/extract_request_groups/recent?type=doi' }
10
+ let(:create_url) { 'http://localhost:3003/cps-action/api/extracts/v1/extract_request_groups' }
11
+
12
+ context 'when successful' do
13
+
14
+ let!(:recent_stub) { stub_request(:get, recent_url).to_return(body: '[]') }
15
+ let!(:create_stub) { stub_request(:post, create_url).to_return(body: '{"id": 1, "status": "empty", "doi_version": "1.1", "year": "2017", "extract_requests": [{"id": 10}, {"id": 11}]}') }
16
+
17
+ it 'makes 2 API calls' do
18
+ command.execute
19
+ expect(recent_stub).to have_been_requested.times(1)
20
+ expect(create_stub).to have_been_requested.times(1)
21
+ end
22
+
23
+ it 'writes to sdtout' do
24
+ command.execute
25
+ expect(output.string).to match /doi extract with id \d+ submitted./im
26
+ end
27
+ end
28
+
29
+ context 'when an existing extract is processing' do
30
+ let!(:recent_stub) { stub_request(:get, recent_url).to_return(body: '[{"id": 1, "status": "submitted"}]') }
31
+ let!(:create_stub) { stub_request(:post, create_url) }
32
+
33
+ it 'makes 1 API call' do
34
+ command.execute rescue DoiExtractor::CommandFailError
35
+ expect(recent_stub).to have_been_requested.times(1)
36
+ expect(create_stub).not_to have_been_requested
37
+ end
38
+
39
+ it 'raises a CommandFailError' do
40
+ expect { command.execute }.to raise_error DoiExtractor::CommandFailError
41
+ end
42
+ end
43
+
44
+ end
@@ -0,0 +1,139 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe DoiExtractor::DownloadCommand do
4
+
5
+ let(:base_path) { File.expand_path(File.dirname(__FILE__) + '/../testdata/') }
6
+ let(:path) { File.join(base_path, '2017_v1.1') }
7
+ let(:options) { DoiExtractor::Options.for_command('download', project: 'cps', environment: 'local', extract_group_id: 1, api_password: 'abc123', download_base_path: base_path, force: true).tap {|o| o.validate } }
8
+ let(:output) { StringIO.new }
9
+ let(:input) { TestInput.new }
10
+ let(:command) { DoiExtractor::DownloadCommand.new(options, output, input) }
11
+
12
+ let(:complete_extract_group_json) {
13
+ {
14
+ id: 1,
15
+ year: '2017',
16
+ doi_version: '1.1',
17
+ status: 'complete',
18
+ all_data_available: true,
19
+ citation: 'this is a citation',
20
+ codebook_extract: {id: 40, extract_file_name: 'cps_004.dat.gz', samples: [{id: 100, name: '1990a'}, {id: 200, name: '2000a'}, {id: 300, name: '2010a'}], files: [{filename: 'cps_004.cbk', ext: 'cbk'}, {filename: 'cps_004.xml', ext: 'xml'}]},
21
+ extract_requests: [
22
+ {id: 10, extract_file_name: 'cps_001.dat.gz', samples: [{id: 100, name: '1990a'}], files: [{filename: 'cps_001.dat.gz', ext: 'dat.gz'}, {filename: 'cps_001.cbk', ext: 'cbk'}, {filename: 'cps_001.xml', ext: 'xml'}]},
23
+ {id: 20, extract_file_name: 'cps_002.dat.gz', samples: [{id: 200, name: '2000a'}], files: [{filename: 'cps_002.dat.gz', ext: 'dat.gz'}, {filename: 'cps_002.cbk', ext: 'cbk'}, {filename: 'cps_002.xml', ext: 'xml'}]},
24
+ {id: 30, extract_file_name: 'cps_003.dat.gz', samples: [{id: 300, name: '2010a'}], files: [{filename: 'cps_003.dat.gz', ext: 'dat.gz'}, {filename: 'cps_003.cbk', ext: 'cbk'}, {filename: 'cps_003.xml', ext: 'xml'}]}
25
+ ]
26
+ }
27
+ }
28
+
29
+ let(:submitted_extract_group_json) {
30
+ {
31
+ id: 2,
32
+ year: '2017',
33
+ doi_version: '1.1',
34
+ status: 'submitted',
35
+ extract_requess: []
36
+ }
37
+ }
38
+
39
+ def stub_get_extract_group(id, group_json)
40
+ url = "http://localhost:3003/cps-action/api/extracts/v1/extract_request_groups/#{id}"
41
+ if group_json
42
+ stub_request(:get, url).to_return(body: JSON.dump(group_json))
43
+ else
44
+ stub_request(:get, url).to_return(status: 404)
45
+ end
46
+ end
47
+
48
+ before do
49
+ if Dir.exist?(path)
50
+ FileUtils.rm_rf(path)
51
+ end
52
+ end
53
+
54
+ context 'when an extract is available' do
55
+ let!(:get_stub) { stub_get_extract_group(1, complete_extract_group_json) }
56
+
57
+ def stub_file_download(er, f)
58
+ stub_request(:get, "http://localhost:3003/cps-action/api/extracts/v1/extract_requests/#{er[:id]}/file/#{f[:ext]}").to_return(body: f[:filename])
59
+ end
60
+
61
+ let!(:download_stubs) {
62
+ [].tap do |stubs|
63
+ complete_extract_group_json[:extract_requests].each do |er|
64
+ er[:files].each do |f|
65
+ stubs << stub_file_download(er, f)
66
+ end
67
+ end
68
+ stubs << stub_file_download(complete_extract_group_json[:codebook_extract], complete_extract_group_json[:codebook_extract][:files].last)
69
+ end
70
+ }
71
+
72
+ it 'executes all requests' do
73
+ command.execute
74
+ expect(get_stub).to have_been_requested.times(1)
75
+ download_stubs.each do |s|
76
+ expect(s).to have_been_requested.times(1)
77
+ end
78
+ end
79
+
80
+ it 'packages everything' do
81
+ command.execute
82
+ complete_extract_group_json[:extract_requests].each do |er|
83
+ s = er[:samples].first[:name]
84
+
85
+ expect(File.exist?(File.join(path, "#{s}.tar.gz"))).to be_truthy
86
+ end
87
+ expect(File.exist?(File.join(path, "summary.txt"))).to be_truthy
88
+ end
89
+
90
+ it 'adds the citation to the summary file' do
91
+ command.execute
92
+ txt = File.read(File.join(path, "summary.txt"))
93
+ expect(txt).to match /this is a citation/
94
+ end
95
+
96
+ it 'cleans up the tmp folder' do
97
+ command.execute
98
+ expect(File.exist?(File.join(path, 'tmp'))).to be_falsey
99
+ end
100
+
101
+ it 'does not prompt the user when forced it true' do
102
+ input.add_answer(/.*/, ->{ raise 'no asking' })
103
+ command.execute
104
+ end
105
+
106
+ context 'when force is not set' do
107
+ let(:options) { DoiExtractor::Options.for_command('download', project: 'cps', environment: 'local', extract_group_id: 1, api_password: 'abc123', download_base_path: base_path).tap {|o| o.validate } }
108
+
109
+ before do
110
+ input.add_answer(/download/, 'y')
111
+ end
112
+
113
+ it 'asks for user input' do
114
+ command.execute
115
+ expect(input.asked?(/download/)).to be_truthy
116
+ end
117
+ end
118
+ end
119
+
120
+ context 'user cancels download' do
121
+ let(:options) { DoiExtractor::Options.for_command('download', project: 'cps', environment: 'local', extract_group_id: 1, api_password: 'abc123', download_base_path: base_path, force: false).tap {|o| o.validate } }
122
+ let!(:get_stub) { stub_get_extract_group(1, complete_extract_group_json) }
123
+
124
+ before do
125
+ input.add_answer(/download/, 'n')
126
+ end
127
+
128
+ it 'asks for input' do
129
+ expect { command.execute }.to raise_error DoiExtractor::CommandFailError, /cancelled/
130
+ expect(input.asked?(/download/)).to be_truthy
131
+ end
132
+
133
+ it 'does not create the output path' do
134
+ expect { command.execute }.to raise_error DoiExtractor::CommandFailError, /cancelled/
135
+ expect(File.exist?(path)).to be_falsey
136
+ end
137
+ end
138
+
139
+ end