Skip to content

Commit ae429ed

Browse files
authored
Merge pull request #51 from didww/export-csv-gz-decompression-v2
Export csv gz decompression
2 parents 83d39a1 + 77dd8b0 commit ae429ed

5 files changed

Lines changed: 71 additions & 17 deletions

File tree

lib/didww/resource/export.rb

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# frozen_string_literal: true
22
require 'forwardable'
33
require 'down/http'
4+
require 'zlib'
5+
require 'stringio'
46
require 'didww/callback/const'
57

68
module DIDWW
@@ -52,11 +54,23 @@ def initialize(params = {})
5254
super params.reverse_merge(filters: {})
5355
end
5456

55-
def csv
57+
def download
5658
return unless url.present?
5759
Down::Http.new(headers: { 'Api-Key' => DIDWW::Client.api_key, 'X-DIDWW-API-Version' => DIDWW::Client.api_version }).open(url)
5860
end
5961

62+
def csv
63+
file = download
64+
return unless file
65+
gz = Zlib::GzipReader.new(file)
66+
begin
67+
StringIO.new(gz.read)
68+
ensure
69+
gz.close unless gz.closed?
70+
file.close if file.respond_to?(:close) && !file.closed?
71+
end
72+
end
73+
6074
def complete?
6175
status == STATUS_COMPLETED
6276
end

spec/didww/resources/export_spec.rb

Lines changed: 54 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -32,26 +32,27 @@
3232
end
3333
end
3434

35-
describe '#csv' do
36-
let (:csv_io) { export.csv }
35+
describe '#download' do
36+
let (:download_io) { export.download }
3737

3838
describe 'when file is ready' do
3939
before do
4040
stub_request(:get, export.url).to_return(
4141
status: 200,
42-
body: api_fixture('exports/id/get/csv_download/200', ext: :csv),
43-
headers: { 'Content-Type' => 'text/csv' }
42+
body: File.binread(File.expand_path('../../fixtures/exports/id/get/csv_download/200.csv.gz', __dir__)),
43+
headers: { 'Content-Type' => 'application/octet-stream' }
4444
)
4545
end
4646
it 'does not raise an error' do
47-
expect { export.csv }.to_not raise_error
47+
expect { export.download }.to_not raise_error
4848
end
49-
it 'returs a readable object' do
50-
expect(csv_io).to be_kind_of(Down::ChunkedIO)
51-
expect(csv_io.read).to be_kind_of(String)
49+
it 'returns a readable object' do
50+
expect(download_io).to be_kind_of(Down::ChunkedIO)
51+
expect(download_io.read).to be_kind_of(String)
5252
end
53-
it 'has csv caption' do
54-
expect(csv_io.read).to start_with('Date/Time (UTC),Source,DID,Destination')
53+
it 'returns gzip data' do
54+
magic = download_io.read(2)
55+
expect(magic.bytes).to eq([0x1f, 0x8b])
5556
end
5657
end
5758

@@ -61,11 +62,11 @@
6162
end
6263
it 'does not call the api' do
6364
WebMock.reset!
64-
expect { export.csv }.to_not raise_error
65+
expect { export.download }.to_not raise_error
6566
expect(a_request(:any, /.*/)).to_not have_been_made
6667
end
67-
it 'returs nil' do
68-
expect(csv_io).to be_nil
68+
it 'returns nil' do
69+
expect(download_io).to be_nil
6970
end
7071
end
7172

@@ -74,13 +75,52 @@
7475
stub_request(:get, export.url).to_return(status: 404, body: '')
7576
end
7677
it 'raises a NotFound error' do
77-
expect { export.csv }.to raise_error(Down::ClientError)
78+
expect { export.download }.to raise_error(Down::ClientError)
7879
end
7980
end
8081

8182
end
8283
end
8384

85+
describe '#csv' do
86+
let (:export) do
87+
stub_didww_request(:get, "/exports/#{id}").to_return(
88+
status: 200,
89+
body: api_fixture('exports/id/get/without_includes/200'),
90+
headers: json_api_headers
91+
)
92+
client.exports.find(id).first
93+
end
94+
95+
describe 'when file is ready' do
96+
before do
97+
stub_request(:get, export.url).to_return(
98+
status: 200,
99+
body: File.binread(File.expand_path('../../fixtures/exports/id/get/csv_download/200.csv.gz', __dir__)),
100+
headers: { 'Content-Type' => 'application/octet-stream' }
101+
)
102+
end
103+
it 'does not raise an error' do
104+
expect { export.csv }.to_not raise_error
105+
end
106+
it 'returns a StringIO' do
107+
expect(export.csv).to be_kind_of(StringIO)
108+
end
109+
it 'has csv caption' do
110+
expect(export.csv.read).to start_with('Date/Time Start (UTC)')
111+
end
112+
end
113+
114+
describe 'when url is empty' do
115+
before do
116+
export.url = nil
117+
end
118+
it 'returns nil' do
119+
expect(export.csv).to be_nil
120+
end
121+
end
122+
end
123+
84124
context 'when Export does not exist' do
85125
it 'raises a NotFound error' do
86126
stub_didww_request(:get, "/exports/#{id}").to_return(

spec/fixtures/exports/get/without_includes/200.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"export_type": "cdr_in",
88
"status": "Completed",
99
"created_at": "2017-06-25T14:56:31.513Z",
10-
"url": "https://sandbox-api.didww.com/v3/exports/a4f6b765-f20c-45c7-98d2-80c2f3a41517.csv"
10+
"url": "https://sandbox-api.didww.com/v3/exports/a4f6b765-f20c-45c7-98d2-80c2f3a41517.csv.gz"
1111
}
1212
},
1313
{
253 Bytes
Binary file not shown.

spec/fixtures/exports/id/get/without_includes/200.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"export_type": "cdr_in",
77
"status": "Completed",
88
"created_at": "2017-06-25T14:56:31.513Z",
9-
"url": "https://sandbox-api.didww.com/v3/exports/a4f6b765-f20c-45c7-98d2-80c2f3a41517.csv"
9+
"url": "https://sandbox-api.didww.com/v3/exports/a4f6b765-f20c-45c7-98d2-80c2f3a41517.csv.gz"
1010
}
1111
}
1212
}

0 commit comments

Comments
 (0)