|
2 | 2 |
|
3 | 3 | describe BulkZombieUrlUploader do
|
4 | 4 | let(:filename) { 'test_file.csv' }
|
5 |
| - let(:filepath) { '/path/to/test_file.csv' } |
| 5 | + let(:filepath) { Rails.root.join('spec', 'fixtures', 'files', filename) } |
6 | 6 | let(:uploader) { described_class.new(filename, filepath) }
|
7 |
| - let(:results) { instance_double(BulkZombieUrls::Results) } |
8 |
| - let(:csv_content) do |
9 |
| - <<~CSV |
10 |
| - URL,DOC_ID |
11 |
| - http://example.com,doc1 |
12 |
| - ,doc2 |
13 |
| - http://missingdoc.com, |
14 |
| - CSV |
15 |
| - end |
| 7 | + let(:results_double) { instance_double('BulkZombieUrls::Results') } |
16 | 8 |
|
17 | 9 | before do
|
18 |
| - allow(File).to receive(:read).with(filepath).and_return(csv_content) |
19 |
| - allow(BulkZombieUrls::Results).to receive(:new).and_return(results) |
20 |
| - allow(results).to receive(:add_error) |
21 |
| - allow(results).to receive(:delete_ok) |
22 |
| - allow(results).to receive(:increment_updated) |
23 |
| - uploader.instance_variable_set(:@results, results) # Ensure `@results` is initialized |
| 10 | + allow(BulkZombieUrls::Results).to receive(:new).and_return(results_double) |
| 11 | + allow(results_double).to receive(:add_error) |
| 12 | + allow(results_double).to receive(:delete_ok) |
| 13 | + allow(results_double).to receive(:increment_updated) |
24 | 14 | end
|
25 | 15 |
|
26 | 16 | describe '#initialize' do
|
27 | 17 | it 'assigns filename and filepath' do
|
28 | 18 | expect(uploader.instance_variable_get(:@file_name)).to eq(filename)
|
29 | 19 | expect(uploader.instance_variable_get(:@file_path)).to eq(filepath)
|
| 20 | + expect(uploader.results).to be_nil |
30 | 21 | end
|
31 | 22 | end
|
32 | 23 |
|
33 |
| - describe '#upload_urls' do |
34 |
| - context 'with valid CSV content' do |
35 |
| - it 'processes each row in the CSV' do |
36 |
| - allow(uploader).to receive(:process_row) |
37 |
| - uploader.send(:upload_urls) |
38 |
| - expect(uploader).to have_received(:process_row).exactly(3).times |
| 24 | + describe '#upload' do |
| 25 | + subject { uploader.upload } |
| 26 | + |
| 27 | + before do |
| 28 | + allow(uploader).to receive(:initialize_results).and_call_original |
| 29 | + allow(uploader).to receive(:process_upload) |
| 30 | + allow(uploader).to receive(:log_upload_error) |
| 31 | + end |
| 32 | + |
| 33 | + it 'initializes results correctly' do |
| 34 | + expect { subject }.not_to raise_error |
| 35 | + end |
| 36 | + |
| 37 | + context 'when no error occurs' do |
| 38 | + it 'initializes results correctly' do |
| 39 | + expect { subject }.not_to raise_error |
39 | 40 | end
|
40 | 41 | end
|
41 | 42 |
|
42 |
| - context 'with invalid CSV content' do |
43 |
| - let(:csv_error) { CSV::MalformedCSVError.new('Invalid CSV format', 'Line causing error') } |
| 43 | + context 'when an error occurs' do |
| 44 | + let(:error) { StandardError.new('Test Error') } |
44 | 45 |
|
45 | 46 | before do
|
46 |
| - allow(CSV).to receive(:parse).and_raise(csv_error) |
47 |
| - allow(Rails.logger).to receive(:error) |
| 47 | + allow(uploader).to receive(:process_upload).and_raise(error) |
| 48 | + end |
| 49 | + |
| 50 | + it 'logs the upload error' do |
| 51 | + expect(uploader).to receive(:log_upload_error).with(error) |
| 52 | + subject |
48 | 53 | end
|
| 54 | + end |
| 55 | + end |
| 56 | + |
| 57 | + describe '#initialize_results' do |
| 58 | + subject { uploader.send(:initialize_results) } |
| 59 | + |
| 60 | + it 'initializes the @results object' do |
| 61 | + expect { subject }.not_to raise_error |
| 62 | + expect(uploader.instance_variable_get(:@results)).to eq(results_double) |
| 63 | + end |
| 64 | + end |
| 65 | + |
| 66 | + describe '#process_upload' do |
| 67 | + subject { uploader.send(:process_upload) } |
| 68 | + |
| 69 | + let(:csv_content) { "URL,DOC_ID\nhttp://example.com,123\n" } |
| 70 | + let(:parsed_csv) { CSV.parse(csv_content, headers: true) } |
| 71 | + |
| 72 | + before do |
| 73 | + allow(File).to receive(:read).with(filepath).and_return(csv_content) |
| 74 | + allow(CSV).to receive(:parse).and_return(parsed_csv) |
| 75 | + allow(uploader).to receive(:process_row) |
| 76 | + end |
| 77 | + |
| 78 | + it 'parses the CSV and processes each row' do |
| 79 | + expect(CSV).to receive(:parse).and_return(parsed_csv) |
| 80 | + expect(uploader).to receive(:process_row).with(parsed_csv.first) |
| 81 | + subject |
| 82 | + end |
| 83 | + end |
| 84 | + |
| 85 | + describe '#parse_csv' do |
| 86 | + subject { uploader.send(:parse_csv) } |
| 87 | + |
| 88 | + let(:csv_content) { "URL,DOC_ID\nhttp://example.com,123\n" } |
| 89 | + |
| 90 | + before do |
| 91 | + allow(File).to receive(:read).with(filepath).and_return(csv_content) |
| 92 | + end |
| 93 | + |
| 94 | + context 'with valid CSV headers' do |
| 95 | + it 'returns parsed CSV' do |
| 96 | + expect(subject).to be_a(CSV::Table) |
| 97 | + end |
| 98 | + end |
49 | 99 |
|
50 |
| - it 'handles the CSV error and logs it' do |
51 |
| - expect(results).to receive(:add_error).with('Invalid CSV format', 'Entire file') |
52 |
| - uploader.send(:upload_urls) |
53 |
| - expect(Rails.logger).to have_received(:error).with(/Error parsing CSV/) |
| 100 | + context 'with missing headers' do |
| 101 | + let(:csv_content) { "INVALID_HEADER\nhttp://example.com\n" } |
| 102 | + |
| 103 | + it 'raises a CSV::MalformedCSVError' do |
| 104 | + expect { subject }.to raise_error(CSV::MalformedCSVError) |
54 | 105 | end
|
55 | 106 | end
|
56 | 107 | end
|
57 | 108 |
|
58 | 109 | describe '#process_row' do
|
59 |
| - let(:row) { { 'URL' => 'http://example.com', 'DOC_ID' => 'doc1' } } |
| 110 | + subject { uploader.send(:process_row, row) } |
| 111 | + |
| 112 | + let(:row) { { 'URL' => 'http://example.com', 'DOC_ID' => '123' } } |
| 113 | + |
| 114 | + context 'when @results is not initialized' do |
| 115 | + before do |
| 116 | + uploader.instance_variable_set(:@results, nil) |
| 117 | + end |
| 118 | + |
| 119 | + it 'raises an error' do |
| 120 | + expect { subject }.to raise_error(BulkZombieUrlUploader::Error, 'Results object not initialized') |
| 121 | + end |
| 122 | + end |
60 | 123 |
|
61 |
| - context 'when DOC_ID is blank' do |
62 |
| - let(:row) { { 'URL' => 'http://example.com', 'DOC_ID' => nil } } |
| 124 | + context 'when @results is initialized' do |
| 125 | + before do |
| 126 | + uploader.send(:initialize_results) |
| 127 | + end |
63 | 128 |
|
64 |
| - it 'adds an error and logs it' do |
65 |
| - allow(Rails.logger).to receive(:error) |
66 |
| - uploader.send(:process_row, row) |
67 |
| - expect(results).to have_received(:add_error).with('Document ID is missing', 'http://example.com') |
68 |
| - expect(Rails.logger).to have_received(:error).with(/Document ID is mandatory/) |
| 129 | + it 'does not raise an error' do |
| 130 | + expect { subject }.not_to raise_error |
69 | 131 | end
|
70 | 132 | end
|
71 | 133 | end
|
72 | 134 |
|
73 |
| - describe '#process_url_with_rescue' do |
74 |
| - let(:row) { { 'URL' => 'http://example.com', 'DOC_ID' => 'doc1' } } |
| 135 | + describe '#handle_url_processing' do |
| 136 | + subject { uploader.send(:handle_url_processing, url, document_id, row) } |
75 | 137 |
|
76 |
| - before do |
77 |
| - allow(uploader).to receive(:process_url) |
| 138 | + let(:url) { 'http://example.com' } |
| 139 | + let(:document_id) { '123' } |
| 140 | + let(:row) { { 'URL' => url, 'DOC_ID' => document_id } } |
| 141 | + |
| 142 | + context 'when no error occurs' do |
| 143 | + before do |
| 144 | + allow(uploader).to receive(:process_url_with_rescue) |
| 145 | + allow(uploader).to receive(:update_results) |
| 146 | + end |
| 147 | + |
| 148 | + it 'processes the URL and updates results' do |
| 149 | + expect(uploader).to receive(:process_url_with_rescue).with(url, document_id) |
| 150 | + expect(uploader).to receive(:update_results) |
| 151 | + subject |
| 152 | + end |
78 | 153 | end
|
79 | 154 |
|
80 |
| - it 'processes the URL and updates results' do |
81 |
| - uploader.send(:process_url_with_rescue, 'http://example.com', 'doc1', row) |
82 |
| - expect(results).to have_received(:delete_ok) |
83 |
| - expect(results).to have_received(:increment_updated) |
| 155 | + context 'when an error occurs' do |
| 156 | + let(:error) { StandardError.new('Test Error') } |
| 157 | + |
| 158 | + before do |
| 159 | + allow(uploader).to receive(:process_url_with_rescue).and_raise(error) |
| 160 | + allow(uploader).to receive(:handle_processing_error) |
| 161 | + end |
| 162 | + |
| 163 | + it 'handles processing error' do |
| 164 | + expect(uploader).to receive(:handle_processing_error).with(error, url, document_id, row) |
| 165 | + subject |
| 166 | + end |
| 167 | + end |
| 168 | + end |
| 169 | + |
| 170 | + describe '#process_url' do |
| 171 | + subject { uploader.send(:process_url, url, document_id) } |
| 172 | + |
| 173 | + let(:document_id) { '123' } |
| 174 | + |
| 175 | + context 'when URL is present' do |
| 176 | + let(:url) { 'http://example.com' } |
| 177 | + |
| 178 | + before do |
| 179 | + allow(uploader).to receive(:process_url_with_searchgov) |
| 180 | + end |
| 181 | + |
| 182 | + it 'processes URL with Searchgov' do |
| 183 | + expect(uploader).to receive(:process_url_with_searchgov).with(url, document_id) |
| 184 | + subject |
| 185 | + end |
84 | 186 | end
|
85 | 187 |
|
86 |
| - context 'when an error occurs during processing' do |
87 |
| - let(:error) { StandardError.new('Processing error') } |
| 188 | + context 'when URL is blank' do |
| 189 | + let(:url) { nil } |
88 | 190 |
|
89 | 191 | before do
|
90 |
| - allow(uploader).to receive(:process_url).and_raise(error) |
91 |
| - allow(Rails.logger).to receive(:error) |
| 192 | + allow(uploader).to receive(:delete_document) |
92 | 193 | end
|
93 | 194 |
|
94 |
| - it 'handles the error and logs it' do |
95 |
| - uploader.send(:process_url_with_rescue, 'http://example.com', 'doc1', row) |
96 |
| - expect(results).to have_received(:add_error).with('Processing error', 'http://example.com') |
97 |
| - expect(Rails.logger).to have_received(:error).with(/Failure to process bulk upload zombie URL row/) |
| 195 | + it 'deletes the document' do |
| 196 | + expect(uploader).to receive(:delete_document).with(document_id) |
| 197 | + subject |
98 | 198 | end
|
99 | 199 | end
|
100 | 200 | end
|
|
0 commit comments