// Path: src/main/java/org/learning/by/example/reactive/microservices/model/GeographicCoordinates.java
// public final class GeographicCoordinates {
// 
//     public double getLatitude() {
//         return latitude;
//     }
// 
//     public double getLongitude() {
//         return longitude;
//     }
// 
//     private final double latitude;
//     private final double longitude;
// 
//     @JsonCreator
//     public GeographicCoordinates(@JsonProperty("latitude") double latitude, @JsonProperty("longitude") double longitude) {
//         this.latitude = latitude;
//         this.longitude = longitude;
//     }
// }
// 
// Path: src/main/java/org/learning/by/example/reactive/microservices/model/SunriseSunset.java
// public class SunriseSunset {
// 
//     public String getSunrise() {
//         return sunrise;
//     }
// 
//     public String getSunset() {
//         return sunset;
//     }
// 
//     private final String sunrise;
//     private final String sunset;
// 
//     @JsonCreator
//     public SunriseSunset(@JsonProperty("sunrise") final String sunrise, @JsonProperty("sunset") final String sunset) {
//         this.sunrise = sunrise;
//         this.sunset = sunset;
//     }
// }
// 
// Path: src/main/java/org/learning/by/example/reactive/microservices/services/GeoLocationService.java
// public interface GeoLocationService {
// 
//     Mono<GeographicCoordinates> fromAddress(Mono<String> addressMono);
// }
// 
// Path: src/main/java/org/learning/by/example/reactive/microservices/services/SunriseSunsetService.java
// public interface SunriseSunsetService {
// 
//     Mono<SunriseSunset> fromGeographicCoordinates(Mono<GeographicCoordinates> geographicCoordinatesMono);
// }
// 
// Path: src/test/java/org/learning/by/example/reactive/microservices/test/BasicIntegrationTest.java
// public abstract class BasicIntegrationTest {
//     private WebTestClient client;
// 
//     protected void bindToRouterFunction(final RouterFunction<?> routerFunction) {
//         client = WebTestClient.bindToRouterFunction(routerFunction).build();
//     }
// 
//     protected void bindToServerPort(final int port) {
//         client = WebTestClient.bindToServer().baseUrl("http://localhost:" + port).build();
//     }
// 
//     protected String get(final Function<UriBuilder, URI> builder) {
//         return get(builder, HttpStatus.OK);
//     }
// 
//     private String get(final Function<UriBuilder, URI> builder, final HttpStatus status) {
//         return new String(client.get()
//                 .uri(builder)
//                 .accept(TEXT_HTML).exchange()
//                 .expectStatus().isEqualTo(status)
//                 .expectHeader().contentType(TEXT_HTML)
//                 .expectBody().returnResult().getResponseBody());
//     }
// 
//     protected <T> T get(final Function<UriBuilder, URI> builder, final HttpStatus status, final Class<T> type) {
//         return client.get()
//                 .uri(builder)
//                 .accept(APPLICATION_JSON_UTF8).exchange()
//                 .expectStatus().isEqualTo(status)
//                 .expectHeader().contentType(APPLICATION_JSON_UTF8)
//                 .expectBody(type)
//                 .returnResult().getResponseBody();
//     }
// 
//     protected <T> T get(final Function<UriBuilder, URI> builder, final Class<T> type) {
//         return get(builder, HttpStatus.OK, type);
//     }
// 
//     protected <T, K> T post(final Function<UriBuilder, URI> builder, final HttpStatus status, final K object, final Class<T> type) {
//         return client.post()
//                 .uri(builder)
//                 .body(BodyInserters.fromObject(object))
//                 .accept(APPLICATION_JSON_UTF8).exchange()
//                 .expectStatus().isEqualTo(status)
//                 .expectHeader().contentType(APPLICATION_JSON_UTF8)
//                 .expectBody(type)
//                 .returnResult().getResponseBody();
//     }
// 
//     protected <T, K> T post(final Function<UriBuilder, URI> builder, final K object, final Class<T> type) {
//         return post(builder, HttpStatus.OK, object, type);
//     }
// }


import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.learning.by.example.reactive.microservices.model.GeographicCoordinates;
import org.learning.by.example.reactive.microservices.model.SunriseSunset;
import org.learning.by.example.reactive.microservices.services.GeoLocationService;
import org.learning.by.example.reactive.microservices.services.SunriseSunsetService;
import org.learning.by.example.reactive.microservices.test.BasicIntegrationTest;
import org.learning.by.example.reactive.microservices.test.tags.IntegrationTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.web.reactive.function.server.RouterFunction;
import reactor.core.publisher.Mono;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.reset;
package org.learning.by.example.reactive.microservices.routers;



@IntegrationTest
@DisplayName("MainRouter Integration Tests")
class MainRouterTest extends BasicIntegrationTest {

