1 // Copyright 2021 The Android Open Source Project 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package com.google.android.downloader; 16 17 import static com.google.common.truth.Truth.assertThat; 18 import static java.nio.charset.StandardCharsets.UTF_8; 19 import static org.junit.Assert.assertThrows; 20 import static org.mockito.ArgumentMatchers.any; 21 import static org.mockito.Mockito.when; 22 23 import com.google.common.collect.ImmutableList; 24 import com.google.common.io.Files; 25 import com.google.common.net.HttpHeaders; 26 import com.google.common.util.concurrent.ListenableFuture; 27 import com.google.common.util.concurrent.MoreExecutors; 28 import com.google.testing.mockito.Mocks; 29 import java.io.File; 30 import java.io.IOException; 31 import java.net.HttpURLConnection; 32 import java.nio.ByteBuffer; 33 import java.nio.channels.FileChannel; 34 import java.nio.channels.WritableByteChannel; 35 import java.nio.file.StandardOpenOption; 36 import java.util.concurrent.ExecutionException; 37 import org.junit.Before; 38 import org.junit.Rule; 39 import org.junit.Test; 40 import org.junit.rules.TemporaryFolder; 41 import org.junit.runner.RunWith; 42 import org.junit.runners.JUnit4; 43 import org.mockito.Mock; 44 45 /** Unit tests for DataUrlEngine. */ 46 @RunWith(JUnit4.class) 47 public class DataUrlEngineTest { 48 @Rule public TemporaryFolder temporaryFolder = new TemporaryFolder(); 49 @Rule public Mocks mocks = new Mocks(this); 50 51 @Mock WritableByteChannel mockByteChannel; 52 53 private DataUrlEngine engine; 54 55 @Before setUp()56 public void setUp() { 57 engine = new DataUrlEngine(MoreExecutors.newDirectExecutorService()); 58 } 59 60 @Test executeRequest()61 public void executeRequest() throws Exception { 62 File file = temporaryFolder.newFile(); 63 FileChannel channel = FileChannel.open(file.toPath(), StandardOpenOption.WRITE); 64 65 UrlRequest request = engine.createRequest("data:text/plain;base64,Zm9vYmFy").build(); 66 UrlResponse response = request.send().get(); 67 long bytesWritten = response.readResponseBody(channel).get(); 68 response.close(); 69 channel.close(); 70 71 assertThat(bytesWritten).isGreaterThan(0L); 72 assertThat(Files.asCharSource(file, UTF_8).read()).isEqualTo("foobar"); 73 assertThat(response.getResponseCode()).isEqualTo(HttpURLConnection.HTTP_OK); 74 assertThat(response.getResponseHeaders()) 75 .containsExactly(HttpHeaders.CONTENT_TYPE, ImmutableList.of("text/plain")); 76 } 77 78 @Test executeRequest_invalidDataUrl()79 public void executeRequest_invalidDataUrl() throws Exception { 80 UrlRequest request = engine.createRequest("data:text/plain;base64,foobar*").build(); 81 ListenableFuture<? extends UrlResponse> responseFuture = request.send(); 82 83 ExecutionException exception = assertThrows(ExecutionException.class, responseFuture::get); 84 assertThat(exception).hasCauseThat().isInstanceOf(RequestException.class); 85 } 86 87 @Test executeRequest_writeError()88 public void executeRequest_writeError() throws Exception { 89 when(mockByteChannel.isOpen()).thenReturn(true); 90 when(mockByteChannel.write(any(ByteBuffer.class))).thenThrow(new IOException()); 91 92 UrlRequest request = engine.createRequest("data:text/plain;base64,Zm9vYmFy").build(); 93 UrlResponse response = request.send().get(); 94 ListenableFuture<Long> writeFuture = response.readResponseBody(mockByteChannel); 95 96 ExecutionException exception = assertThrows(ExecutionException.class, writeFuture::get); 97 assertThat(exception).hasCauseThat().isInstanceOf(RequestException.class); 98 99 response.close(); 100 101 assertThat(response.getResponseCode()).isEqualTo(HttpURLConnection.HTTP_OK); 102 assertThat(response.getResponseHeaders()) 103 .containsExactly(HttpHeaders.CONTENT_TYPE, ImmutableList.of("text/plain")); 104 } 105 } 106