Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

QA-15348: Fixes for the condition property of json overrides #1323

Merged
merged 7 commits into from
Nov 1, 2024
Merged
Show file tree
Hide file tree
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 @@ -118,18 +118,18 @@ private Form getEditorForm(ExtendedNodeType primaryNodeType, JCRNodeWrapper exis
final SortedSet<DefinitionRegistryItem> mergeSet = new TreeSet<>(DefinitionRegistryItemComparator.INSTANCE);

// First, primary node type and inherited
addFormNodeType(primaryNodeType, site, mergeSet, locale, false, processedNodeTypes);
addFormNodeType(currentNode, primaryNodeType, site, mergeSet, locale, false, processedNodeTypes);

// Available extends mixins
List<ExtendedNodeType> extendMixins = getExtendMixins(primaryNodeType, site);
for (ExtendedNodeType extendMixin : extendMixins) {
addFormNodeType(extendMixin, site, mergeSet, locale, true, processedNodeTypes);
addFormNodeType(currentNode, extendMixin, site, mergeSet, locale, true, processedNodeTypes);
}

// Mixins added on node
if (existingNode != null) {
for (ExtendedNodeType mixinNodeType : existingNode.getMixinNodeTypes()) {
addFormNodeType(mixinNodeType, site, mergeSet, locale, false, processedNodeTypes);
addFormNodeType(currentNode, mixinNodeType, site, mergeSet, locale, false, processedNodeTypes);
}
}

Expand Down Expand Up @@ -253,11 +253,11 @@ private static Map<String, Object> replaceBySubstitutor(Map<String, Object> sele
return map;
}

private void addFormNodeType(ExtendedNodeType nodeType, JCRSiteNode site, SortedSet<DefinitionRegistryItem> formDefinitionsToMerge, Locale locale, boolean singleFieldSet, Set<String> processedNodeTypes) throws RepositoryException {
private void addFormNodeType(JCRNodeWrapper node, ExtendedNodeType nodeType, JCRSiteNode site, SortedSet<DefinitionRegistryItem> formDefinitionsToMerge, Locale locale, boolean singleFieldSet, Set<String> processedNodeTypes) throws RepositoryException {
if (!processedNodeTypes.contains(nodeType.getName())) {
formDefinitionsToMerge.add(FormGenerator.generateForm(nodeType, locale, singleFieldSet));
formDefinitionsToMerge.addAll(staticDefinitionsRegistry.getFormsForType(nodeType, site));
formDefinitionsToMerge.addAll(staticDefinitionsRegistry.getFieldSetsForType(nodeType, site));
formDefinitionsToMerge.addAll(staticDefinitionsRegistry.getFormsForType(node, nodeType, site));
formDefinitionsToMerge.addAll(staticDefinitionsRegistry.getFieldSetsForType(node, nodeType, site));

processedNodeTypes.add(nodeType.getName());
processedNodeTypes.addAll(nodeType.getSupertypeSet().stream().map(ExtendedNodeType::getName).collect(Collectors.toList()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import org.jahia.modules.contenteditor.api.forms.model.*;
import org.jahia.modules.contenteditor.utils.ContentEditorUtils;
import org.jahia.services.content.JCRNodeWrapper;
import org.jahia.services.content.decorator.JCRSiteNode;
import org.jahia.services.content.nodetypes.ExtendedNodeType;
import org.jahia.services.content.nodetypes.NodeTypeRegistry;
Expand All @@ -39,6 +40,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.jcr.RepositoryException;
import javax.jcr.nodetype.NoSuchNodeTypeException;
import java.io.IOException;
import java.net.URL;
Expand Down Expand Up @@ -95,11 +97,12 @@ public void bundleChanged(BundleEvent event) {
* @param site
* @return form definitions that match the type
*/
public Collection<Form> getFormsForType(ExtendedNodeType type, JCRSiteNode site) {
public Collection<Form> getFormsForType(JCRNodeWrapper node, ExtendedNodeType type, JCRSiteNode site) {
return forms.stream()
.filter(definition -> definition.getConditionNodeTypeName() != null)
.filter(definition -> type.isNodeType(definition.getConditionNodeTypeName()) &&
(definition.getCondition() == null || matchCondition(definition.getCondition(), type, site)))
.filter(definition -> checkMixinCondition(definition.getCondition(), node))
.collect(Collectors.toCollection(ArrayList::new));
}

Expand All @@ -109,14 +112,41 @@ public Collection<Form> getFormsForType(ExtendedNodeType type, JCRSiteNode site)
* @param type to look at
* @return form definitions that match the type
*/
public Collection<FieldSet> getFieldSetsForType(ExtendedNodeType type, JCRSiteNode site) {
public Collection<FieldSet> getFieldSetsForType(JCRNodeWrapper node, ExtendedNodeType type, JCRSiteNode site) {
return fieldSets.stream()
.filter(definition -> definition.getConditionNodeTypeName() != null)
.filter(definition -> type.isNodeType(definition.getConditionNodeTypeName()) &&
(definition.getCondition() == null || matchCondition(definition.getCondition(), type, site)))
.filter(definition -> checkMixinCondition(definition.getCondition(), node))
.collect(Collectors.toCollection(ArrayList::new));
}

public boolean checkMixinCondition(Condition condition, JCRNodeWrapper node) {
// step 1 - check if we have condition
if (condition == null) return true;

String conditionType = condition.getNodeType();
if (conditionType == null) return true;

// step 2 - get definition from name
ExtendedNodeType conditionTypeDefinition;
try {
conditionTypeDefinition = NodeTypeRegistry.getInstance().getNodeType(conditionType);
} catch (NoSuchNodeTypeException e) {
return true;
}

// step 3 - check if the condition node is a mixin
if (!conditionTypeDefinition.isMixin()) return true;

// step 4 - check if node has the mixin
try {
return Arrays.stream(node.getMixinNodeTypes()).anyMatch(m -> m.getName().equals(conditionType));
} catch (RepositoryException e) {
return true;
}
}

public boolean matchCondition(Condition condition, ExtendedNodeType type, JCRSiteNode site) {
return (condition.getOrderable() == null || type.hasOrderableChildNodes()) &&
(condition.getWithPermission() == null || site.hasPermission(condition.getWithPermission())) &&
Expand Down
17 changes: 9 additions & 8 deletions tests/cypress/e2e/contentEditor/choiceTree.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,17 @@ describe('Test Choicetree selector type', () => {
});
});

beforeEach('', () => {
beforeEach('Login and load content folders', () => {
cy.loginAndStoreSession();
jcontent = JContent.visit(siteKey, 'en', 'content-folders/contents');
});

after('Clean up test env', () => {
deleteSite(siteKey);
deleteNode('/sites/systemsite/categories/choiceTreeCategoryRoot');
cy.logout();
});

it('can handle choice tree selector with a custom root path', () => {
// Create content
const contentEditor = jcontent.createContent('testChoiceTree');
Expand Down Expand Up @@ -126,7 +133,7 @@ describe('Test Choicetree selector type', () => {
choiceTree.getEntries().should('contain', 'choiceTreeContent2');
});

it.only('displays the Choice tree selector for single value', () => {
it.skip('displays the Choice tree selector for single value', () => {
Copy link
Contributor

Choose a reason for hiding this comment

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

disabled for now as this is flaky even on nightly. Will create separate ticket.

const contentEditor = jcontent.createContent('testChoiceTree');
contentEditor.openSection('Content');
const choiceTreeField = contentEditor.getChoiceTreeField('cent:testChoiceTree_singleChoiceTree', false);
Expand Down Expand Up @@ -157,10 +164,4 @@ describe('Test Choicetree selector type', () => {
choiceTree.getEntries().should('contain', 'choiceTreeCategory1');
// Simple check that category selector is displayed properly with expected values.
});

after('Clean up test env', () => {
cy.loginAndStoreSession();
deleteSite(siteKey);
deleteNode('/sites/systemsite/categories/choiceTreeCategoryRoot');
});
});
16 changes: 5 additions & 11 deletions tests/cypress/e2e/contentEditor/hidePreview.cy.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
import {addNode, createSite, deleteSite, getNodeByPath} from '@jahia/cypress';
import {CategoryManager, JContent} from '../../page-object';

const siteKey = 'hidePreviewSite';

const initVisit = () => {
const jcontent = JContent.visit(siteKey, 'en', 'home.html');
jcontent.switchToPageBuilder();
return jcontent;
};

describe('Hide Preview testsuite', () => {
const siteKey = 'hidePreviewSite';

before('Create site and content', () => {
createSite(siteKey);
addNode({
Expand All @@ -31,26 +25,26 @@ describe('Hide Preview testsuite', () => {

beforeEach('login and visit home', () => {
cy.login();
initVisit();
});

it('Preview shouldn\'t exist for a site', () => {
JContent.visit(siteKey, 'en', 'home.html');
getNodeByPath(`/sites/${siteKey}`).then(res => {
cy.visit(`/jahia/administration/digitall/settings/properties#(contentEditor:!((formKey:modal_0,isFullscreen:!t,lang:en,mode:edit,site:${siteKey},uilang:en,uuid:'${res.data.jcr.nodeByPath.uuid}')))`);
});
cy.get('iframe[data-sel-role="edit-preview-frame"]').should('not.exist');
});

it('Preview shouldn\'t exist for a content folder', () => {
const jcontent = initVisit();
const jcontent = JContent.visit(siteKey, 'en', 'home.html');
jcontent.getAccordionItem('content-folders').click();
const ce = jcontent.editComponentByText('ContentFolder');
ce.switchToAdvancedMode();
cy.get('iframe[data-sel-role="edit-preview-frame"]').should('not.exist');
});

it('Preview should be visible for a content', () => {
const jcontent = initVisit();
const jcontent = JContent.visit(siteKey, 'en', 'home.html');
jcontent.getAccordionItem('content-folders').click();
const ce = jcontent.editComponentByText('Text');
ce.switchToAdvancedMode();
Expand Down
43 changes: 43 additions & 0 deletions tests/cypress/e2e/contentEditor/jsonOverrides/extendMixins.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import {JContent} from '../../../page-object';
import {SmallTextField} from '../../../page-object/fields';
import {createSite, deleteSite, enableModule} from '@jahia/cypress';

// This test makes use of jmix_freezeSystemName.json form override from jcontent-test-module
describe('Extend Mixins tests with CE', () => {
const siteKey = 'extendMixinsSite';

before(() => {
createSite(siteKey);
enableModule('jcontent-test-module', siteKey);
});

after(() => {
cy.logout();
deleteSite(siteKey);
});

beforeEach(() => {
cy.loginAndStoreSession();
});

it('Applies extend mixin only if it is enabled on the node', () => {
const jcontent = JContent.visit(siteKey, 'en', 'pages');
let contentEditor = jcontent.editPage();
const systemNameFieldSel = 'nt:base_ce:systemName';

cy.log('Verify conditional override is not applied');
let systemNameField = contentEditor.getField(SmallTextField, systemNameFieldSel);
systemNameField.isNotReadOnly();

cy.log('Enable the mixin');
contentEditor.toggleOption('jmix:freezeSystemName');
contentEditor.save();

cy.log('Verify conditional override is applied after applying mixin');
contentEditor = jcontent.editPage();
systemNameField = contentEditor.getField(SmallTextField, systemNameFieldSel);
systemNameField.isReadOnly();

contentEditor.cancel();
});
});
19 changes: 14 additions & 5 deletions tests/cypress/e2e/jcontent/search.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,24 +87,29 @@ describe('Search tests', () => {
});

describe('after close', () => {
it('should go back to content-folders after close', () => {
beforeEach(() => {
cy.loginAndStoreSession();
});

after(() => {
cy.logout();
});

it('should go back to content-folders after close', () => {
jcontent = JContent.visit('jcontentSite', 'en', 'content-folders/contents');
jcontent.getBasicSearch().openSearch().searchTerm('test').executeSearch().close();
jcontent.getAccordionItem('content-folders').getTreeItem('contents').shouldBeSelected();
jcontent.shouldBeInMode('List');
});

it('should go back to pages after close', () => {
cy.loginAndStoreSession();
jcontent = JContent.visit('jcontentSite', 'en', 'pages/home');
jcontent.getBasicSearch().openSearch().searchTerm('test').executeSearch().close();
jcontent.getAccordionItem('pages').getTreeItem('home').shouldBeSelected();
jcontent.shouldBeInMode('Page Builder - Beta');
});

it('should go back to default', () => {
cy.loginAndStoreSession();
cy.visit('/jahia/jcontent/jcontentSite/en/search/sites/jcontentSite/contents?params=(searchContentType:%27%27,searchPath:/sites/digitall/home,searchTerms:test)');
jcontent = new JContent();
new BasicSearch(jcontent).close();
Expand All @@ -114,12 +119,16 @@ describe('Search tests', () => {
});

describe('advanced search', {testIsolation: false}, () => {
before(() => {
beforeEach(() => {
cy.loginAndStoreSession();
jcontent = JContent.visit('jcontentSite', 'en', 'content-folders/contents');
});

after(() => {
cy.logout();
});

it('should find event by from ', () => {
jcontent = JContent.visit('jcontentSite', 'en', 'content-folders/contents');
jcontent.selectAccordion('pages');
basicSearch = jcontent.getBasicSearch().openSearch().switchToAdvanced()
.searchFrom('jnt:event')
Expand Down
22 changes: 11 additions & 11 deletions tests/cypress/e2e/menuActions/areaActions.cy.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {JContent, JContentPageBuilder} from '../../page-object';
import {JContent} from '../../page-object';
describe('Area actions', () => {
let jcontent: JContentPageBuilder;
let jcontent: JContent;

before(() => {
cy.executeGroovy('jcontent/createSite.groovy', {SITEKEY: 'jcontentSite'});
Expand All @@ -14,21 +14,20 @@ describe('Area actions', () => {

beforeEach(() => {
cy.loginAndStoreSession();
jcontent = JContent
.visit('jcontentSite', 'en', 'pages/home')
.switchToPageBuilder();
jcontent = JContent.visit('jcontentSite', 'en', 'pages/home');
});

it('Checks that delete, copy and cut menu items are not present on areas in page builder', () => {
const jcontentPageBuilder = jcontent.switchToPageBuilder();
cy.apollo({mutationFile: 'jcontent/createTextContentUnderPath.graphql', variables: {
path: '/sites/jcontentSite/home/landing'
}});
// eslint-disable-next-line cypress/no-unnecessary-waiting
cy.wait(3000);
jcontent.refresh();
jcontentPageBuilder.refresh();
// eslint-disable-next-line cypress/no-unnecessary-waiting
cy.wait(3000);
const menu = jcontent.getModule('/sites/jcontentSite/home/landing')
const menu = jcontentPageBuilder.getModule('/sites/jcontentSite/home/landing')
.contextMenu(true);
menu.shouldNotHaveItem('Delete');
menu.shouldNotHaveItem('Copy');
Expand All @@ -37,14 +36,15 @@ describe('Area actions', () => {
});

it('Checks that content can be pasted into the area', () => {
jcontent.getModule('/sites/jcontentSite/home/area-main/test-content1').contextMenu(true).select('Copy');
jcontent.getModule('/sites/jcontentSite/home/landing')
const jcontentPageBuilder = jcontent.switchToPageBuilder();
jcontentPageBuilder.getModule('/sites/jcontentSite/home/area-main/test-content1').contextMenu(true).select('Copy');
jcontentPageBuilder.getModule('/sites/jcontentSite/home/landing')
.contextMenu(true, false)
.select('Paste');
jcontent.refresh();
jcontentPageBuilder.refresh();
// eslint-disable-next-line cypress/no-unnecessary-waiting
cy.wait(3000);
jcontent.getModule('/sites/jcontentSite/home/landing/test-content1').should('exist');
jcontentPageBuilder.getModule('/sites/jcontentSite/home/landing/test-content1').should('exist');
});

it('Checks that delete, copy and cut menu items are not present on areas in structured view', () => {
Expand Down
18 changes: 15 additions & 3 deletions tests/cypress/e2e/pageBuilder/boxesHeader.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,20 @@ describe('Page builder', () => {

beforeEach(() => {
cy.loginAndStoreSession();
jcontent = JContent
.visit('jcontentSite', 'en', 'pages/home')
.switchToPageBuilder();
});

describe('boxes and header', function () {
it('should show box when hovering', () => {
jcontent = JContent
.visit('jcontentSite', 'en', 'pages/home')
.switchToPageBuilder();
jcontent.getModule('/sites/jcontentSite/home/landing').hover().should('have.attr', 'data-current', 'true');
});

it('should show box with name, status and edit buttons', () => {
jcontent = JContent
.visit('jcontentSite', 'en', 'pages/home')
.switchToPageBuilder();
jcontent.getModule('/sites/jcontentSite/home/area-main/test-content4').click();
const header = jcontent.getModule('/sites/jcontentSite/home/area-main/test-content4').getHeader();
header.get().find('p').contains('test-content4');
Expand All @@ -35,17 +38,26 @@ describe('Page builder', () => {
});

it('should trim long titles', () => {
jcontent = JContent
.visit('jcontentSite', 'en', 'pages/home')
.switchToPageBuilder();
jcontent.getModule('/sites/jcontentSite/home/area-main/test-content8-long-text').click();
const header = jcontent.getModule('/sites/jcontentSite/home/area-main/test-content8-long-text').getHeader();
header.get().find('p').contains('Lorem ipsum dolor sit am...');
});

it('should show create buttons', () => {
jcontent = JContent
.visit('jcontentSite', 'en', 'pages/home')
.switchToPageBuilder();
jcontent.getModule('/sites/jcontentSite/home/landing').getCreateButtons().getButton('New content');
});
});

it('Click on links should open modal', () => {
jcontent = JContent
.visit('jcontentSite', 'en', 'pages/home')
.switchToPageBuilder();
jcontent.getSecondaryNav().get().find('[data-sel-role="home"] .moonstone-treeView_itemToggle').click();
cy.contains('external-link').click();
cy.contains('The link redirects to an external URL');
Expand Down
Loading
Loading