mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-18 03:01:05 +01:00
change cypress tests to ui only
This commit is contained in:
@@ -24,30 +24,55 @@
|
|||||||
|
|
||||||
describe("With Anonymous mode disabled", () => {
|
describe("With Anonymous mode disabled", () => {
|
||||||
it("Should show login page without primary navigation", () => {
|
it("Should show login page without primary navigation", () => {
|
||||||
setUserPermissions("_anonymous", ["repository:read,pull:*"]);
|
loginUser("scmadmin", "scmadmin");
|
||||||
setAnonymousMode("OFF");
|
setAnonymousMode("OFF");
|
||||||
|
|
||||||
cy.visit("http://localhost:8081/scm/repos/");
|
cy.get("li")
|
||||||
|
.contains("Logout")
|
||||||
|
.click();
|
||||||
cy.contains("Please login to proceed");
|
cy.contains("Please login to proceed");
|
||||||
cy.get("div").not("Login");
|
cy.get("div").not("Login");
|
||||||
cy.get("div").not("Repositories");
|
cy.get("div").not("Repositories");
|
||||||
});
|
});
|
||||||
it("Should redirect after login", () => {
|
it("Should redirect after login", () => {
|
||||||
cy.visit("http://localhost:8081/scm/me/");
|
loginUser("scmadmin", "scmadmin");
|
||||||
cy.get("div.field.username > div > input").type("scmadmin");
|
|
||||||
cy.get("div.field.password > div > input").type("scmadmin");
|
cy.visit("http://localhost:8081/scm/me");
|
||||||
cy.get("button")
|
|
||||||
.contains("Login")
|
|
||||||
.click();
|
|
||||||
cy.contains("Profile");
|
cy.contains("Profile");
|
||||||
|
cy.get("li")
|
||||||
|
.contains("Logout")
|
||||||
|
.click();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("With Anonymous mode protocol only enabled", () => {
|
describe("With Anonymous mode protocol only enabled", () => {
|
||||||
it("Should show login page without primary navigation", () => {
|
it("Should show login page without primary navigation", () => {
|
||||||
setUserPermissions("_anonymous", ["repository:read,pull:*"]);
|
loginUser("scmadmin", "scmadmin");
|
||||||
setAnonymousMode("PROTOCOL_ONLY");
|
setAnonymousMode("PROTOCOL_ONLY");
|
||||||
|
|
||||||
|
// Give anonymous user permissions
|
||||||
|
cy.get("li")
|
||||||
|
.contains("Users")
|
||||||
|
.click();
|
||||||
|
cy.get("td")
|
||||||
|
.contains("_anonymous")
|
||||||
|
.click();
|
||||||
|
cy.get("a")
|
||||||
|
.contains("Settings")
|
||||||
|
.click();
|
||||||
|
cy.get("li")
|
||||||
|
.contains("Permissions")
|
||||||
|
.click();
|
||||||
|
cy.get("label")
|
||||||
|
.contains("Read all repositories")
|
||||||
|
.click();
|
||||||
|
cy.get("button")
|
||||||
|
.contains("Set permissions")
|
||||||
|
.click();
|
||||||
|
|
||||||
|
cy.get("li")
|
||||||
|
.contains("Logout")
|
||||||
|
.click();
|
||||||
cy.visit("http://localhost:8081/scm/repos/");
|
cy.visit("http://localhost:8081/scm/repos/");
|
||||||
cy.contains("Please login to proceed");
|
cy.contains("Please login to proceed");
|
||||||
cy.get("div").not("Login");
|
cy.get("div").not("Login");
|
||||||
@@ -57,9 +82,12 @@ describe("With Anonymous mode protocol only enabled", () => {
|
|||||||
|
|
||||||
describe("With Anonymous mode fully enabled", () => {
|
describe("With Anonymous mode fully enabled", () => {
|
||||||
it("Should show repositories overview with Login button in primary navigation", () => {
|
it("Should show repositories overview with Login button in primary navigation", () => {
|
||||||
setUserPermissions("_anonymous", ["repository:read,pull:*"]);
|
loginUser("scmadmin", "scmadmin");
|
||||||
setAnonymousMode("FULL");
|
setAnonymousMode("FULL");
|
||||||
|
|
||||||
|
cy.get("li")
|
||||||
|
.contains("Logout")
|
||||||
|
.click();
|
||||||
cy.visit("http://localhost:8081/scm/repos/");
|
cy.visit("http://localhost:8081/scm/repos/");
|
||||||
cy.contains("Overview of available repositories");
|
cy.contains("Overview of available repositories");
|
||||||
cy.contains("SCM Anonymous");
|
cy.contains("SCM Anonymous");
|
||||||
@@ -79,6 +107,9 @@ describe("With Anonymous mode fully enabled", () => {
|
|||||||
|
|
||||||
cy.visit("http://localhost:8081/scm/login");
|
cy.visit("http://localhost:8081/scm/login");
|
||||||
cy.contains("SCM Administrator");
|
cy.contains("SCM Administrator");
|
||||||
|
cy.get("li")
|
||||||
|
.contains("Logout")
|
||||||
|
.click();
|
||||||
});
|
});
|
||||||
it("Should logout and direct to login page", () => {
|
it("Should logout and direct to login page", () => {
|
||||||
loginUser("scmadmin", "scmadmin");
|
loginUser("scmadmin", "scmadmin");
|
||||||
@@ -98,75 +129,39 @@ describe("With Anonymous mode fully enabled", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("Disable anonymous mode after tests", () => {
|
||||||
|
it("Disable anonymous mode after tests", () => {
|
||||||
|
loginUser("scmadmin", "scmadmin");
|
||||||
|
setAnonymousMode("OFF");
|
||||||
|
|
||||||
|
cy.get("li")
|
||||||
|
.contains("Logout")
|
||||||
|
.click();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const setAnonymousMode = anonymousMode => {
|
||||||
|
cy.get("li")
|
||||||
|
.contains("Administration")
|
||||||
|
.click();
|
||||||
|
cy.get("li")
|
||||||
|
.contains("Settings")
|
||||||
|
.click();
|
||||||
|
cy.get("select")
|
||||||
|
.contains("Disabled")
|
||||||
|
.parent()
|
||||||
|
.select(anonymousMode)
|
||||||
|
.should("have.value", anonymousMode);
|
||||||
|
cy.get("button")
|
||||||
|
.contains("Submit")
|
||||||
|
.click();
|
||||||
|
};
|
||||||
|
|
||||||
const loginUser = (username, password) => {
|
const loginUser = (username, password) => {
|
||||||
const loginUrl = `http://localhost:8081/scm/api/v2/auth/access_token`;
|
cy.visit("http://localhost:8081/scm/login");
|
||||||
|
cy.get("div.field.username > div > input").type(username);
|
||||||
cy.request({
|
cy.get("div.field.password > div > input").type(password);
|
||||||
method: "POST",
|
cy.get("button")
|
||||||
url: loginUrl,
|
.contains("Login")
|
||||||
body: {
|
.click();
|
||||||
cookie: true,
|
|
||||||
username: username,
|
|
||||||
password: password,
|
|
||||||
grantType: "password"
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const setUserPermissions = (user, permissions) => {
|
|
||||||
const MEDIA_TYPE = "application/vnd.scmm-permissionCollection+json;v=2";
|
|
||||||
const userPermissionUrl = `http://localhost:8081/scm/api/v2/users/${user}/permissions`;
|
|
||||||
|
|
||||||
cy.request({
|
|
||||||
method: "PUT",
|
|
||||||
url: userPermissionUrl,
|
|
||||||
body: { permissions: permissions },
|
|
||||||
headers: { "content-type": MEDIA_TYPE },
|
|
||||||
auth: {
|
|
||||||
user: "scmadmin",
|
|
||||||
pass: "scmadmin",
|
|
||||||
sendImmediately: true
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const setAnonymousMode = anonMode => {
|
|
||||||
const MEDIA_TYPE = "application/vnd.scmm-config+json;v=2";
|
|
||||||
|
|
||||||
const content = {
|
|
||||||
adminGroups: [],
|
|
||||||
adminUsers: [],
|
|
||||||
anonymousMode: anonMode,
|
|
||||||
baseUrl: "http://localhost:8081/scm",
|
|
||||||
dateFormat: "YYYY-MM-DD HH:mm:ss",
|
|
||||||
disableGroupingGrid: false,
|
|
||||||
enableProxy: false,
|
|
||||||
enabledXsrfProtection: false,
|
|
||||||
forceBaseUrl: false,
|
|
||||||
loginAttemptLimit: 100,
|
|
||||||
loginAttemptLimitTimeout: 300,
|
|
||||||
loginInfoUrl: "https://login-info.scm-manager.org/api/v1/login-info",
|
|
||||||
namespaceStrategy: "UsernameNamespaceStrategy",
|
|
||||||
pluginUrl:
|
|
||||||
"https://oss.cloudogu.com/jenkins/job/scm-manager/job/scm-manager-bitbucket/job/plugin-snapshot/job/master/lastSuccessfulBuild/artifact/plugins/plugin-center.json",
|
|
||||||
proxyExcludes: [],
|
|
||||||
proxyPassword: null,
|
|
||||||
proxyPort: 8080,
|
|
||||||
proxyServer: "proxy.mydomain.com",
|
|
||||||
proxyUser: null,
|
|
||||||
realmDescription: "SONIA :: SCM Manager",
|
|
||||||
skipFailedAuthenticators: false
|
|
||||||
};
|
|
||||||
|
|
||||||
cy.request({
|
|
||||||
method: "PUT",
|
|
||||||
url: "http://localhost:8081/scm/api/v2/config",
|
|
||||||
body: content,
|
|
||||||
headers: { "content-type": MEDIA_TYPE },
|
|
||||||
auth: {
|
|
||||||
user: "scmadmin",
|
|
||||||
pass: "scmadmin",
|
|
||||||
sendImmediately: true
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -33,9 +33,10 @@ type Props = RoutingProps & {
|
|||||||
label: string;
|
label: string;
|
||||||
title?: string;
|
title?: string;
|
||||||
icon?: string;
|
icon?: string;
|
||||||
|
className?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
const NavLink: FC<Props> = ({ to, activeWhenMatch, activeOnlyWhenExact, icon, label, title }) => {
|
const NavLink: FC<Props> = ({ to, activeWhenMatch, activeOnlyWhenExact, icon, label, title, className }) => {
|
||||||
const active = useActiveMatch({ to, activeWhenMatch, activeOnlyWhenExact });
|
const active = useActiveMatch({ to, activeWhenMatch, activeOnlyWhenExact });
|
||||||
|
|
||||||
const context = useMenuContext();
|
const context = useMenuContext();
|
||||||
@@ -52,7 +53,7 @@ const NavLink: FC<Props> = ({ to, activeWhenMatch, activeOnlyWhenExact, icon, la
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<li title={collapsed ? title : undefined}>
|
<li title={collapsed ? title : undefined}>
|
||||||
<Link className={classNames(active ? "is-active" : "", collapsed ? "has-text-centered" : "")} to={to}>
|
<Link className={classNames(active ? "is-active" : "", collapsed ? "has-text-centered" : "", className)} to={to}>
|
||||||
{showIcon}
|
{showIcon}
|
||||||
{collapsed ? null : label}
|
{collapsed ? null : label}
|
||||||
</Link>
|
</Link>
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ class PrimaryNavigation extends React.Component<Props> {
|
|||||||
return (to: string, match: string, label: string, linkName: string) => {
|
return (to: string, match: string, label: string, linkName: string) => {
|
||||||
const link = links[linkName];
|
const link = links[linkName];
|
||||||
if (link) {
|
if (link) {
|
||||||
const navigationItem = <PrimaryNavigationLink to={to} match={match} label={t(label)} key={linkName} />;
|
const navigationItem = <PrimaryNavigationLink className={t(label)} to={to} match={match} label={t(label)} key={linkName} />;
|
||||||
navigationItems.push(navigationItem);
|
navigationItems.push(navigationItem);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -23,19 +23,21 @@
|
|||||||
*/
|
*/
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import { Route, Link } from "react-router-dom";
|
import { Route, Link } from "react-router-dom";
|
||||||
|
import classNames from "classnames";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
to: string;
|
to: string;
|
||||||
label: string;
|
label: string;
|
||||||
match?: string;
|
match?: string;
|
||||||
activeOnlyWhenExact?: boolean;
|
activeOnlyWhenExact?: boolean;
|
||||||
|
className?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PrimaryNavigationLink extends React.Component<Props> {
|
class PrimaryNavigationLink extends React.Component<Props> {
|
||||||
renderLink = (route: any) => {
|
renderLink = (route: any) => {
|
||||||
const { to, label } = this.props;
|
const { to, label, className } = this.props;
|
||||||
return (
|
return (
|
||||||
<li className={route.match ? "is-active" : ""}>
|
<li className={classNames(route.match ? "is-active" : "", className)}>
|
||||||
<Link to={to}>{label}</Link>
|
<Link to={to}>{label}</Link>
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -32,9 +32,10 @@ type Props = RoutingProps & {
|
|||||||
label: string;
|
label: string;
|
||||||
title?: string;
|
title?: string;
|
||||||
icon?: string;
|
icon?: string;
|
||||||
|
className?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
const SubNavigation: FC<Props> = ({ to, activeOnlyWhenExact, activeWhenMatch, icon, title, label, children }) => {
|
const SubNavigation: FC<Props> = ({ to, activeOnlyWhenExact, activeWhenMatch, icon, title, label, children, className }) => {
|
||||||
const context = useMenuContext();
|
const context = useMenuContext();
|
||||||
const collapsed = context.isCollapsed();
|
const collapsed = context.isCollapsed();
|
||||||
|
|
||||||
@@ -60,7 +61,7 @@ const SubNavigation: FC<Props> = ({ to, activeOnlyWhenExact, activeWhenMatch, ic
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<li title={collapsed ? title : undefined}>
|
<li title={collapsed ? title : undefined}>
|
||||||
<Link className={classNames(active ? "is-active" : "", collapsed ? "has-text-centered" : "")} to={to}>
|
<Link className={classNames(active ? "is-active" : "", collapsed ? "has-text-centered" : "", className)} to={to}>
|
||||||
<i className={classNames(defaultIcon, "fa-fw")} /> {collapsed ? "" : label}
|
<i className={classNames(defaultIcon, "fa-fw")} /> {collapsed ? "" : label}
|
||||||
</Link>
|
</Link>
|
||||||
{childrenList}
|
{childrenList}
|
||||||
|
|||||||
@@ -133,6 +133,7 @@ class Admin extends React.Component<Props> {
|
|||||||
icon="fas fa-info-circle"
|
icon="fas fa-info-circle"
|
||||||
label={t("admin.menu.informationNavLink")}
|
label={t("admin.menu.informationNavLink")}
|
||||||
title={t("admin.menu.informationNavLink")}
|
title={t("admin.menu.informationNavLink")}
|
||||||
|
className={t("admin.menu.informationNavLink")}
|
||||||
/>
|
/>
|
||||||
{(availablePluginsLink || installedPluginsLink) && (
|
{(availablePluginsLink || installedPluginsLink) && (
|
||||||
<SubNavigation
|
<SubNavigation
|
||||||
@@ -140,12 +141,13 @@ class Admin extends React.Component<Props> {
|
|||||||
icon="fas fa-puzzle-piece"
|
icon="fas fa-puzzle-piece"
|
||||||
label={t("plugins.menu.pluginsNavLink")}
|
label={t("plugins.menu.pluginsNavLink")}
|
||||||
title={t("plugins.menu.pluginsNavLink")}
|
title={t("plugins.menu.pluginsNavLink")}
|
||||||
|
className={t("plugins.menu.pluginsNavLink")}
|
||||||
>
|
>
|
||||||
{installedPluginsLink && (
|
{installedPluginsLink && (
|
||||||
<NavLink to={`${url}/plugins/installed/`} label={t("plugins.menu.installedNavLink")} />
|
<NavLink to={`${url}/plugins/installed/`} label={t("plugins.menu.installedNavLink")} className={t("plugins.menu.installedNavLink")}/>
|
||||||
)}
|
)}
|
||||||
{availablePluginsLink && (
|
{availablePluginsLink && (
|
||||||
<NavLink to={`${url}/plugins/available/`} label={t("plugins.menu.availableNavLink")} />
|
<NavLink to={`${url}/plugins/available/`} label={t("plugins.menu.availableNavLink")} className={t("plugins.menu.availableNavLink")} />
|
||||||
)}
|
)}
|
||||||
</SubNavigation>
|
</SubNavigation>
|
||||||
)}
|
)}
|
||||||
@@ -154,6 +156,7 @@ class Admin extends React.Component<Props> {
|
|||||||
icon="fas fa-user-shield"
|
icon="fas fa-user-shield"
|
||||||
label={t("repositoryRole.navLink")}
|
label={t("repositoryRole.navLink")}
|
||||||
title={t("repositoryRole.navLink")}
|
title={t("repositoryRole.navLink")}
|
||||||
|
className={t("repositoryRole.navLink")}
|
||||||
activeWhenMatch={this.matchesRoles}
|
activeWhenMatch={this.matchesRoles}
|
||||||
activeOnlyWhenExact={false}
|
activeOnlyWhenExact={false}
|
||||||
/>
|
/>
|
||||||
@@ -162,8 +165,9 @@ class Admin extends React.Component<Props> {
|
|||||||
to={`${url}/settings/general`}
|
to={`${url}/settings/general`}
|
||||||
label={t("admin.menu.settingsNavLink")}
|
label={t("admin.menu.settingsNavLink")}
|
||||||
title={t("admin.menu.settingsNavLink")}
|
title={t("admin.menu.settingsNavLink")}
|
||||||
|
className={t("admin.menu.settingsNavLink")}
|
||||||
>
|
>
|
||||||
<NavLink to={`${url}/settings/general`} label={t("admin.menu.generalNavLink")} />
|
<NavLink to={`${url}/settings/general`} label={t("admin.menu.generalNavLink")} className={t("admin.menu.generalNavLink")}/>
|
||||||
<ExtensionPoint name="admin.setting" props={extensionProps} renderAll={true} />
|
<ExtensionPoint name="admin.setting" props={extensionProps} renderAll={true} />
|
||||||
</SubNavigation>
|
</SubNavigation>
|
||||||
</SecondaryNavigation>
|
</SecondaryNavigation>
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ class EditUserNavLink extends React.Component<Props> {
|
|||||||
if (!this.isEditable()) {
|
if (!this.isEditable()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return <NavLink to={editUrl} label={t("singleUser.menu.generalNavLink")} />;
|
return <NavLink to={editUrl} label={t("singleUser.menu.generalNavLink")} className={t("singleUser.menu.generalNavLink")}/>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ class ChangePasswordNavLink extends React.Component<Props> {
|
|||||||
if (!this.hasPermissionToSetPassword()) {
|
if (!this.hasPermissionToSetPassword()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return <NavLink to={passwordUrl} label={t("singleUser.menu.setPasswordNavLink")} />;
|
return <NavLink to={passwordUrl} label={t("singleUser.menu.setPasswordNavLink")} className={t("singleUser.menu.setPasswordNavLink")}/>;
|
||||||
}
|
}
|
||||||
|
|
||||||
hasPermissionToSetPassword = () => {
|
hasPermissionToSetPassword = () => {
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ class ChangePermissionNavLink extends React.Component<Props> {
|
|||||||
if (!this.hasPermissionToSetPermission()) {
|
if (!this.hasPermissionToSetPermission()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return <NavLink to={permissionsUrl} label={t("singleUser.menu.setPermissionsNavLink")} />;
|
return <NavLink to={permissionsUrl} label={t("singleUser.menu.setPermissionsNavLink")} className={t("singleUser.menu.setPermissionsNavLink")}/>;
|
||||||
}
|
}
|
||||||
|
|
||||||
hasPermissionToSetPermission = () => {
|
hasPermissionToSetPermission = () => {
|
||||||
|
|||||||
@@ -114,11 +114,13 @@ class SingleUser extends React.Component<Props> {
|
|||||||
icon="fas fa-info-circle"
|
icon="fas fa-info-circle"
|
||||||
label={t("singleUser.menu.informationNavLink")}
|
label={t("singleUser.menu.informationNavLink")}
|
||||||
title={t("singleUser.menu.informationNavLink")}
|
title={t("singleUser.menu.informationNavLink")}
|
||||||
|
className={t("singleUser.menu.informationNavLink")}
|
||||||
/>
|
/>
|
||||||
<SubNavigation
|
<SubNavigation
|
||||||
to={`${url}/settings/general`}
|
to={`${url}/settings/general`}
|
||||||
label={t("singleUser.menu.settingsNavLink")}
|
label={t("singleUser.menu.settingsNavLink")}
|
||||||
title={t("singleUser.menu.settingsNavLink")}
|
title={t("singleUser.menu.settingsNavLink")}
|
||||||
|
className={t("singleUser.menu.settingsNavLink")}
|
||||||
>
|
>
|
||||||
<EditUserNavLink user={user} editUrl={`${url}/settings/general`} />
|
<EditUserNavLink user={user} editUrl={`${url}/settings/general`} />
|
||||||
<SetPasswordNavLink user={user} passwordUrl={`${url}/settings/password`} />
|
<SetPasswordNavLink user={user} passwordUrl={`${url}/settings/password`} />
|
||||||
|
|||||||
Reference in New Issue
Block a user