diff --git a/test/nuxeo-breadcrumb.test.js b/test/nuxeo-breadcrumb.test.js index 7ea92d1ce2..ec3ce2b3ad 100644 --- a/test/nuxeo-breadcrumb.test.js +++ b/test/nuxeo-breadcrumb.test.js @@ -108,6 +108,29 @@ suite('nuxeo-breadcrumb', () => { }); }); + suite('Visibility without breadcrum entries', () => { + const document2 = { + 'entity-type': 'document', + contextParameters: {}, + path: '/default-domain/workspaces/my workspace/folder 1/folder 2/folder 3/my file', + title: 'my file', + type: 'File', + uid: '7', + }; + setup(async () => { + server = await login(); + breadcrumb = await fixture( + html` + + `, + ); + }); + + test('Should display a breadcrumb when document does not have breadcrumb entries', async () => { + expect(isElementVisible(breadcrumb)).to.be.true; + }); + }); + suite('Breadcrumb composition', () => { test('Should display all the ancestors except the last one when document has breadcrumb entries', async () => { const ancestors = breadcrumb.shadowRoot.querySelector('#ancestors'); @@ -164,4 +187,33 @@ suite('nuxeo-breadcrumb', () => { expect(ancestors.childElementCount).to.be.below(6); }); }); + suite('Title', () => { + test('title should not return title if document is not present or type is root', async () => { + const document3 = { + type: 'Root', + title: 'breadcrumb', + }; + expect(breadcrumb._title(document3)).to.be.not.equal(document3.title); + expect(breadcrumb._title()).to.be.undefined; + }); + test('Should return title when document.type is not root', async () => { + const document4 = { + title: 'breadcrumb', + }; + expect(breadcrumb._title(document4)).to.equal(document4.title); + }); + }); + + suite('Icon', () => { + test('Should return concat when document and url is present else empty', async () => { + const document5 = { + properties: { + 'common:icon': 'testicon', + }, + }; + const url = 'path/'; + expect(breadcrumb._icon(document5, '')).to.equal(''); + expect(breadcrumb._icon(document5, url)).to.equal('path/testicon'); + }); + }); }); diff --git a/test/nuxeo-document-tree.test.js b/test/nuxeo-document-tree.test.js index a1855d9157..5f6c6d624f 100644 --- a/test/nuxeo-document-tree.test.js +++ b/test/nuxeo-document-tree.test.js @@ -25,6 +25,7 @@ let rootDocument; let levelOneDocuments; let levelTwoDocuments; let levelThreeDocuments; +let levelFourDocuments; let levelOneDocument; let levelTwoDocument; let uidCounter; @@ -263,6 +264,10 @@ suite('nuxeo-document-tree', () => { // assert there's no icon to expand the node const icon = node.querySelector('iron-icon'); expect(icon).to.be.null; + expect(documentTree._icon(false)).to.be.equal('icons:folder'); + expect(documentTree._icon(true)).to.be.equal('icons:folder-open'); + expect(documentTree._loading(false)).to.be.equal(''); + expect(documentTree._documentChanged()).to.be.undefined; }); test('Icons should be updated due to tree node expansion', async () => { @@ -312,6 +317,23 @@ suite('nuxeo-document-tree', () => { isElementVisible(documentTree.shadowRoot.querySelector('.parents')); }); + test('Tree breadcrumb is present with root document', async () => { + // set the new document that contains the breadcrumb + + levelFourDocuments = [ + generateDocument({ type: 'Root', parentRef: '7', parentPath: '/Folder6/Folder7', isFolderish: false }), + generateDocument({ type: 'File', parentRef: '8', parentPath: '/Folder6/Folder8', isFolderish: false }), + ]; + const [doc] = levelFourDocuments; + documentTree.currentDocument = doc; + await flush(); + await waitForChildListMutation(documentTree.$.tree); + await waitForTreeNodeLoading(documentTree); + + const nodes = getTreeNodes(documentTree); + expect(nodes).to.have.length(4); + }); + test('Tree should collapse when clicking on a document', async () => { // expand the nodes to reach the leaf (expanding two levels) let node = getTreeNodeByUid(documentTree, 4); @@ -395,6 +417,24 @@ suite('nuxeo-document-tree', () => { }); }); + test('Should not remove document when documents to be deleted are not present', async () => { + // fire the event to remove the documents from the tree + const documentsToDelete = null; + window.dispatchEvent( + new CustomEvent('nuxeo-documents-deleted', { + detail: { + documents: documentsToDelete, + }, + }), + ); + await flush(); + await waitForTreeNodeLoading(documentTree); + + // assert that the documents are not removed + const nodes = getTreeNodes(documentTree); + expect(nodes).to.have.length(4); + }); + test('Should update the tree when a document is created', async () => { // the newly created document const document = generateDocument({ @@ -454,5 +494,27 @@ suite('nuxeo-document-tree', () => { expect(node).to.be.not.null; expect(node.querySelector('.node-name').textContent.trim()).to.be.equal(title); }); + + test('When server responded with 403', async () => { + // set a new title a document to validate the refresh-display updates the tree + const title = 'New doc title'; + levelOneDocuments[0].title = title; + // override the response to retrieve the updated document + generatePageProviderResponse(levelOneDocuments); + server.respondWith('GET', '/api/v1/path/Folder4/Folder6', [403, jsonHeader, JSON.stringify(levelTwoDocument)]); + + // dispatch the refresh-display event + window.dispatchEvent(new CustomEvent('refresh-display')); + await flush(); + await waitForChildListMutation(documentTree.$.tree); + await waitForTreeNodeLoading(documentTree); + + // check we still have all the tree nodes + const nodes = getTreeNodes(documentTree); + expect(nodes).to.have.length(4); + // assert the node has the updated title + const node = Array.from(nodes).find((n) => n.data.title === title); + expect(node).to.be.undefined; + }); }); }); diff --git a/test/nuxeo-edit-documents-button.test.js b/test/nuxeo-edit-documents-button.test.js index 93b8e9b8ac..c3d05011a4 100644 --- a/test/nuxeo-edit-documents-button.test.js +++ b/test/nuxeo-edit-documents-button.test.js @@ -386,6 +386,48 @@ suite('nuxeo-edit-documents-button', () => { expect(isElementVisible(dialog)).to.be.false; }); + test('Should submit form when properties are modified correctly when update mode is replace', async () => { + button = await buildButton(); + const { dialog, save } = button.$; + const natureWidget = getWidget('dc:nature'); + const natureBulkWidget = getBulkWidget(natureWidget); + const expiredWidget = getWidget('dc:expired'); + // open the bulk edit dialog + button.$$('.action').click(); + await waitForDialogOpen(dialog); + // set dc:nature update mode to remove + natureBulkWidget.updateMode = 'replace'; + natureWidget.value = 'test'; + // set a dc:expired date + expiredWidget.value = new Date(); + // click the save button + save.click(); + await waitForDialogClose(dialog); + // check that dialog is closed + expect(isElementVisible(dialog)).to.be.false; + }); + + test('Should submit form when properties are modified correctly when update mode is addvalues', async () => { + button = await buildButton(); + const { dialog, save } = button.$; + const natureWidget = getWidget('dc:nature'); + const natureBulkWidget = getBulkWidget(natureWidget); + const expiredWidget = getWidget('dc:expired'); + // open the bulk edit dialog + button.$$('.action').click(); + await waitForDialogOpen(dialog); + // set dc:nature update mode to remove + natureBulkWidget.updateMode = 'addValues'; + natureWidget.value = 'test'; + // set a dc:expired date + expiredWidget.value = new Date(); + // click the save button + save.click(); + await waitForDialogClose(dialog); + // check that dialog is closed + expect(isElementVisible(dialog)).to.be.false; + }); + test('Should show the append option only if the field is multivalued', async () => { button = await buildButton(); const { dialog } = button.$; diff --git a/test/nuxeo-grid.test.js b/test/nuxeo-grid.test.js index ec1e6db947..9dd48b444b 100644 --- a/test/nuxeo-grid.test.js +++ b/test/nuxeo-grid.test.js @@ -149,6 +149,81 @@ suite('nuxeo-grid', () => { expect(console.warn.notCalled).to.be.true; }); + suite('Should generate proper style when partial properties are set', () => { + test('Should not log warning when column property is not set', async () => { + grid.columns = 3; + grid.rows = 4; + grid.rowGap = '8px'; + grid.columnGap = '8px'; + grid.gap = '16px'; + grid.alignItems = 'center'; + grid.justifyItems = 'center'; + grid.justify = ''; + + const [top, main] = grid.querySelectorAll('*'); + top.setAttribute('data-row', '1'); + top.setAttribute('data-column-span', '1'); + main.setAttribute('data-row', '2'); + main.setAttribute('data-column-span', '2'); + main.setAttribute('data-row-span', '2'); + + await flush(); + expect(console.warn.notCalled).to.be.true; + }); + + test('Should not log warning when only row span property is set', async () => { + grid.columns = 0; + grid.rows = 0; + grid.rowGap = '8px'; + grid.columnGap = '8px'; + grid.gap = '16px'; + grid.alignItems = 'center'; + grid.justifyItems = 'center'; + + const [main] = grid.querySelectorAll('*'); + main.setAttribute('data-row-span', '1'); + main.setAttribute('data-row-span', '2'); + + await flush(); + expect(console.warn.notCalled).to.be.true; + }); + + test('Should not log warning when only when only column span property is set', async () => { + grid.columns = 0; + grid.rows = 0; + grid.rowGap = '8px'; + grid.columnGap = '8px'; + grid.gap = '16px'; + grid.alignItems = 'center'; + grid.justifyItems = 'center'; + + const [top, main] = grid.querySelectorAll('*'); + top.setAttribute('data-column-span', '3'); + main.setAttribute('data-column-span', '2'); + await flush(); + expect(console.warn.notCalled).to.be.true; + }); + + test('Should generate proper style when align and justify properties are set', async () => { + grid.columns = 0; + grid.rows = 0; + grid.rowGap = '8px'; + grid.columnGap = '8px'; + grid.gap = '16px'; + grid.alignItems = 'center'; + grid.justifyItems = 'center'; + + const [main] = grid.querySelectorAll('*'); + main.setAttribute('data-row-span', '1'); + main.setAttribute('data-row-span', '2'); + main.setAttribute('data-align', 'center'); + main.setAttribute('data-justify', 'center'); + + await flush(); + expect(console.warn.notCalled).to.be.true; + }); + }); + test('Should generate proper style when column and row templates are set', async () => { grid.columns = 100; // this will be ignored if templateColumns is defined grid.rows = 300; // this will be ignored if templateRows is defined @@ -194,6 +269,52 @@ suite('nuxeo-grid', () => { grid-row: 3; } } +`; + expect(getStyle(grid)).to.equal(expected); + expect(console.warn.notCalled).to.be.true; + }); + test('Should generate proper style when align and justify items are empty', async () => { + grid.columns = 100; // this will be ignored if templateColumns is defined + grid.rows = 300; // this will be ignored if templateRows is defined + grid.rowGap = '8px'; + grid.columnGap = '8px'; + grid.gap = '16px'; + grid.alignItems = ''; + grid.justifyItems = ''; + grid.templateColumns = '1fr 300px auto'; + grid.templateRows = '2fr auto 200px'; + grid.columnspan = '1'; + await flush(); + const expected = `:host { + display: grid; + grid-template-columns: 1fr 300px auto; + grid-template-rows: 2fr auto 200px; + grid-gap: 16px; + grid-column-gap: 8px; + grid-row-gap: 8px; +} +@media (max-width: 1024px) { + :host { + display: grid; + grid-template-columns: 1fr; + grid-template-rows: auto; + grid-gap: 16px; + grid-column-gap: 8px; + grid-row-gap: 8px; + } + ::slotted([data-child-id="1"]) { + grid-column: 1; + grid-row: 1; + } + ::slotted([data-child-id="2"]) { + grid-column: 1; + grid-row: 2; + } + ::slotted([data-child-id="3"]) { + grid-column: 1; + grid-row: 3; + } +} `; expect(getStyle(grid)).to.equal(expected); expect(console.warn.notCalled).to.be.true;