Spring Boot Atlassian Connect MockMvc integration testing

Hi,

I want to develop some SpringBoot MockMvc integration tests that simulate the call from a Confluence Cloud dynamic macro. A code snippet from the integration unit test can be seen below:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc // need this in Spring Boot test
public class ModelGenAtlassianConnectPluginMockMvcTest {

	@Autowired
	private MockMvc mockMvc;
	@Test
	public void TestModelGen() {
		try {

			StringBuilder sb = new StringBuilder("/model-gen?");
			for (String key : PARAMETERS.keySet()) {
				sb.append(key).append("=").append(PARAMETERS.get(key)).append("&");
			}
			this.mockMvc.perform(get(sb.toString())).andDo(print()).andExpect(status().isOk())
					.andExpect(content().string(containsString(.....)));
		} catch (Exception e) {
			e.printStackTrace();
			fail(e.getMessage());
		}
	}

The PARAMETERS being passed simulate the parameters passed by the macro, including the JWT auth token. For the purposes of testing I am substituting a token generated by Confluence Cloud and sent to the app in PROD (realise that this is not a long term solution but just wanted to get a basic response coming back).

The problem is that I am getting the following error when the unit test runs:

2021-04-08 17:40:02.173 DEBUG 54770 --- [           main] c.a.c.s.i.a.j.JwtAuthenticationProvider  : Parsed JWT: {"sub":"XXX","qsh":"YYY","iss":"ZZZ","context":{},"exp":1617798091,"iat":1617797911}
2021-04-08 17:40:02.241 DEBUG 54770 --- [           main] c.a.c.s.i.a.j.JwtAuthenticationProvider  : Could not find an installed host for the provided client key: ZZZ
2021-04-08 17:40:02.247  WARN 54770 --- [           main] c.a.c.s.i.a.jwt.JwtAuthenticationFilter  : Failed to authenticate request

com.atlassian.connect.spring.internal.auth.jwt.UnknownJwtIssuerException: Could not find an installed host for the provided client key: ZZZ

The MockMvc HTTP headers are as follows:

MockHttpServletRequest:
      HTTP Method = GET
      Request URI = /model-gen
       Parameters = {jwt=[XXX], lic=[active], xdm_e=[https://cpas.atlassian.net], cp=[/wiki], space=[196609], xdm_c=[channel-visio-publisher-for-confluence__visio-publisher-for-confluence1796614187510529806], spaceKey=[VM], scrolling=[no], cv=[1.952.0], xdm_deprecated_addon_key_do_not_use=[visio-publisher-for-confluence], width=[100%], checksum=[a812ab04c31134b459f9e236dd9d85fc2757d3ad6593b0220ad0f2543e1371f4], html=[WBC Group System], frameborder=[hide], page=[737542234], height=[1000]}
          Headers = []
             Body = null
    Session Attrs = {}

Handler:
             Type = null

Async:
    Async started = false
     Async result = null

Resolved Exception:
             Type = null

ModelAndView:
        View name = null
             View = null
            Model = null

FlashMap:
       Attributes = null

MockHttpServletResponse:
           Status = 200
    Error message = null
          Headers = [X-Content-Type-Options:"nosniff", X-XSS-Protection:"1; mode=block", Cache-Control:"no-cache, no-store, max-age=0, must-revalidate", Pragma:"no-cache", Expires:"0", Referrer-Policy:"origin-when-cross-origin"]
     Content type = null
             Body = 
    Forwarded URL = /error
   Redirected URL = null
          Cookies = []

Is there a simple way to disable JWT authentication for the purposes of unit tests, or can a dummy JWT be substituted? Any assistance would be gratefully received.

Thanks and regards
Andrew

Hi @AndrewTyson,

NoAuthenticationIT provides an example for you to follow:

@SpringBootTest(..., properties = "atlassian.connect.require-auth-exclude-paths=/no-auth")

I double-checked that the test passes fine with MockMvc as well (and fails without the require-auth-exclude-paths property):

mvc.perform(get("/no-auth"))
    .andExpect(status().isOk())
    .andExpect(content().string(is("No authentication required")));

If you need a security context, have a look at BaseApplicationIT#setJwtAuthenticatedPrincipal for how to pass a TestingAuthenticationToken into SecurityContextHolder.

3 Likes

Thanks @epehrson - appreciated!