aboutsummaryrefslogtreecommitdiffstats
path: root/spec/services/zip_service_spec.rb
blob: 540de5bfc8a2bdc46b15a524cd7886c337992b5b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
RSpec.describe ZipService, type: :zip do

  let( :unzipper ){ described_class.new( zip_data, allowed_lines ) }
  subject { unzipper.subdirs }

  let( :allowed_lines ){ Set.new(%w{C00108 C00109}) }
  let( :zip_data ){ zip_archive.data }
  let( :zip_archive ){ make_zip zip_name, zip_content }

  context 'one, legal, referential' do
    let( :zip_name ){ 'one_referential_ok.zip' }
    let( :zip_content ){ first_referential_ok_data }

    it 'yields correct output' do
      subject.each do | subdir |
        expect_correct_subdir subdir, make_zip('expected.zip', first_referential_ok_data)
      end
    end
  end

  context 'two, legal, referentials' do
    let( :zip_name ){ 'two_referential_ok.zip' }
    let( :zip_content ){ first_referential_ok_data.merge( second_referential_ok_data ) }
    let( :expected_zips ){ [
      make_zip('expected.zip', first_referential_ok_data),
      make_zip('expected.zip', second_referential_ok_data)
    ] }

    it 'yields correct output' do
      subject.zip(expected_zips).each do | subdir, expected_zip |
        expect_correct_subdir subdir, expected_zip
      end
    end
  end

  context 'one referential with a spurious directory' do
    let( :zip_name ){ 'one_referential_spurious.zip' }
    let( :zip_content ){ first_referential_spurious_data }

    it 'returns a not ok object' do
      expect_incorrect_subdir subject.first, expected_spurious: %w{SPURIOUS}
    end
  end

  context 'one referential without calendar' do
    let( :zip_name ){ 'one_referential_no_calendar.zip' }
    let( :zip_content ){ first_referential_no_calendar_data }

    it 'returns a not ok object' do
      expect_incorrect_subdir subject.first, expected_missing_calendar: true
    end
  end

  context 'one referential with an unparsable calendar' do
    let( :zip_name ){ 'one_referential_unparsable_calendar.zip' }
    let( :zip_content ){ first_referential_unparsable_calendar_data }

    it 'returns a not ok object' do
      expect_incorrect_subdir subject.first, expected_wrong_calendar: true
    end
  end

  context 'one referential with a foreign line' do
    let( :zip_name ){ 'one_referential_foreign.zip' }
    let( :zip_content ){ first_referential_foreign_data }

    it 'returns a not ok object' do
      expect_incorrect_subdir subject.first, expected_foreign_lines: %w{C00110}
    end
  end

  context '1st ref ok, 2nd foreign line, 3rd spurious' do
    let( :zip_name ){ '3-mixture.zip' }
    let( :zip_content ){ first_referential_ok_data
                           .merge(first_referential_foreign_data)
                           .merge(first_referential_spurious_data) }

    it 'returns 3 objects accordingly' do
      subdirs = subject.to_a

      expect_correct_subdir subdirs.first, make_zip('expected.zip', first_referential_ok_data)

      expect_incorrect_subdir subdirs.second, expected_foreign_lines: %w{C00110}
      expect_incorrect_subdir subdirs.third,  expected_spurious: %W{SPURIOUS}
    end
  end

  context 'one messed up' do
    let( :zip_name ){ 'one_messed_up.zip' }
    let( :zip_content ){ messed_up_referential_data }

    it 'returns a not ok object (all error information provided)' do
      expect_incorrect_subdir subject.first,
                                expected_foreign_lines: %w{C00110 C00111},
                                expected_spurious: %w{SPURIOUS1 SPURIOUS2}
    end

  end

  # Regression treated in #5281
  context 'one_first_level_dir' do
    let( :zip_data ){ File.read fixtures_path('regression-5281.zip') }
    let( :zip_name ){ 'regression_5281' }

    let( :allowed_lines ){
      Set.new([*164..168, 171].map{|line| "C00#{line}"})
    }

    let( :subdirs ){ subject.to_a }

    it 'returns one not ok object' do
      expect( subdirs.size ).to eq(1)
      expect( subdirs.first ).not_to be_ok
      expect( subdirs.first.spurious ).to eq(%w{OFFRE_SNTYO_1_20170820120001 OFFRE_SNTYO_2_20170820120001})
    end
  end

  # Behaviour
  # ---------
  def expect_correct_subdir subdir, expected_zip
    expect( subdir ).to be_ok
    expect( subdir.foreign_lines ).to be_empty
    expect( subdir.spurious ).to be_empty
    subdir.stream.tap do | stream |
      stream.rewind
      expect( stream.read ).to eq(expected_zip.data)
    end
  end

  def expect_incorrect_subdir subdir, expected_spurious: [], expected_foreign_lines: [], expected_missing_calendar: false, expected_wrong_calendar: false
    expect( subdir ).not_to be_ok
    expect( subdir.foreign_lines ).to eq(expected_foreign_lines)
    expect( subdir.spurious ).to eq(expected_spurious)
    expect( subdir.missing_calendar ).to eq(expected_missing_calendar)
    expect( subdir.wrong_calendar ).to eq(expected_wrong_calendar)
  end

  # Data
  # ----
  let :valid_calendar do
    """
    <netex:PublicationDelivery xmlns:netex=\"http://www.netex.org.uk/netex\">
      <netex:ValidBetween>
        <netex:FromDate>2017-03-01</netex:FromDate>
        <netex:ToDate>2017-03-31</netex:ToDate>
      </netex:ValidBetween>
    </netex:PublicationDelivery>
    """
  end
  let :first_referential_ok_data do
    {
       'Referential1/calendriers.xml'     => valid_calendar,
       'Referential1/commun.xml'          => 'common',
       'Referential1/offre_C00108_9.xml'  => 'line 108 ref 1',
       'Referential1/offre_C00109_10.xml' => 'line 109 ref 1'
    }
  end
  let :first_referential_foreign_data do
    {
       'Referential2/calendriers.xml'     => valid_calendar,
       'Referential2/commun.xml'          => 'common',
       'Referential2/offre_C00110_11.xml' => 'foreign line ref 1',
       'Referential2/offre_C00108_9.xml'  => 'line 108 ref 1',
       'Referential2/offre_C00109_10.xml' => 'line 109 ref 1'
    }
  end
  let :first_referential_spurious_data do
    {
       'Referential3/calendriers.xml'     => valid_calendar,
       'Referential3/commun.xml'          => 'common',
       'Referential3/SPURIOUS/commun.xml' => 'common',
       'Referential3/offre_C00108_9.xml'  => 'line 108 ref 1',
       'Referential3/offre_C00109_10.xml' => 'line 109 ref 1'
    }
  end
  let :second_referential_ok_data do
    {
       'Referential4/calendriers.xml'     => valid_calendar,
       'Referential4/commun.xml'          => 'common',
       'Referential4/offre_C00108_9.xml'  => 'line 108 ref 2',
       'Referential4/offre_C00109_10.xml' => 'line 109 ref 2'
    }
  end
  let :messed_up_referential_data do
    {
       'Referential5/calendriers.xml'      => valid_calendar,
       'Referential5/commun.xml'           => 'common',
       'Referential5/SPURIOUS1/commun.xml' => 'common',
       'Referential5/SPURIOUS2/commun.xml' => 'common',
       'Referential5/offre_C00110_11.xml'  => 'foreign line ref 1',
       'Referential5/offre_C00111_11.xml'  => 'foreign line ref 1',
       'Referential5/offre_C00108_9.xml'   => 'line 108 ref 1',
       'Referential5/offre_C00109_10.xml'  => 'line 109 ref 1'
    }
  end
  let :first_referential_no_calendar_data do
    {
       'Referential6/commun.xml'          => 'common',
       'Referential6/offre_C00108_9.xml'  => 'line 108 ref 1',
       'Referential6/offre_C00109_10.xml' => 'line 109 ref 1'
    }
  end
  let :first_referential_unparsable_calendar_data do
    {
       'Referential7/calendriers.xml'     => 'calendriers',
       'Referential7/commun.xml'          => 'common',
       'Referential7/offre_C00108_9.xml'  => 'line 108 ref 1',
       'Referential7/offre_C00109_10.xml' => 'line 109 ref 1'
    }
  end


end