Context
Verification pass for PR #91 (build/scala-3-migration @ 6510427732), running the full ScalaTest suite against a clean in-memory H2 database (the project's default test backend), as a single serial process to avoid this container's 4-core resource contention with the sharded run_tests_parallel.sh runner.
Build: BUILD SUCCESS. Full-suite result:
obp-commons: 43 succeeded, 0 failed, 5 ignored
obp-api: 3738 run, 3736 succeeded, 2 failed, 10 canceled, 5 ignored, 1 pending
3736/3738 (99.95%) pass. The 2 failures:
Failure 1 — ConsentOwnershipTests.scala:133
Scenario: The PSU may read their own consent when the consent itself is the credential *** FAILED ***
401 did not equal 200 (ConsentOwnershipTests.scala:133)
When The consent is presented as the credential, so cc.user is its shadow user
Then The read resolves the human behind the consent and succeeds -- this used to be a 404
The scenario's own Then text ("this used to be a 404") implies this asserts a previous fix. Immediately before the failure, the log shows:
WARN code.api.util.Consent$ - consumer_validation_method_for_consent is empty while request consumer_id=NONE - consent_id=..., aud=...
Failure 2 — ConsentsTest.scala:353
Scenario: We will call the Create, Get and Delete endpoints with user credentials *** FAILED ***
401 did not equal 200 (ConsentsTest.scala:353)
Same consumer_validation_method_for_consent is empty while request consumer_id=NONE warning immediately precedes it, at the point where the test uses a Consent-JWT/Consent-Id header (consent-as-credential auth) rather than a bearer token.
What I traced (not a full root-cause, flagging honestly)
Both scenarios hit ConsentUtil.checkConsent → tppIsConsentHolder
(obp-api/src/main/scala/code/api/util/ConsentUtil.scala:282-306). That function returns false
whenever callContext.consumer doesn't resolve to a consumer matching the consent's stored
consumer_id. When callContext.consumer is None, requestConsumerId becomes "NONE", which
takes the 401 branch unconditionally — the consumer_validation_method_for_consent warning logged
alongside it is diagnostic only, not the actual gate. So the proximate question is why
callContext.consumer isn't resolving in this consent-as-credential path, not the props value
itself (both test scenarios do correctly call setPropsValues("consumer_validation_method_for_consent" -> "CONSUMER_KEY_VALUE") before the request).
I have not isolated this further to a specific PR #91 commit/dependency change. I flag it as a
candidate because PR #91's description explicitly replaces scalacache with a new in-house memoize
layer and bumps json4s 3.6.12→4.1.0-M8 — either could plausibly affect consumer/prop resolution
across an async boundary — but I have not proven either is the cause. It's equally possible this is
pre-existing (unrelated to PR #91) and I haven't run the baseline to rule that out.
Reproduction caveat
Running just these two test classes in isolation (-DwildcardSuites=code.api.v5_1_0.ConsentsTest,code.api.v5_1_0.ConsentOwnershipTests) does not reproduce cleanly — nearly every scenario in ConsentsTest fails with 401 when run standalone, which points to the class depending on shared fixture/consumer-registration state seeded by an earlier class in the full suite run. That's a separate, pre-existing test-isolation gap unrelated to this specific failure — mentioning it so nobody else burns time on the same isolated-rerun path expecting a clean repro.
Environment
- JDK 25 (temurin), Scala 2.13.18, H2 in-memory (
jdbc:h2:mem:OBPTest_H2_v2.1.214;..., the project default when test.default.props has no db.driver/db.url)
- Single-process
mvn -pl obp-commons,obp-api scalatest:test -DfailIfNoTests=false (not the sharded runner, to avoid resource contention)
Suggested next step
Someone with more context on the scalacache→memoize migration or the json4s bump should check whether consumer resolution in the consent-as-credential path (callContext.consumer population before ConsentUtil.checkConsent) changed behavior — or confirm via a baseline (develop-obp) run whether these two scenarios already failed before PR #91.
Context
Verification pass for PR #91 (
build/scala-3-migration@6510427732), running the full ScalaTest suite against a clean in-memory H2 database (the project's default test backend), as a single serial process to avoid this container's 4-core resource contention with the shardedrun_tests_parallel.shrunner.Build:
BUILD SUCCESS. Full-suite result:obp-commons: 43 succeeded, 0 failed, 5 ignoredobp-api: 3738 run, 3736 succeeded, 2 failed, 10 canceled, 5 ignored, 1 pending3736/3738 (99.95%) pass. The 2 failures:
Failure 1 —
ConsentOwnershipTests.scala:133The scenario's own
Thentext ("this used to be a 404") implies this asserts a previous fix. Immediately before the failure, the log shows:Failure 2 —
ConsentsTest.scala:353Same
consumer_validation_method_for_consent is empty while request consumer_id=NONEwarning immediately precedes it, at the point where the test uses aConsent-JWT/Consent-Idheader (consent-as-credential auth) rather than a bearer token.What I traced (not a full root-cause, flagging honestly)
Both scenarios hit
ConsentUtil.checkConsent→tppIsConsentHolder(
obp-api/src/main/scala/code/api/util/ConsentUtil.scala:282-306). That function returnsfalsewhenever
callContext.consumerdoesn't resolve to a consumer matching the consent's storedconsumer_id. WhencallContext.consumerisNone,requestConsumerIdbecomes"NONE", whichtakes the 401 branch unconditionally — the
consumer_validation_method_for_consentwarning loggedalongside it is diagnostic only, not the actual gate. So the proximate question is why
callContext.consumerisn't resolving in this consent-as-credential path, not the props valueitself (both test scenarios do correctly call
setPropsValues("consumer_validation_method_for_consent" -> "CONSUMER_KEY_VALUE")before the request).I have not isolated this further to a specific PR #91 commit/dependency change. I flag it as a
candidate because PR #91's description explicitly replaces
scalacachewith a new in-house memoizelayer and bumps json4s 3.6.12→4.1.0-M8 — either could plausibly affect consumer/prop resolution
across an async boundary — but I have not proven either is the cause. It's equally possible this is
pre-existing (unrelated to PR #91) and I haven't run the baseline to rule that out.
Reproduction caveat
Running just these two test classes in isolation (
-DwildcardSuites=code.api.v5_1_0.ConsentsTest,code.api.v5_1_0.ConsentOwnershipTests) does not reproduce cleanly — nearly every scenario inConsentsTestfails with 401 when run standalone, which points to the class depending on shared fixture/consumer-registration state seeded by an earlier class in the full suite run. That's a separate, pre-existing test-isolation gap unrelated to this specific failure — mentioning it so nobody else burns time on the same isolated-rerun path expecting a clean repro.Environment
jdbc:h2:mem:OBPTest_H2_v2.1.214;..., the project default whentest.default.propshas nodb.driver/db.url)mvn -pl obp-commons,obp-api scalatest:test -DfailIfNoTests=false(not the sharded runner, to avoid resource contention)Suggested next step
Someone with more context on the scalacache→memoize migration or the json4s bump should check whether consumer resolution in the consent-as-credential path (
callContext.consumerpopulation beforeConsentUtil.checkConsent) changed behavior — or confirm via a baseline (develop-obp) run whether these two scenarios already failed before PR #91.