@VisibleForTesting
  ExportResult<PhotosContainerResource> exportPhotos(
      TokensAndUrlAuthData authData,
      Optional<IdOnlyContainerResource> albumData,
      Optional<PaginationData> paginationData,
      UUID jobId)
      throws IOException, InvalidTokenException, PermissionDeniedException, UploadErrorException {
    Optional<String> albumId = Optional.empty();
    if (albumData.isPresent()) {
      albumId = Optional.of(albumData.get().getId());
    }
    Optional<String> paginationToken = getPhotosPaginationToken(paginationData);

    MediaItemSearchResponse mediaItemSearchResponse =
        getOrCreatePhotosInterface(authData).listMediaItems(albumId, paginationToken);

    PaginationData nextPageData = null;
    if (!Strings.isNullOrEmpty(mediaItemSearchResponse.getNextPageToken())) {
      nextPageData =
          new StringPaginationToken(
              PHOTO_TOKEN_PREFIX + mediaItemSearchResponse.getNextPageToken());
    }
    ContinuationData continuationData = new ContinuationData(nextPageData);

    PhotosContainerResource containerResource = null;
    GoogleMediaItem[] mediaItems = mediaItemSearchResponse.getMediaItems();
    if (mediaItems != null && mediaItems.length > 0) {
      List<PhotoModel> photos = convertPhotosList(albumId, mediaItems, jobId);
      containerResource = new PhotosContainerResource(null, photos);
    }

    ResultType resultType = ResultType.CONTINUE;
    if (nextPageData == null) {
      resultType = ResultType.END;
    }

    return new ExportResult<>(resultType, containerResource, continuationData);
  }
@Test
  public void photoModelConversionErrorsSkipped() throws Exception {
    // These media items fail when converting because MediaItem.isPhoto() returns false.
    GoogleMediaItem failedGoogleMediaItem1 = setUpSinglePhoto("uri1", "failed-photo-1");
    failedGoogleMediaItem1.setMediaMetadata(new MediaMetadata());

    GoogleMediaItem failedGoogleMediaItem2 = setUpSinglePhoto("uri2", "failed-photo-2");
    failedGoogleMediaItem2.setMediaMetadata(new MediaMetadata());

    GoogleMediaItem[] mediaItems = {
        setUpSinglePhoto("uri3", "photoId1"),
        failedGoogleMediaItem1,
        setUpSinglePhoto("uri4", "photoId2"),
        setUpSinglePhoto("uri5", "photoId3"),
        failedGoogleMediaItem2,
        setUpSinglePhoto("uri6", "photoId4")
    };

    MediaItemSearchResponse mediaItemSearchResponse = new MediaItemSearchResponse();
    mediaItemSearchResponse.setMediaItems(mediaItems);
    mediaItemSearchResponse.setNextPageToken(null);

    when(photosInterface.listMediaItems(any(), any())).thenReturn(mediaItemSearchResponse);

    ExportResult<PhotosContainerResource> result =
        googlePhotosExporter.exportPhotos(authData, Optional.of(new IdOnlyContainerResource("albumId")), Optional.empty(), uuid);

    assertThat(result.getExportedData().getPhotos()).hasSize(4);
    assertThat(
        result.getExportedData()
            .getPhotos()
            .stream()
            .map(photo -> photo.getDataId())
            .collect(Collectors.toList()))
        .isEqualTo(
            Arrays.stream(mediaItems)
                .map(mediaItem -> mediaItem.getId())
                .filter(id -> !(id.equals(failedGoogleMediaItem1.getId()) || id.equals(failedGoogleMediaItem2.getId())))
                .collect(Collectors.toList()));
  }