mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-01 19:15:52 +01:00
restore context path support
This commit is contained in:
@@ -7,7 +7,8 @@ type Props = {
|
|||||||
class GitAvatar extends React.Component<Props> {
|
class GitAvatar extends React.Component<Props> {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return <img src="/images/git-logo.png" alt="Git Logo" />;
|
// TODO we have to use Image from ui-components
|
||||||
|
return <img src="/scm/images/git-logo.png" alt="Git Logo" />;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ type Props = {
|
|||||||
class HgAvatar extends React.Component<Props> {
|
class HgAvatar extends React.Component<Props> {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return <img src="/images/hg-logo.png" alt="Mercurial Logo" />;
|
// TODO we have to use Image from ui-components
|
||||||
|
return <img src="/scm/images/hg-logo.png" alt="Mercurial Logo" />;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ type Props = {
|
|||||||
class SvnAvatar extends React.Component<Props> {
|
class SvnAvatar extends React.Component<Props> {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return <img src="/images/svn-logo.gif" alt="Subversion Logo" />;
|
// TODO we have to use Image from ui-components
|
||||||
|
return <img src="/scm/images/svn-logo.gif" alt="Subversion Logo" />;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,7 @@
|
|||||||
"pre-commit": "jest && flow && eslint src"
|
"pre-commit": "jest && flow && eslint src"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@scm-manager/ui-bundler": "^0.0.3",
|
"@scm-manager/ui-bundler": "^0.0.4",
|
||||||
"babel-eslint": "^8.2.6",
|
"babel-eslint": "^8.2.6",
|
||||||
"enzyme": "^3.3.0",
|
"enzyme": "^3.3.0",
|
||||||
"enzyme-adapter-react-16": "^1.1.1",
|
"enzyme-adapter-react-16": "^1.1.1",
|
||||||
|
|||||||
@@ -8,8 +8,8 @@
|
|||||||
manifest.json provides metadata used when your web app is added to the
|
manifest.json provides metadata used when your web app is added to the
|
||||||
homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
|
homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
|
||||||
-->
|
-->
|
||||||
<link rel="manifest" href="/manifest.json">
|
<link rel="manifest" href="/scm/manifest.json">
|
||||||
<link rel="shortcut icon" href="/favicon.ico">
|
<link rel="shortcut icon" href="/scm/favicon.ico">
|
||||||
<!--
|
<!--
|
||||||
Notice the use of %PUBLIC_URL% in the tags above.
|
Notice the use of %PUBLIC_URL% in the tags above.
|
||||||
It will be replaced with the URL of the `public` folder during the build.
|
It will be replaced with the URL of the `public` folder during the build.
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
work correctly both with client-side routing and a non-root public URL.
|
work correctly both with client-side routing and a non-root public URL.
|
||||||
Learn how to configure a non-root public URL by running `npm run build`.
|
Learn how to configure a non-root public URL by running `npm run build`.
|
||||||
-->
|
-->
|
||||||
<base href="/">
|
<base href="/scm">
|
||||||
<title>SCM-Manager</title>
|
<title>SCM-Manager</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@@ -37,7 +37,10 @@
|
|||||||
To begin the development, run `npm start` or `yarn start`.
|
To begin the development, run `npm start` or `yarn start`.
|
||||||
To create a production bundle, use `npm run build` or `yarn build`.
|
To create a production bundle, use `npm run build` or `yarn build`.
|
||||||
-->
|
-->
|
||||||
<script src="vendor.bundle.js"></script>
|
<script>
|
||||||
<script src="scm-ui.bundle.js"></script>
|
window.ctxPath = "/scm";
|
||||||
|
</script>
|
||||||
|
<script src="/scm/vendor.bundle.js"></script>
|
||||||
|
<script src="/scm/scm-ui.bundle.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
// @flow
|
// @flow
|
||||||
|
import { contextPath } from "./urls";
|
||||||
// get api base url from environment
|
|
||||||
const apiUrl = process.env.API_URL || process.env.PUBLIC_URL || "";
|
|
||||||
|
|
||||||
export const NOT_FOUND_ERROR = Error("not found");
|
export const NOT_FOUND_ERROR = Error("not found");
|
||||||
export const UNAUTHORIZED_ERROR = Error("unauthorized");
|
export const UNAUTHORIZED_ERROR = Error("unauthorized");
|
||||||
@@ -34,7 +32,7 @@ export function createUrl(url: string) {
|
|||||||
if (url.indexOf("/") !== 0) {
|
if (url.indexOf("/") !== 0) {
|
||||||
urlWithStartingSlash = "/" + urlWithStartingSlash;
|
urlWithStartingSlash = "/" + urlWithStartingSlash;
|
||||||
}
|
}
|
||||||
return `${apiUrl}/api/rest/v2${urlWithStartingSlash}`;
|
return `${contextPath}/api/rest/v2${urlWithStartingSlash}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
class ApiClient {
|
class ApiClient {
|
||||||
|
|||||||
18
scm-ui/src/components/Image.js
Normal file
18
scm-ui/src/components/Image.js
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
//@flow
|
||||||
|
import React from "react";
|
||||||
|
import { withContextPath } from "../urls";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
src: string,
|
||||||
|
alt: string,
|
||||||
|
className: any
|
||||||
|
};
|
||||||
|
|
||||||
|
class Image extends React.Component<Props> {
|
||||||
|
render() {
|
||||||
|
const { src, alt, className } = this.props;
|
||||||
|
return <img className={className} src={withContextPath(src)} alt={alt} />;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Image;
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { translate } from "react-i18next";
|
import { translate } from "react-i18next";
|
||||||
import injectSheet from "react-jss";
|
import injectSheet from "react-jss";
|
||||||
|
import Image from "./Image";
|
||||||
|
|
||||||
const styles = {
|
const styles = {
|
||||||
wrapper: {
|
wrapper: {
|
||||||
@@ -35,7 +36,7 @@ class Loading extends React.Component<Props> {
|
|||||||
return (
|
return (
|
||||||
<div className={classes.wrapper}>
|
<div className={classes.wrapper}>
|
||||||
<div className={classes.loading}>
|
<div className={classes.loading}>
|
||||||
<img
|
<Image
|
||||||
className={classes.image}
|
className={classes.image}
|
||||||
src="/images/loading.svg"
|
src="/images/loading.svg"
|
||||||
alt={t("loading.alt")}
|
alt={t("loading.alt")}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
//@flow
|
//@flow
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { translate } from "react-i18next";
|
import { translate } from "react-i18next";
|
||||||
|
import Image from "./Image";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
t: string => string
|
t: string => string
|
||||||
@@ -9,7 +10,7 @@ type Props = {
|
|||||||
class Logo extends React.Component<Props> {
|
class Logo extends React.Component<Props> {
|
||||||
render() {
|
render() {
|
||||||
const { t } = this.props;
|
const { t } = this.props;
|
||||||
return <img src="images/logo.png" alt={t("logo.alt")} />;
|
return <Image src="/images/logo.png" alt={t("logo.alt")} />;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -62,11 +62,7 @@ class PluginLoader extends React.Component<Props, State> {
|
|||||||
|
|
||||||
const promises = [];
|
const promises = [];
|
||||||
for (let bundle of plugin.bundles) {
|
for (let bundle of plugin.bundles) {
|
||||||
// skip old bundles
|
promises.push(this.loadBundle(bundle));
|
||||||
// TODO remove old bundles
|
|
||||||
if (bundle.indexOf("/") !== 0) {
|
|
||||||
promises.push(this.loadBundle(bundle));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return Promise.all(promises);
|
return Promise.all(promises);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import { SubmitButton } from "../components/buttons";
|
|||||||
|
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
import ErrorNotification from "../components/ErrorNotification";
|
import ErrorNotification from "../components/ErrorNotification";
|
||||||
|
import Image from "../components/Image";
|
||||||
|
|
||||||
const styles = {
|
const styles = {
|
||||||
avatar: {
|
avatar: {
|
||||||
@@ -105,7 +106,7 @@ class Login extends React.Component<Props, State> {
|
|||||||
<p className="subtitle">{t("login.subtitle")}</p>
|
<p className="subtitle">{t("login.subtitle")}</p>
|
||||||
<div className={classNames("box", classes.avatarSpacing)}>
|
<div className={classNames("box", classes.avatarSpacing)}>
|
||||||
<figure className={classes.avatar}>
|
<figure className={classes.avatar}>
|
||||||
<img
|
<Image
|
||||||
className={classes.avatarImage}
|
className={classes.avatarImage}
|
||||||
src="/images/blib.jpg"
|
src="/images/blib.jpg"
|
||||||
alt={t("login.logo-alt")}
|
alt={t("login.logo-alt")}
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ import i18n from "i18next";
|
|||||||
import Backend from "i18next-fetch-backend";
|
import Backend from "i18next-fetch-backend";
|
||||||
import LanguageDetector from "i18next-browser-languagedetector";
|
import LanguageDetector from "i18next-browser-languagedetector";
|
||||||
import { reactI18nextModule } from "react-i18next";
|
import { reactI18nextModule } from "react-i18next";
|
||||||
|
import { withContextPath } from "./urls";
|
||||||
|
|
||||||
const loadPath =
|
const loadPath = withContextPath("/locales/{{lng}}/{{ns}}.json");
|
||||||
(process.env.PUBLIC_URL || "") + "/locales/{{lng}}/{{ns}}.json";
|
|
||||||
|
|
||||||
// TODO load locales for moment
|
// TODO load locales for moment
|
||||||
|
|
||||||
|
|||||||
@@ -16,11 +16,11 @@ import createReduxStore from "./createReduxStore";
|
|||||||
import { ConnectedRouter } from "react-router-redux";
|
import { ConnectedRouter } from "react-router-redux";
|
||||||
import PluginLoader from "./components/PluginLoader";
|
import PluginLoader from "./components/PluginLoader";
|
||||||
|
|
||||||
const publicUrl: string = process.env.PUBLIC_URL || "";
|
import { contextPath } from "./urls";
|
||||||
|
|
||||||
// Create a history of your choosing (we're using a browser history in this case)
|
// Create a history of your choosing (we're using a browser history in this case)
|
||||||
const history: BrowserHistory = createHistory({
|
const history: BrowserHistory = createHistory({
|
||||||
basename: publicUrl
|
basename: contextPath
|
||||||
});
|
});
|
||||||
|
|
||||||
// Add the reducer to your store on the `router` key
|
// Add the reducer to your store on the `router` key
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { ExtensionPoint } from "@scm-manager/ui-extensions";
|
import { ExtensionPoint } from "@scm-manager/ui-extensions";
|
||||||
import type { Repository } from "../../types/Repositories";
|
import type { Repository } from "../../types/Repositories";
|
||||||
|
import Image from "../../../components/Image";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
repository: Repository
|
repository: Repository
|
||||||
@@ -13,7 +14,7 @@ class RepositoryAvatar extends React.Component<Props> {
|
|||||||
return (
|
return (
|
||||||
<p className="image is-64x64">
|
<p className="image is-64x64">
|
||||||
<ExtensionPoint name="repos.repository-avatar" props={{ repository }}>
|
<ExtensionPoint name="repos.repository-avatar" props={{ repository }}>
|
||||||
<img src="/images/blib.jpg" alt="Logo" />
|
<Image src="/images/blib.jpg" alt="Logo" />
|
||||||
</ExtensionPoint>
|
</ExtensionPoint>
|
||||||
</p>
|
</p>
|
||||||
);
|
);
|
||||||
|
|||||||
6
scm-ui/src/urls.js
Normal file
6
scm-ui/src/urls.js
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
// @flow
|
||||||
|
export const contextPath = window.ctxPath || "";
|
||||||
|
|
||||||
|
export function withContextPath(path: string) {
|
||||||
|
return contextPath + path;
|
||||||
|
}
|
||||||
@@ -703,9 +703,9 @@
|
|||||||
node-fetch "^2.1.1"
|
node-fetch "^2.1.1"
|
||||||
url-template "^2.0.8"
|
url-template "^2.0.8"
|
||||||
|
|
||||||
"@scm-manager/ui-bundler@^0.0.3":
|
"@scm-manager/ui-bundler@^0.0.4":
|
||||||
version "0.0.3"
|
version "0.0.4"
|
||||||
resolved "https://registry.yarnpkg.com/@scm-manager/ui-bundler/-/ui-bundler-0.0.3.tgz#06f99d8b17e9aa1bb6e69c2732160e1f46724c3c"
|
resolved "https://registry.yarnpkg.com/@scm-manager/ui-bundler/-/ui-bundler-0.0.4.tgz#0191a026d25b826692bccbc2b76d550388dd5528"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/core" "^7.0.0-rc.2"
|
"@babel/core" "^7.0.0-rc.2"
|
||||||
"@babel/plugin-proposal-class-properties" "^7.0.0-rc.2"
|
"@babel/plugin-proposal-class-properties" "^7.0.0-rc.2"
|
||||||
@@ -720,6 +720,7 @@
|
|||||||
budo "^11.3.2"
|
budo "^11.3.2"
|
||||||
colors "^1.3.1"
|
colors "^1.3.1"
|
||||||
commander "^2.17.1"
|
commander "^2.17.1"
|
||||||
|
fast-xml-parser "^3.12.0"
|
||||||
jest "^23.5.0"
|
jest "^23.5.0"
|
||||||
jest-junit "^5.1.0"
|
jest-junit "^5.1.0"
|
||||||
node-mkdirs "^0.0.1"
|
node-mkdirs "^0.0.1"
|
||||||
@@ -2830,6 +2831,12 @@ fast-levenshtein@~2.0.4:
|
|||||||
version "2.0.6"
|
version "2.0.6"
|
||||||
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
|
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
|
||||||
|
|
||||||
|
fast-xml-parser@^3.12.0:
|
||||||
|
version "3.12.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-3.12.0.tgz#84ddcd98ca005f94e99af3ac387adc32ffb239d8"
|
||||||
|
dependencies:
|
||||||
|
nimnjs "^1.3.2"
|
||||||
|
|
||||||
fb-watchman@^2.0.0:
|
fb-watchman@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.0.tgz#54e9abf7dfa2f26cd9b1636c588c1afc05de5d58"
|
resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.0.tgz#54e9abf7dfa2f26cd9b1636c588c1afc05de5d58"
|
||||||
@@ -5040,6 +5047,21 @@ nice-try@^1.0.4:
|
|||||||
version "1.0.4"
|
version "1.0.4"
|
||||||
resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.4.tgz#d93962f6c52f2c1558c0fbda6d512819f1efe1c4"
|
resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.4.tgz#d93962f6c52f2c1558c0fbda6d512819f1efe1c4"
|
||||||
|
|
||||||
|
nimn-date-parser@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/nimn-date-parser/-/nimn-date-parser-1.0.0.tgz#4ce55d1fd5ea206bbe82b76276f7b7c582139351"
|
||||||
|
|
||||||
|
nimn_schema_builder@^1.0.0:
|
||||||
|
version "1.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/nimn_schema_builder/-/nimn_schema_builder-1.1.0.tgz#b370ccf5b647d66e50b2dcfb20d0aa12468cd247"
|
||||||
|
|
||||||
|
nimnjs@^1.3.2:
|
||||||
|
version "1.3.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/nimnjs/-/nimnjs-1.3.2.tgz#a6a877968d87fad836375a4f616525e55079a5ba"
|
||||||
|
dependencies:
|
||||||
|
nimn-date-parser "^1.0.0"
|
||||||
|
nimn_schema_builder "^1.0.0"
|
||||||
|
|
||||||
node-fetch@^1.0.1:
|
node-fetch@^1.0.1:
|
||||||
version "1.7.3"
|
version "1.7.3"
|
||||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef"
|
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef"
|
||||||
|
|||||||
@@ -1,25 +1,34 @@
|
|||||||
package sonia.scm.api.v2.resources;
|
package sonia.scm.api.v2.resources;
|
||||||
|
|
||||||
|
import com.google.common.base.Strings;
|
||||||
import de.otto.edison.hal.Links;
|
import de.otto.edison.hal.Links;
|
||||||
import sonia.scm.plugin.PluginWrapper;
|
import sonia.scm.plugin.PluginWrapper;
|
||||||
|
import sonia.scm.util.HttpUtil;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static de.otto.edison.hal.Links.linkingTo;
|
import static de.otto.edison.hal.Links.linkingTo;
|
||||||
|
|
||||||
public class UIPluginDtoMapper {
|
public class UIPluginDtoMapper {
|
||||||
|
|
||||||
private ResourceLinks resourceLinks;
|
private final ResourceLinks resourceLinks;
|
||||||
|
private final HttpServletRequest request;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public UIPluginDtoMapper(ResourceLinks resourceLinks) {
|
public UIPluginDtoMapper(ResourceLinks resourceLinks, HttpServletRequest request) {
|
||||||
this.resourceLinks = resourceLinks;
|
this.resourceLinks = resourceLinks;
|
||||||
|
this.request = request;
|
||||||
}
|
}
|
||||||
|
|
||||||
public UIPluginDto map(PluginWrapper plugin) {
|
public UIPluginDto map(PluginWrapper plugin) {
|
||||||
UIPluginDto dto = new UIPluginDto(
|
UIPluginDto dto = new UIPluginDto(
|
||||||
plugin.getPlugin().getInformation().getName(),
|
plugin.getPlugin().getInformation().getName(),
|
||||||
plugin.getPlugin().getResources().getScriptResources()
|
getScriptResources(plugin)
|
||||||
);
|
);
|
||||||
|
|
||||||
Links.Builder linksBuilder = linkingTo()
|
Links.Builder linksBuilder = linkingTo()
|
||||||
@@ -31,4 +40,22 @@ public class UIPluginDtoMapper {
|
|||||||
return dto;
|
return dto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Set<String> getScriptResources(PluginWrapper wrapper) {
|
||||||
|
Set<String> scriptResources = wrapper.getPlugin().getResources().getScriptResources();
|
||||||
|
if (scriptResources != null) {
|
||||||
|
return scriptResources.stream()
|
||||||
|
.map(this::addContextPath)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
}
|
||||||
|
return Collections.emptySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String addContextPath(String resource) {
|
||||||
|
String ctxPath = request.getContextPath();
|
||||||
|
if (Strings.isNullOrEmpty(ctxPath)) {
|
||||||
|
return resource;
|
||||||
|
}
|
||||||
|
return HttpUtil.append(ctxPath, resource);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package sonia.scm.api.v2.resources;
|
|||||||
import com.webcohesion.enunciate.metadata.rs.ResponseCode;
|
import com.webcohesion.enunciate.metadata.rs.ResponseCode;
|
||||||
import com.webcohesion.enunciate.metadata.rs.StatusCodes;
|
import com.webcohesion.enunciate.metadata.rs.StatusCodes;
|
||||||
import com.webcohesion.enunciate.metadata.rs.TypeHint;
|
import com.webcohesion.enunciate.metadata.rs.TypeHint;
|
||||||
import de.otto.edison.hal.HalRepresentation;
|
|
||||||
import sonia.scm.plugin.PluginLoader;
|
import sonia.scm.plugin.PluginLoader;
|
||||||
import sonia.scm.plugin.PluginWrapper;
|
import sonia.scm.plugin.PluginWrapper;
|
||||||
import sonia.scm.web.VndMediaType;
|
import sonia.scm.web.VndMediaType;
|
||||||
|
|||||||
@@ -12,14 +12,13 @@ import org.junit.Test;
|
|||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.junit.MockitoJUnitRunner;
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
import sonia.scm.api.rest.resources.PluginResource;
|
|
||||||
import sonia.scm.plugin.*;
|
import sonia.scm.plugin.*;
|
||||||
import sonia.scm.web.VndMediaType;
|
import sonia.scm.web.VndMediaType;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND;
|
import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND;
|
||||||
import static javax.servlet.http.HttpServletResponse.SC_OK;
|
import static javax.servlet.http.HttpServletResponse.SC_OK;
|
||||||
@@ -36,12 +35,15 @@ public class UIRootResourceTest {
|
|||||||
@Mock
|
@Mock
|
||||||
private PluginLoader pluginLoader;
|
private PluginLoader pluginLoader;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private HttpServletRequest request;
|
||||||
|
|
||||||
private final URI baseUri = URI.create("/");
|
private final URI baseUri = URI.create("/");
|
||||||
private final ResourceLinks resourceLinks = ResourceLinksMock.createMock(baseUri);
|
private final ResourceLinks resourceLinks = ResourceLinksMock.createMock(baseUri);
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUpRestService() {
|
public void setUpRestService() {
|
||||||
UIPluginDtoMapper mapper = new UIPluginDtoMapper(resourceLinks);
|
UIPluginDtoMapper mapper = new UIPluginDtoMapper(resourceLinks, request);
|
||||||
UIPluginDtoCollectionMapper collectionMapper = new UIPluginDtoCollectionMapper(resourceLinks, mapper);
|
UIPluginDtoCollectionMapper collectionMapper = new UIPluginDtoCollectionMapper(resourceLinks, mapper);
|
||||||
|
|
||||||
UIPluginResource pluginResource = new UIPluginResource(pluginLoader, collectionMapper, mapper);
|
UIPluginResource pluginResource = new UIPluginResource(pluginLoader, collectionMapper, mapper);
|
||||||
@@ -149,6 +151,24 @@ public class UIRootResourceTest {
|
|||||||
assertTrue(response.getContentAsString().contains("\"self\":{\"href\":\"" + uri + "\"}"));
|
assertTrue(response.getContentAsString().contains("\"self\":{\"href\":\"" + uri + "\"}"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldHaveBundleWithContextPath() throws Exception {
|
||||||
|
when(request.getContextPath()).thenReturn("/scm");
|
||||||
|
mockPlugins(mockPlugin("awesome", "Awesome", createPluginResources("my/bundle.js")));
|
||||||
|
|
||||||
|
String uri = "/v2/ui/plugins/awesome";
|
||||||
|
MockHttpRequest request = MockHttpRequest.get(uri);
|
||||||
|
MockHttpResponse response = new MockHttpResponse();
|
||||||
|
|
||||||
|
dispatcher.invoke(request, response);
|
||||||
|
|
||||||
|
assertEquals(SC_OK, response.getStatus());
|
||||||
|
|
||||||
|
System.out.println();
|
||||||
|
|
||||||
|
assertTrue(response.getContentAsString().contains("/scm/my/bundle.js"));
|
||||||
|
}
|
||||||
|
|
||||||
private void mockPlugins(PluginWrapper... plugins) {
|
private void mockPlugins(PluginWrapper... plugins) {
|
||||||
when(pluginLoader.getInstalledPlugins()).thenReturn(Lists.newArrayList(plugins));
|
when(pluginLoader.getInstalledPlugins()).thenReturn(Lists.newArrayList(plugins));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user