Class TicketsWebServiceTest
java.lang.Object
ubic.gemma.rest.TicketsWebServiceTest
@ExtendWith(org.mockito.junit.jupiter.MockitoExtension.class)
public class TicketsWebServiceTest
extends Object
Pure Mockito unit tests for
TicketsWebService covering the
read-only endpoints introduced in Phase B-2 of
AUDIT_AS_WORKFLOW_RECCE.md. Does NOT stand up Jersey; the focus is
the WebService → service wiring and the VO projection shape.- Author:
- paul
-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionvoidvoidvoidvoidA scratchpad is never resolved, so counting one as open work would put every curator permanently behind.voidThe route provisions through the service and hands back the projection.voidvoidvoidvoidvoidvoidThe default lives in the@DefaultValueannotation, which JAX-RS applies during parameter binding — calling the method directly never sees it, so it is asserted on the wire contract itself.voidvoidThe caller's identity decides whose scratchpad is worth offering, so it has to reach the service.voidA limit the endpoint will not honour is refused, not quietly reduced — a silent clamp teaches the client nothing about why it got 100 rows back when it asked for 500.voidvoidvoidsetUp()voidvoidA screening agent opens a ticket and says what its screen asked.voidvoidvoidvoidvoidvoidvoidAn ordinary ticket carries none, and creating one must not invent an empty payload.voidvoid🛑 ONE ACCESSION CAN NAME SEVERAL DATASETS, and all of them become targets.voidNothing carries the accession as an accession, so the short name is tried before giving up.voidA caller holding a GEO accession opens a ticket in one call, and the type defaults to the category the curation store's ownREVIEWmaps onto.voidAn accession naming nothing is a 404 and opens NO ticket.voidvoidvoidvoidvoidvoidvoidvoidvoidvoidvoidvoidvoidvoidvoidvoidvoidvoidvoidvoidvoidvoidvoidvoidAnnotation-level auth guard: the write-side endpoints must carry@PreAuthorize("isAuthenticated()").
-
Constructor Details
-
TicketsWebServiceTest
public TicketsWebServiceTest()
-
-
Method Details
-
setUp
@BeforeEach public void setUp() -
testGetTickets_passesFiltersThrough
@Test public void testGetTickets_passesFiltersThrough() -
testGetTickets_defaultsAreNullFilters
@Test public void testGetTickets_defaultsAreNullFilters() -
getTickets_passesNewFilterArgs_through
@Test public void getTickets_passesNewFilterArgs_through() -
getMyQueue_returnsOpenAndRecentlyResolved_forCallingUser
@Test public void getMyQueue_returnsOpenAndRecentlyResolved_forCallingUser() -
getMyQueue_returns401_whenAnonymous
@Test public void getMyQueue_returns401_whenAnonymous() -
getMyQueueSummary_returnsCountsAndOldestOpen
@Test public void getMyQueueSummary_returnsCountsAndOldestOpen() -
getScratchpad_provisionsAndReturnsTheCallersOwn
@Test public void getScratchpad_provisionsAndReturnsTheCallersOwn()The route provisions through the service and hands back the projection. The two VO fields asserted are what a client needs to recognize it and to know it can add to it. -
getScratchpad_returns401_whenAnonymous
@Test public void getScratchpad_returns401_whenAnonymous() -
getScratchpad_requiresAuthentication
- Throws:
NoSuchMethodException
-
getOpenTicketSummary_holdsScratchpadsOutOfTotalOpen_butStillReportsThem
@Test public void getOpenTicketSummary_holdsScratchpadsOutOfTotalOpen_butStillReportsThem()A scratchpad is never resolved, so counting one as open work would put every curator permanently behind. It comes out oftotalOpen— but it is NOT hidden: it is reported on its own field and still appears in the breakdown, sototalOpen + scratchpadOpenis the sum ofbyTypeand a caller can add it back. -
testGetTicket_includesEvents
@Test public void testGetTicket_includesEvents() -
testGetTicket_notFound
@Test public void testGetTicket_notFound() -
testGetTicketEvents_returnsEventList
@Test public void testGetTicketEvents_returnsEventList() -
testGetTicketEvents_notFound
@Test public void testGetTicketEvents_notFound() -
testOpenTicketsForExpressionExperiment_delegatesToService
@Test public void testOpenTicketsForExpressionExperiment_delegatesToService() -
testOpenTicketsForArrayDesign_delegatesToService
@Test public void testOpenTicketsForArrayDesign_delegatesToService() -
testCreateTicket_happyPath
@Test public void testCreateTicket_happyPath() -
testCreateTicketFromAccession_resolvesAndOpens
@Test public void testCreateTicketFromAccession_resolvesAndOpens()A caller holding a GEO accession opens a ticket in one call, and the type defaults to the category the curation store's ownREVIEWmaps onto. -
testCreateTicketFromAccession_aSplitAccessionTargetsEveryPart
@Test public void testCreateTicketFromAccession_aSplitAccessionTargetsEveryPart()🛑 ONE ACCESSION CAN NAME SEVERAL DATASETS, and all of them become targets.A GSE split during import backs one experiment per split. Taking the head of the collection would open a ticket over one arbitrary part and silently drop the rest — a review that looks complete and is not, which is worse than a 400. This is the whole reason the route resolves rather than the caller.
-
testCreateTicketFromAccession_fallsBackToShortName
@Test public void testCreateTicketFromAccession_fallsBackToShortName()Nothing carries the accession as an accession, so the short name is tried before giving up. -
testCreateTicketFromAccession_unknownAccessionOpensNothing
@Test public void testCreateTicketFromAccession_unknownAccessionOpensNothing()An accession naming nothing is a 404 and opens NO ticket.A ticket pointing at a dataset that could not be resolved is worse than no ticket: it reads as work waiting rather than as the error it is.
-
testCreateTicket_carriesTheScreenPayload
@Test public void testCreateTicket_carriesTheScreenPayload()A screening agent opens a ticket and says what its screen asked. The payload is stored verbatim and comes back on the created ticket, so the UI can render the question rather than a fixed GEO-scrape table with Include/Exclude (uib, 2026-09-03). -
testCreateTicket_withoutAPayloadLeavesItUnset
@Test public void testCreateTicket_withoutAPayloadLeavesItUnset()An ordinary ticket carries none, and creating one must not invent an empty payload. -
testCreateTicket_missingTitle_throws400
@Test public void testCreateTicket_missingTitle_throws400() -
testCreateTicket_nullBody_throws400
@Test public void testCreateTicket_nullBody_throws400() -
testUpdateTicket_stateTransition
@Test public void testUpdateTicket_stateTransition() -
testUpdateTicket_addComment
@Test public void testUpdateTicket_addComment() -
testUpdateTicket_clearAssignee
@Test public void testUpdateTicket_clearAssignee() -
testUpdateTicket_notFound_throws404
@Test public void testUpdateTicket_notFound_throws404() -
testDeleteTicket_softCancels
@Test public void testDeleteTicket_softCancels() -
testDeleteTicket_alreadyCancelled_noTransition
@Test public void testDeleteTicket_alreadyCancelled_noTransition() -
testDeleteTicket_notFound_throws404
@Test public void testDeleteTicket_notFound_throws404() -
testCreateTicket_withBodyAndMode_persistsBoth
@Test public void testCreateTicket_withBodyAndMode_persistsBoth() -
testCreateTicket_withTargetStatus_seedsUNDERWAY
@Test public void testCreateTicket_withTargetStatus_seedsUNDERWAY() -
testCreateTicket_multiTargetMixedTypes_passesAllThrough
@Test public void testCreateTicket_multiTargetMixedTypes_passesAllThrough() -
testCreateTicket_GEO_SCRAPE_WATERMARK_target
@Test public void testCreateTicket_GEO_SCRAPE_WATERMARK_target() -
testUpdateTicket_setsBodyAndMode
@Test public void testUpdateTicket_setsBodyAndMode() -
testUpdateTicket_clearBody_explicitNull
@Test public void testUpdateTicket_clearBody_explicitNull() -
testUpdateTicket_bodyAbsent_doesNotClearExisting
@Test public void testUpdateTicket_bodyAbsent_doesNotClearExisting() -
testUpdateTicket_setsTitle
@Test public void testUpdateTicket_setsTitle() -
testPatchTicket_delegatesToUpdateTicket
@Test public void testPatchTicket_delegatesToUpdateTicket() -
testCancelToReopen_lifecycle
@Test public void testCancelToReopen_lifecycle() -
testUpdateTargetStatus_delegatesToService
@Test public void testUpdateTargetStatus_delegatesToService() -
testUpdateTargetStatus_unknownTarget_returns404
@Test public void testUpdateTargetStatus_unknownTarget_returns404() -
testUpdateTargetStatus_missingBody_returns400
@Test public void testUpdateTargetStatus_missingBody_returns400() -
testWriteEndpoints_requireAuthentication
Annotation-level auth guard: the write-side endpoints must carry@PreAuthorize("isAuthenticated()"). At runtime Spring's method- security AOP turns the missing/anonymous principal into a 401/403; here we verify the precondition that produces that runtime behaviour without standing up the Spring container.- Throws:
NoSuchMethodException
-
searchTickets_returnsTheHitsInTheOrderTheServiceGaveThem
@Test public void searchTickets_returnsTheHitsInTheOrderTheServiceGaveThem() -
searchTickets_requiresAQuery
@Test public void searchTickets_requiresAQuery() -
searchTickets_refusesALimitAboveTheMaximum_ratherThanClampingIt
@Test public void searchTickets_refusesALimitAboveTheMaximum_ratherThanClampingIt()A limit the endpoint will not honour is refused, not quietly reduced — a silent clamp teaches the client nothing about why it got 100 rows back when it asked for 500. -
searchTickets_acceptsALimitAtTheMaximum
@Test public void searchTickets_acceptsALimitAtTheMaximum() -
searchTickets_openOnlyDefaultsToTrueOnTheWire
The default lives in the@DefaultValueannotation, which JAX-RS applies during parameter binding — calling the method directly never sees it, so it is asserted on the wire contract itself.- Throws:
NoSuchMethodException
-
searchTickets_openOnlyFalseIsPassedThrough
@Test public void searchTickets_openOnlyFalseIsPassedThrough() -
searchTickets_passesTheCallersContactId_forScratchpadScoping
@Test public void searchTickets_passesTheCallersContactId_forScratchpadScoping()The caller's identity decides whose scratchpad is worth offering, so it has to reach the service. -
searchTickets_anonymousCallerIsServedWithNoContactId
@Test public void searchTickets_anonymousCallerIsServedWithNoContactId()
-