Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ describe("Set publisher access control and visibility by roles", () => {
cy.loginToPublisher(publisher, password);
})

it.only("Set role based API Store visibility and access control for the api", () => {
it("Set role based API Store visibility and access control for the api", () => {
const role = 'internal/everyone';
Utils.addAPI({ name: apiName, version: apiVersion }).then((apiId) => {
cy.visit(`/publisher/apis/${apiId}/overview`);
Expand Down Expand Up @@ -57,4 +57,93 @@ describe("Set publisher access control and visibility by roles", () => {
Utils.deleteAPI(apiId);
});
});

describe("Admin user access control validation", () => {
const { carbonUsername, carbonPassword } = Utils.getUserInfo();
const adminApiName = Utils.generateName();
const adminApiVersion = '1.0.0';

before(function () {
// Login as admin user who has apim:admin permission
cy.loginToPublisher(carbonUsername, carbonPassword);
});

it("Admin user should bypass user role validation when setting access control", () => {
const systemRole = 'Internal/system'; // This is a system role, not a user role

Utils.addAPI({ name: adminApiName, version: adminApiVersion }).then((apiId) => {
cy.visit(`/publisher/apis/${apiId}/overview`);
cy.get('#itest-api-details-portal-config-acc').click();
cy.get('#left-menu-itemDesignConfigurations').click();

// Select the restricted by role option for access control
cy.get('#accessControl-selector').click();
cy.get('#access-control-restricted-by-roles').click();

// Add a system role that would normally trigger user role validation error for non-admin users
cy.get('[data-testid="access-control-select-role"]').type(`${systemRole}{enter}`);

// Verify no validation error appears for admin users
cy.get('[data-testid="access-control-select-role"]').should('not.contain', 'At least one role must be associated with the API creator');
cy.get('[data-testid="access-control-select-role"]').should('not.have.class', 'Mui-error');
Comment on lines +84 to +88
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# Find the test file and examine the context
fd -n "02-set-publisher-access-control-and-visibility-by-roles.spec.js" -x cat -n {}

Repository: wso2/apim-apps

Length of output: 288


🏁 Script executed:

# Search for the access-control-select-role component implementation
rg -n 'data-testid="access-control-select-role"' -A 5 -B 5 --type=js --type=jsx

Repository: wso2/apim-apps

Length of output: 85


🏁 Script executed:

# Look for Material-UI FormControl/FormHelperText patterns in the codebase to understand error rendering
rg -n 'FormHelperText|Mui-error' -A 2 -B 2 --type=js --type=jsx | head -100

Repository: wso2/apim-apps

Length of output: 85


🏁 Script executed:

# Find the test file
fd "02-set-publisher-access-control-and-visibility-by-roles.spec.js"

Repository: wso2/apim-apps

Length of output: 175


🏁 Script executed:

# Search for the access-control-select-role component with proper type
rg 'data-testid="access-control-select-role"' -A 5 -B 5 --type=js

Repository: wso2/apim-apps

Length of output: 11374


🏁 Script executed:

# Look for Material-UI patterns in component files
rg 'FormHelperText|Mui-error' -A 3 -B 3 --type=js | head -150

Repository: wso2/apim-apps

Length of output: 22937


Fix error assertion selectors to target Material-UI FormHelperText component.

The assertions checking for error messages and error classes won't work because Material-UI renders validation errors in the FormHelperText component, which is a sibling to the input element, not a child of it.

Replace:

cy.get('[data-testid="access-control-select-role"]').should('not.contain', 'At least one role must be associated with the API creator');
cy.get('[data-testid="access-control-select-role"]').should('not.have.class', 'Mui-error');

With selectors that target the FormHelperText element:

cy.get('[data-testid="access-control-select-role"]').parent().find('.MuiFormHelperText-root.Mui-error').should('not.exist');

Or check the parent FormControl element for the error state.

🤖 Prompt for AI Agents
In
tests/cypress/integration/publisher/005-design-config/02-set-publisher-access-control-and-visibility-by-roles.spec.js
around lines 84 to 88, the two assertions target the select element itself but
Material‑UI renders validation text in a sibling FormHelperText and marks error
state on the FormControl; update the assertions to query the FormHelperText
under the select's parent (e.g. use
parent().find('.MuiFormHelperText-root.Mui-error') and assert it does not exist)
or alternatively assert the parent FormControl does not have the error state
class; replace the two failing assertions with one that checks
parent().find('.MuiFormHelperText-root.Mui-error').should('not.exist') or an
equivalent FormControl error check.


// Verify save button is enabled (not disabled due to validation errors)
cy.get('#design-config-save-btn').should('not.be.disabled');

// Save the configuration successfully
cy.get('#design-config-save-btn').scrollIntoView().click();

// Verify the configuration was saved without errors
cy.get('div[data-testid="access-control-select-role"] span').contains(systemRole).should('exist');

// Test is done. Now delete the api
Utils.deleteAPI(apiId);
});
});
});

describe("Non-admin user access control validation", () => {
const { publisher, password } = Utils.getUserInfo();
const nonAdminApiName = Utils.generateName();
const nonAdminApiVersion = '1.0.0';

before(function () {
// Login as non-admin user (regular publisher)
cy.loginToPublisher(publisher, password);
});

it("Non-admin user should still see user role validation when configuring system-only roles", () => {
const systemRole = 'internal/subscriber'; // This is a system role, not a user role

Utils.addAPI({ name: nonAdminApiName, version: nonAdminApiVersion }).then((apiId) => {
cy.visit(`/publisher/apis/${apiId}/overview`);
cy.get('#itest-api-details-portal-config-acc').click();
cy.get('#left-menu-itemDesignConfigurations').click();

// Select the restricted by role option for access control
cy.get('#accessControl-selector').click();
cy.get('#access-control-restricted-by-roles').click();

// Add a system role that should trigger user role validation error for non-admin users
cy.get('[data-testid="access-control-select-role"]').type(`${systemRole}{enter}`);

// Wait for validation to complete
cy.wait(1000);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Replace arbitrary wait with explicit assertion.

Using cy.wait(1000) is a Cypress anti-pattern that makes tests slower and potentially flaky. Cypress automatically retries assertions, so you should wait for a specific UI state instead.

🔎 Replace the arbitrary wait with a condition-based wait:
 // Add a system role that should trigger user role validation error for non-admin users
 cy.get('[data-testid="access-control-select-role"]').type(`${systemRole}{enter}`);

-// Wait for validation to complete
-cy.wait(1000);
+// Wait for validation by checking for either error state or stable UI
+cy.get('[data-testid="access-control-select-role"]').should('be.visible');

 // Verify validation error appears for non-admin users

Or wait for a specific validation element to appear:

// Wait for error message to appear
cy.get('[data-testid="access-control-select-role"]')
  .parents('form')
  .find('.MuiFormHelperText-root.Mui-error', { timeout: 5000 })
  .should('exist');
🤖 Prompt for AI Agents
In
tests/cypress/integration/publisher/005-design-config/02-set-publisher-access-control-and-visibility-by-roles.spec.js
around line 131, replace the arbitrary cy.wait(1000) with an explicit assertion
that waits for a specific UI state; identify the element or message that
indicates the operation completed (for example the access-control select or an
error/helper text) and use cy.get(...) or cy.contains(...).should(...) with an
appropriate timeout so Cypress retries until the expected element exists or is
visible instead of using a fixed sleep.


// Verify validation error appears for non-admin users
// Note: The exact error message and selectors may need adjustment based on actual implementation
cy.get('[data-testid="access-control-select-role"]').then(($element) => {
// Check if error state is present (either through error class or error message)
const hasErrorClass = $element.hasClass('Mui-error') || $element.find('.Mui-error').length > 0;
const hasErrorMessage = $element.text().includes('At least one role must be associated with the API creator');

// For non-admin users, either error styling or validation message should be present
expect(hasErrorClass || hasErrorMessage).to.be.true;
});
Comment on lines +135 to +142
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Refactor to use native Cypress assertions for retry-ability.

The current approach using .then() with jQuery-style checks and expect() defeats Cypress's built-in retry mechanism. If the validation is still processing, this will fail immediately instead of retrying.

🔎 Refactor to use Cypress should() assertions:
-// Verify validation error appears for non-admin users
-// Note: The exact error message and selectors may need adjustment based on actual implementation
-cy.get('[data-testid="access-control-select-role"]').then(($element) => {
-    // Check if error state is present (either through error class or error message)
-    const hasErrorClass = $element.hasClass('Mui-error') || $element.find('.Mui-error').length > 0;
-    const hasErrorMessage = $element.text().includes('At least one role must be associated with the API creator');
-
-    // For non-admin users, either error styling or validation message should be present
-    expect(hasErrorClass || hasErrorMessage).to.be.true;
-});
+// Verify validation error appears for non-admin users
+// Check for error class on the input or its parent
+cy.get('[data-testid="access-control-select-role"]')
+  .parents('.MuiFormControl-root')
+  .should('satisfy', ($el) => {
+    return $el.find('.Mui-error').length > 0 || 
+           $el.text().includes('At least one role must be associated with the API creator');
+  });

Or more explicitly:

// Check for error helper text
cy.get('[data-testid="access-control-select-role"]')
  .parents('.MuiFormControl-root')
  .find('.MuiFormHelperText-root')
  .should('satisfy', ($helperText) => {
    return $helperText.hasClass('Mui-error') || 
           $helperText.text().includes('At least one role must be associated');
  });

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In
tests/cypress/integration/publisher/005-design-config/02-set-publisher-access-control-and-visibility-by-roles.spec.js
around lines 135 to 142, replace the .then() block that performs jQuery checks
and a synchronous expect with native Cypress assertions that support retry;
target the form control/helper text (e.g. climb to .MuiFormControl-root and
.MuiFormHelperText-root) and use .should(...) — either .should('satisfy', fn)
that checks for .hasClass('Mui-error') OR includes the error text, or chain
.should('have.class','Mui-error').or().should('contain.text','At least one role
must be associated') — this preserves retryability and reliably asserts the
error state for non-admin users.


// Test is done. Now delete the api
Utils.deleteAPI(apiId);
});
});
});
});