Class ExperimentalFactorServiceTest

java.lang.Object
ubic.gemma.core.util.test.BaseTest5
ubic.gemma.core.util.test.BaseDatabaseTest5
ubic.gemma.persistence.service.expression.experiment.ExperimentalFactorServiceTest

@ContextConfiguration public class ExperimentalFactorServiceTest extends BaseDatabaseTest5
  • Constructor Details

    • ExperimentalFactorServiceTest

      public ExperimentalFactorServiceTest()
  • Method Details

    • testDeleteExperimentalFactor

      @Test public void testDeleteExperimentalFactor()
    • testDeleteExperimentalFactorUsedByASample

      @Test public void testDeleteExperimentalFactorUsedByASample()
    • testFactorIsStillAttachedToItsDesignWhenFindByFactorIsCalled

      @Test public void testFactorIsStillAttachedToItsDesignWhenFindByFactorIsCalled()
      🛑 The factor is STILL IN its design's factor collection when bioMaterialService.findByFactor is called. Detaching first denies the call.

      BioMaterialService#findByFactor is @Secured({"IS_AUTHENTICATED_ANONYMOUSLY","ACL_SECURABLE_READ"}). An ExperimentalFactor is a SecuredChild, and ParentIdentityRetrievalStrategyImpl resolves its ACL parent via ExpressionExperimentDao.findIdByFactor, whose HQL joins ed.experimentalFactors. Removing the factor from that collection first makes the query auto-flush the pending removal and match no row: null parent identity, no inherited ACL, and the vote denies — for an administrator, because the lookup found nothing rather than a permission being refused.

      🛑 This context has no security interceptor, so there is no 403 to assert here; what it pins is the ordering the interceptor depends on. That is also why the first attempt at this bug missed: removing the caller's duplicate detach in applyDesignChange left this one, one level down, one line before the call that actually trips.

      cab measured it on GSE19804 twice — 2026-09-09 and again on 2026-09-10 against the first fix, with a byte-identical stack naming ExperimentalFactorServiceImpl.remove line 70.