@Test
public void testFinishUploadingLargeFile() throws B2Exception, IOException {

    final long contentLen = (3 * ACCOUNT_AUTH.getRecommendedPartSize() + 124);
    final B2ContentSource contentSource = mock(B2ContentSource.class);
    when(contentSource.getContentLength()).thenReturn(contentLen);
    final B2UploadFileRequest request = B2UploadFileRequest
            .builder(bucketId(1), fileName(1), B2ContentTypes.TEXT_PLAIN, contentSource)
            .build();
    final B2FileVersion largeFileVersion = new B2FileVersion(fileId(1),
            fileName(1),
            contentLen,
            B2ContentTypes.TEXT_PLAIN,
            null,
            null,
            B2Collections.mapOf(),
            "upload",
            B2Clock.get().wallClockMillis());
    final String largeFileId = largeFileVersion.getFileId();
    // arrange to find that two parts -- the first and third -- have already been uploaded.
    final List<B2Part> alreadyUploadedParts = listOf(
            new B2Part(largeFileId, 1, 1041, makeSha1(1), makeMd5(1), 1111),
            new B2Part(largeFileId, 3, 1042, makeSha1(3), makeMd5(3), 3333)
    );
    final B2ListPartsResponse listPartsResponse = new B2ListPartsResponse(alreadyUploadedParts, null);
    when(webifier.listParts(anyObject(), anyObject())).thenReturn(listPartsResponse);
    // arrange to answer get_upload_part_url (which will be called several times, but it's ok to reuse the same value since it's all mocked!)
    final B2GetUploadPartUrlRequest partUrlRequest = B2GetUploadPartUrlRequest.builder(largeFileId).build();
    final B2UploadPartUrlResponse partUrl = new B2UploadPartUrlResponse(largeFileId, "uploadPartUrl", "uploadPartAuthToken");
    when(webifier.getUploadPartUrl(anyObject(), eq(partUrlRequest))).thenReturn(partUrl);
    // arrange to answer upload_part
    final B2Part part = makePart(2);
    when(webifier.uploadPart(anyObject(), anyObject())).thenReturn(part);
    // arrange to answer finish_large_file
    final B2FinishLargeFileRequest finishRequest = new B2FinishLargeFileRequest(largeFileId, listOf(B2TestHelpers.SAMPLE_SHA1));
    when(webifier.finishLargeFile(anyObject(), eq(finishRequest))).thenReturn(largeFileVersion);
    client.finishUploadingLargeFile(largeFileVersion, request, executor);
    verify(contentSource, times(1)).getContentLength();
    verify(contentSource, times(1)).getSha1OrNull();
    verify(contentSource, times(1)).createContentSourceWithRangeOrNull(anyLong(), anyLong());
    verifyNoMoreInteractions(contentSource); // the webifier is a mock, so it doesn't do normal things
    // we should be using the existing largeFile, not starting a new one.
    verify(webifier, never()).startLargeFile(anyObject(), anyObject());
    // we're only uploading 1 of the three, since two were already uploaded
    verify(webifier, times(1)).getUploadPartUrl(anyObject(), anyObject());
    verify(webifier, times(1)).uploadPart(anyObject(), anyObject());
    verify(webifier, times(1)).finishLargeFile(anyObject(), anyObject());
}