0

I am using Spring Boot 2.0.6 and have set up a test for a controller: the method is as follows:

@Secured("ROLE_ADMIN")
@GetMapping(value = {"/maintainers/aircrafts/workorders/workitems/{wid}/parts"}, produces = "application/json")
@ResponseStatus(value = HttpStatus.OK)
Response<Page<WorkItem>> getPagedParts(
        @PathVariable("wid") Optional<Long> workItemId,
        @PageableDefault(page = DEFAULT_PAGE_NUMBER, size = DEFAULT_PAGE_SIZE)
        @SortDefault.SortDefaults({
                @SortDefault(sort = "partName", direction = Sort.Direction.ASC),
                @SortDefault(sort = "partSpecification", direction = Sort.Direction.ASC)
        }) Pageable pageable) {
    LOG.info("looking for work: {}", workItemId);
    return Response.of(workItemService.findAllPartsForWorkItem(workItemId.get(), pageable));
}

As you can see, it is supposed to do paging and sorting, but it doesn't even get past the path:

The test that tests it is as follows:

@ActiveProfiles("embedded")
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@EnableConfigurationProperties
@EnableJpaRepositories({ "au.com.avmaint.api" })
@AutoConfigureMockMvc
public class WorkItemControllerPartsFunctionalTest {

    private static final Logger LOG = LoggerFactory.getLogger(WorkItemControllerFunctionalTest.class);

    private String adminJwtToken;

    @Autowired
    private WebApplicationContext context;

    @Autowired
    private MockMvc mvc;

    @Autowired
    private UserService userService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private CasaService casaService;

    @Autowired
    private MaintainerService maintainerService;

    @Autowired
    private MaintenanceContractService maintenanceContractService;

    @Autowired
    private WorkSetService workSetService;

    @Autowired
    private WorkSetTemplateService workSetTemplateService;

    @Autowired
    private AircraftService aircraftService;

    Maintainer franks;
    MaintenanceContract contract;

    @Before
    public void setup() {
        mvc = MockMvcBuilders
                .webAppContextSetup(context)
                .apply(springSecurity())
                .build();

        franks = MaintainerFixtures.createFranksMaintainer(maintainerService, maintenanceContractService, casaService);

        adminJwtToken = UserAndRoleFixtures.adminToken(userService, roleService, franks);

        contract = WorkItemFixtures.makeDetailedJobOnContract(franks, maintainerService, maintenanceContractService, workSetTemplateService, casaService, aircraftService);


    }

    @Test
    public void findingWorkItemsWithoutParts() throws Exception {

        Set<WorkSet> sets = contract.getWorkOrders().stream().findFirst().get().getWorkSets();

        WorkSet hundredHourly = sets.stream().filter(s -> s.getName().equals("100 Hourly for PA-31")).findFirst().orElse(null);

        WorkItem opening = hundredHourly.getWorkItems().stream().filter(wi -> wi.getTitle().equals("Opening the aircraft")).findFirst().orElse(null);

        LOG.info("opening item: {}", opening);

        LOG.info("HUNDRED: {}", hundredHourly);

        mvc.perform(get("/maintainers/aircrafts/workorders/workitems/" + opening.getId() + "/parts")
                .header(AUTHORIZATION_HEADER, "Bearer " + adminJwtToken))
                .andDo(print())
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.payload").isNotEmpty())
                .andExpect(jsonPath("$.payload.content").isNotEmpty())
                .andExpect(jsonPath("$.payload.pageable").isNotEmpty())
                .andExpect(jsonPath("$.payload.last").value(false))
                .andExpect(jsonPath("$.payload.totalPages").value(3))           // page count
                .andExpect(jsonPath("$.payload.totalElements").value(9))       // total count
                .andExpect(jsonPath("$.payload.size").value(4))                // elements per page
                .andExpect(jsonPath("$.payload.numberOfElements").value(4))    // elements in page
                .andExpect(jsonPath("$.payload.number").value(0))               // current page number
                .andExpect(jsonPath("$.payload.content").isArray())
                // oops, lets not check dates, they're created on the instant
                .andExpect(jsonPath("$.payload.content[0].pos").value("1"))
                .andExpect(jsonPath("$.payload.content[0].title").value("Opening the aircraft"))
                .andExpect(jsonPath("$.payload.content[0].category").value("AIRFRAME"))
        ;

    }

    @After
    public void tearDown() {

        MaintainerFixtures.removeFranks(franks, maintainerService, aircraftService);
        WorkItemFixtures.killJobs(workSetService, workSetTemplateService);
        UserAndRoleFixtures.killAllUsers(userService, roleService);
    }
}

As the project makes extensive use of JPA, there are annotations and a lot of data setup, but all of this has worked fine with other tests and there don't appear to be any problems with the data. In fact a peek at the JSON output for the work order that this method should be querying...

work order JSON

Basically has all the data correctly set up. The spring boot startup includes this line:

2018-11-12 06:32:17.362  INFO 83372 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/maintainers/aircrafts/workorders/workitems/{wid}/parts],methods=[GET],produces=[application/json]}" onto au.com.avmaint.api.common.Response<org.springframework.data.domain.Page<au.com.avmaint.api.aircraft.model.WorkItem>> au.com.avmaint.api.aircraft.WorkItemController.getPagedParts(java.util.Optional<java.lang.Long>,org.springframework.data.domain.Pageable)

So the path appears to be OK

and now to the .andDo(print()) output:

MockHttpServletRequest:
      HTTP Method = GET
      Request URI = /maintainers/aircrafts/workorders/workitems/5/parts
       Parameters = {}
          Headers = {Authorization=[Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJmcmFua0BmcmFua3MuY29tIiwic2NvcGVzIjpbIlJPTEVfQURNSU4iLCJST0xFX0JBU0lDIl0sImV4cCI6MTU0MjgyODczOH0.QOTiyWG_pVL9qb8MDG-2c_nkTnsIzceUH-5vvtmpZhBcdro9HqVADojK0-c6B1sAOOYOcprpwg4-wrBF0PGweg]}
             Body = <no character encoding set>
    Session Attrs = {}

Handler:
             Type = org.springframework.web.servlet.resource.ResourceHttpRequestHandler

Async:
    Async started = false
     Async result = null

Resolved Exception:
             Type = null

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

FlashMap:
       Attributes = null

MockHttpServletResponse:
           Status = 404
    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], X-Frame-Options=[DENY]}
     Content type = null
             Body = 
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

and the 404. So I guess I'm breaking something somewhere, I just can't see what it is, can anyone help with this?

Michael Coxon
  • 3,337
  • 8
  • 46
  • 68

1 Answers1

0

Sorry everyone, the effect of tearing my hair out for ages, finally posting the question and then finding the problem moments later.

The issue was that I forgot to put /api as the prefix on the path in the test. This prefix is put on the top of every controller with:

@RestController
@RequestMapping("/api")
public class WorkItemController {

so, yeah: it works now

Michael Coxon
  • 3,337
  • 8
  • 46
  • 68