package com.example.todo;
import java.time.Instant;
import java.util.Base64;
import java.util.List;
import javax.crypto.SecretKey;
import org.junit.jupiter.api.Test;
import org.springframework.security.oauth2.jose.jws.MacAlgorithm;
import org.springframework.security.oauth2.jwt.*;
import static org.junit.jupiter.api.Assertions.*;
class JwtTest {
    final SecurityConfig config=new SecurityConfig();
    final SecretKey key=config.jwtKey(Base64.getEncoder().encodeToString(new byte[32]));
    String token(String issuer,String audience,Instant expires) {
        JwtClaimsSet claims=JwtClaimsSet.builder().issuer(issuer).subject("alice")
            .audience(List.of(audience)).issuedAt(Instant.now().minusSeconds(1000)).expiresAt(expires).build();
        return config.jwtEncoder(key).encode(JwtEncoderParameters.from(JwsHeader.with(MacAlgorithm.HS256).build(),claims)).getTokenValue();
    }
    @Test void validTokenAccepted() {
        assertEquals("alice",config.jwtDecoder(key,"todo-training","todo-api")
            .decode(token("todo-training","todo-api",Instant.now().plusSeconds(900))).getSubject());
    }
    @Test void invalidClaimsAndSignatureRejected() {
        JwtDecoder decoder=config.jwtDecoder(key,"todo-training","todo-api");
        assertThrows(JwtException.class,() -> decoder.decode(token("other","todo-api",Instant.now().plusSeconds(900))));
        assertThrows(JwtException.class,() -> decoder.decode(token("todo-training","other",Instant.now().plusSeconds(900))));
        assertThrows(JwtException.class,() -> decoder.decode(token("todo-training","todo-api",Instant.now().minusSeconds(300))));
        byte[] other=new byte[32]; other[0]=1;
        JwtDecoder wrongKey=config.jwtDecoder(config.jwtKey(Base64.getEncoder().encodeToString(other)),"todo-training","todo-api");
        assertThrows(JwtException.class,() -> wrongKey.decode(token("todo-training","todo-api",Instant.now().plusSeconds(900))));
    }
}
