|
1 | 1 | package io.split.android.client.network; |
2 | 2 |
|
3 | 3 | import static org.junit.Assert.assertEquals; |
| 4 | +import static org.junit.Assert.assertFalse; |
4 | 5 | import static org.junit.Assert.assertNotNull; |
5 | 6 | import static org.junit.Assert.assertNull; |
6 | 7 | import static org.junit.Assert.assertSame; |
|
12 | 13 | import org.junit.Test; |
13 | 14 | import org.mockito.Mock; |
14 | 15 |
|
| 16 | +import java.io.ByteArrayInputStream; |
| 17 | +import java.io.ByteArrayOutputStream; |
15 | 18 | import java.io.IOException; |
16 | 19 | import java.io.InputStream; |
17 | 20 | import java.net.MalformedURLException; |
@@ -367,8 +370,159 @@ public void urlCanBeRetrieved() { |
367 | 370 | } |
368 | 371 |
|
369 | 372 | @Test(expected = IOException.class) |
370 | | - public void getOutputStreamThrows() throws IOException { |
| 373 | + public void getOutputStreamThrowsWhenNotEnabled() throws IOException { |
371 | 374 | mAdapter = new HttpResponseConnectionAdapter(mTestUrl, mMockResponse, mTestCertificates); |
| 375 | + // Should throw exception since doOutput is not enabled |
372 | 376 | mAdapter.getOutputStream(); |
373 | 377 | } |
| 378 | + |
| 379 | + @Test |
| 380 | + public void setDoOutputEnablesOutput() { |
| 381 | + mAdapter = new HttpResponseConnectionAdapter(mTestUrl, mMockResponse, mTestCertificates); |
| 382 | + |
| 383 | + // Initially doOutput should be false |
| 384 | + assertEquals(false, mAdapter.getDoOutput()); |
| 385 | + |
| 386 | + // After setting doOutput to true, getDoOutput should return true |
| 387 | + mAdapter.setDoOutput(true); |
| 388 | + assertEquals(true, mAdapter.getDoOutput()); |
| 389 | + } |
| 390 | + |
| 391 | + @Test |
| 392 | + public void getOutputStreamAfterEnablingOutput() throws IOException { |
| 393 | + mAdapter = new HttpResponseConnectionAdapter(mTestUrl, mMockResponse, mTestCertificates); |
| 394 | + mAdapter.setDoOutput(true); |
| 395 | + |
| 396 | + assertNotNull("Output stream should not be null when doOutput is enabled", mAdapter.getOutputStream()); |
| 397 | + } |
| 398 | + |
| 399 | + @Test |
| 400 | + public void writeToOutputStream() throws IOException { |
| 401 | + // Create a ByteArrayOutputStream to capture the written data |
| 402 | + ByteArrayOutputStream testOutputStream = new ByteArrayOutputStream(); |
| 403 | + |
| 404 | + // Use the constructor that accepts a custom OutputStream |
| 405 | + mAdapter = new HttpResponseConnectionAdapter(mTestUrl, mMockResponse, mTestCertificates, testOutputStream); |
| 406 | + mAdapter.setDoOutput(true); |
| 407 | + |
| 408 | + // Write test data to the output stream |
| 409 | + String testData = "Test output data"; |
| 410 | + mAdapter.getOutputStream().write(testData.getBytes(StandardCharsets.UTF_8)); |
| 411 | + |
| 412 | + // Verify that the data was written correctly |
| 413 | + assertEquals("Written data should match the input", testData, testOutputStream.toString(StandardCharsets.UTF_8.name())); |
| 414 | + } |
| 415 | + |
| 416 | + @Test |
| 417 | + public void disconnectClosesOutputStream() throws IOException { |
| 418 | + // Create a custom OutputStream that tracks if it's been closed |
| 419 | + TestOutputStream testOutputStream = new TestOutputStream(); |
| 420 | + |
| 421 | + mAdapter = new HttpResponseConnectionAdapter(mTestUrl, mMockResponse, mTestCertificates, testOutputStream); |
| 422 | + mAdapter.setDoOutput(true); |
| 423 | + |
| 424 | + // Get the output stream and write some data |
| 425 | + mAdapter.getOutputStream().write("Test".getBytes(StandardCharsets.UTF_8)); |
| 426 | + |
| 427 | + // Verify the stream is not closed yet |
| 428 | + assertFalse("Output stream should not be closed before disconnect", testOutputStream.isClosed()); |
| 429 | + |
| 430 | + // Disconnect should close the output stream |
| 431 | + mAdapter.disconnect(); |
| 432 | + |
| 433 | + // Verify the stream was closed |
| 434 | + assertTrue("Output stream should be closed after disconnect", testOutputStream.isClosed()); |
| 435 | + } |
| 436 | + |
| 437 | + @Test |
| 438 | + public void disconnectClosesInputStream() throws IOException { |
| 439 | + // Create a custom InputStream that tracks if it's been closed |
| 440 | + TestInputStream testInputStream = new TestInputStream("Test response data".getBytes(StandardCharsets.UTF_8)); |
| 441 | + TestOutputStream testOutputStream = new TestOutputStream(); |
| 442 | + |
| 443 | + // Create adapter with injected test input stream |
| 444 | + when(mMockResponse.getHttpStatus()).thenReturn(200); |
| 445 | + mAdapter = new HttpResponseConnectionAdapter( |
| 446 | + mTestUrl, |
| 447 | + mMockResponse, |
| 448 | + mTestCertificates, |
| 449 | + testOutputStream, |
| 450 | + testInputStream, |
| 451 | + null); |
| 452 | + |
| 453 | + // Get the input stream and read some data to simulate usage |
| 454 | + InputStream stream = mAdapter.getInputStream(); |
| 455 | + byte[] buffer = new byte[10]; |
| 456 | + stream.read(buffer); |
| 457 | + |
| 458 | + // Verify the stream is not closed yet |
| 459 | + assertFalse("Input stream should not be closed before disconnect", testInputStream.isClosed()); |
| 460 | + |
| 461 | + // Disconnect should close the input stream |
| 462 | + mAdapter.disconnect(); |
| 463 | + |
| 464 | + // Verify the stream was closed |
| 465 | + assertTrue("Input stream should be closed after disconnect", testInputStream.isClosed()); |
| 466 | + } |
| 467 | + |
| 468 | + /** |
| 469 | + * Custom OutputStream implementation for testing that tracks if it's been closed. |
| 470 | + */ |
| 471 | + private static class TestOutputStream extends ByteArrayOutputStream { |
| 472 | + private boolean mClosed = false; |
| 473 | + |
| 474 | + @Override |
| 475 | + public void close() throws IOException { |
| 476 | + super.close(); |
| 477 | + mClosed = true; |
| 478 | + } |
| 479 | + |
| 480 | + public boolean isClosed() { |
| 481 | + return mClosed; |
| 482 | + } |
| 483 | + } |
| 484 | + |
| 485 | + private static class TestInputStream extends ByteArrayInputStream { |
| 486 | + private boolean mClosed = false; |
| 487 | + |
| 488 | + public TestInputStream(byte[] data) { |
| 489 | + super(data); |
| 490 | + } |
| 491 | + |
| 492 | + @Override |
| 493 | + public void close() throws IOException { |
| 494 | + super.close(); |
| 495 | + mClosed = true; |
| 496 | + } |
| 497 | + |
| 498 | + public boolean isClosed() { |
| 499 | + return mClosed; |
| 500 | + } |
| 501 | + } |
| 502 | + |
| 503 | + @Test |
| 504 | + public void disconnectClosesErrorStream() throws IOException { |
| 505 | + TestInputStream testErrorStream = new TestInputStream("Error data".getBytes(StandardCharsets.UTF_8)); |
| 506 | + TestOutputStream testOutputStream = new TestOutputStream(); |
| 507 | + |
| 508 | + when(mMockResponse.getHttpStatus()).thenReturn(404); // Error status |
| 509 | + mAdapter = new HttpResponseConnectionAdapter( |
| 510 | + mTestUrl, |
| 511 | + mMockResponse, |
| 512 | + mTestCertificates, |
| 513 | + testOutputStream, |
| 514 | + null, |
| 515 | + testErrorStream); |
| 516 | + |
| 517 | + // Get the error stream and read some data to simulate usage |
| 518 | + InputStream stream = mAdapter.getErrorStream(); |
| 519 | + byte[] buffer = new byte[10]; |
| 520 | + stream.read(buffer); |
| 521 | + |
| 522 | + assertFalse("Error stream should not be closed before disconnect", testErrorStream.isClosed()); |
| 523 | + |
| 524 | + mAdapter.disconnect(); |
| 525 | + |
| 526 | + assertTrue("Error stream should be closed after disconnect", testErrorStream.isClosed()); |
| 527 | + } |
374 | 528 | } |
0 commit comments