@Test
    public void testAjaxRequestAfterStandardRequestShouldNotOverrideState() throws MalformedURLException, URISyntaxException {
        var client = getClient();
        client.setCallbackUrl(CALLBACK_URL);
        client.setAjaxRequestResolver(new AjaxRequestResolver() {
            boolean first = true;
            @Override
            public boolean isAjax(final CallContext ctx) {
                /*
                 * Considers that the first request is not ajax, all the subsequent ones are
                 */
                if (first) {
                    first = false;
                    return false;
                } else {
                    return true;
                }
            }
            @Override
            public HttpAction buildAjaxResponse(final CallContext ctx, final RedirectionActionBuilder redirectionActionBuilder) {
                return new StatusAction(401);
            }
        });

        val webContext = MockWebContext.create();
        val sessionStore = new MockSessionStore();
        val ctx = new CallContext(webContext, sessionStore, ProfileManagerFactory.DEFAULT);

        WithLocationAction firstRequestAction = (FoundAction) client.getRedirectionAction(ctx).orElse(null);
        var state = TestsHelper.splitQuery(new URL(firstRequestAction.getLocation())).get("state");

        try {
            //noinspection ThrowableNotThrown
            client.getRedirectionAction(ctx);
            fail("Ajax request should throw exception");
        } catch (Exception e) {
            var stateAfterAjax = (State) sessionStore.get(webContext, client.getStateSessionAttributeName()).orElse(null);
            assertEquals("subsequent ajax request should not override the state in the session store", state, stateAfterAjax.toString());
        }

    }
This class tests client redirects.

@author Jerome Leleu
@since 1.0.0
pac4j-oidc/src/test/java/org/pac4j/oidc/client/OidcRedirectTests.java