Search code examples
spring-bootunit-testingjunit4junit5

Unit test case in Springboot MockMvc returns 403 Forbidden


I wrote unit test case for controller for Post api. But test case failed. For refernce I have put output log details. So please Any one help me where I am getting wrong. This is api for PDFTaggerController . Here @RequestPart FileContent is pdf document .

@RequestMapping(value = "/v1/getFillableFormElements", method = RequestMethod.POST)
    public @ResponseBody HttpEntity getFillableFormElements(@RequestPart("FileContent") @Valid 
    MultipartFile FileContent, @RequestParam int pageNo) throws IOException {
    FormElementsService formElementsService = new 
     FormElementsServiceImpl();         
  formElementsService .process(pdfFilePath,returnFilePath);
            return setReturnHttpHeaders(returnFilePath);
}

test case for above

@WebMvcTest
@ContextConfiguration(classes = PDFTaggerController.class) 
public class PDFTaggerControllerTests {
    @MockBean
    PDFTaggerController controller;
    @Autowired
    private MockMvc mockMvc;
    @Autowired
    private WebApplicationContext webApplicationContext;

    @Before()
    public void setup()
    {
        mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
    }
    
    @Test
    public void getFillableFormElements() throws Exception {
        File file = new File("C:\\Downloads\\sample.pdf");
        FileInputStream fileInputStream = new FileInputStream(file);
        MockMultipartFile firstFile = new MockMultipartFile("file", file.getName(), 
        "multipart/.pdf", fileInputStream);
        
        doNothing().when(retrieveFillableFormElementsService).process(anyString(), anyString());             
        mockMvc.perform(MockMvcRequestBuilders.multipart("/api/v1/getFillableFormElements")
                 .file(firstFile)
                 .param("pageNo", "0"))
                 .andExpect(status().isOk());
    }
}

And this is the output of the test getting

MockHttpServletRequest:
      HTTP Method = POST
      Request URI = /api/v1/getFillableFormElements
       Parameters = {pageNo=[0]}
          Headers = [Content-Type:"multipart/form-data;charset=UTF-8"]
             Body = null
    Session Attrs = {org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository.CSRF_TOKEN=org.springframework.security.web.csrf.DefaultCsrfToken@5d08976a}

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 = 403
    Error message = Forbidden
          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", X-Frame-Options:"DENY"]
     Content type = null
             Body = 
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

Spring Security config

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private AuthenticationEntryPoint authenticationEntryPoint;
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/api/v1/status");
    }
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable().
        authorizeRequests().antMatchers("*").permitAll()
        .antMatchers("/pingnot").anonymous()
        .antMatchers("/**").authenticated().and().exceptionHandling().and().httpBasic()
        .authenticationEntryPoint(authenticationEntryPoint).and().sessionManagement()
        .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        http.authorizeRequests().antMatchers("/swagger-ui.html").authenticated().and()
        .formLogin().permitAll().and()
        .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED);
        http.addFilterBefore(new BasicAuthenticationFilter(authenticationManager()), BasicAuthenticationFilter.class);
    }

Solution

  • I did following changes in my code and it starts working for me after a lot of explorations. First I changed

    @RequestParam int pageNo
    

    to

    @RequestParam (value = "pageNo", required =false) Integer pageNo
    

    and for removing the 403 forbidden error . Then I added dependency in gradle file

    testImplementation ('org.springframework.security:spring-security-test')
    

    and added the

    @AutoConfigureMockMvc(addFilters = false)
    

    annotation to PDFTaggerControllerTests class.

    Last, I added

    mockMvc.perform(MockMvcRequestBuilders.multipart("/api/v1/getFillableFormElements")
                     .file(firstFile)
                     .header("Authorization", appropriateToken)
                     .with(csrf())
                     .requestAttr("pageNo", 0))
                     .andExpect(status().isOk());