Skip to content
Open
28 changes: 27 additions & 1 deletion nx2/blocks/ew-actions/ew-actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
runAemPreviewOrPublish,
} from '../../utils/aem-preview-publish.js';
import { versions } from '../../utils/api.js';
import { fetchDaConfigs, getFirstSheet } from '../../utils/daConfig.js';
import { getConfig } from '../../scripts/nx.js';
import '../shared/menu/menu.js';

Expand Down Expand Up @@ -51,11 +52,27 @@ function buildPrepareDetails(state) {
};
}

async function shouldHidePublish(hashState) {
const { org, site } = hashState || {};
const fullpath = buildPrepareDetails(hashState)?.fullpath;
if (!org || !site || !fullpath) return false;

try {
const configs = await Promise.all(fetchDaConfigs({ org, site }));
const configTab = configs.flatMap((config) => getFirstSheet(config) || []);
const publishConfigs = configTab.filter((c) => c.key === 'editor.hidePublish' && c.value);
return publishConfigs.some((c) => fullpath.startsWith(c.value));
} catch {
return false;
}
}

class NXEwActions extends LitElement {
static properties = {
_busy: { state: true },
_hasError: { state: true },
_hashState: { state: true },
_hidePublish: { state: true },
_prepareReady: { state: true },
// phase: 'error' | 'pending' | 'result'
_dialog: { state: true },
Expand Down Expand Up @@ -97,6 +114,15 @@ class NXEwActions extends LitElement {
this._unsubHash?.();
}

update(changed) {
super.update(changed);
if (changed.has('_hashState') && this._hashState) this._updateHidePublish();
}

async _updateHidePublish() {
this._hidePublish = await shouldHidePublish(this._hashState);
}

_togglePrepareMenu(e) {
e.preventDefault();
const btn = this._prepareBtn;
Expand Down Expand Up @@ -269,7 +295,7 @@ class NXEwActions extends LitElement {
size="m"
.items=${[
{ id: 'preview', label: 'Preview' },
{ id: 'publish', label: 'Publish' },
...(this._hidePublish ? [] : [{ id: 'publish', label: 'Publish' }]),
]}
@select=${(e) => this._pickAem(e.detail.id)}
>
Expand Down
131 changes: 131 additions & 0 deletions test/nx2/blocks/ew-actions/ew-actions.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
import { expect } from '@esm-bundle/chai';
import { DA_ADMIN } from '../../../../nx2/utils/utils.js';
import '../../../../nx2/blocks/ew-actions/ew-actions.js';

let seq = 0;
// Unique org/site per test avoids collisions with daConfig.js's module-level fetch cache.
function uniq(prefix) {
seq += 1;
return `${prefix}${Date.now()}${seq}`;
}

function installFetch(responsesByUrlSubstring) {
const origFetch = window.fetch;
// Sort longest-key-first: the org-level config URL is a substring of the
// site-level one, so a naive first-match would always serve the org config.
const entries = Object.entries(responsesByUrlSubstring).sort(([a], [b]) => b.length - a.length);
window.fetch = async (url, opts) => {
const match = entries.find(([key]) => url.includes(key));
if (match) return new Response(JSON.stringify(match[1]), { status: 200 });
return origFetch(url, opts);
};
return () => { window.fetch = origFetch; };
}

async function makeEl() {
const el = document.createElement('nx-ew-actions');
document.body.append(el);
await el.updateComplete;
return el;
}

describe('nx-ew-actions', () => {
let el;
let restoreFetch;

afterEach(() => {
el?.remove();
restoreFetch?.();
});

describe('_updateHidePublish', () => {
it('does not hide publish when there is no open document', async () => {
el = await makeEl();
el._hashState = null;
await el._updateHidePublish();
expect(el._hidePublish).to.be.false;
});

it('hides publish when a matching editor.hidePublish config exists', async () => {
const org = uniq('org');
const site = uniq('site');
restoreFetch = installFetch({
[`${DA_ADMIN}/config/${org}/`]: { data: [{ key: 'editor.hidePublish', value: `/${org}/${site}/test` }] },
[`${DA_ADMIN}/config/${org}/${site}/`]: { data: [] },
});

el = await makeEl();
el._hashState = { org, site, path: '/test/page' };
await el._updateHidePublish();

expect(el._hidePublish).to.be.true;
});

it('keeps publish when the editor.hidePublish config does not match the path', async () => {
const org = uniq('org');
const site = uniq('site');
restoreFetch = installFetch({
[`${DA_ADMIN}/config/${org}/`]: { data: [{ key: 'editor.hidePublish', value: `/${org}/${site}/other` }] },
[`${DA_ADMIN}/config/${org}/${site}/`]: { data: [] },
});

el = await makeEl();
el._hashState = { org, site, path: '/test/page' };
await el._updateHidePublish();

expect(el._hidePublish).to.be.false;
});

it('ORs editor.hidePublish rows across org- and site-level configs', async () => {
const org = uniq('org');
const site = uniq('site');
restoreFetch = installFetch({
[`${DA_ADMIN}/config/${org}/`]: { data: [{ key: 'editor.hidePublish', value: `/${org}/${site}/other` }] },
[`${DA_ADMIN}/config/${org}/${site}/`]: { data: [{ key: 'editor.hidePublish', value: `/${org}/${site}/test` }] },
});

el = await makeEl();
el._hashState = { org, site, path: '/test/page' };
await el._updateHidePublish();

expect(el._hidePublish).to.be.true;
});
});

describe('render', () => {
it('includes both preview and publish menu items when publish is not hidden', async () => {
const org = uniq('org');
const site = uniq('site');
restoreFetch = installFetch({
[`${DA_ADMIN}/config/${org}/`]: { data: [] },
[`${DA_ADMIN}/config/${org}/${site}/`]: { data: [] },
});

el = await makeEl();
el._hashState = { org, site, path: '/test/page' };
await el._updateHidePublish();
await el.updateComplete;

const ids = el.shadowRoot.querySelector('nx-menu').items.map((i) => i.id);
expect(ids).to.include.members(['preview', 'publish']);
});

it('omits the publish menu item (keeps preview) when publish is hidden', async () => {
const org = uniq('org');
const site = uniq('site');
restoreFetch = installFetch({
[`${DA_ADMIN}/config/${org}/`]: { data: [{ key: 'editor.hidePublish', value: `/${org}/${site}/test` }] },
[`${DA_ADMIN}/config/${org}/${site}/`]: { data: [] },
});

el = await makeEl();
el._hashState = { org, site, path: '/test/page' };
await el._updateHidePublish();
await el.updateComplete;

const ids = el.shadowRoot.querySelector('nx-menu').items.map((i) => i.id);
expect(ids).to.include('preview');
expect(ids).to.not.include('publish');
});
});
});
Loading