Lesson 5 of 6
Authorizations, feature control and messages
11 min
Listen to this lesson
Feature control answers "can it happen?", authorization answers "may you do it?", and messages tell the user what went wrong. All three are visible to users, all three are easy to break, and all three are often tested only by clicking in CMQ. This lesson moves them into ABAP Unit, with Contoso's rules: a CLOSED agreement cannot be updated, deleted or closed again; only users authorized for company code 1910 may change the Alternadores del Norte agreements; every error tells the user which field to fix.
Testing instance feature control
Kenji's instance feature handler returns if_abap_behv=>fc-o-disabled for update, delete and closeAgreement when Status is CLOSED. There are two ways to test it, and the suite uses both.
- Ask for permissions.
GET PERMISSIONS ENTITY ZR_CMC_CoreAgreementwith a request for update, delete and the action, for a CLOSED agreement created in the test. Assert the result reports each as disabled, and as enabled for an OPEN agreement. - Attempt the operation. As a consumer (not in local mode),
MODIFY ENTITIES ... UPDATEthe CLOSED agreement. Assert the key appears infailedand the change was not applied. - Unit-test the handler. Call the feature method as a friend, with the buffer double holding one OPEN and one CLOSED agreement, and assert the
%featuresvalues per key.
Testing authorization
The authorization handler checks Contoso's authorization object for agreements (illustrative name ZCMC_CAGR, with company code and activity) using AUTHORITY-CHECK. A developer running the tests usually has full authorization, so a test that "checks" authorization proves nothing unless it restricts the user. SAP's authority check test helper, CL_AUNIT_AUTHORITY_CHECK, does that: the test gets a controller with get_controller( ), builds an authorization object set, and calls restrict_authorizations_to( ... ). The cheat sheet stresses that the helper only restricts the test user's authorizations; it never grants new ones.
| Test | Restricted to | Expected result |
|---|---|---|
| update_1710_allowed | ZCMC_CAGR with company code 1710, change | Update of a 1710 agreement succeeds |
| update_1910_denied | ZCMC_CAGR with company code 1710 only | Update of a 1910 agreement is in failed, with an authorization message |
| display_only_user | ZCMC_CAGR with display activity only | Create, update and closeAgreement all denied |
| no_authorization_at_all | An empty set | Every modifying operation denied; nothing in the buffer |
Contoso's authorization tests: one positive and several negative cases, each with an explicit restriction.
Remember what the advanced RAP course noted: authorization methods are not called for every draft action, and read access is governed separately by CDS access control. Unit tests on doubles do not exercise access control the way real users experience it, so the 1710/1910 read separation is also tested with real test users in CMQ.
Testing messages
A RAP message is an entry in reported with a message object in %msg, an optional field marking in %element, and for drafts a %state_area. For the user, the field marking is what makes an error fixable. Contoso's message tests assert:
- The message class and number, read from the message object, not the text.
- The severity: an error for a rejected save, a warning for a deposit above the usual 45.00 per unit.
- The element:
%element-ValidTo = if_abap_behv=>mk-onfor validateDates, DepositPerUnit for validateDeposit. - The pairing: every key in
failedhas at least one message inreported. A failure with no message leaves the user stuck.
Prechecks and the early rejection
Contoso's create operation has a precheck: a new agreement for a customer and product that already has an OPEN agreement is rejected before it enters the buffer. Prechecks run in the interaction phase, so the test asserts right after MODIFY ENTITIES: the %cid appears in failed with a message, and mapped has no entry for it. Arrange the duplicate through the CDS double (an OPEN agreement for 17100001 already in the data) rather than by creating and committing one first; the test stays fast and does not depend on the save sequence. A second test with a different product proves the precheck does not block legitimate agreements, which is the defect key users notice first.
- Is it about the state of the data?Yes → instance feature control, tested with GET PERMISSIONS and an attempted update · No → next question
- Is it about who the user is?Yes → authorization, tested with CL_AUNIT_AUTHORITY_CHECK restrictions · No → next question
- Is it about consistency at save?Yes → validation, tested at commit or Prepare · No → it may not be a rule at all
- Does the user see what to fix?Yes → assert class, number and element · No → defect, even if the save is blocked
What goes wrong in testing
- Testing as a superuser. Authorization tests without restrictions always pass.
- Local mode in tests.
IN LOCAL MODEandPRIVILEGEDskip checks; use them in tests only when that is the point. - Greyed-out button as proof. A disabled button in the UI does not prove that the API rejects the operation.
- Failed without reported. Kenji's first close action rejected closed agreements silently; only a pairing assertion found it.
What would you do?
Nadia, the security and GRC lead, asks how Kenji proves that a Detroit user cannot change an Alternadores del Norte agreement. Kenji shows a green test that updates a 1910 agreement and expects failure. What should Nadia check first?
- Test feature control with GET PERMISSIONS and with an attempted operation from a consumer.
- Authorization tests must restrict the test user with CL_AUNIT_AUTHORITY_CHECK; it never grants authorizations.
- Local mode and PRIVILEGED skip checks: tests that prove rules must not use them.
- Assert message class, number, severity and marked element, and pair every failed key with a message.
Check your understanding · not graded
Lesson check
1. Why must an authorization test restrict the test user?
2. What does CL_AUNIT_AUTHORITY_CHECK do to authorizations?
3. Which EML statement asks a BO which operations are enabled?
4. Why should a feature control test not run in local mode?
5. What makes a validation error fixable for the user?