Skip to content

Commit 9b08035

Browse files
committed
test: Decorator should see interceptor-bound ScopedValue
1 parent 9c28e01 commit 9b08035

1 file changed

Lines changed: 47 additions & 0 deletions

File tree

src/test/java/com/retailsvc/http/internal/DispatchHandlerTest.java

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,31 +2,56 @@
22

33
import static java.net.HttpURLConnection.HTTP_OK;
44
import static org.assertj.core.api.Assertions.assertThat;
5+
import static org.mockito.ArgumentMatchers.any;
6+
import static org.mockito.ArgumentMatchers.anyString;
7+
import static org.mockito.Mockito.doAnswer;
58
import static org.mockito.Mockito.mock;
69
import static org.mockito.Mockito.when;
710

811
import com.retailsvc.http.Request;
912
import com.retailsvc.http.RequestHandler;
13+
import com.retailsvc.http.RequestInterceptor;
1014
import com.retailsvc.http.Response;
15+
import com.retailsvc.http.ResponseDecorator;
1116
import com.sun.net.httpserver.Headers;
1217
import com.sun.net.httpserver.HttpExchange;
18+
import java.util.HashMap;
1319
import java.util.List;
1420
import java.util.Map;
1521
import java.util.concurrent.atomic.AtomicBoolean;
22+
import java.util.concurrent.atomic.AtomicReference;
1623
import org.junit.jupiter.api.Test;
1724

1825
class DispatchHandlerTest {
1926

27+
private static final ScopedValue<String> CORRELATION_ID = ScopedValue.newInstance();
28+
2029
private static HttpExchange stubExchange() {
2130
HttpExchange exchange = mock(HttpExchange.class);
2231
when(exchange.getResponseHeaders()).thenReturn(new Headers());
32+
Map<String, Object> attrs = new HashMap<>();
33+
doAnswer(
34+
inv -> {
35+
attrs.put(inv.getArgument(0), inv.getArgument(1));
36+
return null;
37+
})
38+
.when(exchange)
39+
.setAttribute(anyString(), any());
40+
when(exchange.getAttribute(anyString())).thenAnswer(inv -> attrs.get(inv.getArgument(0)));
2341
return exchange;
2442
}
2543

2644
private static DispatchHandler dispatcher(Map<String, RequestHandler> handlers) {
2745
return new DispatchHandler(handlers, List.of(), List.of(), new ResponseRenderer(Map.of()));
2846
}
2947

48+
private static DispatchHandler dispatcher(
49+
Map<String, RequestHandler> handlers,
50+
List<RequestInterceptor> interceptors,
51+
List<ResponseDecorator> decorators) {
52+
return new DispatchHandler(handlers, interceptors, decorators, new ResponseRenderer(Map.of()));
53+
}
54+
3055
private static void withRequest(String operationId, ScopedValue.CallableOp<Void, Exception> body)
3156
throws Exception {
3257
Request req = new Request(new byte[0], null, null, operationId, Map.of(), null, n -> null);
@@ -52,4 +77,26 @@ void invokesRegisteredHandler() throws Exception {
5277

5378
assertThat(called.get()).isTrue();
5479
}
80+
81+
@Test
82+
void decoratorSeesInterceptorBoundScopedValue() throws Exception {
83+
RequestHandler ok = req -> Response.status(HTTP_OK);
84+
RequestInterceptor bindCid =
85+
(request, next) -> ScopedValue.where(CORRELATION_ID, "cid-123").call(next::proceed);
86+
ResponseDecorator stampCid =
87+
(req, resp) -> resp.withHeader("X-Correlation-Id", CORRELATION_ID.get());
88+
89+
HttpExchange ex = stubExchange();
90+
AtomicReference<Response> rendered = new AtomicReference<>();
91+
92+
withRequest(
93+
"get-x",
94+
() -> {
95+
dispatcher(Map.of("get-x", ok), List.of(bindCid), List.of(stampCid)).handle(ex);
96+
rendered.set((Response) ex.getAttribute(DispatchHandler.RESPONSE_ATTR));
97+
return null;
98+
});
99+
100+
assertThat(rendered.get().headers()).containsEntry("X-Correlation-Id", "cid-123");
101+
}
55102
}

0 commit comments

Comments
 (0)