package study.reactivesecurity;

import java.net.URI;
import java.net.http.*;
import java.time.Duration;
import org.junit.jupiter.api.Test;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.server.LocalServerPort;
import static org.junit.jupiter.api.Assertions.*;

@DirtiesContext(classMode=DirtiesContext.ClassMode.AFTER_CLASS)
@SpringBootTest(classes=SecurityLab.class,webEnvironment=SpringBootTest.WebEnvironment.RANDOM_PORT,
    properties={"server.address=127.0.0.1","spring.main.web-application-type=reactive"})
class JwtHttpTest {
    @Autowired JwtKeys keys;
    @LocalServerPort int port;
    @Test void realReactiveDecoderRejectsIndependentBadClaimsThenRecovers() throws Exception {
        assertEquals(200,get("valid"));
        for(String variant:new String[]{"signature","issuer","audience","expired","future"}) {
            assertEquals(401,get(variant),variant);
            assertEquals(200,get("valid"),"recovery after "+variant);
        }
        assertEquals(403,get("scope"));
        assertEquals(200,get("valid"));
    }
    int get(String variant) throws Exception {
        try(var client=HttpClient.newHttpClient()) {
            var request=HttpRequest.newBuilder(URI.create("http://127.0.0.1:"+port+"/jwt/who"))
                .timeout(Duration.ofSeconds(5)).header("Authorization","Bearer "+keys.token(variant)).GET().build();
            int status=client.send(request,HttpResponse.BodyHandlers.ofString()).statusCode();
            System.out.println("U31OBSERVE jwt variant="+variant+" status="+status);
            return status;
        }
    }
}
