blob: 756836afaa829d9b90b9e5e3d1af35d0fb184652 [file] [log] [blame]
/*
* Copyright 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.bluetooth.opp;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.database.MatrixCursor;
import android.net.Uri;
import android.provider.OpenableColumns;
import android.util.Log;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
import com.android.bluetooth.BluetoothMethodProxy;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.io.FileInputStream;
import java.io.IOException;
@RunWith(AndroidJUnit4.class)
public class BluetoothOppSendFileInfoTest {
Context mContext;
MatrixCursor mCursor;
@Mock
BluetoothMethodProxy mCallProxy;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
BluetoothMethodProxy.setInstanceForTesting(mCallProxy);
}
@After
public void tearDown() {
BluetoothMethodProxy.setInstanceForTesting(null);
}
@Test
public void createInstance_withFileInputStream() {
String fileName = "abc.txt";
String type = "text/plain";
long length = 10000;
FileInputStream inputStream = mock(FileInputStream.class);
int status = BluetoothShare.STATUS_SUCCESS;
BluetoothOppSendFileInfo info =
new BluetoothOppSendFileInfo(fileName, type, length, inputStream, status);
assertThat(info.mStatus).isEqualTo(status);
assertThat(info.mFileName).isEqualTo(fileName);
assertThat(info.mLength).isEqualTo(length);
assertThat(info.mInputStream).isEqualTo(inputStream);
assertThat(info.mMimetype).isEqualTo(type);
}
@Test
public void createInstance_withoutFileInputStream() {
String type = "text/plain";
long length = 10000;
int status = BluetoothShare.STATUS_SUCCESS;
String data = "Testing is boring";
BluetoothOppSendFileInfo info =
new BluetoothOppSendFileInfo(data, type, length, status);
assertThat(info.mStatus).isEqualTo(status);
assertThat(info.mData).isEqualTo(data);
assertThat(info.mLength).isEqualTo(length);
assertThat(info.mMimetype).isEqualTo(type);
}
@Test
public void generateFileInfo_withUnsupportedScheme_returnsSendFileInfoError() {
String type = "text/plain";
Uri uri = Uri.parse("https://www.google.com");
BluetoothOppSendFileInfo info = BluetoothOppSendFileInfo.generateFileInfo(mContext, uri,
type, true);
assertThat(info).isEqualTo(BluetoothOppSendFileInfo.SEND_FILE_INFO_ERROR);
}
@Test
public void generateFileInfo_withForbiddenExternalUri_returnsSendFileInfoError() {
String type = "text/plain";
Uri uri = Uri.parse("content://com.android.bluetooth.map.MmsFileProvider:8080");
BluetoothOppSendFileInfo info = BluetoothOppSendFileInfo.generateFileInfo(mContext, uri,
type, true);
assertThat(info).isEqualTo(BluetoothOppSendFileInfo.SEND_FILE_INFO_ERROR);
}
@Test
public void generateFileInfo_withoutPermissionForAccessingUri_returnsSendFileInfoError() {
String type = "text/plain";
Uri uri = Uri.parse("content:///hello/world");
doThrow(new SecurityException()).when(mCallProxy).contentResolverQuery(
any(), eq(uri), any(), any(), any(),
any());
BluetoothOppSendFileInfo info = BluetoothOppSendFileInfo.generateFileInfo(mContext, uri,
type, true);
assertThat(info).isEqualTo(BluetoothOppSendFileInfo.SEND_FILE_INFO_ERROR);
}
@Test
public void generateFileInfo_withUncorrectableMismatch_returnsSendFileInfoError()
throws IOException {
String type = "text/plain";
Uri uri = Uri.parse("content:///hello/world");
long fileLength = 0;
String fileName = "coolName.txt";
AssetFileDescriptor fd = mock(AssetFileDescriptor.class);
FileInputStream fs = mock(FileInputStream.class);
mCursor = new MatrixCursor(new String[]{
OpenableColumns.DISPLAY_NAME, OpenableColumns.SIZE
});
mCursor.addRow(new Object[]{fileName, fileLength});
doReturn(mCursor).when(mCallProxy).contentResolverQuery(
any(), eq(uri), any(), any(), any(),
any());
doReturn(fd).when(mCallProxy).contentResolverOpenAssetFileDescriptor(
any(), eq(uri), any());
doReturn(0L).when(fd).getLength();
doThrow(new IOException()).when(fd).createInputStream();
doReturn(fs).when(mCallProxy).contentResolverOpenInputStream(any(), eq(uri));
doReturn(0, -1).when(fs).read(any(), anyInt(), anyInt());
BluetoothOppSendFileInfo info = BluetoothOppSendFileInfo.generateFileInfo(mContext, uri,
type, true);
assertThat(info).isEqualTo(BluetoothOppSendFileInfo.SEND_FILE_INFO_ERROR);
}
@Test
public void generateFileInfo_withCorrectableMismatch_returnInfoWithCorrectLength()
throws IOException {
String type = "text/plain";
Uri uri = Uri.parse("content:///hello/world");
long fileLength = 0;
long correctFileLength = 1000;
String fileName = "coolName.txt";
AssetFileDescriptor fd = mock(AssetFileDescriptor.class);
FileInputStream fs = mock(FileInputStream.class);
mCursor = new MatrixCursor(new String[]{
OpenableColumns.DISPLAY_NAME, OpenableColumns.SIZE
});
mCursor.addRow(new Object[]{fileName, fileLength});
doReturn(mCursor).when(mCallProxy).contentResolverQuery(
any(), eq(uri), any(), any(), any(),
any());
doReturn(fd).when(mCallProxy).contentResolverOpenAssetFileDescriptor(
any(), eq(uri), any());
doReturn(0L).when(fd).getLength();
doReturn(fs).when(fd).createInputStream();
// the real size will be returned in getStreamSize(fs)
doReturn((int) correctFileLength, -1).when(fs).read(any(), anyInt(), anyInt());
BluetoothOppSendFileInfo info = BluetoothOppSendFileInfo.generateFileInfo(mContext, uri,
type, true);
assertThat(info.mInputStream).isEqualTo(fs);
assertThat(info.mFileName).isEqualTo(fileName);
assertThat(info.mLength).isEqualTo(correctFileLength);
assertThat(info.mStatus).isEqualTo(0);
}
@Test
public void generateFileInfo_withFileUriNotInExternalStorageDir_returnFileErrorInfo() {
String type = "text/plain";
Uri uri = Uri.parse("file:///obviously/not/in/external/storage");
BluetoothOppSendFileInfo info = BluetoothOppSendFileInfo.generateFileInfo(mContext, uri,
type, true);
assertThat(info).isEqualTo(BluetoothOppSendFileInfo.SEND_FILE_INFO_ERROR);
}
}