/*
 * Copyright 2002-2017 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package sample;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.rsocket.context.RSocketServerInitializedEvent;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.ApplicationListener;
import org.springframework.messaging.rsocket.RSocketRequester;
import org.springframework.security.rsocket.metadata.BasicAuthenticationEncoder;
import org.springframework.security.rsocket.metadata.UsernamePasswordMetadata;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringRunner;

import org.junit.Test;
import org.junit.runner.RunWith;
import reactor.core.publisher.Mono;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.springframework.security.rsocket.metadata.UsernamePasswordMetadata.BASIC_AUTHENTICATION_MIME_TYPE;

/**
 * @author Rob Winch
 * @since 5.0
 */
@RunWith(SpringRunner.class)
@TestPropertySource(properties = "spring.rsocket.server.port=0")
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class HelloRSocketApplicationITests {

	@Autowired
	RSocketRequester.Builder requester;

	@Test
	public void messageWhenAuthenticatedThenSuccess() {
		UsernamePasswordMetadata credentials = new UsernamePasswordMetadata("user", "password");
		RSocketRequester requester = this.requester
				.rsocketStrategies(builder -> builder.encoder(new BasicAuthenticationEncoder()))
				.setupMetadata(credentials, BASIC_AUTHENTICATION_MIME_TYPE)
				.connectTcp("localhost", getPort())
				.block();

		String message = requester.route("message")
				.data(Mono.empty())
				.retrieveMono(String.class)
				.block();

		assertThat(message).isEqualTo("Hello");
	}

	@Test
	public void messageWhenNotAuthenticatedThenError() {
		RSocketRequester requester = this.requester
				.connectTcp("localhost", getPort())
				.block();

		assertThatThrownBy(() -> requester.route("message")
				.data(Mono.empty())
				.retrieveMono(String.class)
				.block())
				.isNotNull();
	}

	// FIXME: Waiting for @LocalRSocketServerPort
	// https://github.com/spring-projects/spring-boot/pull/18287

	@Autowired
	Config config;

	private int getPort() {
		return this.config.port;
	}

	@TestConfiguration
	static class Config implements ApplicationListener<RSocketServerInitializedEvent> {
		private int port;

		@Override
		public void onApplicationEvent(RSocketServerInitializedEvent event) {
			this.port = event.getServer().address().getPort();
		}
	}
}

@@ -17,17 +17,17 @@
 2002-201
-7
+9
  the ori
@@ -743,16 +743,21 @@
 context.
+Local
 RSocketS
@@ -761,31 +761,19 @@
 etServer
-InitializedEven
+Por
 t;%0Aimpor
@@ -832,128 +832,8 @@
 st;%0A
-import org.springframework.boot.test.context.TestConfiguration;%0Aimport org.springframework.context.ApplicationListener;%0A
 impo
@@ -1533,16 +1533,41 @@
 b Winch%0A
+ * @author Edd%C3%BA Mel%C3%A9ndez%0A
  * @sinc
@@ -1842,16 +1842,53 @@
 ester;%0A%0A
+%09@LocalRSocketServerPort%0A%09int port;%0A%0A
 %09@Test%0A%09
@@ -2250,33 +2250,33 @@
 localhost%22, 
-getP
+this.p
 ort
-()
 )%0A%09%09%09%09.block
@@ -2579,25 +2579,25 @@
 lhost%22, 
-getP
+this.p
 ort
-()
 )%0A%09%09%09%09.b
@@ -2755,472 +2755,6 @@
 %09%7D%0A%0A
-%09// FIXME: Waiting for @LocalRSocketServerPort%0A%09// https://github.com/spring-projects/spring-boot/pull/18287%0A%0A%09@Autowired%0A%09Config config;%0A%0A%09private int getPort() %7B%0A%09%09return this.config.port;%0A%09%7D%0A%0A%09@TestConfiguration%0A%09static class Config implements ApplicationListener%3CRSocketServerInitializedEvent%3E %7B%0A%09%09private int port;%0A%0A%09%09@Override%0A%09%09public void onApplicationEvent(RSocketServerInitializedEvent event) %7B%0A%09%09%09this.port = event.getServer().address().getPort();%0A%09%09%7D%0A%09%7D%0A
 %7D%0A

Use LocalRSocketServerPort annotation