Class AnalysisResultSetsWebServiceTest

java.lang.Object
org.glassfish.jersey.test.JerseyTest
All Implemented Interfaces:
org.springframework.beans.factory.Aware, org.springframework.context.ApplicationContextAware

public class AnalysisResultSetsWebServiceTest extends BaseJerseyIntegrationTest5
  • Constructor Details

    • AnalysisResultSetsWebServiceTest

      public AnalysisResultSetsWebServiceTest()
  • Method Details

    • setupMocks

      @BeforeEach public void setupMocks()
    • removeFixtures

      @AfterEach public void removeFixtures()
    • testFindAllWhenNoDatasetsAreProvidedThenReturnLatestAnalysisResults

      @Test public void testFindAllWhenNoDatasetsAreProvidedThenReturnLatestAnalysisResults()
    • testFindAllDoesNotServePrivateResultSetsToAnonymousCallers

      @Test public void testFindAllDoesNotServePrivateResultSetsToAnonymousCallers()
      🔒 The LISTING is ACL-filtered, not just the id-taking loaders.

      GET /resultSets/{id} was guarded on 2026-08-24; the two listing methods were not, and ?filter=id = <id> reaches one result set through the listing just as directly. Anonymously that served the analysis, subset factor, factor values and ontology terms of a private experiment's result set.

      🛑 The admin half is not decoration — it is the known-positive that proves this query can return the fixture at all. Without it an anonymous empty result would be indistinguishable from a listing that returns nothing for an unrelated reason, which is the shape of a screen that cannot fail.

    • testFindAllWithFilters

      @Test public void testFindAllWithFilters()
    • testFindAllWithFiltersAndCollections

      @Test public void testFindAllWithFiltersAndCollections()
    • testFindAllWithInvalidFilters

      @Test public void testFindAllWithInvalidFilters()
    • testFindAllWithDatasetIdsThenReturnLatestAnalysisResults

      @Test public void testFindAllWithDatasetIdsThenReturnLatestAnalysisResults()
    • testFindAllWhenDatasetDoesNotExistThenRaise404NotFound

      @Test public void testFindAllWhenDatasetDoesNotExistThenRaise404NotFound()
    • testFindAllWithDatabaseEntriesThenReturnLatestAnalysisResults

      @Test public void testFindAllWithDatabaseEntriesThenReturnLatestAnalysisResults()
    • testFindAllWhenDatabaseEntryDoesNotExistThenRaise404NotFound

      @Test public void testFindAllWhenDatabaseEntryDoesNotExistThenRaise404NotFound()
    • testFindByIdThenReturn200Success

      @Test public void testFindByIdThenReturn200Success()
    • testFindByIdWhenExcludeResultsThenReturn200Success

      @Test public void testFindByIdWhenExcludeResultsThenReturn200Success()
    • testFindByIdWhenInvalidIdentifierThenThrowMalformedArgException

      @Test public void testFindByIdWhenInvalidIdentifierThenThrowMalformedArgException()
    • testFindByIdWhenResultSetDoesNotExistsThenReturn404NotFoundError

      @Test public void testFindByIdWhenResultSetDoesNotExistsThenReturn404NotFoundError()
    • testFindByIdToTsv

      @Test public void testFindByIdToTsv()
    • testSubsetAnalysisResultSetsAreVisibleViaTheSourceExperiment

      @Test public void testSubsetAnalysisResultSetsAreVisibleViaTheSourceExperiment()
      🛑 A SUBSET analysis's result sets must be visible to a caller who can read the SOURCE experiment.

      The ACL restriction added with the /resultSets leak fix bound analysis.experimentAnalyzed.id as an ExpressionExperiment id. For a subset analysis that is an ExpressionExperimentSubSet id, which matches no ExpressionExperiment ACL row — so every subset analysis's result sets vanished for everyone but admins, who bypass the predicate entirely and therefore could not see the damage.

      Measured on production: GSE191016 (eid 39118) is PUBLIC with 24 subset result sets. Admin saw 24, anonymous saw 0, and the ACL chain was correct throughout — result set → analysis → experiment, all inheriting, the experiment granting IS_AUTHENTICATED_ANONYMOUSLY. Nothing was wrong with the data.

      🛑 The original leak test could not catch this: its fixture analyses a whole experiment, which is the one shape the broken predicate handled. Hence a subset fixture here rather than another assertion there.