1717
1818package io.github.nstdio.http.ext
1919
20+ import io.kotest.matchers.types.shouldBeSameInstanceAs
2021import org.apache.commons.io.IOUtils
2122import org.assertj.core.api.Assertions
2223import org.assertj.core.api.Assertions.assertThatExceptionOfType
@@ -48,161 +49,170 @@ import java.util.zip.InflaterInputStream
4849
4950@ExtendWith(MockitoExtension ::class )
5051internal class DecompressingBodyHandlerTest {
51- private lateinit var handler: DecompressingBodyHandler <* >
52-
53- @Mock
54- private lateinit var mockHandler: BodyHandler <Any >
55-
56- @Mock
57- private lateinit var mockSubscriber: BodySubscriber <Any >
58-
59- @BeforeEach
60- fun setUp () {
61- handler = DecompressingBodyHandler (mockHandler, DecompressingBodyHandler .Options (false , false ))
62- }
63-
64- @AfterEach
65- fun tearDown () {
66- Mockito .verifyNoInteractions(mockSubscriber)
67- }
68-
69- @Test
70- fun shouldReturnOriginalSub () {
71- // given
72- val responseInfo = ImmutableResponseInfo .builder()
73- .headers(HttpHeaders .of(Map .of(), Headers .ALLOW_ALL ))
74- .build()
75- given(mockHandler.apply (responseInfo)).willReturn(mockSubscriber)
76-
77- // when
78- val actual = handler.apply (responseInfo)
79-
80- // then
81- Assertions .assertThat(actual).isSameAs(mockSubscriber)
82- verify(mockHandler).apply (responseInfo)
83- verifyNoMoreInteractions(mockHandler)
84- }
85-
86- @Test
87- fun shouldReturnDirectSubscriptionWhenDirect () {
88- val options = DecompressingBodyHandler .Options (false , false )
89- val handler = DecompressingBodyHandler .ofDirect(options)
90- val responseInfo = ImmutableResponseInfo .builder()
91- .headers(HttpHeadersBuilder ().add(" Content-Encoding" , " gzip" ).build())
92- .build()
93-
94- // when
95- val actual = handler.apply (responseInfo)
96-
97- // then
98- Assertions .assertThat(actual).isExactlyInstanceOf(AsyncMappingSubscriber ::class .java)
99- }
100-
101- @Test
102- fun shouldReturnOriginalSubWhenDirectivesUnsupported () {
103- // given
104- val responseInfo = ImmutableResponseInfo .builder()
105- .headers(HttpHeadersBuilder ().add(Headers .HEADER_CONTENT_ENCODING , " compress,br,identity1,abc" ).build())
106- .build()
107- given(mockHandler.apply (responseInfo)).willReturn(mockSubscriber)
108-
109- // when
110- val actual = handler.apply (responseInfo)
111-
112- // then
113- Assertions .assertThat(actual).isSameAs(mockSubscriber)
114- verify(mockHandler).apply (responseInfo)
115- verifyNoMoreInteractions(mockHandler)
52+ private lateinit var handler: DecompressingBodyHandler <* >
53+
54+ @Mock
55+ private lateinit var mockHandler: BodyHandler <Any >
56+
57+ @Mock
58+ private lateinit var mockSubscriber: BodySubscriber <Any >
59+
60+ @BeforeEach
61+ fun setUp () {
62+ handler = DecompressingBodyHandler (mockHandler, DecompressingBodyHandler .Options (false , false ))
63+ }
64+
65+ @AfterEach
66+ fun tearDown () {
67+ Mockito .verifyNoInteractions(mockSubscriber)
68+ }
69+
70+ @Test
71+ fun shouldReturnOriginalSub () {
72+ // given
73+ val responseInfo = ImmutableResponseInfo .builder()
74+ .headers(HttpHeaders .of(Map .of(), Headers .ALLOW_ALL ))
75+ .build()
76+ given(mockHandler.apply (responseInfo)).willReturn(mockSubscriber)
77+
78+ // when
79+ val actual = handler.apply (responseInfo)
80+
81+ // then
82+ Assertions .assertThat(actual).isSameAs(mockSubscriber)
83+ verify(mockHandler).apply (responseInfo)
84+ verifyNoMoreInteractions(mockHandler)
85+ }
86+
87+ @Test
88+ fun shouldReturnDirectSubscriptionWhenDirect () {
89+ val options = DecompressingBodyHandler .Options (false , false )
90+ val handler = DecompressingBodyHandler .ofDirect(options)
91+ val responseInfo = ImmutableResponseInfo .builder()
92+ .headers(HttpHeadersBuilder ().add(" Content-Encoding" , " gzip" ).build())
93+ .build()
94+
95+ // when
96+ val actual = handler.apply (responseInfo)
97+
98+ // then
99+ Assertions .assertThat(actual).isExactlyInstanceOf(AsyncMappingSubscriber ::class .java)
100+ }
101+
102+ @Test
103+ fun shouldReturnOriginalSubWhenDirectivesUnsupported () {
104+ // given
105+ val responseInfo = ImmutableResponseInfo .builder()
106+ .headers(HttpHeadersBuilder ().add(Headers .HEADER_CONTENT_ENCODING , " compress,br,identity1,abc" ).build())
107+ .build()
108+ given(mockHandler.apply (responseInfo)).willReturn(mockSubscriber)
109+
110+ // when
111+ val actual = handler.apply (responseInfo)
112+
113+ // then
114+ Assertions .assertThat(actual).isSameAs(mockSubscriber)
115+ verify(mockHandler).apply (responseInfo)
116+ verifyNoMoreInteractions(mockHandler)
117+ }
118+
119+ @ParameterizedTest
120+ @ValueSource(strings = [" gzip" , " x-gzip" ])
121+ @Throws(
122+ IOException ::class
123+ )
124+ fun shouldReturnGzipInputStream (directive : String? ) {
125+ val gzipContent = ByteArrayInputStream (Compression .gzip(" abc" ))
126+
127+ // when
128+ val fn = handler.decompressionFn(directive)
129+ val `in ` = fn.apply (gzipContent)
130+
131+ // then
132+ Assertions .assertThat(`in `).isInstanceOf(GZIPInputStream ::class .java)
133+ Assertions .assertThat(IOUtils .toString(`in `, StandardCharsets .UTF_8 )).isEqualTo(" abc" )
134+ }
135+
136+ @Test
137+ @Throws(IOException ::class )
138+ fun shouldReturnDeflateInputStream () {
139+ val deflateContent = ByteArrayInputStream (Compression .deflate(" abc" ))
140+
141+ // when
142+ val fn = handler.decompressionFn(" deflate" )
143+ val `in ` = fn.apply (deflateContent)
144+
145+ // then
146+ Assertions .assertThat(`in `).isInstanceOf(InflaterInputStream ::class .java)
147+ Assertions .assertThat(IOUtils .toString(`in `, StandardCharsets .UTF_8 )).isEqualTo(" abc" )
148+ }
149+
150+ @Nested
151+ internal inner class FailureControlOptionsTest {
152+ @ParameterizedTest
153+ @ValueSource(strings = [" compress" , " br" ])
154+ fun shouldThrowUnsupportedOperationException (directive : String? ) {
155+ // given
156+ val handler = BodyHandlers .decompressingBuilder()
157+ .failOnUnsupportedDirectives(true )
158+ .failOnUnknownDirectives(true )
159+ .build(mockHandler) as DecompressingBodyHandler
160+
161+ // when + then
162+ assertThatExceptionOfType(UnsupportedOperationException ::class .java)
163+ .isThrownBy { handler.decompressionFn(directive) }
164+ .withMessage(" Compression directive '%s' is not supported" , directive)
116165 }
117166
118167 @ParameterizedTest
119- @ValueSource(strings = [" gzip" , " x-gzip" ])
120- @Throws(
121- IOException ::class
122- )
123- fun shouldReturnGzipInputStream (directive : String? ) {
124- val gzipContent = ByteArrayInputStream (Compression .gzip(" abc" ))
125-
126- // when
127- val fn = handler.decompressionFn(directive)
128- val `in ` = fn.apply (gzipContent)
129-
130- // then
131- Assertions .assertThat(`in `).isInstanceOf(GZIPInputStream ::class .java)
132- Assertions .assertThat(IOUtils .toString(`in `, StandardCharsets .UTF_8 )).isEqualTo(" abc" )
168+ @ValueSource(strings = [" " , " abc" , " gz" , " a" ])
169+ fun shouldThrowIllegalArgumentException (directive : String? ) {
170+ val handler = BodyHandlers .decompressingBuilder()
171+ .failOnUnsupportedDirectives(true )
172+ .failOnUnknownDirectives(true )
173+ .build(mockHandler) as DecompressingBodyHandler
174+ // when + then
175+ assertThatIllegalArgumentException()
176+ .isThrownBy { handler.decompressionFn(directive) }
177+ .withMessage(" Unknown compression directive '%s'" , directive)
133178 }
134179
135- @Test
136- @Throws(IOException ::class )
137- fun shouldReturnDeflateInputStream () {
138- val deflateContent = ByteArrayInputStream (Compression .deflate(" abc" ))
139-
140- // when
141- val fn = handler.decompressionFn(" deflate" )
142- val `in ` = fn.apply (deflateContent)
143-
144- // then
145- Assertions .assertThat(`in `).isInstanceOf(InflaterInputStream ::class .java)
146- Assertions .assertThat(IOUtils .toString(`in `, StandardCharsets .UTF_8 )).isEqualTo(" abc" )
180+ @ParameterizedTest
181+ @ValueSource(strings = [" compress" , " br" ])
182+ @DisplayName(" Should not throw exception when 'failOnUnsupportedDirectives' is 'false'" )
183+ fun shouldNotThrowUnsupportedOperationException (directive : String? ) {
184+ // given
185+ val handler = BodyHandlers .decompressingBuilder()
186+ .failOnUnsupportedDirectives(false )
187+ .failOnUnknownDirectives(true )
188+ .build(mockHandler) as DecompressingBodyHandler
189+ val s = InputStream .nullInputStream()
190+
191+ // when
192+ val fn = handler.decompressionFn(directive)
193+ val actual = fn.apply (s)
194+
195+ // then
196+ actual shouldBeSameInstanceAs s
147197 }
148198
149- @Nested
150- internal inner class FailureControlOptionsTest {
151- @ParameterizedTest
152- @ValueSource(strings = [" compress" , " br" ])
153- fun shouldThrowUnsupportedOperationException (directive : String? ) {
154- // given
155- val options = DecompressingBodyHandler .Options (true , true )
156- val handler = DecompressingBodyHandler (mockHandler, options)
157-
158- // when + then
159- assertThatExceptionOfType(UnsupportedOperationException ::class .java)
160- .isThrownBy { handler.decompressionFn(directive) }
161- .withMessage(" Compression directive '%s' is not supported" , directive)
162- }
163-
164- @ParameterizedTest
165- @ValueSource(strings = [" " , " abc" , " gz" , " a" ])
166- fun shouldThrowIllegalArgumentException (directive : String? ) {
167- val handler = DecompressingBodyHandler (mockHandler, DecompressingBodyHandler .Options (true , true ))
168- // when + then
169- assertThatIllegalArgumentException()
170- .isThrownBy { handler.decompressionFn(directive) }
171- .withMessage(" Unknown compression directive '%s'" , directive)
172- }
173-
174- @ParameterizedTest
175- @ValueSource(strings = [" compress" , " br" ])
176- @DisplayName(" Should not throw exception when 'failOnUnsupportedDirectives' is 'false'" )
177- fun shouldNotThrowUnsupportedOperationException (directive : String? ) {
178- // given
179- val options = DecompressingBodyHandler .Options (false , true )
180- val handler = DecompressingBodyHandler (mockHandler, options)
181- val `in ` = InputStream .nullInputStream()
182-
183- // when
184- val fn = handler.decompressionFn(directive)
185- val actual = fn.apply (`in `)
186-
187- // then
188- Assertions .assertThat(actual).isSameAs(`in `)
189- }
190-
191- @ParameterizedTest
192- @ValueSource(strings = [" " , " abc" , " gz" , " a" ])
193- @DisplayName(" Should not throw exception when 'failOnUnknownDirectives' is 'false'" )
194- fun shouldNotIllegalArgumentException (directive : String? ) {
195- // given
196- val options = DecompressingBodyHandler .Options (true , false )
197- val handler = DecompressingBodyHandler (mockHandler, options)
198- val `in ` = InputStream .nullInputStream()
199-
200- // when
201- val fn = handler.decompressionFn(directive)
202- val actual = fn.apply (`in `)
203-
204- // then
205- Assertions .assertThat(actual).isSameAs(`in `)
206- }
199+ @ParameterizedTest
200+ @ValueSource(strings = [" " , " abc" , " gz" , " a" ])
201+ @DisplayName(" Should not throw exception when 'failOnUnknownDirectives' is 'false'" )
202+ fun shouldNotIllegalArgumentException (directive : String? ) {
203+ // given
204+ val handler = BodyHandlers .decompressingBuilder()
205+ .failOnUnsupportedDirectives(true )
206+ .failOnUnknownDirectives(false )
207+ .build(mockHandler) as DecompressingBodyHandler
208+ val s = InputStream .nullInputStream()
209+
210+ // when
211+ val fn = handler.decompressionFn(directive)
212+ val actual = fn.apply (s)
213+
214+ // then
215+ actual shouldBeSameInstanceAs s
207216 }
217+ }
208218}
0 commit comments