    private static final String STATIC_ROUTE = "/index.html";
    private static final String LOCATION_PATH = "/api/location";
    private static final String ADDRESS_ARG = "{address}";
    private static final double GOOGLE_LAT = 37.4224082;
    private static final double GOOGLE_LNG = -122.0856086;
    private static final String GOOGLE_ADDRESS = "1600 Amphitheatre Parkway, Mountain View, CA";
    private static final String SUNRISE_TIME = "12:55:17 PM";
    private static final String SUNSET_TIME = "3:14:28 AM";

// Path: src/main/java/org/learning/by/example/reactive/microservices/model/GeographicCoordinates.java
// public final class GeographicCoordinates {
// 
//     public double getLatitude() {
//         return latitude;
//     }
// 
//     public double getLongitude() {
//         return longitude;
//     }
// 
//     private final double latitude;
//     private final double longitude;
// 
//     @JsonCreator
//     public GeographicCoordinates(@JsonProperty("latitude") double latitude, @JsonProperty("longitude") double longitude) {
//         this.latitude = latitude;
//         this.longitude = longitude;
//     }
// }
// 
// Path: src/main/java/org/learning/by/example/reactive/microservices/model/SunriseSunset.java
// public class SunriseSunset {
// 
//     public String getSunrise() {
//         return sunrise;
//     }
// 
//     public String getSunset() {
//         return sunset;
//     }
// 
//     private final String sunrise;
//     private final String sunset;
// 
//     @JsonCreator
//     public SunriseSunset(@JsonProperty("sunrise") final String sunrise, @JsonProperty("sunset") final String sunset) {
//         this.sunrise = sunrise;
//         this.sunset = sunset;
//     }
// }
// 
// Path: src/main/java/org/learning/by/example/reactive/microservices/services/GeoLocationService.java
// public interface GeoLocationService {
// 
//     Mono<GeographicCoordinates> fromAddress(Mono<String> addressMono);
// }
// 
// Path: src/main/java/org/learning/by/example/reactive/microservices/services/SunriseSunsetService.java
// public interface SunriseSunsetService {
// 
//     Mono<SunriseSunset> fromGeographicCoordinates(Mono<GeographicCoordinates> geographicCoordinatesMono);
// }
// 
// Path: src/test/java/org/learning/by/example/reactive/microservices/test/BasicIntegrationTest.java
// public abstract class BasicIntegrationTest {
//     private WebTestClient client;
// 
//     protected void bindToRouterFunction(final RouterFunction<?> routerFunction) {
//         client = WebTestClient.bindToRouterFunction(routerFunction).build();
//     }
// 
//     protected void bindToServerPort(final int port) {
//         client = WebTestClient.bindToServer().baseUrl("http://localhost:" + port).build();
//     }
// 
//     protected String get(final Function<UriBuilder, URI> builder) {
//         return get(builder, HttpStatus.OK);
//     }
// 
//     private String get(final Function<UriBuilder, URI> builder, final HttpStatus status) {
//         return new String(client.get()
//                 .uri(builder)
//                 .accept(TEXT_HTML).exchange()
//                 .expectStatus().isEqualTo(status)
//                 .expectHeader().contentType(TEXT_HTML)
//                 .expectBody().returnResult().getResponseBody());
//     }
// 
//     protected <T> T get(final Function<UriBuilder, URI> builder, final HttpStatus status, final Class<T> type) {
//         return client.get()
//                 .uri(builder)
//                 .accept(APPLICATION_JSON_UTF8).exchange()
//                 .expectStatus().isEqualTo(status)
//                 .expectHeader().contentType(APPLICATION_JSON_UTF8)
//                 .expectBody(type)
//                 .returnResult().getResponseBody();
//     }
// 
//     protected <T> T get(final Function<UriBuilder, URI> builder, final Class<T> type) {
//         return get(builder, HttpStatus.OK, type);
//     }
// 
//     protected <T, K> T post(final Function<UriBuilder, URI> builder, final HttpStatus status, final K object, final Class<T> type) {
//         return client.post()
//                 .uri(builder)
//                 .body(BodyInserters.fromObject(object))
//                 .accept(APPLICATION_JSON_UTF8).exchange()
//                 .expectStatus().isEqualTo(status)
//                 .expectHeader().contentType(APPLICATION_JSON_UTF8)
//                 .expectBody(type)
//                 .returnResult().getResponseBody();
//     }
// 
//     protected <T, K> T post(final Function<UriBuilder, URI> builder, final K object, final Class<T> type) {
//         return post(builder, HttpStatus.OK, object, type);
//     }
// }


// Path: src/test/java/org/learning/by/example/reactive/microservices/routers/MainRouterTest.java
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.learning.by.example.reactive.microservices.model.GeographicCoordinates;
import org.learning.by.example.reactive.microservices.model.SunriseSunset;
import org.learning.by.example.reactive.microservices.services.GeoLocationService;
import org.learning.by.example.reactive.microservices.services.SunriseSunsetService;
import org.learning.by.example.reactive.microservices.test.BasicIntegrationTest;
import org.learning.by.example.reactive.microservices.test.tags.IntegrationTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.web.reactive.function.server.RouterFunction;
import reactor.core.publisher.Mono;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.reset;

package org.learning.by.example.reactive.microservices.routers;



@IntegrationTest
@DisplayName("MainRouter Integration Tests")
class MainRouterTest extends BasicIntegrationTest {

    private static final String STATIC_ROUTE = "/index.html";
    private static final String LOCATION_PATH = "/api/location";
    private static final String ADDRESS_ARG = "{address}";
    private static final double GOOGLE_LAT = 37.4224082;
    private static final double GOOGLE_LNG = -122.0856086;
    private static final String GOOGLE_ADDRESS = "1600 Amphitheatre Parkway, Mountain View, CA";
    private static final String SUNRISE_TIME = "12:55:17 PM";
    private static final String SUNSET_TIME = "3:14:28 AM";

    private static final Mono<GeographicCoordinates> GOOGLE_LOCATION = Mono.just(new GeographicCoordinates(GOOGLE_LAT, GOOGLE_LNG));