// Path: pipeline-application/src/main/java/com/smoketurner/pipeline/application/exceptions/AmazonS3ConstraintException.java
// public class AmazonS3ConstraintException extends Exception {
// 
//   private static final long serialVersionUID = 1L;
// 
//   public AmazonS3ConstraintException() {
//     super();
//   }
// 
//   public AmazonS3ConstraintException(final Throwable cause) {
//     super(cause);
//   }
// 
//   public AmazonS3ConstraintException(final String message) {
//     super(message);
//   }
// 
//   public AmazonS3ConstraintException(final String message, final Throwable cause) {
//     super(message, cause);
//   }
// }
// 
// Path: pipeline-application/src/main/java/com/smoketurner/pipeline/application/exceptions/AmazonS3ZeroSizeException.java
// public class AmazonS3ZeroSizeException extends Exception {
// 
//   private static final long serialVersionUID = 1L;
// 
//   public AmazonS3ZeroSizeException() {
//     super();
//   }
// 
//   public AmazonS3ZeroSizeException(final Throwable cause) {
//     super(cause);
//   }
// 
//   public AmazonS3ZeroSizeException(final String message) {
//     super(message);
//   }
// 
//   public AmazonS3ZeroSizeException(final String message, final Throwable cause) {
//     super(message, cause);
//   }
// }


import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import com.amazonaws.AmazonClientException;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.event.S3EventNotification.S3BucketEntity;
import com.amazonaws.services.s3.event.S3EventNotification.S3Entity;
import com.amazonaws.services.s3.event.S3EventNotification.S3EventNotificationRecord;
import com.amazonaws.services.s3.event.S3EventNotification.S3ObjectEntity;
import com.amazonaws.services.s3.model.GetObjectRequest;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.S3Object;
import com.smoketurner.pipeline.application.exceptions.AmazonS3ConstraintException;
import com.smoketurner.pipeline.application.exceptions.AmazonS3ZeroSizeException;
import org.junit.Before;
import org.junit.Test;
    final S3BucketEntity bucket = new S3BucketEntity("bucket-name", null, null);
    final S3ObjectEntity object =
        new S3ObjectEntity("object-key", 100L, "object eTag", "object version", null);
    final S3Entity s3 = new S3Entity(null, bucket, object, null);
    record =
        new S3EventNotificationRecord(
            "us-east-1", null, "aws:s3", "1970-01-01T00:00:00.000Z", "2.0", null, null, s3, null);
  }

  @Test
  public void testFetch() throws Exception {
    final S3Object expected = new S3Object();
    expected.setKey("object-key");
    expected.setBucketName("bucket-name");
    expected.getObjectMetadata().setContentLength(100);

    when(mockS3.getObject(any(GetObjectRequest.class))).thenReturn(expected);

    final S3Object actual = downloader.fetch(record);
    verify(mockS3).getObject(any(GetObjectRequest.class));
    assertThat(actual).isEqualTo(expected);
  }

  @Test
  public void testFetchInvalidETag() throws Exception {
    when(mockS3.getObject(any(GetObjectRequest.class))).thenReturn(null);

    try {
      final S3Object download = downloader.fetch(record);
      assertThat(download).isNull();
// Path: pipeline-application/src/main/java/com/smoketurner/pipeline/application/exceptions/AmazonS3ConstraintException.java
// public class AmazonS3ConstraintException extends Exception {
// 
//   private static final long serialVersionUID = 1L;
// 
//   public AmazonS3ConstraintException() {
//     super();
//   }
// 
//   public AmazonS3ConstraintException(final Throwable cause) {
//     super(cause);
//   }
// 
//   public AmazonS3ConstraintException(final String message) {
//     super(message);
//   }
// 
//   public AmazonS3ConstraintException(final String message, final Throwable cause) {
//     super(message, cause);
//   }
// }
// 
// Path: pipeline-application/src/main/java/com/smoketurner/pipeline/application/exceptions/AmazonS3ZeroSizeException.java
// public class AmazonS3ZeroSizeException extends Exception {
// 
//   private static final long serialVersionUID = 1L;
// 
//   public AmazonS3ZeroSizeException() {
//     super();
//   }
// 
//   public AmazonS3ZeroSizeException(final Throwable cause) {
//     super(cause);
//   }
// 
//   public AmazonS3ZeroSizeException(final String message) {
//     super(message);
//   }
// 
//   public AmazonS3ZeroSizeException(final String message, final Throwable cause) {
//     super(message, cause);
//   }
// }


// Path: pipeline-application/src/test/java/com/smoketurner/pipeline/application/core/AmazonS3DownloaderTest.java
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import com.amazonaws.AmazonClientException;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.event.S3EventNotification.S3BucketEntity;
import com.amazonaws.services.s3.event.S3EventNotification.S3Entity;
import com.amazonaws.services.s3.event.S3EventNotification.S3EventNotificationRecord;
import com.amazonaws.services.s3.event.S3EventNotification.S3ObjectEntity;
import com.amazonaws.services.s3.model.GetObjectRequest;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.S3Object;
import com.smoketurner.pipeline.application.exceptions.AmazonS3ConstraintException;
import com.smoketurner.pipeline.application.exceptions.AmazonS3ZeroSizeException;
import org.junit.Before;
import org.junit.Test;

    final S3BucketEntity bucket = new S3BucketEntity("bucket-name", null, null);
    final S3ObjectEntity object =
        new S3ObjectEntity("object-key", 100L, "object eTag", "object version", null);
    final S3Entity s3 = new S3Entity(null, bucket, object, null);
    record =
        new S3EventNotificationRecord(
            "us-east-1", null, "aws:s3", "1970-01-01T00:00:00.000Z", "2.0", null, null, s3, null);
  }

  @Test
  public void testFetch() throws Exception {
    final S3Object expected = new S3Object();
    expected.setKey("object-key");
    expected.setBucketName("bucket-name");
    expected.getObjectMetadata().setContentLength(100);

    when(mockS3.getObject(any(GetObjectRequest.class))).thenReturn(expected);

    final S3Object actual = downloader.fetch(record);
    verify(mockS3).getObject(any(GetObjectRequest.class));
    assertThat(actual).isEqualTo(expected);
  }

  @Test
  public void testFetchInvalidETag() throws Exception {
    when(mockS3.getObject(any(GetObjectRequest.class))).thenReturn(null);

    try {
      final S3Object download = downloader.fetch(record);
      assertThat(download).isNull();
      failBecauseExceptionWasNotThrown(AmazonS3ConstraintException.class);