diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 000000000..1c3cdbc27
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,7 @@
+FROM nginx
+
+COPY nginx.conf /etc/nginx/nginx.conf
+
+WORKDIR /usr/share/nginx/html
+COPY dist/ .
+
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 000000000..3ecf2b560
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,8 @@
+version: '3.1'
+
+services:
+ app:
+ image: 'alfresco/content-app'
+ build: '.'
+ ports:
+ - 3000:80
diff --git a/e2e/components/login/login.ts b/e2e/components/login/login.ts
index 742f08635..ceb89a61c 100644
--- a/e2e/components/login/login.ts
+++ b/e2e/components/login/login.ts
@@ -19,7 +19,7 @@ import { by, ElementFinder, promise } from 'protractor';
import { Component } from '../component';
export class LoginComponent extends Component {
- static selector = 'alfresco-login';
+ static selector = 'adf-login';
private locators = {
usernameInput: by.css('input#username'),
diff --git a/e2e/pages/login-page.ts b/e2e/pages/login-page.ts
index 2a6f90f33..d5ca2dc98 100644
--- a/e2e/pages/login-page.ts
+++ b/e2e/pages/login-page.ts
@@ -40,7 +40,10 @@ export class LoginPage extends Page {
const { submitButton } = this.login;
const hasSumbitButton = EC.presenceOf(submitButton);
- return browser.wait(hasSumbitButton, BROWSER_WAIT_TIMEOUT);
+ return browser.wait(hasSumbitButton, BROWSER_WAIT_TIMEOUT)
+ .then(() => browser.executeScript('window.localStorage.clear();'))
+ .then(() => browser.executeScript('window.sessionStorage.clear();'))
+ .then(() => browser.driver.manage().deleteAllCookies());
});
}
diff --git a/e2e/pages/logout-page.ts b/e2e/pages/logout-page.ts
index f1c0b65ce..5a8f6082a 100644
--- a/e2e/pages/logout-page.ts
+++ b/e2e/pages/logout-page.ts
@@ -22,7 +22,7 @@ import { APP_ROUTES } from '../configs';
export class LogoutPage extends Page {
/** @override */
constructor() {
- super(APP_ROUTES.LOGOUT);
+ super(APP_ROUTES.LOGIN);
}
/** @override */
diff --git a/e2e/pages/page.ts b/e2e/pages/page.ts
index 0ee4009cb..7ec381401 100644
--- a/e2e/pages/page.ts
+++ b/e2e/pages/page.ts
@@ -18,7 +18,7 @@
import { browser, element, by, ElementFinder, promise } from 'protractor';
export abstract class Page {
- private static USE_HASH_STRATEGY = true;
+ private static USE_HASH_STRATEGY = false;
private locators = {
app: by.css('app-root'),
diff --git a/e2e/suites/actions/create-folder.test.ts b/e2e/suites/actions/create-folder.test.ts
index 27d5f37de..c608562cf 100644
--- a/e2e/suites/actions/create-folder.test.ts
+++ b/e2e/suites/actions/create-folder.test.ts
@@ -17,21 +17,24 @@
import { protractor, browser, by, ElementFinder } from 'protractor';
-import { APP_ROUTES, BROWSER_WAIT_TIMEOUT } from '../../configs';
+import { APP_ROUTES, BROWSER_WAIT_TIMEOUT, SITE_VISIBILITY, SITE_ROLES } from '../../configs';
import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages';
import { CreateOrEditFolderDialog } from '../../components/dialog/create-edit-folder-dialog';
-import { LocalStorageUtility } from '../../utilities/local-storage';
+import { Utils } from '../../utilities/utils';
import { RepoClient, NodeContentTree } from '../../utilities/repo-client/repo-client';
describe('Create folder', () => {
const username = 'jane.doe';
const password = 'jane.doe';
+ const parent = 'parent-folder';
const folderName1 = 'my-folder1';
const folderName2 = 'my-folder2';
const folderDescription = 'description of my folder';
const duplicateFolderName = 'duplicate-folder-name';
- const nameWithSpaces = ' folder name ';
+ const nameWithSpaces = ' folder-name ';
+
+ const siteName = 'site-private';
const apis = {
admin: new RepoClient(),
@@ -55,7 +58,10 @@ describe('Create folder', () => {
beforeAll(done => {
apis.admin.people.createUser(username, password)
- .then(() => apis.user.nodes.createFolders([ duplicateFolderName ]))
+ .then(() => apis.admin.sites.createSite(siteName, SITE_VISIBILITY.PRIVATE))
+ .then(() => apis.admin.nodes.createFolders([ folderName1 ], `Sites/${siteName}/documentLibrary`))
+ .then(() => apis.admin.sites.addSiteMember(siteName, username, SITE_ROLES.SITE_CONSUMER))
+ .then(() => apis.user.nodes.createFolders([ duplicateFolderName ], parent))
.then(() => loginPage.load())
.then(() => loginPage.loginWith(username, password))
.then(done);
@@ -74,80 +80,84 @@ describe('Create folder', () => {
afterAll(done => {
Promise
.all([
- apis.user.nodes.deleteNodes([
- folderName1,
- folderName2,
- duplicateFolderName,
- nameWithSpaces.trim()
- ]),
+ apis.user.nodes.deleteNodes([ parent ]),
logoutPage.load()
- .then(() => LocalStorageUtility.clear())
+ .then(() => Utils.clearLocalStorage())
])
.then(done);
});
it('option is enabled when having enough permissions', () => {
- personalFilesPage.sidenav.openNewMenu()
- .then((menu) => {
- const isEnabled = menu.getItemByLabel('Create folder').getWebElement().isEnabled();
+ personalFilesPage.dataTable.doubleClickOnRowByContainingText(parent)
+ .then(() => personalFilesPage.sidenav.openNewMenu()
+ .then((menu) => {
+ const isEnabled = menu.getItemByLabel('Create folder').getWebElement().isEnabled();
- expect(isEnabled).toBe(true, 'Create folder is not enabled');
- });
+ expect(isEnabled).toBe(true, 'Create folder is not enabled');
+ })
+ );
});
it('creates new folder with name', () => {
- openCreateDialog()
- .then(() => createDialog.enterName(folderName1).clickCreate())
- .then(() => createDialog.waitForDialogToClose())
- .then(() => dataTable.waitForHeader())
- .then(() => {
- const isPresent = dataTable.getRowByContainingText(folderName1).isPresent();
- expect(isPresent).toBe(true, 'Folder not displayed in list view');
- });
+ personalFilesPage.dataTable.doubleClickOnRowByContainingText(parent)
+ .then(() => openCreateDialog()
+ .then(() => createDialog.enterName(folderName1).clickCreate())
+ .then(() => createDialog.waitForDialogToClose())
+ .then(() => dataTable.waitForHeader())
+ .then(() => {
+ const isPresent = dataTable.getRowByContainingText(folderName1).isPresent();
+ expect(isPresent).toBe(true, 'Folder not displayed in list view');
+ })
+ );
});
it('creates new folder with name and description', () => {
- openCreateDialog()
- .then(() => {
- createDialog
- .enterName(folderName2)
- .enterDescription(folderDescription)
- .clickCreate();
- })
- .then(() => createDialog.waitForDialogToClose())
- .then(() => dataTable.waitForHeader())
- .then(() => {
- const isPresent = dataTable.getRowByContainingText(folderName2).isPresent();
- expect(isPresent).toBe(true, 'Folder not displayed in list view');
- })
- .then(() => {
- apis.user.nodes.getNodeDescription(folderName2)
- .then((description) => {
- expect(description).toEqual(folderDescription, 'Description is not correct');
- });
- });
+ personalFilesPage.dataTable.doubleClickOnRowByContainingText(parent)
+ .then(() => openCreateDialog()
+ .then(() => {
+ createDialog
+ .enterName(folderName2)
+ .enterDescription(folderDescription)
+ .clickCreate();
+ })
+ .then(() => createDialog.waitForDialogToClose())
+ .then(() => dataTable.waitForHeader())
+ .then(() => {
+ const isPresent = dataTable.getRowByContainingText(folderName2).isPresent();
+ expect(isPresent).toBe(true, 'Folder not displayed in list view');
+ })
+ .then(() => {
+ apis.user.nodes.getNodeDescription(folderName2)
+ .then((description) => {
+ expect(description).toEqual(folderDescription, 'Description is not correct');
+ });
+ })
+ );
});
it('enabled option tooltip', () => {
- personalFilesPage.sidenav.openNewMenu()
- .then(menu => {
- const action = browser.actions().mouseMove(menu.getItemByLabel('Create folder'));
- action.perform();
+ personalFilesPage.dataTable.doubleClickOnRowByContainingText(parent)
+ .then(() => personalFilesPage.sidenav.openNewMenu()
+ .then(menu => {
+ const action = browser.actions().mouseMove(menu.getItemByLabel('Create folder'));
+ action.perform();
- return menu;
- })
- .then((menu) => {
- const tooltip = menu.getItemTooltip('Create folder');
- expect(tooltip).toContain('Create new folder');
- });
+ return menu;
+ })
+ .then((menu) => {
+ const tooltip = menu.getItemTooltip('Create folder');
+ expect(tooltip).toContain('Create new folder');
+ })
+ );
});
it('option is disabled when not enough permissions', () => {
- // refactor after implementing Breadcrumb automation component
- const breadcrumbRoot: ElementFinder = protractor.element(by.css('.adf-breadcrumb-item[title="User Homes"]'));
+ const fileLibrariesPage = new BrowsingPage(APP_ROUTES.FILE_LIBRARIES);
- browser.actions().mouseMove(breadcrumbRoot).click().perform()
- .then(() => personalFilesPage.sidenav.openNewMenu())
+ fileLibrariesPage.sidenav.navigateToLinkByLabel('File Libraries')
+ .then(() => fileLibrariesPage.dataTable.doubleClickOnRowByContainingText(siteName))
+ .then(() => fileLibrariesPage.dataTable.doubleClickOnRowByContainingText(folderName1))
+ .then(() => fileLibrariesPage.sidenav.openNewMenu())
.then(menu => {
const isEnabled = menu.getItemByLabel('Create folder').getWebElement().isEnabled();
expect(isEnabled).toBe(false, 'Create folder is not disabled');
@@ -155,11 +165,12 @@ describe('Create folder', () => {
});
it('disabled option tooltip', () => {
- // refactor after implementing Breadcrumb automation component
- const breadcrumbRoot: ElementFinder = protractor.element(by.css('.adf-breadcrumb-item[title="User Homes"]'));
+ const fileLibrariesPage = new BrowsingPage(APP_ROUTES.FILE_LIBRARIES);
- browser.actions().mouseMove(breadcrumbRoot).click().perform()
- .then(() => personalFilesPage.sidenav.openNewMenu())
+ fileLibrariesPage.sidenav.navigateToLinkByLabel('File Libraries')
+ .then(() => fileLibrariesPage.dataTable.doubleClickOnRowByContainingText(siteName))
+ .then(() => fileLibrariesPage.dataTable.doubleClickOnRowByContainingText(folderName1))
+ .then(() => fileLibrariesPage.sidenav.openNewMenu())
.then(menu => {
const action = browser.actions().mouseMove(menu.getItemByLabel('Create folder'));
action.perform()
@@ -171,107 +182,123 @@ describe('Create folder', () => {
});
it('dialog UI elements', () => {
- openCreateDialog().then(() => {
- const dialogTitle = createDialog.getTitle();
- const isFolderNameDisplayed = createDialog.nameInput.getWebElement().isDisplayed();
- const isDescriptionDisplayed = createDialog.descriptionTextArea.getWebElement().isDisplayed();
- const isCreateEnabled = createDialog.createButton.getWebElement().isEnabled();
- const isCancelEnabled = createDialog.cancelButton.getWebElement().isEnabled();
+ personalFilesPage.dataTable.doubleClickOnRowByContainingText(parent)
+ .then(() => openCreateDialog().then(() => {
+ const dialogTitle = createDialog.getTitle();
+ const isFolderNameDisplayed = createDialog.nameInput.getWebElement().isDisplayed();
+ const isDescriptionDisplayed = createDialog.descriptionTextArea.getWebElement().isDisplayed();
+ const isCreateEnabled = createDialog.createButton.getWebElement().isEnabled();
+ const isCancelEnabled = createDialog.cancelButton.getWebElement().isEnabled();
- expect(dialogTitle).toBe('Create new folder');
- expect(isFolderNameDisplayed).toBe(true, 'Name input is not displayed');
- expect(isDescriptionDisplayed).toBe(true, 'Description field is not displayed');
- expect(isCreateEnabled).toBe(false, 'Create button is not disabled');
- expect(isCancelEnabled).toBe(true, 'Cancel button is not enabled');
- });
+ expect(dialogTitle).toBe('Create new folder');
+ expect(isFolderNameDisplayed).toBe(true, 'Name input is not displayed');
+ expect(isDescriptionDisplayed).toBe(true, 'Description field is not displayed');
+ expect(isCreateEnabled).toBe(false, 'Create button is not disabled');
+ expect(isCancelEnabled).toBe(true, 'Cancel button is not enabled');
+ })
+ );
});
it('with empty folder name', () => {
- openCreateDialog()
- .then(() => {
- createDialog.deleteNameWithBackspace();
- })
- .then(() => {
- const isCreateEnabled = createDialog.createButton.getWebElement().isEnabled();
- const validationMessage = createDialog.getValidationMessage();
+ personalFilesPage.dataTable.doubleClickOnRowByContainingText(parent)
+ .then(() => openCreateDialog()
+ .then(() => {
+ createDialog.deleteNameWithBackspace();
+ })
+ .then(() => {
+ const isCreateEnabled = createDialog.createButton.getWebElement().isEnabled();
+ const validationMessage = createDialog.getValidationMessage();
- expect(isCreateEnabled).toBe(false, 'Create button is enabled');
- expect(validationMessage).toMatch('Folder name is required');
- });
+ expect(isCreateEnabled).toBe(false, 'Create button is enabled');
+ expect(validationMessage).toMatch('Folder name is required');
+ })
+ );
});
it('with folder name ending with a dot "."', () => {
- openCreateDialog()
- .then(() => createDialog.enterName('folder-name.'))
- .then((dialog) => {
- const isCreateEnabled = dialog.createButton.getWebElement().isEnabled();
- const validationMessage = dialog.getValidationMessage();
+ personalFilesPage.dataTable.doubleClickOnRowByContainingText(parent)
+ .then(() => openCreateDialog()
+ .then(() => createDialog.enterName('folder-name.'))
+ .then((dialog) => {
+ const isCreateEnabled = dialog.createButton.getWebElement().isEnabled();
+ const validationMessage = dialog.getValidationMessage();
- expect(isCreateEnabled).toBe(false, 'Create button is not disabled');
- expect(validationMessage).toMatch(`Folder name can't end with a period .`);
- });
+ expect(isCreateEnabled).toBe(false, 'Create button is not disabled');
+ expect(validationMessage).toMatch(`Folder name can't end with a period .`);
+ })
+ );
});
it('with folder name containing special characters', () => {
const namesWithSpecialChars = [ 'a*a', 'a"a', 'aa', `a\\a`, 'a/a', 'a?a', 'a:a', 'a|a' ];
- openCreateDialog()
- .then(() => {
- namesWithSpecialChars.forEach(name => {
- createDialog.enterName(name);
+ personalFilesPage.dataTable.doubleClickOnRowByContainingText(parent)
+ .then(() => openCreateDialog()
+ .then(() => {
+ namesWithSpecialChars.forEach(name => {
+ createDialog.enterName(name);
- const isCreateEnabled = createDialog.createButton.getWebElement().isEnabled();
- const validationMessage = createDialog.getValidationMessage();
+ const isCreateEnabled = createDialog.createButton.getWebElement().isEnabled();
+ const validationMessage = createDialog.getValidationMessage();
- expect(isCreateEnabled).toBe(false, 'Create button is not disabled');
- expect(validationMessage).toContain(`Folder name can't contain these characters`);
- });
- });
+ expect(isCreateEnabled).toBe(false, 'Create button is not disabled');
+ expect(validationMessage).toContain(`Folder name can't contain these characters`);
+ });
+ })
+ );
});
it('with folder name containing only spaces', () => {
- openCreateDialog()
- .then(() => createDialog.enterName(' '))
- .then((dialog) => {
- const isCreateEnabled = dialog.createButton.getWebElement().isEnabled();
- const validationMessage = dialog.getValidationMessage();
+ personalFilesPage.dataTable.doubleClickOnRowByContainingText(parent)
+ .then(() => openCreateDialog()
+ .then(() => createDialog.enterName(' '))
+ .then((dialog) => {
+ const isCreateEnabled = dialog.createButton.getWebElement().isEnabled();
+ const validationMessage = dialog.getValidationMessage();
- expect(isCreateEnabled).toBe(false, 'Create button is not disabled');
- expect(validationMessage).toMatch(`Folder name can't contain only spaces`);
- });
+ expect(isCreateEnabled).toBe(false, 'Create button is not disabled');
+ expect(validationMessage).toMatch(`Folder name can't contain only spaces`);
+ })
+ );
});
it('cancel folder creation', () => {
- openCreateDialog()
- .then(() => {
- createDialog
- .enterName('test')
- .enterDescription('test description')
- .clickCancel();
- })
- .then(() => expect(createDialog.component.isPresent()).not.toBe(true, 'dialog is not closed'));
+ personalFilesPage.dataTable.doubleClickOnRowByContainingText(parent)
+ .then(() => openCreateDialog()
+ .then(() => {
+ createDialog
+ .enterName('test')
+ .enterDescription('test description')
+ .clickCancel();
+ })
+ .then(() => expect(createDialog.component.isPresent()).not.toBe(true, 'dialog is not closed'))
+ );
});
it('duplicate folder name', () => {
- openCreateDialog()
- .then(() => createDialog.enterName(duplicateFolderName).clickCreate())
- .then(() => {
- personalFilesPage.getSnackBarMessage()
- .then(message => {
- expect(message).toEqual(`There's already a folder with this name. Try a different name.`);
- expect(createDialog.component.isPresent()).toBe(true, 'dialog is not present');
- });
- });
+ personalFilesPage.dataTable.doubleClickOnRowByContainingText(parent)
+ .then(() => openCreateDialog()
+ .then(() => createDialog.enterName(duplicateFolderName).clickCreate())
+ .then(() => {
+ personalFilesPage.getSnackBarMessage()
+ .then(message => {
+ expect(message).toEqual(`There's already a folder with this name. Try a different name.`);
+ expect(createDialog.component.isPresent()).toBe(true, 'dialog is not present');
+ });
+ })
+ );
});
it('trim ending spaces from folder name', () => {
- openCreateDialog()
- .then(() => createDialog.enterName(nameWithSpaces).clickCreate())
- .then(() => createDialog.waitForDialogToClose())
- .then(() => dataTable.waitForHeader())
- .then(() => {
- const isPresent = dataTable.getRowByContainingText(nameWithSpaces.trim()).isPresent();
- expect(isPresent).toBe(true, 'Folder not displayed in list view');
- });
+ personalFilesPage.dataTable.doubleClickOnRowByContainingText(parent)
+ .then(() => openCreateDialog()
+ .then(() => createDialog.enterName(nameWithSpaces).clickCreate())
+ .then(() => createDialog.waitForDialogToClose())
+ .then(() => dataTable.waitForHeader())
+ .then(() => {
+ const isPresent = dataTable.getRowByContainingText(nameWithSpaces.trim()).isPresent();
+ expect(isPresent).toBe(true, 'Folder not displayed in list view');
+ })
+ );
});
});
diff --git a/e2e/suites/actions/edit-folder.test.ts b/e2e/suites/actions/edit-folder.test.ts
index 47bf0b749..441ba60fa 100644
--- a/e2e/suites/actions/edit-folder.test.ts
+++ b/e2e/suites/actions/edit-folder.test.ts
@@ -20,12 +20,13 @@ import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages';
import { APP_ROUTES, SITE_VISIBILITY, SITE_ROLES } from '../../configs';
import { RepoClient } from '../../utilities/repo-client/repo-client';
import { CreateOrEditFolderDialog } from '../../components/dialog/create-edit-folder-dialog';
-import { LocalStorageUtility } from '../../utilities/local-storage';
+import { Utils } from '../../utilities/utils';
describe('Edit folder', () => {
- const username = 'jane.doe';
- const password = 'jane.doe';
+ const username = 'john.doe';
+ const password = 'john.doe';
+ const parent = 'parent-folder';
const folderName = 'my-folder';
const folderDescription = 'my folder description';
@@ -44,7 +45,7 @@ describe('Edit folder', () => {
const loginPage = new LoginPage();
const logoutPage = new LogoutPage();
- const personalFilesPage = new BrowsingPage();
+ const personalFilesPage = new BrowsingPage(APP_ROUTES.PERSONAL_FILES);
const editDialog = new CreateOrEditFolderDialog();
const dataTable = personalFilesPage.dataTable;
const editButton = personalFilesPage.toolbar.actions.getButtonByTitleAttribute('Edit');
@@ -58,11 +59,11 @@ describe('Edit folder', () => {
])
.then(() => apis.admin.sites.addSiteMember(siteName, username, SITE_ROLES.SITE_CONSUMER))
.then(() => Promise.all([
- apis.user.nodes.createNodeWithProperties( folderName, '', folderDescription ),
- apis.user.nodes.createFolders([ folderNameToEdit, duplicateFolderName ]),
+ apis.user.nodes.createNodeWithProperties( folderName, '', folderDescription, parent ),
+ apis.user.nodes.createFolders([ folderNameToEdit, duplicateFolderName ], parent),
loginPage.load()
]))
- .then(() => { loginPage.loginWith(username, password); })
+ .then(() => loginPage.loginWith(username, password))
.then(done);
});
@@ -80,57 +81,63 @@ describe('Edit folder', () => {
Promise
.all([
apis.admin.sites.deleteSite(siteName, true),
- apis.user.nodes.deleteNodes([ folderName, folderNameEdited, duplicateFolderName ]),
+ apis.user.nodes.deleteNodes([ parent ]),
logoutPage.load()
- .then(() => LocalStorageUtility.clear())
+ .then(() => Utils.clearLocalStorage())
])
.then(done);
});
it('button is enabled when having permissions', () => {
- dataTable.clickOnRowByContainingText(folderName)
- .then(() => {
- expect(editButton.isEnabled()).toBe(true);
- });
+ personalFilesPage.dataTable.doubleClickOnRowByContainingText(parent)
+ .then(() => dataTable.clickOnRowByContainingText(folderName)
+ .then(() => {
+ expect(editButton.isEnabled()).toBe(true);
+ })
+ );
});
it('dialog UI defaults', () => {
- dataTable.clickOnRowByContainingText(folderName)
- .then(() => editButton.click())
- .then(() => {
- expect(editDialog.getTitle()).toBe('Edit folder');
- expect(editDialog.nameInput.getWebElement().getAttribute('value')).toBe(folderName);
- expect(editDialog.descriptionTextArea.getWebElement().getAttribute('value')).toBe(folderDescription);
- expect(editDialog.updateButton.getWebElement().isEnabled()).toBe(true, 'upload button is not enabled');
- expect(editDialog.cancelButton.getWebElement().isEnabled()).toBe(true, 'cancel button is not enabled');
- });
+ personalFilesPage.dataTable.doubleClickOnRowByContainingText(parent)
+ .then(() => dataTable.clickOnRowByContainingText(folderName)
+ .then(() => editButton.click())
+ .then(() => {
+ expect(editDialog.getTitle()).toBe('Edit folder');
+ expect(editDialog.nameInput.getWebElement().getAttribute('value')).toBe(folderName);
+ expect(editDialog.descriptionTextArea.getWebElement().getAttribute('value')).toBe(folderDescription);
+ expect(editDialog.updateButton.getWebElement().isEnabled()).toBe(true, 'upload button is not enabled');
+ expect(editDialog.cancelButton.getWebElement().isEnabled()).toBe(true, 'cancel button is not enabled');
+ })
+ );
});
it('folder properties are modified when pressing OK', () => {
- dataTable.clickOnRowByContainingText(folderNameToEdit)
- .then(() => editButton.click())
- .then(() => {
- editDialog
- .enterName(folderNameEdited)
- .enterDescription(folderDescriptionEdited)
- .clickUpdate();
- })
- .then(() => editDialog.waitForDialogToClose())
- .then(() => dataTable.waitForHeader())
- .then(() => {
- const isPresent = dataTable.getRowByContainingText(folderNameEdited).isPresent();
- expect(isPresent).toBe(true, 'Folder not displayed in list view');
- })
- .then(() => {
- apis.user.nodes.getNodeDescription(folderNameEdited)
- .then((description) => {
- expect(description).toEqual(folderDescriptionEdited);
- });
- });
+ personalFilesPage.dataTable.doubleClickOnRowByContainingText(parent)
+ .then(() => dataTable.clickOnRowByContainingText(folderNameToEdit)
+ .then(() => editButton.click())
+ .then(() => {
+ editDialog
+ .enterName(folderNameEdited)
+ .enterDescription(folderDescriptionEdited)
+ .clickUpdate();
+ })
+ .then(() => editDialog.waitForDialogToClose())
+ .then(() => dataTable.waitForHeader())
+ .then(() => {
+ const isPresent = dataTable.getRowByContainingText(folderNameEdited).isPresent();
+ expect(isPresent).toBe(true, 'Folder not displayed in list view');
+ })
+ .then(() => {
+ apis.user.nodes.getNodeDescription(folderNameEdited)
+ .then((description) => {
+ expect(description).toEqual(folderDescriptionEdited);
+ });
+ })
+ );
});
it('button is not displayed when not enough permissions', () => {
- const fileLibrariesPage = new BrowsingPage();
+ const fileLibrariesPage = new BrowsingPage(APP_ROUTES.FILE_LIBRARIES);
fileLibrariesPage.sidenav.navigateToLinkByLabel('File Libraries')
.then(() => fileLibrariesPage.dataTable.doubleClickOnRowByContainingText(siteName))
@@ -141,71 +148,85 @@ describe('Edit folder', () => {
});
it('with empty folder name', () => {
- dataTable.clickOnRowByContainingText(folderName)
- .then(() => editButton.click())
- .then(() => {
- editDialog.deleteNameWithBackspace();
- })
- .then(() => {
- expect(editDialog.updateButton.getWebElement().isEnabled()).toBe(false, 'upload button is not enabled');
- expect(editDialog.getValidationMessage()).toMatch('Folder name is required');
- });
+ personalFilesPage.dataTable.doubleClickOnRowByContainingText(parent)
+ .then(() => dataTable.clickOnRowByContainingText(folderName)
+ .then(() => editButton.click())
+ .then(() => {
+ editDialog.deleteNameWithBackspace();
+ })
+ .then(() => {
+ expect(editDialog.updateButton.getWebElement().isEnabled()).toBe(false, 'upload button is not enabled');
+ expect(editDialog.getValidationMessage()).toMatch('Folder name is required');
+ })
+ );
});
it('with name with special characters', () => {
const namesWithSpecialChars = [ 'a*a', 'a"a', 'aa', `a\\a`, 'a/a', 'a?a', 'a:a', 'a|a' ];
- dataTable.clickOnRowByContainingText(folderName)
- .then(() => editButton.click())
- .then(() => {
- namesWithSpecialChars.forEach(name => {
- editDialog.enterName(name);
+ personalFilesPage.dataTable.doubleClickOnRowByContainingText(parent)
+ .then(() => dataTable.clickOnRowByContainingText(folderName)
+ .then(() => editButton.click())
+ .then(() => {
+ namesWithSpecialChars.forEach(name => {
+ editDialog.enterName(name);
- expect(editDialog.updateButton.getWebElement().isEnabled()).toBe(false, 'upload button is not disabled');
- expect(editDialog.getValidationMessage()).toContain(`Folder name can't contain these characters`);
- });
- });
+ expect(editDialog.updateButton.getWebElement().isEnabled()).toBe(false, 'upload button is not disabled');
+ expect(editDialog.getValidationMessage()).toContain(`Folder name can't contain these characters`);
+ });
+ })
+ );
});
it('with name ending with a dot', () => {
- dataTable.clickOnRowByContainingText(folderName)
- .then(() => editButton.click())
- .then(() => editDialog.nameInput.sendKeys('.'))
- .then(() => {
- expect(editDialog.updateButton.getWebElement().isEnabled()).toBe(false, 'upload button is not enabled');
- expect(editDialog.getValidationMessage()).toMatch(`Folder name can't end with a period .`);
- });
+ personalFilesPage.dataTable.doubleClickOnRowByContainingText(parent)
+ .then(() => dataTable.clickOnRowByContainingText(folderName)
+ .then(() => editButton.click())
+ .then(() => editDialog.nameInput.sendKeys('.'))
+ .then(() => {
+ expect(editDialog.updateButton.getWebElement().isEnabled()).toBe(false, 'upload button is not enabled');
+ expect(editDialog.getValidationMessage()).toMatch(`Folder name can't end with a period .`);
+ })
+ );
});
it('Cancel button', () => {
- dataTable.clickOnRowByContainingText(folderName)
- .then(() => editButton.click())
- .then(() => editDialog.clickCancel())
- .then(() => { expect(editDialog.component.isPresent()).not.toBe(true, 'dialog is not closed'); });
+ personalFilesPage.dataTable.doubleClickOnRowByContainingText(parent)
+ .then(() => dataTable.clickOnRowByContainingText(folderName)
+ .then(() => editButton.click())
+ .then(() => editDialog.clickCancel())
+ .then(() => {
+ expect(editDialog.component.isPresent()).not.toBe(true, 'dialog is not closed');
+ })
+ );
});
it('with duplicate folder name', () => {
- dataTable.clickOnRowByContainingText(folderName)
- .then(() => editButton.click())
- .then(() => editDialog.enterName(duplicateFolderName).clickUpdate())
- .then(() => {
- personalFilesPage.getSnackBarMessage()
- .then(message => {
- expect(message).toEqual(`There's already a folder with this name. Try a different name.`);
- expect(editDialog.component.isPresent()).toBe(true, 'dialog is not present');
- });
- });
+ personalFilesPage.dataTable.doubleClickOnRowByContainingText(parent)
+ .then(() => dataTable.clickOnRowByContainingText(folderName)
+ .then(() => editButton.click())
+ .then(() => editDialog.enterName(duplicateFolderName).clickUpdate())
+ .then(() => {
+ personalFilesPage.getSnackBarMessage()
+ .then(message => {
+ expect(message).toEqual(`There's already a folder with this name. Try a different name.`);
+ expect(editDialog.component.isPresent()).toBe(true, 'dialog is not present');
+ });
+ })
+ );
});
it('trim ending spaces', () => {
- dataTable.clickOnRowByContainingText(folderName)
- .then(() => editButton.click())
- .then(() => editDialog.nameInput.sendKeys(' '))
- .then(() => editDialog.clickUpdate())
- .then(() => editDialog.waitForDialogToClose())
- .then(() => {
- expect(personalFilesPage.snackBar.isPresent()).not.toBe(true, 'notification appears');
- expect(dataTable.getRowByContainingText(folderName).isPresent()).toBe(true, 'Folder not displayed in list view');
- });
+ personalFilesPage.dataTable.doubleClickOnRowByContainingText(parent)
+ .then(() => dataTable.clickOnRowByContainingText(folderName)
+ .then(() => editButton.click())
+ .then(() => editDialog.nameInput.sendKeys(' '))
+ .then(() => editDialog.clickUpdate())
+ .then(() => editDialog.waitForDialogToClose())
+ .then(() => {
+ expect(personalFilesPage.snackBar.isPresent()).not.toBe(true, 'notification appears');
+ expect(dataTable.getRowByContainingText(folderName).isPresent()).toBe(true, 'Folder not displayed in list view');
+ })
+ );
});
});
diff --git a/e2e/suites/application/page-titles.test.ts b/e2e/suites/application/page-titles.test.ts
index b9085a6f7..6906435af 100644
--- a/e2e/suites/application/page-titles.test.ts
+++ b/e2e/suites/application/page-titles.test.ts
@@ -19,7 +19,7 @@ import { browser } from 'protractor';
import { SIDEBAR_LABELS } from '../../configs';
import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages';
-import { LocalStorageUtility } from '../../utilities/local-storage';
+import { Utils } from '../../utilities/utils';
describe('Page titles', () => {
const loginPage = new LoginPage();
@@ -65,7 +65,7 @@ describe('Page titles', () => {
afterAll(done => {
logoutPage.load()
- .then(() => LocalStorageUtility.clear())
+ .then(() => Utils.clearLocalStorage())
.then(done);
});
diff --git a/e2e/suites/authentication/login.test.ts b/e2e/suites/authentication/login.test.ts
index 922386dad..56d804805 100644
--- a/e2e/suites/authentication/login.test.ts
+++ b/e2e/suites/authentication/login.test.ts
@@ -19,7 +19,7 @@ import { browser } from 'protractor';
import { APP_ROUTES } from '../../configs';
import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages';
-import { LocalStorageUtility } from '../../utilities/local-storage';
+import { Utils } from '../../utilities/utils';
import { RepoClient } from '../../utilities/repo-client/repo-client';
describe('Login', () => {
@@ -63,7 +63,7 @@ describe('Login', () => {
afterEach(done => {
logoutPage.load()
- .then(() => LocalStorageUtility.clear())
+ .then(() => Utils.clearLocalStorage())
.then(done);
});
diff --git a/e2e/suites/authentication/logout.test.ts b/e2e/suites/authentication/logout.test.ts
index 050e2913a..6a48edc25 100644
--- a/e2e/suites/authentication/logout.test.ts
+++ b/e2e/suites/authentication/logout.test.ts
@@ -19,7 +19,7 @@ import { browser } from 'protractor';
import { APP_ROUTES, BROWSER_WAIT_TIMEOUT } from '../../configs';
import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages';
-import { LocalStorageUtility } from '../../utilities/local-storage';
+import { Utils } from '../../utilities/utils';
import { RepoClient } from '../../utilities/repo-client/repo-client';
describe('Logout', () => {
@@ -48,7 +48,7 @@ describe('Logout', () => {
afterEach((done) => {
logoutPage.load()
- .then(() => LocalStorageUtility.clear())
+ .then(() => Utils.clearLocalStorage())
.then(done);
});
diff --git a/e2e/suites/list-views/personal-files.test.ts b/e2e/suites/list-views/personal-files.test.ts
index 891e729a6..efe263793 100644
--- a/e2e/suites/list-views/personal-files.test.ts
+++ b/e2e/suites/list-views/personal-files.test.ts
@@ -19,7 +19,7 @@ import { browser } from 'protractor';
import { APP_ROUTES } from '../../configs';
import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages';
-import { LocalStorageUtility } from '../../utilities/local-storage';
+import { Utils } from '../../utilities/utils';
import { RepoClient, NodeContentTree } from '../../utilities/repo-client/repo-client';
describe('Personal Files', () => {
@@ -81,7 +81,7 @@ describe('Personal Files', () => {
afterAll(done => {
logoutPage.load()
- .then(() => LocalStorageUtility.clear())
+ .then(() => Utils.clearLocalStorage())
.then(done);
});
@@ -109,7 +109,7 @@ describe('Personal Files', () => {
afterAll(done => {
logoutPage.load()
- .then(() => LocalStorageUtility.clear())
+ .then(() => Utils.clearLocalStorage())
.then(done);
});
diff --git a/e2e/suites/navigation/side-navigation.test.ts b/e2e/suites/navigation/side-navigation.test.ts
index 93e6219fe..bf6c8541d 100644
--- a/e2e/suites/navigation/side-navigation.test.ts
+++ b/e2e/suites/navigation/side-navigation.test.ts
@@ -19,7 +19,7 @@ import { browser } from 'protractor';
import { APP_ROUTES, SIDEBAR_LABELS } from '../../configs';
import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages';
-import { LocalStorageUtility } from '../../utilities/local-storage';
+import { Utils } from '../../utilities/utils';
describe('Side navigation', () => {
const loginPage = new LoginPage();
@@ -38,7 +38,7 @@ describe('Side navigation', () => {
afterAll(done => {
logoutPage.load()
- .then(() => LocalStorageUtility.clear())
+ .then(() => Utils.clearLocalStorage())
.then(done);
});
diff --git a/e2e/suites/pagination/pagination.test.ts b/e2e/suites/pagination/pagination.test.ts
index f0298ff51..7fb40c359 100644
--- a/e2e/suites/pagination/pagination.test.ts
+++ b/e2e/suites/pagination/pagination.test.ts
@@ -19,7 +19,7 @@ import { browser } from 'protractor';
import { APP_ROUTES } from '../../configs';
import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages';
-import { LocalStorageUtility } from '../../utilities/local-storage';
+import { Utils } from '../../utilities/utils';
import { RepoClient, NodeContentTree } from '../../utilities/repo-client/repo-client';
describe('Pagination', () => {
@@ -75,7 +75,7 @@ describe('Pagination', () => {
afterAll(done => {
logoutPage
.load()
- .then(() => LocalStorageUtility.clear())
+ .then(() => Utils.clearLocalStorage())
.then(() => nodesApi.deleteNodes([ content.name ]))
.then(done);
});
diff --git a/e2e/utilities/repo-client/apis/favorites/favorites-api.ts b/e2e/utilities/repo-client/apis/favorites/favorites-api.ts
new file mode 100644
index 000000000..ced51018d
--- /dev/null
+++ b/e2e/utilities/repo-client/apis/favorites/favorites-api.ts
@@ -0,0 +1,60 @@
+/*!
+ * @license
+ * Copyright 2017 Alfresco Software, Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { promise } from 'protractor';
+import { RepoApi } from '../repo-api';
+import { NodesApi } from '../nodes/nodes-api';
+import { RepoClient } from './../../repo-client';
+
+export class FavoritesApi extends RepoApi {
+
+ addFavorite(api: RepoClient, nodeType: string, name: string): Promise {
+ return api.nodes.getNodeByPath(name)
+ .then((response) => {
+ const { id } = response.data.entry;
+ return ([{
+ target: {
+ [nodeType]: {
+ guid: id
+ }
+ }
+ }]);
+ })
+ .then((data) => {
+ return this.post(`/people/-me-/favorites`, { data });
+ })
+ .catch(this.handleError);
+ }
+
+ getFavorite(api: RepoClient, name: string): Promise {
+ return api.nodes.getNodeByPath(name)
+ .then((response) => {
+ const { id } = response.data.entry;
+ return this.get(`/people/-me-/favorites/${id}`);
+ })
+ .catch((response) => Promise.resolve(response));
+ }
+
+ removeFavorite(api: RepoClient, nodeType: string, name: string): Promise {
+ return api.nodes.getNodeByPath(name)
+ .then((response) => {
+ const { id } = response.data.entry;
+ return this.delete(`/people/-me-/favorites/${id}`);
+ })
+ .catch(this.handleError);
+ }
+}
diff --git a/e2e/utilities/repo-client/repo-client.ts b/e2e/utilities/repo-client/repo-client.ts
index 80d37360b..889c4c1f3 100644
--- a/e2e/utilities/repo-client/repo-client.ts
+++ b/e2e/utilities/repo-client/repo-client.ts
@@ -20,12 +20,13 @@ import { RepoClientAuth, RepoClientConfig } from './repo-client-models';
import { PeopleApi } from './apis/people/people-api';
import { NodesApi } from './apis/nodes/nodes-api';
import { SitesApi } from './apis/sites/sites-api';
+import { FavoritesApi } from './apis/favorites/favorites-api';
export class RepoClient {
public people: PeopleApi = new PeopleApi(this.auth, this.config);
public nodes: NodesApi = new NodesApi(this.auth, this.config);
public sites: SitesApi = new SitesApi(this.auth, this.config);
- // public favorites: FavoritesApi = new FavoritesApi(this.auth, this.config);
+ public favorites: FavoritesApi = new FavoritesApi(this.auth, this.config);
// public shared: SharedLinksApi = new SharedLinksApi(this.auth, this.config);
constructor(
diff --git a/e2e/utilities/local-storage.ts b/e2e/utilities/utils.ts
similarity index 64%
rename from e2e/utilities/local-storage.ts
rename to e2e/utilities/utils.ts
index 46d7d7926..0a6072f68 100644
--- a/e2e/utilities/local-storage.ts
+++ b/e2e/utilities/utils.ts
@@ -17,18 +17,14 @@
import { browser, promise } from 'protractor';
-declare var window;
-
-export class LocalStorageUtility {
- static clear(): promise.Promise {
- return browser.executeScript(() => {
- return window.localStorage.clear();
- });
+export class Utils {
+ // generate a random value
+ static random(): string {
+ return Math.random().toString(36).substring(3, 10);
}
- static getTicket(): promise.Promise {
- return browser.executeScript(() => {
- return window.localStorage.getItem('ticket-ECM');
- });
+ // local storage
+ static clearLocalStorage(): promise.Promise {
+ return browser.executeScript('window.localStorage.clear();');
}
}
diff --git a/nginx.conf b/nginx.conf
new file mode 100644
index 000000000..ea9434b3d
--- /dev/null
+++ b/nginx.conf
@@ -0,0 +1,25 @@
+worker_processes 1;
+
+events {
+ worker_connections 1024;
+}
+
+http {
+ server {
+ listen 80;
+ server_name localhost;
+
+ root /usr/share/nginx/html;
+ index index.html index.htm;
+ include /etc/nginx/mime.types;
+
+ gzip on;
+ gzip_min_length 1000;
+ gzip_proxied expired no-cache no-store private auth;
+ gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;
+
+ location / {
+ try_files $uri $uri/ /index.html;
+ }
+ }
+}
diff --git a/package.json b/package.json
index 5349356db..7319ef40a 100644
--- a/package.json
+++ b/package.json
@@ -6,6 +6,8 @@
"ng": "ng",
"start": "ng serve --open",
"build": "ng build",
+ "build:prod": "ng build --prod",
+ "build:dev": "ng build && node postbuild-dev.js",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e",
@@ -24,17 +26,17 @@
"@angular/platform-browser": "4.4.5",
"@angular/platform-browser-dynamic": "4.4.5",
"@angular/router": "4.4.5",
- "@ngx-translate/core": "7.0.0",
- "alfresco-js-api": "1.10.0-beta5",
+ "@ngx-translate/core": "8.0.0",
+ "alfresco-js-api": "1.10.0-beta6",
"core-js": "^2.4.1",
"hammerjs": "2.0.8",
- "ng2-alfresco-core": "1.10.0-beta5",
- "ng2-alfresco-datatable": "1.10.0-beta5",
- "ng2-alfresco-documentlist": "1.10.0-beta5",
- "ng2-alfresco-login": "1.10.0-beta5",
- "ng2-alfresco-search": "1.10.0-beta5",
- "ng2-alfresco-upload": "1.10.0-beta5",
- "ng2-alfresco-viewer": "1.10.0-beta5",
+ "ng2-alfresco-core": "1.10.0-beta6",
+ "ng2-alfresco-datatable": "1.10.0-beta6",
+ "ng2-alfresco-documentlist": "1.10.0-beta6",
+ "ng2-alfresco-login": "1.10.0-beta6",
+ "ng2-alfresco-search": "1.10.0-beta6",
+ "ng2-alfresco-upload": "1.10.0-beta6",
+ "ng2-alfresco-viewer": "1.10.0-beta6",
"pdfjs-dist": "1.8.557",
"rxjs": "5.1.0",
"wsrv": "0.2.2",
@@ -44,14 +46,14 @@
"@angular/cli": "1.4.7",
"@angular/compiler-cli": "4.4.5",
"@angular/language-service": "4.4.5",
- "@types/jasmine": "~2.5.53",
- "@types/jasminewd2": "~2.0.2",
+ "@types/jasmine": "^2.5.53",
+ "@types/jasminewd2": "^2.0.2",
"@types/node": "~6.0.60",
"codelyzer": "~3.2.0",
- "jasmine-core": "~2.6.2",
- "jasmine-reporters": "2.2.1",
- "jasmine-spec-reporter": "~4.1.0",
- "jasmine2-protractor-utils": "1.3.0",
+ "jasmine-core": "^2.6.2",
+ "jasmine-reporters": "^2.2.1",
+ "jasmine-spec-reporter": "^4.1.0",
+ "jasmine2-protractor-utils": "^1.3.0",
"karma": "~1.7.0",
"karma-chrome-launcher": "~2.1.1",
"karma-cli": "~1.0.1",
@@ -59,7 +61,7 @@
"karma-jasmine": "~1.1.0",
"karma-jasmine-html-reporter": "^0.2.2",
"node-rest-client": "^3.1.0",
- "protractor": "~5.1.2",
+ "protractor": "^5.1.2",
"ts-node": "~3.2.0",
"tslint": "~5.7.0",
"typescript": "~2.3.3"
diff --git a/postbuild-dev.js b/postbuild-dev.js
new file mode 100644
index 000000000..02544050d
--- /dev/null
+++ b/postbuild-dev.js
@@ -0,0 +1,26 @@
+/*!
+ * @license
+ * Copyright 2017 Alfresco Software, Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var fs = require('fs');
+var config = require('./dist/app.config.json');
+
+config.ecmHost = 'http://localhost:8080';
+
+fs.writeFileSync(
+ './dist/app.config.json',
+ JSON.stringify(config, null, 4)
+);
diff --git a/protractor.conf.js b/protractor.conf.js
index 9db00659f..9141ac324 100644
--- a/protractor.conf.js
+++ b/protractor.conf.js
@@ -8,49 +8,54 @@ const jasmineReporters = require('jasmine-reporters');
const projectRoot = path.resolve(__dirname);
exports.config = {
- allScriptsTimeout: 11000,
- specs: [
- './e2e/**/*.test.ts'
- ],
- capabilities: {
- 'browserName': 'chrome',
- chromeOptions: {
- prefs: {
- 'credentials_enable_service': false
+ allScriptsTimeout: 11000,
+ specs: [
+ './e2e/suites/authentication/*.test.ts',
+ './e2e/suites/list-views/*.test.ts',
+ './e2e/suites/application/page-titles.test.ts',
+ './e2e/suites/navigation/side-navigation.test.ts',
+ './e2e/suites/pagination/pagination.test.ts',
+ './e2e/suites/actions/*.test.ts'
+ ],
+ capabilities: {
+ 'browserName': 'chrome',
+ chromeOptions: {
+ prefs: {
+ 'credentials_enable_service': false
+ }
}
- }
- },
- directConnect: true,
- baseUrl: 'http://localhost:3000',
- framework: 'jasmine',
- jasmineNodeOpts: {
- showColors: true,
- defaultTimeoutInterval: 30000,
- print: function() {}
- },
- plugins: [{
- package: 'jasmine2-protractor-utils',
- disableHTMLReport: false,
- disableScreenshot: false,
- screenshotOnExpectFailure: true,
- screenshotOnSpecFailure: false,
- clearFoldersBeforeTest: true,
- htmlReportDir: `${projectRoot}/e2e-output/html-report/`,
- screenshotPath: `${projectRoot}/e2e-output/screenshots/`
- }],
- onPrepare() {
- require('ts-node').register({
- project: 'e2e/tsconfig.e2e.json'
- });
- jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
+ },
+ directConnect: true,
+ baseUrl: 'http://localhost:3000',
+ framework: 'jasmine2',
+ jasmineNodeOpts: {
+ showColors: true,
+ defaultTimeoutInterval: 30000,
+ print: function() {}
+ },
+ plugins: [{
+ package: 'jasmine2-protractor-utils',
+ disableHTMLReport: false,
+ disableScreenshot: false,
+ screenshotOnExpectFailure: true,
+ screenshotOnSpecFailure: false,
+ clearFoldersBeforeTest: true,
+ htmlReportDir: `${projectRoot}/e2e-output/html-report/`,
+ screenshotPath: `${projectRoot}/e2e-output/screenshots/`
+ }],
+ onPrepare() {
+ require('ts-node').register({
+ project: 'e2e/tsconfig.e2e.json'
+ });
+ jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
- jasmine.getEnv().addReporter(new jasmineReporters.JUnitXmlReporter({
- consolidateAll: true,
- savePath: `${projectRoot}/e2e-output/junit-report`,
- filePrefix: 'results.xml',
- useDotNotation: false,
- useFullTestName: false,
- reportFailedUrl: true
- }));
- }
+ jasmine.getEnv().addReporter(new jasmineReporters.JUnitXmlReporter({
+ consolidateAll: true,
+ savePath: `${projectRoot}/e2e-output/junit-report`,
+ filePrefix: 'results.xml',
+ useDotNotation: false,
+ useFullTestName: false,
+ reportFailedUrl: true
+ }));
+ }
};
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 36072abef..9be78dbd3 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -46,7 +46,6 @@ import { SidenavComponent } from './components/sidenav/sidenav.component';
imports: [
BrowserModule,
RouterModule.forRoot(APP_ROUTES, {
- useHash: true,
enableTracing: false // enable for debug only
}),
AdfModule,
diff --git a/src/app/common/common.module.ts b/src/app/common/common.module.ts
index 5e008c78c..a31010d56 100644
--- a/src/app/common/common.module.ts
+++ b/src/app/common/common.module.ts
@@ -23,10 +23,6 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { AdfModule } from '../adf.module';
import { MaterialModule } from './material.module';
-import { FolderDialogComponent } from './dialogs/folder-dialog.component';
-
-import { FolderCreateDirective } from './directives/folder-create.directive';
-import { FolderEditDirective } from './directives/folder-edit.directive';
import { NodeCopyDirective } from './directives/node-copy.directive';
import { NodeDeleteDirective } from './directives/node-delete.directive';
import { NodeMoveDirective } from './directives/node-move.directive';
@@ -51,10 +47,6 @@ export function modules() {
export function declarations() {
return [
- FolderDialogComponent,
-
- FolderCreateDirective,
- FolderEditDirective,
NodeCopyDirective,
NodeDeleteDirective,
NodeMoveDirective,
@@ -77,9 +69,7 @@ export function providers() {
@NgModule({
imports: modules(),
declarations: declarations(),
- entryComponents: [
- FolderDialogComponent
- ],
+ entryComponents: [],
providers: providers(),
exports: [
...modules(),
diff --git a/src/app/common/dialogs/folder-dialog.component.html b/src/app/common/dialogs/folder-dialog.component.html
deleted file mode 100644
index b392bea9d..000000000
--- a/src/app/common/dialogs/folder-dialog.component.html
+++ /dev/null
@@ -1,62 +0,0 @@
-
- {{
- (editing
- ? 'APP.FOLDER_DIALOG.EDIT_FOLDER_TITLE'
- : 'APP.FOLDER_DIALOG.CREATE_FOLDER_TITLE'
- ) | translate
- }}
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/app/common/dialogs/folder-dialog.component.spec.ts b/src/app/common/dialogs/folder-dialog.component.spec.ts
deleted file mode 100644
index ef118baa6..000000000
--- a/src/app/common/dialogs/folder-dialog.component.spec.ts
+++ /dev/null
@@ -1,260 +0,0 @@
-/*!
- * @license
- * Copyright 2017 Alfresco Software, Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import { TestBed, async } from '@angular/core/testing';
-import { Observable } from 'rxjs/Rx';
-import { MatDialogModule, MatDialogRef } from '@angular/material';
-import { CoreModule, NodesApiService, TranslationService, NotificationService } from 'ng2-alfresco-core';
-
-import {BrowserDynamicTestingModule} from '@angular/platform-browser-dynamic/testing';
-import { FolderDialogComponent } from './folder-dialog.component';
-import { ComponentFixture } from '@angular/core/testing';
-
-describe('FolderDialogComponent', () => {
-
- let fixture: ComponentFixture;
- let component: FolderDialogComponent;
- let translationService: TranslationService;
- let nodesApi: NodesApiService;
- let notificationService: NotificationService;
- let dialogRef;
-
- beforeEach(async(() => {
- dialogRef = {
- close: jasmine.createSpy('close')
- };
-
- TestBed.configureTestingModule({
- imports: [
- CoreModule,
- MatDialogModule
- ],
- declarations: [
- FolderDialogComponent
- ],
- providers: [
- { provide: MatDialogRef, useValue: dialogRef }
- ]
- })
- .compileComponents();
- }));
-
- beforeEach(() => {
- fixture = TestBed.createComponent(FolderDialogComponent);
- component = fixture.componentInstance;
-
- nodesApi = TestBed.get(NodesApiService);
- notificationService = TestBed.get(NotificationService);
-
- translationService = TestBed.get(TranslationService);
- spyOn(translationService, 'get').and.returnValue(Observable.of('message'));
- });
-
- describe('Edit', () => {
-
- beforeEach(() => {
- component.data = {
- folder: {
- id: 'node-id',
- name: 'folder-name',
- properties: {
- ['cm:description']: 'folder-description'
- }
- }
- };
- component.ngOnInit();
- });
-
- it('should init form with folder name and description', () => {
- expect(component.name).toBe('folder-name');
- expect(component.description).toBe('folder-description');
- });
-
- it('should update form input', () => {
- component.form.controls['name'].setValue('folder-name-update');
- component.form.controls['description'].setValue('folder-description-update');
-
- expect(component.name).toBe('folder-name-update');
- expect(component.description).toBe('folder-description-update');
- });
-
- it('should submit updated values if form is valid', () => {
- spyOn(nodesApi, 'updateNode').and.returnValue(Observable.of({}));
-
- component.form.controls['name'].setValue('folder-name-update');
- component.form.controls['description'].setValue('folder-description-update');
-
- component.submit();
-
- expect(nodesApi.updateNode).toHaveBeenCalledWith(
- 'node-id',
- {
- name: 'folder-name-update',
- properties: {
- 'cm:title': 'folder-name-update',
- 'cm:description': 'folder-description-update'
- }
- }
- );
- });
-
- it('should call dialog to close with form data when submit is succesfluly', () => {
- const folder = {
- data: 'folder-data'
- };
-
- spyOn(nodesApi, 'updateNode').and.returnValue(Observable.of(folder));
-
- component.submit();
-
- expect(dialogRef.close).toHaveBeenCalledWith(folder);
- });
-
- it('should not submit if form is invalid', () => {
- spyOn(nodesApi, 'updateNode');
-
- component.form.controls['name'].setValue('');
- component.form.controls['description'].setValue('');
-
- component.submit();
-
- expect(component.form.valid).toBe(false);
- expect(nodesApi.updateNode).not.toHaveBeenCalled();
- });
-
- it('should not call dialog to close if submit fails', () => {
- spyOn(nodesApi, 'updateNode').and.returnValue(Observable.throw('error'));
- spyOn(component, 'handleError').and.callFake(val => val);
-
- component.submit();
-
- expect(component.handleError).toHaveBeenCalled();
- expect(dialogRef.close).not.toHaveBeenCalled();
- });
- });
-
- describe('Create', () => {
- beforeEach(() => {
- component.data = {
- parentNodeId: 'parentNodeId',
- folder: null
- };
- component.ngOnInit();
- });
-
- it('should init form with empty inputs', () => {
- expect(component.name).toBe('');
- expect(component.description).toBe('');
- });
-
- it('should update form input', () => {
- component.form.controls['name'].setValue('folder-name-update');
- component.form.controls['description'].setValue('folder-description-update');
-
- expect(component.name).toBe('folder-name-update');
- expect(component.description).toBe('folder-description-update');
- });
-
- it('should submit updated values if form is valid', () => {
- spyOn(nodesApi, 'createFolder').and.returnValue(Observable.of({}));
-
- component.form.controls['name'].setValue('folder-name-update');
- component.form.controls['description'].setValue('folder-description-update');
-
- component.submit();
-
- expect(nodesApi.createFolder).toHaveBeenCalledWith(
- 'parentNodeId',
- {
- name: 'folder-name-update',
- properties: {
- 'cm:title': 'folder-name-update',
- 'cm:description': 'folder-description-update'
- }
- }
- );
- });
-
- it('should call dialog to close with form data when submit is succesfluly', () => {
- const folder = {
- data: 'folder-data'
- };
-
- component.form.controls['name'].setValue('name');
- component.form.controls['description'].setValue('description');
-
- spyOn(nodesApi, 'createFolder').and.returnValue(Observable.of(folder));
-
- component.submit();
-
- expect(dialogRef.close).toHaveBeenCalledWith(folder);
- });
-
- it('should not submit if form is invalid', () => {
- spyOn(nodesApi, 'createFolder');
-
- component.form.controls['name'].setValue('');
- component.form.controls['description'].setValue('');
-
- component.submit();
-
- expect(component.form.valid).toBe(false);
- expect(nodesApi.createFolder).not.toHaveBeenCalled();
- });
-
- it('should not call dialog to close if submit fails', () => {
- spyOn(nodesApi, 'createFolder').and.returnValue(Observable.throw('error'));
- spyOn(component, 'handleError').and.callFake(val => val);
-
- component.form.controls['name'].setValue('name');
- component.form.controls['description'].setValue('description');
-
- component.submit();
-
- expect(component.handleError).toHaveBeenCalled();
- expect(dialogRef.close).not.toHaveBeenCalled();
- });
- });
-
- describe('handleError()', () => {
- it('should raise error for 409', () => {
- spyOn(notificationService, 'openSnackMessage').and.stub();
-
- const error = {
- message: '{ "error": { "statusCode" : 409 } }'
- };
-
- component.handleError(error);
-
- expect(notificationService.openSnackMessage).toHaveBeenCalled();
- expect(translationService.get).toHaveBeenCalledWith('APP.MESSAGES.ERRORS.EXISTENT_FOLDER');
- });
-
- it('should raise generic error', () => {
- spyOn(notificationService, 'openSnackMessage').and.stub();
-
- const error = {
- message: '{ "error": { "statusCode" : 123 } }'
- };
-
- component.handleError(error);
-
- expect(notificationService.openSnackMessage).toHaveBeenCalled();
- expect(translationService.get).toHaveBeenCalledWith('APP.MESSAGES.ERRORS.GENERIC');
- });
- });
-});
diff --git a/src/app/common/dialogs/folder-dialog.component.ts b/src/app/common/dialogs/folder-dialog.component.ts
deleted file mode 100644
index e8a395511..000000000
--- a/src/app/common/dialogs/folder-dialog.component.ts
+++ /dev/null
@@ -1,138 +0,0 @@
-/*!
- * @license
- * Copyright 2017 Alfresco Software, Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import { Observable } from 'rxjs/Rx';
-
-import { Component, Inject, Optional, OnInit } from '@angular/core';
-import { FormGroup, FormBuilder, Validators } from '@angular/forms';
-import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
-
-import { TranslationService, NodesApiService, NotificationService } from 'ng2-alfresco-core';
-import { MinimalNodeEntryEntity } from 'alfresco-js-api';
-
-import { forbidSpecialCharacters, forbidEndingDot, forbidOnlySpaces } from './folder-name.validators';
-
-@Component({
- selector: 'app-folder-dialog',
- templateUrl: './folder-dialog.component.html'
-})
-export class FolderDialogComponent implements OnInit {
- form: FormGroup;
- folder: MinimalNodeEntryEntity = null;
-
- constructor(
- private formBuilder: FormBuilder,
- private dialog: MatDialogRef,
- private nodesApi: NodesApiService,
- private translation: TranslationService,
- private notification: NotificationService,
- @Optional()
- @Inject(MAT_DIALOG_DATA)
- public data: any
- ) {}
-
- get editing(): boolean {
- return !!this.data.folder;
- }
-
- ngOnInit() {
- const { folder } = this.data;
- let name = '', description = '';
-
- if (folder) {
- const { properties } = folder;
-
- name = folder.name || '';
- description = properties ? properties['cm:description'] : '';
- }
-
- const validators = {
- name: [
- Validators.required,
- forbidSpecialCharacters,
- forbidEndingDot,
- forbidOnlySpaces
- ]
- };
-
- this.form = this.formBuilder.group({
- name: [ name, validators.name ],
- description: [ description ]
- });
- }
-
- get name(): string {
- const { name } = this.form.value;
-
- return (name || '').trim();
- }
-
- get description(): string {
- const { description } = this.form.value;
-
- return (description || '').trim();
- }
-
- private get properties(): any {
- const { name: title, description } = this;
-
- return {
- 'cm:title': title,
- 'cm:description': description
- };
- }
-
- private create(): Observable {
- const { name, properties, nodesApi, data: { parentNodeId} } = this;
- return nodesApi.createFolder(parentNodeId, { name, properties });
- }
-
- private edit(): Observable {
- const { name, properties, nodesApi, data: { folder: { id: nodeId }} } = this;
- return nodesApi.updateNode(nodeId, { name, properties });
- }
-
- submit() {
- const { form, dialog, editing } = this;
-
- if (!form.valid) { return; }
-
- (editing ? this.edit() : this.create())
- .subscribe(
- (folder: MinimalNodeEntryEntity) => dialog.close(folder),
- (error) => this.handleError(error)
- );
- }
-
- handleError(error: any): any {
- let i18nMessageString = 'APP.MESSAGES.ERRORS.GENERIC';
-
- try {
- const { error: { statusCode } } = JSON.parse(error.message);
-
- if (statusCode === 409) {
- i18nMessageString = 'APP.MESSAGES.ERRORS.EXISTENT_FOLDER';
- }
- } catch (err) { /* Do nothing, keep the original message */ }
-
- this.translation.get(i18nMessageString).subscribe(message => {
- this.notification.openSnackMessage(message, 3000);
- });
-
- return error;
- }
-}
diff --git a/src/app/common/dialogs/folder-name.validators.ts b/src/app/common/dialogs/folder-name.validators.ts
deleted file mode 100644
index 714ac127f..000000000
--- a/src/app/common/dialogs/folder-name.validators.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-/*!
- * @license
- * Copyright 2017 Alfresco Software, Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import { FormControl } from '@angular/forms';
-
-const I18N_ERRORS_PATH = 'APP.FOLDER_DIALOG.FOLDER_NAME.ERRORS';
-
-export function forbidSpecialCharacters({ value }: FormControl) {
- const specialCharacters: RegExp = /([\*\"\<\>\\\/\?\:\|])/;
- const isValid: boolean = !specialCharacters.test(value);
-
- return (isValid) ? null : {
- message: `${I18N_ERRORS_PATH}.SPECIAL_CHARACTERS`
- };
-}
-
-export function forbidEndingDot({ value }: FormControl) {
- const isValid: boolean = ((value || '').split('').pop() !== '.');
-
- return isValid ? null : {
- message: `${I18N_ERRORS_PATH}.ENDING_DOT`
- };
-}
-
-export function forbidOnlySpaces({ value }: FormControl) {
- const isValid: boolean = !!((value || '')).trim();
-
- return isValid ? null : {
- message: `${I18N_ERRORS_PATH}.ONLY_SPACES`
- };
-}
diff --git a/src/app/common/directives/folder-create.directive.spec.ts b/src/app/common/directives/folder-create.directive.spec.ts
deleted file mode 100644
index a77ef95da..000000000
--- a/src/app/common/directives/folder-create.directive.spec.ts
+++ /dev/null
@@ -1,96 +0,0 @@
-/*!
- * @license
- * Copyright 2017 Alfresco Software, Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import { TestBed, ComponentFixture } from '@angular/core/testing';
-import { By } from '@angular/platform-browser';
-import { Component } from '@angular/core';
-import { Observable } from 'rxjs/Rx';
-import { MatDialogModule, MatDialog } from '@angular/material';
-
-import { FolderCreateDirective } from './folder-create.directive';
-import { ContentManagementService } from '../services/content-management.service';
-
-@Component({
- template: ''
-})
-class TestComponent {
- parentNode = '';
-}
-
-describe('FolderCreateDirective', () => {
- let fixture: ComponentFixture;
- let element;
- let node: any;
- let dialog: MatDialog;
- let contentService: ContentManagementService;
- let dialogRefMock;
-
- const event: any = {
- type: 'click',
- preventDefault: () => null
- };
-
- beforeEach(() => {
- TestBed.configureTestingModule({
- imports: [ MatDialogModule ],
- declarations: [
- TestComponent,
- FolderCreateDirective
- ]
- ,
- providers: [
- ContentManagementService
- ]
- });
-
- fixture = TestBed.createComponent(TestComponent);
- element = fixture.debugElement.query(By.directive(FolderCreateDirective));
- dialog = TestBed.get(MatDialog);
- contentService = TestBed.get(ContentManagementService);
- });
-
- beforeEach(() => {
- node = { entry: { id: 'nodeId' } };
-
- dialogRefMock = {
- afterClosed: val => Observable.of(val)
- };
-
- spyOn(dialog, 'open').and.returnValue(dialogRefMock);
- });
-
- it('emits createFolder event when input value is not undefined', () => {
- spyOn(dialogRefMock, 'afterClosed').and.returnValue(Observable.of(node));
-
- contentService.createFolder.subscribe((val) => {
- expect(val).toBe(node);
- });
-
- element.triggerEventHandler('click', event);
- fixture.detectChanges();
- });
-
- it('does not emits createFolder event when input value is undefined', () => {
- spyOn(dialogRefMock, 'afterClosed').and.returnValue(Observable.of(null));
- spyOn(contentService.createFolder, 'next');
-
- element.triggerEventHandler('click', event);
- fixture.detectChanges();
-
- expect(contentService.createFolder.next).not.toHaveBeenCalled();
- });
-});
diff --git a/src/app/common/directives/folder-create.directive.ts b/src/app/common/directives/folder-create.directive.ts
deleted file mode 100644
index 36d6a67f7..000000000
--- a/src/app/common/directives/folder-create.directive.ts
+++ /dev/null
@@ -1,66 +0,0 @@
-/*!
- * @license
- * Copyright 2017 Alfresco Software, Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import { Directive, HostListener, Input } from '@angular/core';
-import { MatDialog, MatDialogConfig } from '@angular/material';
-
-import { MinimalNodeEntryEntity } from 'alfresco-js-api';
-
-import { FolderDialogComponent } from '../dialogs/folder-dialog.component';
-import { ContentManagementService } from '../services/content-management.service';
-
-@Directive({
- selector: '[app-create-folder]'
-})
-export class FolderCreateDirective {
- static DIALOG_WIDTH: number = 400;
-
- @Input('app-create-folder')
- parentNodeId: string;
-
- @HostListener('click', [ '$event' ])
- onClick(event) {
- event.preventDefault();
- this.openDialog();
- }
-
- constructor(
- public dialogRef: MatDialog,
- public content: ContentManagementService
- ) {}
-
- private get dialogConfig(): MatDialogConfig {
- const { DIALOG_WIDTH: width } = FolderCreateDirective;
- const { parentNodeId } = this;
-
- return {
- data: { parentNodeId },
- width: `${width}px`
- };
- }
-
- private openDialog(): void {
- const { dialogRef, dialogConfig, content } = this;
- const dialogInstance = dialogRef.open(FolderDialogComponent, dialogConfig);
-
- dialogInstance.afterClosed().subscribe((node: MinimalNodeEntryEntity) => {
- if (node) {
- content.createFolder.next(node);
- }
- });
- }
-}
diff --git a/src/app/common/directives/folder-edit.directive.spec.ts b/src/app/common/directives/folder-edit.directive.spec.ts
deleted file mode 100644
index a330ef9f8..000000000
--- a/src/app/common/directives/folder-edit.directive.spec.ts
+++ /dev/null
@@ -1,96 +0,0 @@
-/*!
- * @license
- * Copyright 2017 Alfresco Software, Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import { TestBed, ComponentFixture } from '@angular/core/testing';
-import { By } from '@angular/platform-browser';
-import { Component } from '@angular/core';
-import { Observable } from 'rxjs/Rx';
-import { MatDialogModule, MatDialog } from '@angular/material';
-
-import { FolderEditDirective } from './folder-edit.directive';
-import { ContentManagementService } from '../services/content-management.service';
-
-@Component({
- template: ''
-})
-class TestComponent {
- folder = {};
-}
-
-describe('FolderEditDirective', () => {
- let fixture: ComponentFixture;
- let element;
- let node: any;
- let dialog: MatDialog;
- let contentService: ContentManagementService;
- let dialogRefMock;
-
- const event = {
- type: 'click',
- preventDefault: () => null
- };
-
- beforeEach(() => {
- TestBed.configureTestingModule({
- imports: [ MatDialogModule ],
- declarations: [
- TestComponent,
- FolderEditDirective
- ]
- ,
- providers: [
- ContentManagementService
- ]
- });
-
- fixture = TestBed.createComponent(TestComponent);
- element = fixture.debugElement.query(By.directive(FolderEditDirective));
- dialog = TestBed.get(MatDialog);
- contentService = TestBed.get(ContentManagementService);
- });
-
- beforeEach(() => {
- node = { entry: { id: 'folderId' } };
-
- dialogRefMock = {
- afterClosed: val => Observable.of(val)
- };
-
- spyOn(dialog, 'open').and.returnValue(dialogRefMock);
- });
-
- it('emits editFolder event when input value is not undefined', () => {
- spyOn(dialogRefMock, 'afterClosed').and.returnValue(Observable.of(node));
-
- contentService.createFolder.subscribe((val) => {
- expect(val).toBe(node);
- });
-
- element.triggerEventHandler('click', event);
- fixture.detectChanges();
- });
-
- it('does not emits FolderEditDirective event when input value is undefined', () => {
- spyOn(dialogRefMock, 'afterClosed').and.returnValue(Observable.of(null));
- spyOn(contentService.createFolder, 'next');
-
- element.triggerEventHandler('click', event);
- fixture.detectChanges();
-
- expect(contentService.createFolder.next).not.toHaveBeenCalled();
- });
-});
diff --git a/src/app/common/directives/folder-edit.directive.ts b/src/app/common/directives/folder-edit.directive.ts
deleted file mode 100644
index 482c510e5..000000000
--- a/src/app/common/directives/folder-edit.directive.ts
+++ /dev/null
@@ -1,67 +0,0 @@
-/*!
- * @license
- * Copyright 2017 Alfresco Software, Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import { Directive, HostListener, ElementRef, Input } from '@angular/core';
-import { MatDialog, MatDialogConfig } from '@angular/material';
-
-import { MinimalNodeEntryEntity } from 'alfresco-js-api';
-
-import { FolderDialogComponent } from '../dialogs/folder-dialog.component';
-import { ContentManagementService } from '../services/content-management.service';
-
-@Directive({
- selector: '[app-edit-folder]'
-})
-export class FolderEditDirective {
- static DIALOG_WIDTH = 400;
-
- @Input('app-edit-folder')
- folder: MinimalNodeEntryEntity;
-
- @HostListener('click', [ '$event' ])
- onClick(event) {
- event.preventDefault();
- this.openDialog();
- }
-
- constructor(
- public dialogRef: MatDialog,
- public elementRef: ElementRef,
- public content: ContentManagementService
- ) {}
-
- private get dialogConfig(): MatDialogConfig {
- const { DIALOG_WIDTH: width } = FolderEditDirective;
- const { folder } = this;
-
- return {
- data: { folder },
- width: `${width}px`
- };
- }
-
- private openDialog(): void {
- const { dialogRef, dialogConfig, content } = this;
- const dialogInstance = dialogRef.open(FolderDialogComponent, dialogConfig);
-
- dialogInstance.afterClosed().subscribe((node: MinimalNodeEntryEntity) => {
- if (node) {
- content.editFolder.next(node);
- }
- });
- }
-}
diff --git a/src/app/common/services/content-management.service.ts b/src/app/common/services/content-management.service.ts
index 3fcc47199..7aa324d71 100644
--- a/src/app/common/services/content-management.service.ts
+++ b/src/app/common/services/content-management.service.ts
@@ -18,12 +18,8 @@
import { Subject } from 'rxjs/Rx';
import { Injectable } from '@angular/core';
-import { MinimalNodeEntryEntity } from 'alfresco-js-api';
-
@Injectable()
export class ContentManagementService {
- createFolder = new Subject();
- editFolder = new Subject();
deleteNode = new Subject();
moveNode = new Subject();
restoreNode = new Subject();
diff --git a/src/app/components/favorites/favorites.component.html b/src/app/components/favorites/favorites.component.html
index 32d684417..1ec5194c5 100644
--- a/src/app/components/favorites/favorites.component.html
+++ b/src/app/components/favorites/favorites.component.html
@@ -25,7 +25,7 @@
mat-icon-button
*ngIf="canEditFolder(documentList.selection)"
title="{{ 'APP.ACTIONS.EDIT' | translate }}"
- [app-edit-folder]="documentList.selection[0]?.entry">
+ [adf-edit-folder]="documentList.selection[0]?.entry">
create
diff --git a/src/app/components/favorites/favorites.component.spec.ts b/src/app/components/favorites/favorites.component.spec.ts
index 0728982b9..ec8e88cdb 100644
--- a/src/app/components/favorites/favorites.component.spec.ts
+++ b/src/app/components/favorites/favorites.component.spec.ts
@@ -20,7 +20,7 @@ import { RouterTestingModule } from '@angular/router/testing';
import { TestBed, async } from '@angular/core/testing';
import { Observable } from 'rxjs/Rx';
-import { CoreModule, NodesApiService, AlfrescoApiService } from 'ng2-alfresco-core';
+import { CoreModule, NodesApiService, AlfrescoApiService, AlfrescoContentService } from 'ng2-alfresco-core';
import { CommonModule } from '../../common/common.module';
import { ContentManagementService } from '../../common/services/content-management.service';
@@ -32,6 +32,7 @@ describe('Favorites Routed Component', () => {
let component: FavoritesComponent;
let nodesApi: NodesApiService;
let alfrescoApi: AlfrescoApiService;
+ let alfrescoContentService: AlfrescoContentService;
let contentService: ContentManagementService;
let router: Router;
let page;
@@ -80,6 +81,7 @@ describe('Favorites Routed Component', () => {
nodesApi = TestBed.get(NodesApiService);
alfrescoApi = TestBed.get(AlfrescoApiService);
+ alfrescoContentService = TestBed.get(AlfrescoContentService);
contentService = TestBed.get(ContentManagementService);
router = TestBed.get(Router);
});
@@ -94,7 +96,7 @@ describe('Favorites Routed Component', () => {
spyOn(component, 'refresh');
fixture.detectChanges();
- contentService.editFolder.next(null);
+ alfrescoContentService.folderEdit.next(null);
expect(component.refresh).toHaveBeenCalled();
});
diff --git a/src/app/components/favorites/favorites.component.ts b/src/app/components/favorites/favorites.component.ts
index cdb5daffd..92ebfdbe8 100644
--- a/src/app/components/favorites/favorites.component.ts
+++ b/src/app/components/favorites/favorites.component.ts
@@ -20,7 +20,7 @@ import { Router } from '@angular/router';
import { Subscription } from 'rxjs/Rx';
import { MinimalNodeEntryEntity, PathElementEntity, PathInfo } from 'alfresco-js-api';
-import { NodesApiService } from 'ng2-alfresco-core';
+import { AlfrescoContentService, NodesApiService } from 'ng2-alfresco-core';
import { DocumentListComponent } from 'ng2-alfresco-documentlist';
import { ContentManagementService } from '../../common/services/content-management.service';
@@ -41,12 +41,13 @@ export class FavoritesComponent extends PageComponent implements OnInit, OnDestr
constructor(
private router: Router,
private nodesApi: NodesApiService,
+ private contentService: AlfrescoContentService,
private content: ContentManagementService) {
super();
}
ngOnInit() {
- this.onEditFolder = this.content.editFolder.subscribe(() => this.refresh());
+ this.onEditFolder = this.contentService.folderEdit.subscribe(() => this.refresh());
this.onMoveNode = this.content.moveNode.subscribe(() => this.refresh());
this.onToggleFavorite = this.content.toggleFavorite
.debounceTime(300).subscribe(() => this.refresh());
diff --git a/src/app/components/files/files.component.html b/src/app/components/files/files.component.html
index 4fdd83895..2341d840a 100644
--- a/src/app/components/files/files.component.html
+++ b/src/app/components/files/files.component.html
@@ -27,7 +27,7 @@
mat-icon-button
*ngIf="canEditFolder(documentList.selection)"
title="{{ 'APP.ACTIONS.EDIT' | translate }}"
- [app-edit-folder]="documentList.selection[0]?.entry">
+ [adf-edit-folder]="documentList.selection[0]?.entry">
create
diff --git a/src/app/components/files/files.component.spec.ts b/src/app/components/files/files.component.spec.ts
index 63e87fe0d..622e3352e 100644
--- a/src/app/components/files/files.component.spec.ts
+++ b/src/app/components/files/files.component.spec.ts
@@ -170,13 +170,13 @@ describe('FilesComponent', () => {
});
it('calls refresh onCreateFolder event', () => {
- contentManagementService.createFolder.next();
+ alfrescoContentService.folderCreate.next();
expect(component.load).toHaveBeenCalled();
});
it('calls refresh editFolder event', () => {
- contentManagementService.editFolder.next();
+ alfrescoContentService.folderEdit.next();
expect(component.load).toHaveBeenCalled();
});
diff --git a/src/app/components/files/files.component.ts b/src/app/components/files/files.component.ts
index 45c2557f6..0a48e3794 100644
--- a/src/app/components/files/files.component.ts
+++ b/src/app/components/files/files.component.ts
@@ -16,7 +16,7 @@
*/
import { Observable, Subscription } from 'rxjs/Rx';
-import { Component, ViewChild, OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';
+import { Component, OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';
import { Router, ActivatedRoute, Params } from '@angular/router';
import { MinimalNodeEntity, MinimalNodeEntryEntity, PathElementEntity, NodePaging, PathElement } from 'alfresco-js-api';
import { UploadService, FileUploadEvent, NodesApiService, AlfrescoContentService, AlfrescoApiService } from 'ng2-alfresco-core';
@@ -60,7 +60,7 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy {
}
ngOnInit() {
- const { route, contentManagementService, nodeActionsService, uploadService } = this;
+ const { route, contentManagementService, contentService, nodeActionsService, uploadService } = this;
const { data } = route.snapshot;
this.routeData = data;
@@ -87,8 +87,8 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy {
this.onCopyNode = nodeActionsService.contentCopied
.subscribe((nodes) => this.onContentCopied(nodes));
- this.onCreateFolder = contentManagementService.createFolder.subscribe(() => this.load());
- this.onEditFolder = contentManagementService.editFolder.subscribe(() => this.load());
+ this.onCreateFolder = contentService.folderCreate.subscribe(() => this.load());
+ this.onEditFolder = contentService.folderEdit.subscribe(() => this.load());
this.onDeleteNode = contentManagementService.deleteNode.subscribe(() => this.load());
this.onMoveNode = contentManagementService.moveNode.subscribe(() => this.load());
this.onRestoreNode = contentManagementService.restoreNode.subscribe(() => this.load());
diff --git a/src/app/components/sidenav/sidenav.component.html b/src/app/components/sidenav/sidenav.component.html
index 43fdaa621..73973dbfd 100644
--- a/src/app/components/sidenav/sidenav.component.html
+++ b/src/app/components/sidenav/sidenav.component.html
@@ -8,8 +8,8 @@