package com.github.timtebeek.rst.controller;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import com.github.timtebeek.rst.MyApp;
import lombok.Getter;
import lombok.Setter;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.TestRestTemplate;
import org.springframework.boot.test.WebIntegrationTest;
import org.springframework.http.ResponseEntity;
import org.springframework.security.oauth2.client.test.OAuth2ContextConfiguration;
import org.springframework.security.oauth2.client.test.OAuth2ContextSetup;
import org.springframework.security.oauth2.client.test.RestTemplateHolder;
import org.springframework.security.oauth2.client.token.grant.password.ResourceOwnerPasswordResourceDetails;
import org.springframework.security.oauth2.common.exceptions.UserDeniedAuthorizationException;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.web.client.RestOperations;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = MyApp.class)
@WebIntegrationTest(randomPort = true)
public class MyControllerIT implements RestTemplateHolder {
	@Value("http://localhost:${local.server.port}")
	@Getter
	String						host;

	@Getter
	@Setter
	RestOperations				restTemplate	= new TestRestTemplate();

	@Rule
	public OAuth2ContextSetup	context			= OAuth2ContextSetup.standard(this);

	@Test
	@OAuth2ContextConfiguration(UserDetails.class)
	public void testHelloUser() {
		ResponseEntity<String> entity = getRestTemplate().getForEntity(host + "/hello", String.class);
		assertTrue(entity.toString(), entity.getStatusCode().is2xxSuccessful());
		assertEquals("Hello user", entity.getBody());
	}

	@Test
	@OAuth2ContextConfiguration(AliceDetails.class)
	public void testHelloAlice() {
		ResponseEntity<String> entity = getRestTemplate().getForEntity(host + "/hello", String.class);
		assertTrue(entity.toString(), entity.getStatusCode().is2xxSuccessful());
		assertEquals("Hello alice", entity.getBody());
	}

	@Test(expected=UserDeniedAuthorizationException.class)
	@OAuth2ContextConfiguration(EveDetails.class)
	public void testHelloEve() {
		getRestTemplate().getForEntity(host + "/hello", String.class);
	}
}

class UserDetails extends ResourceOwnerPasswordResourceDetails {
	public UserDetails(final Object obj) {
		MyControllerIT it = (MyControllerIT) obj;
		setAccessTokenUri(it.getHost() + "/oauth/token");
		setClientId("myclientwith");
		setUsername("user");
		setPassword("password");
	}
}

class AliceDetails extends ResourceOwnerPasswordResourceDetails {
	public AliceDetails(final Object obj) {
		MyControllerIT it = (MyControllerIT) obj;
		setAccessTokenUri(it.getHost() + "/oauth/token");
		setClientId("myclientwith");
		setUsername("alice");
		setPassword("password");
	}
}

class EveDetails extends ResourceOwnerPasswordResourceDetails {
	public EveDetails(final Object obj) {
		MyControllerIT it = (MyControllerIT) obj;
		setAccessTokenUri(it.getHost() + "/oauth/token");
		setClientId("myclientwith");
		setUsername("eve");
		setPassword("password");
	}
}

@@ -132,47 +132,8 @@
 e;%0A%0A
-import com.github.timtebeek.rst.MyApp;%0A
 impo
@@ -351,38 +351,30 @@
 est.
-SpringApplicationConfiguration
+context.SpringBootTest
 ;%0Aim
@@ -412,80 +412,44 @@
 est.
-TestRestTemplate;%0Aimport org.springframework.boot.t
+context.SpringBootT
 est.Web
-IntegrationTes
+Environmen
 t;%0Ai
@@ -1062,141 +1062,160 @@
 ns;%0A
-%0A@RunWith(SpringJUnit4ClassRunner.class)%0A@SpringApplicationConfiguration(classes = MyApp.class)%0A@WebIntegrationTest(randomPort = true
+import org.springframework.web.client.RestTemplate;%0A%0A@RunWith(SpringJUnit4ClassRunner.class)%0A@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT
 )%0Apu
@@ -1322,25 +1322,26 @@
 ort%7D%22)%0A%09
-@Getter%0A%09
+protected 
 String%09%09
@@ -1341,19 +1341,16 @@
 tring%09%09%09
-%09%09%09
 host;%0A%0A%09
@@ -1367,16 +1367,24 @@
 Setter%0A%09
+private 
 RestOper
@@ -1391,18 +1391,16 @@
 ations%09%09
-%09%09
 restTemp
@@ -1410,20 +1410,16 @@
 e%09= new 
-Test
 RestTemp
@@ -1621,36 +1621,33 @@
 tring%3E entity = 
-getR
+r
 estTemplate().ge
@@ -1633,34 +1633,32 @@
 y = restTemplate
-()
 .getForEntity(ho
@@ -1936,20 +1936,17 @@
 ntity = 
-getR
+r
 estTempl
@@ -1940,34 +1940,32 @@
 y = restTemplate
-()
 .getForEntity(ho
@@ -2137,17 +2137,19 @@
 expected
-=
+ = 
 UserDeni
@@ -2263,12 +2263,9 @@
 %7B%0A%09%09
-getR
+r
 estT
@@ -2271,18 +2271,16 @@
 Template
-()
 .getForE
@@ -2491,33 +2491,28 @@
 TokenUri(it.
-getH
+h
 ost
-()
  + %22/oauth/t
@@ -2776,33 +2776,28 @@
 TokenUri(it.
-getH
+h
 ost
-()
  + %22/oauth/t
@@ -3066,17 +3066,12 @@
 (it.
-getH
+h
 ost
-()
  + %22

Use @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) in test