package org.octoprint.api.test;

import static org.junit.Assert.*;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import org.octoprint.api.OctoPrintHttpRequest;
import org.octoprint.api.OctoPrintInstance;
import org.octoprint.api.exceptions.ConnectionFailedException;
import org.octoprint.api.exceptions.InvalidApiKeyException;
import org.octoprint.api.exceptions.NoContentException;
import org.octoprint.api.exceptions.OctoPrintAPIException;

public class ExceptionTest {
	private URL testURL = null;
	private OctoPrintInstance instance = null;
	private OctoPrintHttpRequest request = null;
	
	public ExceptionTest() {
		
		//create a temp url
		try {
			testURL = new URL("http://localhost");
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private HttpURLConnection connectionMock(int response,String output){
		HttpURLConnection conn = Mockito.mock(HttpURLConnection.class);
		
		try{
			Mockito.when(conn.getResponseCode()).thenReturn(response);
			Mockito.when(conn.getInputStream()).thenReturn(new ByteArrayInputStream(output.getBytes()));
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		
		return conn;
	}
	
	@Before
	public void beforeTest() throws Exception {
		instance = new OctoPrintInstance(testURL,"");
		request = Mockito.mock(OctoPrintHttpRequest.class);
		
	}
	
	@Test
	public void successfulUpdateTest(){
		HttpURLConnection conn = this.connectionMock(200, "");
		Mockito.when(request.createConnection(testURL, "")).thenReturn(conn);
		
		assertTrue(instance.executeUpdate(request));
	}
	
	@Test 
	public void successfulQueryTest(){
		HttpURLConnection conn = this.connectionMock(204, "{\"connection\":true}");
		Mockito.when(request.createConnection(testURL, "")).thenReturn(conn);
		
		assertEquals(instance.executeQuery(request).toJson(),"{\"connection\":true}");
	}
	
	@Test(expected = InvalidApiKeyException.class)
	public void invalidKeyTest(){
		
		HttpURLConnection conn = this.connectionMock(InvalidApiKeyException.STATUS_CODE, "");
		Mockito.when(request.createConnection(testURL, "")).thenReturn(conn);
		
		//should throw an invalid API key exception
		instance.executeQuery(request);
		
	}
	
	@Test
	public void nonContentExceptionTest(){
		HttpURLConnection conn = this.connectionMock(NoContentException.STATUS_CODE, "");
		Mockito.when(request.createConnection(testURL, "")).thenReturn(conn);
		
		//should throw an exception, which is caught and then false returned
		assertFalse(instance.executeUpdate(request));
	}
	
	@Test(expected = ConnectionFailedException.class)
	public void connection() throws IOException{
		
		//purposly throw exception so that 
		HttpURLConnection conn = Mockito.mock(HttpURLConnection.class);
		Mockito.when(conn.getResponseCode()).thenThrow(IOException.class);
		
		Mockito.when(request.createConnection(testURL, "")).thenReturn(conn);
		
		//should throw an invalid API key exception
		instance.executeQuery(request);
		
	}
	
	@Test(expected = OctoPrintAPIException.class)
	public void octoprintExceptionTest(){
		
		//throw an error not caught by any others
		HttpURLConnection conn = this.connectionMock(409 , "Conflict Error");
		Mockito.when(request.createConnection(testURL, "")).thenReturn(conn);
		
		//should throw an exception
		instance.executeQuery(request);
		
	}
}

@@ -775,18 +775,17 @@
 = null;%0A
-%09
 %0A
+
 %09public 
@@ -1627,17 +1627,17 @@
 nMock(20
-0
+4
 , %22%22);%0A%09
@@ -1855,17 +1855,17 @@
 nMock(20
-4
+0
 , %22%7B%5C%22co
@@ -2376,32 +2376,69 @@
 ;%0A%09%09%0A%09%7D%0A%09%0A%09@Test
+(expected = NoContentException.class)
 %0A%09public void no
@@ -2654,64 +2654,11 @@
 tion
-, which is caught and then false returned%0A%09%09assertFalse(
+%0A%09%09
 inst
@@ -2661,38 +2661,37 @@
 instance.execute
-Update
+Query
 (request));%0A%09%7D%0A%09
@@ -2675,33 +2675,32 @@
 teQuery(request)
-)
 ;%0A%09%7D%0A%09%0A%09@Test(ex

test should pass now, from 200 to 204 changes