package org.springframework.content.renditions.renderers;

import com.github.paulcwarren.ginkgo4j.Ginkgo4jConfiguration;
import com.github.paulcwarren.ginkgo4j.Ginkgo4jRunner;
import org.apache.poi.POIXMLProperties;
import org.apache.poi.openxml4j.exceptions.NotOfficeXmlFileException;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.junit.runner.RunWith;
import org.springframework.content.commons.renditions.RenditionProvider;
import org.springframework.content.renditions.RenditionException;
import org.springframework.renditions.poi.POIService;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

import static com.github.paulcwarren.ginkgo4j.Ginkgo4jDSL.*;
import static org.hamcrest.CoreMatchers.hasItem;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasItemInArray;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.nullValue;
import static org.hamcrest.core.IsInstanceOf.instanceOf;
import static org.mockito.Matchers.anyObject;
import static org.mockito.Mockito.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

@RunWith(Ginkgo4jRunner.class)
@Ginkgo4jConfiguration(threads = 1)
public class WordToJpegRendererTest {

	private POIService poi;
	private XWPFDocument doc;
	POIXMLProperties props;

	private RenditionProvider renderer;

	private InputStream input;
	private String mimeType;

	private Exception e;

	{
		Describe("WordToJpegRenderer", () -> {
			BeforeEach(() -> {
				poi = mock(POIService.class);
				renderer = new WordToJpegRenderer(poi);
			});
			Context("#consumes", () -> {
				It("should return word ml mimetype", () -> {
					assertThat(renderer.consumes(), is(
							"application/vnd.openxmlformats-officedocument.wordprocessingml.document"));
				});
			});
			Context("#produces", () -> {
				It("should return jpeg mimetype", () -> {
					assertThat(renderer.produces(), hasItemInArray("image/jpg"));
				});
			});
			Context("#convert", () -> {
				JustBeforeEach(() -> {
					try {
						renderer.convert(input, mimeType);
					}
					catch (Exception e) {
						this.e = e;
					}
				});
				Context("given an input stream and a mimetype", () -> {
					BeforeEach(() -> {
						doc = mock(XWPFDocument.class);
						when(poi.xwpfDocument(anyObject())).thenReturn(doc);
						props = mock(POIXMLProperties.class);
						when(doc.getProperties()).thenReturn(props);

						input = new ByteArrayInputStream("".getBytes());
					});
					It("should get the embedded thumbnail from the XWPFDocument's properties",
							() -> {
								verify(props).getThumbnailImage();
							});
					Context("when the input stream is not a valid word file", () -> {
						BeforeEach(() -> {
							doc = mock(XWPFDocument.class);
							doThrow(NotOfficeXmlFileException.class).when(poi)
									.xwpfDocument(anyObject());
						});
						It("should throw a RenditionException", () -> {
							assertThat(e, is(not(nullValue())));
							assertThat(e, is(instanceOf(RenditionException.class)));
						});
					});
					Context("when the word document fails to return properties", () -> {
						BeforeEach(() -> {
							doc = mock(XWPFDocument.class);
							when(poi.xwpfDocument(anyObject())).thenReturn(doc);
							props = mock(POIXMLProperties.class);
							doThrow(Exception.class).when(doc).getProperties();
						});
						It("should throw a RenditionException", () -> {
							assertThat(e, is(not(nullValue())));
							assertThat(e, is(instanceOf(RenditionException.class)));
						});
					});
					Context("when the word document fails to return a thumbnail", () -> {
						BeforeEach(() -> {
							doc = mock(XWPFDocument.class);
							when(poi.xwpfDocument(anyObject())).thenReturn(doc);
							props = mock(POIXMLProperties.class);
							when(doc.getProperties()).thenReturn(props);
							doThrow(IOException.class).when(props).getThumbnailImage();
						});
						It("should throw a RenditionException", () -> {
							assertThat(e, is(not(nullValue())));
							assertThat(e, is(instanceOf(RenditionException.class)));
						});
					});
				});
				Context("given a null input stream", () -> {
					It("should get the embedded thumbnail from the XWPFDocument's properties",
							() -> {
								assertThat(e, is(not(nullValue())));
							});
				});
			});
		});
	}
}

@@ -52,16 +52,110 @@
 erers;%0A%0A
+import java.io.ByteArrayInputStream;%0Aimport java.io.IOException;%0Aimport java.io.InputStream;%0A%0A
 import c
@@ -204,24 +204,24 @@
 figuration;%0A
-
 import com.g
@@ -259,24 +259,63 @@
 go4jRunner;%0A
+import org.apache.poi.POIXMLException;%0A
 import org.a
@@ -496,16 +496,17 @@
 unWith;%0A
+%0A
 import o
@@ -702,94 +702,205 @@
 ort 
-java.io.ByteArrayInputStream;%0Aimport java.io.IOException;%0Aimport java.io.InputStream;%0A
+static com.github.paulcwarren.ginkgo4j.Ginkgo4jDSL.BeforeEach;%0Aimport static com.github.paulcwarren.ginkgo4j.Ginkgo4jDSL.Context;%0Aimport static com.github.paulcwarren.ginkgo4j.Ginkgo4jDSL.Describe;
 %0Aimp
@@ -954,17 +954,18 @@
 go4jDSL.
-*
+It
 ;%0Aimport
@@ -976,41 +976,66 @@
 tic 
-org.hamcrest.CoreMatchers.hasItem
+com.github.paulcwarren.ginkgo4j.Ginkgo4jDSL.JustBeforeEach
 ;%0Aim
@@ -1410,9 +1410,15 @@
 ito.
-*
+doThrow
 ;%0Aim
@@ -1455,16 +1455,58 @@
 o.mock;%0A
+import static org.mockito.Mockito.verify;%0A
 import s
@@ -3708,24 +3708,25 @@
 %0A%09%09%09%09%09%09%09
+%09
 doThrow(
 Exceptio
@@ -3717,16 +3717,22 @@
 doThrow(
+POIXML
 Exceptio

Throw the correct exception for the test