merged 2.0.0

This commit is contained in:
Eduard Heimbuch
2019-09-16 11:01:33 +02:00
13 changed files with 381 additions and 283 deletions

View File

@@ -6,4 +6,8 @@ public abstract class BadRequestException extends ExceptionWithContext {
public BadRequestException(List<ContextEntry> context, String message) {
super(context, message);
}
public BadRequestException(List<ContextEntry> context, String message, Exception cause) {
super(context, message, cause);
}
}

View File

@@ -122,6 +122,7 @@ public class ModifyCommandRequest implements Resetable, Validateable {
}
void cleanup() {
if (content.exists()) {
try {
IOUtil.delete(content);
} catch (IOException e) {
@@ -129,6 +130,7 @@ public class ModifyCommandRequest implements Resetable, Validateable {
}
}
}
}
public static class CreateFileRequest extends ContentModificationRequest {

View File

@@ -3,8 +3,7 @@ import React from "react";
import {Link} from "react-router-dom";
import type {Branch, Repository} from "@scm-manager/ui-types";
import injectSheet from "react-jss";
import { ExtensionPoint, binder } from "@scm-manager/ui-extensions";
import {ButtonGroup} from "./buttons";
import {binder, ExtensionPoint} from "@scm-manager/ui-extensions";
import classNames from "classnames";
type Props = {
@@ -64,33 +63,48 @@ class Breadcrumb extends React.Component<Props> {
}
render() {
const { classes, baseUrl, branch, defaultBranch, branches, revision, path, repository } = this.props;
const {
classes,
baseUrl,
branch,
defaultBranch,
branches,
revision,
path,
repository
} = this.props;
return (
<>
<div className={classes.flexRow}>
<nav className={classNames(classes.flexStart, "breadcrumb sources-breadcrumb")} aria-label="breadcrumbs">
<nav
className={classNames(
classes.flexStart,
"breadcrumb sources-breadcrumb"
)}
aria-label="breadcrumbs"
>
<ul>{this.renderPath()}</ul>
</nav>
{
binder.hasExtension("repos.sources.actionbar") &&
{binder.hasExtension("repos.sources.actionbar") && (
<div className={classes.buttonGroup}>
<ButtonGroup>
<ExtensionPoint
name="repos.sources.actionbar"
props={{
baseUrl,
branch: branch ? branch : defaultBranch,
path,
isBranchUrl: branches &&
branches.filter(b => b.name.replace("/", "%2F") === revision).length > 0,
isBranchUrl:
branches &&
branches.filter(
b => b.name.replace("/", "%2F") === revision
).length > 0,
repository
}}
renderAll={true}
/>
</ButtonGroup>
</div>
}
)}
</div>
<hr className={classes.noMargin} />
</>

View File

@@ -8,13 +8,12 @@ type Props = {
body: any,
footer?: any,
active: boolean,
className?: string
};
class Modal extends React.Component<Props> {
render() {
const { title, closeFunction, body, footer, active } = this.props;
const { title, closeFunction, body, footer, active, className } = this.props;
const isActive = active ? "is-active" : null;
@@ -24,7 +23,7 @@ class Modal extends React.Component<Props> {
}
return (
<div className={classNames("modal", isActive)}>
<div className={classNames("modal", className, isActive)}>
<div className="modal-background" />
<div className="modal-card">
<header className="modal-card-head">

View File

@@ -14,3 +14,9 @@ export const isMailValid = (mail: string) => {
export const isNumberValid = (number: string) => {
return !isNaN(number);
};
const pathRegex = /^((?!\/{2,}).)*$/;
export const isPathValid = (path: string) => {
return pathRegex.test(path);
};

View File

@@ -2,7 +2,6 @@
import * as validator from "./validation";
describe("test name validation", () => {
it("should return false", () => {
// invalid names taken from ValidationUtilTest.java
const invalidNames = [
"@test",
@@ -23,11 +22,11 @@ describe("test name validation", () => {
"!_!"
];
for (let name of invalidNames) {
it(`should return false for '${name}'`, () => {
expect(validator.isNameValid(name)).toBe(false);
}
});
}
it("should return true", () => {
// valid names taken from ValidationUtilTest.java
const validNames = [
"test",
@@ -46,13 +45,13 @@ describe("test name validation", () => {
"and@this"
];
for (let name of validNames) {
it(`should return true for '${name}'`, () => {
expect(validator.isNameValid(name)).toBe(true);
}
});
}
});
describe("test mail validation", () => {
it("should return false", () => {
// invalid taken from ValidationUtilTest.java
const invalid = [
"ostfalia.de",
@@ -63,11 +62,11 @@ describe("test mail validation", () => {
"s.sdorra@[ostfalia.de"
];
for (let mail of invalid) {
it(`should return false for '${mail}'`, () => {
expect(validator.isMailValid(mail)).toBe(false);
}
});
}
it("should return true", () => {
// valid taken from ValidationUtilTest.java
const valid = [
"s.sdorra@ostfalia.de",
@@ -82,22 +81,38 @@ describe("test mail validation", () => {
"\"S Sdorra\"@scm.solutions"
];
for (let mail of valid) {
it(`should return true for '${mail}'`, () => {
expect(validator.isMailValid(mail)).toBe(true);
}
});
}
});
describe("test number validation", () => {
it("should return false", () => {
const invalid = ["1a", "35gu", "dj6", "45,5", "test"];
for (let number of invalid) {
it(`should return false for '${number}'`, () => {
expect(validator.isNumberValid(number)).toBe(false);
}
});
it("should return true", () => {
}
const valid = ["1", "35", "2", "235", "34.4"];
for (let number of valid) {
it(`should return true for '${number}'`, () => {
expect(validator.isNumberValid(number)).toBe(true);
});
}
});
describe("test path validation", () => {
const invalid = ["//", "some//path", "end//"];
for (let path of invalid) {
it(`should return false for '${path}'`, () => {
expect(validator.isPathValid(path)).toBe(false);
});
}
const valid = ["", "/", "dir", "some/path", "end/"];
for (let path of valid) {
it(`should return true for '${path}'`, () => {
expect(validator.isPathValid(path)).toBe(true);
});
}
});

View File

@@ -106,7 +106,6 @@ class Content extends React.Component<Props, State> {
</div>
<div className="buttons is-grouped">
<div className={classes.marginInHeader}>{selector}</div>
<ButtonGroup>
<ExtensionPoint
name="repos.sources.content.actionbar"
props={{
@@ -116,7 +115,6 @@ class Content extends React.Component<Props, State> {
}}
renderAll={true}
/>
</ButtonGroup>
</div>
</article>
</span>

View File

@@ -2,9 +2,9 @@
import { validation } from "@scm-manager/ui-components";
const { isNameValid, isMailValid } = validation;
const { isNameValid, isMailValid, isPathValid } = validation;
export { isNameValid, isMailValid };
export { isNameValid, isMailValid, isPathValid };
export const isDisplayNameValid = (displayName: string) => {
if (displayName) {

View File

@@ -2,18 +2,24 @@
@import "bulma/sass/utilities/functions";
$blue: #33b2e8;
$cyan: $blue;
$green: #00c79b;
$mint: #11dfd0;
$info: $blue;
// $footer-background-color
.is-ellipsis-overflow {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.is-word-break {
-webkit-hyphens: auto;
-moz-hyphens: auto;
-ms-hyphens: auto;
hyphens: auto;
word-break: break-all;
}
.has-rounded-border {
border-radius: 0.25rem;
}
@@ -29,14 +35,6 @@ $info: $blue;
padding: 0 0 0 3.8em !important;
}
.is-word-break {
-webkit-hyphens: auto;
-moz-hyphens: auto;
-ms-hyphens: auto;
hyphens: auto;
word-break: break-all;
}
.main {
min-height: calc(100vh - 260px);
}
@@ -76,6 +74,128 @@ hr.header-with-actions {
@import "bulma/bulma";
@import "bulma-tooltip/dist/css/bulma-tooltip";
$dark-75: scale-color($dark, $lightness: 25%);
$dark-50: scale-color($dark, $lightness: 50%);
$dark-25: scale-color($dark, $lightness: 75%);
$info-75: scale-color($info, $lightness: 25%);
$info-50: scale-color($info, $lightness: 50%);
$info-25: scale-color($info, $lightness: 75%);
$link-75: scale-color($link, $lightness: 25%);
$link-50: scale-color($link, $lightness: 50%);
$link-25: scale-color($link, $lightness: 75%);
$primary-75: scale-color($primary, $lightness: 25%);
$primary-50: scale-color($primary, $lightness: 50%);
$primary-25: scale-color($primary, $lightness: 75%);
$success-75: scale-color($success, $lightness: 25%);
$success-50: scale-color($success, $lightness: 50%);
$success-25: scale-color($success, $lightness: 75%);
$warning-75: scale-color($warning, $lightness: 25%);
$warning-50: scale-color($warning, $lightness: 50%);
$warning-25: scale-color($warning, $lightness: 75%);
$danger-75: scale-color($danger, $lightness: 25%);
$danger-50: scale-color($danger, $lightness: 50%);
$danger-25: scale-color($danger, $lightness: 75%);
:root {
// asc sorted derived-variables
--primary: #{$primary};
--primary-75: #{$primary-75};
--primary-50: #{$primary-50};
--primary-25: #{$primary-25};
--info: #{$info};
--info-75: #{$info-75};
--info-50: #{$info-50};
--info-25: #{$info-25};
--success: #{$success};
--success-75: #{$success-75};
--success-50: #{$success-50};
--success-25: #{$success-25};
--warning: #{$warning};
--warning-75: #{$warning-75};
--warning-50: #{$warning-50};
--warning-25: #{$warning-25};
--danger: #{$danger};
--danger-75: #{$danger-75};
--danger-50: #{$danger-50};
--danger-25: #{$danger-25};
--light: #{$light};
--dark: #{$dark};
--dark-75: #{$dark-75};
--dark-50: #{$dark-50};
--dark-25: #{$dark-25};
--background: #{$background};
--border: #{$border};
--text: #{$text};
--link: #{$link};
--link-75: #{$link-75};
--link-50: #{$link-50};
--link-25: #{$link-25};
}
.has-background-dark-75 {
background-color: $dark-75;
}
.has-background-dark-50 {
background-color: $dark-50;
}
.has-background-dark-25 {
background-color: $dark-25;
}
.has-background-info-75 {
background-color: $info-75;
}
.has-background-info-50 {
background-color: $info-50;
}
.has-background-info-25 {
background-color: $info-25;
}
.has-background-link-75 {
background-color: $link-75;
}
.has-background-link-50 {
background-color: $link-50;
}
.has-background-link-25 {
background-color: $link-25;
}
.has-background-primary-75 {
background-color: $primary-75;
}
.has-background-primary-50 {
background-color: $primary-50;
}
.has-background-primary-25 {
background-color: $primary-25;
}
.has-background-success-75 {
background-color: $success-75;
}
.has-background-success-50 {
background-color: $success-50;
}
.has-background-success-25 {
background-color: $success-25;
}
.has-background-warning-75 {
background-color: $warning-75;
}
.has-background-warning-50 {
background-color: $warning-50;
}
.has-background-warning-25 {
background-color: $warning-25;
}
.has-background-danger-75 {
background-color: $danger-75;
}
.has-background-danger-50 {
background-color: $danger-50;
}
.has-background-danger-25 {
background-color: $danger-25;
}
// import at the end, because we need a lot of stuff from bulma/bulma
.box-link-shadow {
&:hover,

View File

@@ -34,6 +34,7 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;
import static sonia.scm.plugin.PluginTestHelper.createInstalled;
@ExtendWith(MockitoExtension.class)
class InstalledPluginResourceTest {
@@ -86,7 +87,7 @@ class InstalledPluginResourceTest {
@Test
void getInstalledPlugins() throws URISyntaxException, UnsupportedEncodingException {
InstalledPlugin installedPlugin = createPlugin();
InstalledPlugin installedPlugin = createInstalled("");
when(pluginManager.getInstalled()).thenReturn(Collections.singletonList(installedPlugin));
when(collectionMapper.mapInstalled(Collections.singletonList(installedPlugin), Collections.emptyList())).thenReturn(new MockedResultDto());
@@ -105,7 +106,7 @@ class InstalledPluginResourceTest {
PluginInformation pluginInformation = new PluginInformation();
pluginInformation.setVersion("2.0.0");
pluginInformation.setName("pluginName");
InstalledPlugin installedPlugin = createPlugin(pluginInformation);
InstalledPlugin installedPlugin = createInstalled(pluginInformation);
when(pluginManager.getInstalled("pluginName")).thenReturn(Optional.of(installedPlugin));
@@ -124,18 +125,6 @@ class InstalledPluginResourceTest {
}
}
private InstalledPlugin createPlugin() {
return createPlugin(new PluginInformation());
}
private InstalledPlugin createPlugin(PluginInformation information) {
InstalledPlugin plugin = mock(InstalledPlugin.class);
InstalledPluginDescriptor descriptor = mock(InstalledPluginDescriptor.class);
lenient().when(descriptor.getInformation()).thenReturn(information);
lenient().when(plugin.getDescriptor()).thenReturn(descriptor);
return plugin;
}
@Nested
class WithoutAuthorization {

View File

@@ -23,6 +23,8 @@ import static java.util.Collections.emptyList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static sonia.scm.plugin.PluginTestHelper.createAvailable;
import static sonia.scm.plugin.PluginTestHelper.createInstalled;
@ExtendWith(MockitoExtension.class)
class PluginDtoMapperTest {
@@ -74,22 +76,16 @@ class PluginDtoMapperTest {
@Test
void shouldAppendInstalledSelfLink() {
InstalledPlugin plugin = createInstalled();
InstalledPlugin plugin = createInstalled(createPluginInformation());
PluginDto dto = mapper.mapInstalled(plugin, emptyList());
assertThat(dto.getLinks().getLinkBy("self").get().getHref())
.isEqualTo("https://hitchhiker.com/v2/plugins/installed/scm-cas-plugin");
}
private InstalledPlugin createInstalled(PluginInformation information) {
InstalledPlugin plugin = mock(InstalledPlugin.class, Answers.RETURNS_DEEP_STUBS);
when(plugin.getDescriptor().getInformation()).thenReturn(information);
return plugin;
}
@Test
void shouldAppendAvailableSelfLink() {
AvailablePlugin plugin = createAvailable();
AvailablePlugin plugin = createAvailable(createPluginInformation());
PluginDto dto = mapper.mapAvailable(plugin);
assertThat(dto.getLinks().getLinkBy("self").get().getHref())
@@ -98,7 +94,7 @@ class PluginDtoMapperTest {
@Test
void shouldNotAppendInstallLinkWithoutPermissions() {
AvailablePlugin plugin = createAvailable();
AvailablePlugin plugin = createAvailable(createPluginInformation());
PluginDto dto = mapper.mapAvailable(plugin);
assertThat(dto.getLinks().getLinkBy("install")).isEmpty();
@@ -107,7 +103,7 @@ class PluginDtoMapperTest {
@Test
void shouldAppendInstallLink() {
when(subject.isPermitted("plugin:manage")).thenReturn(true);
AvailablePlugin plugin = createAvailable();
AvailablePlugin plugin = createAvailable(createPluginInformation());
PluginDto dto = mapper.mapAvailable(plugin);
assertThat(dto.getLinks().getLinkBy("install").get().getHref())
@@ -125,25 +121,10 @@ class PluginDtoMapperTest {
@Test
void shouldAppendDependencies() {
AvailablePlugin plugin = createAvailable();
AvailablePlugin plugin = createAvailable(createPluginInformation());
when(plugin.getDescriptor().getDependencies()).thenReturn(ImmutableSet.of("one", "two"));
PluginDto dto = mapper.mapAvailable(plugin);
assertThat(dto.getDependencies()).containsOnly("one", "two");
}
private InstalledPlugin createInstalled() {
return createInstalled(createPluginInformation());
}
private AvailablePlugin createAvailable() {
return createAvailable(createPluginInformation());
}
private AvailablePlugin createAvailable(PluginInformation information) {
AvailablePluginDescriptor descriptor = mock(AvailablePluginDescriptor.class);
when(descriptor.getInformation()).thenReturn(information);
return new AvailablePlugin(descriptor);
}
}

View File

@@ -16,7 +16,6 @@ import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import sonia.scm.NotFoundException;
import sonia.scm.ScmConstraintViolationException;
import sonia.scm.event.ScmEventBus;
import sonia.scm.lifecycle.RestartEvent;
@@ -24,8 +23,11 @@ import java.util.List;
import java.util.Optional;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.in;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.*;
import static sonia.scm.plugin.PluginTestHelper.createAvailable;
import static sonia.scm.plugin.PluginTestHelper.createInstalled;
@ExtendWith(MockitoExtension.class)
class DefaultPluginManagerTest {
@@ -71,8 +73,8 @@ class DefaultPluginManagerTest {
@Test
void shouldReturnInstalledPlugins() {
InstalledPlugin review = createInstalled("scm-review-plugin", "1");
InstalledPlugin git = createInstalled("scm-git-plugin", "1");
InstalledPlugin review = createInstalled("scm-review-plugin");
InstalledPlugin git = createInstalled("scm-git-plugin");
when(loader.getInstalledPlugins()).thenReturn(ImmutableList.of(review, git));
@@ -82,8 +84,8 @@ class DefaultPluginManagerTest {
@Test
void shouldReturnReviewPlugin() {
InstalledPlugin review = createInstalled("scm-review-plugin", "1");
InstalledPlugin git = createInstalled("scm-git-plugin", "1");
InstalledPlugin review = createInstalled("scm-review-plugin");
InstalledPlugin git = createInstalled("scm-git-plugin");
when(loader.getInstalledPlugins()).thenReturn(ImmutableList.of(review, git));
@@ -101,8 +103,8 @@ class DefaultPluginManagerTest {
@Test
void shouldReturnAvailablePlugins() {
AvailablePlugin review = createAvailable("scm-review-plugin", "1");
AvailablePlugin git = createAvailable("scm-git-plugin", "1");
AvailablePlugin review = createAvailable("scm-review-plugin");
AvailablePlugin git = createAvailable("scm-git-plugin");
when(center.getAvailable()).thenReturn(ImmutableSet.of(review, git));
@@ -111,35 +113,22 @@ class DefaultPluginManagerTest {
}
@Test
void shouldFilterOutAllInstalledWithSameVersion() {
InstalledPlugin installedGit = createInstalled("scm-git-plugin", "1");
void shouldFilterOutAllInstalled() {
InstalledPlugin installedGit = createInstalled("scm-git-plugin");
when(loader.getInstalledPlugins()).thenReturn(ImmutableList.of(installedGit));
AvailablePlugin review = createAvailable("scm-review-plugin", "1");
AvailablePlugin git = createAvailable("scm-git-plugin", "1");
AvailablePlugin review = createAvailable("scm-review-plugin");
AvailablePlugin git = createAvailable("scm-git-plugin");
when(center.getAvailable()).thenReturn(ImmutableSet.of(review, git));
List<AvailablePlugin> available = manager.getAvailable();
assertThat(available).containsOnly(review);
}
@Test
void shouldKeepInstalledWithOlderVersion() {
InstalledPlugin installedGit = createInstalled("scm-git-plugin", "1");
when(loader.getInstalledPlugins()).thenReturn(ImmutableList.of(installedGit));
AvailablePlugin review = createAvailable("scm-review-plugin", "1");
AvailablePlugin git = createAvailable("scm-git-plugin", "1.1");
when(center.getAvailable()).thenReturn(ImmutableSet.of(review, git));
List<AvailablePlugin> available = manager.getAvailable();
assertThat(available).contains(git, review);
}
@Test
void shouldReturnAvailable() {
AvailablePlugin review = createAvailable("scm-review-plugin", "1");
AvailablePlugin git = createAvailable("scm-git-plugin", "1");
AvailablePlugin review = createAvailable("scm-review-plugin");
AvailablePlugin git = createAvailable("scm-git-plugin");
when(center.getAvailable()).thenReturn(ImmutableSet.of(review, git));
Optional<AvailablePlugin> available = manager.getAvailable("scm-git-plugin");
@@ -148,7 +137,7 @@ class DefaultPluginManagerTest {
@Test
void shouldReturnEmptyForNonExistingAvailable() {
AvailablePlugin review = createAvailable("scm-review-plugin", "1");
AvailablePlugin review = createAvailable("scm-review-plugin");
when(center.getAvailable()).thenReturn(ImmutableSet.of(review));
Optional<AvailablePlugin> available = manager.getAvailable("scm-git-plugin");
@@ -157,10 +146,10 @@ class DefaultPluginManagerTest {
@Test
void shouldReturnEmptyForInstalledPlugin() {
InstalledPlugin installedGit = createInstalled("scm-git-plugin", "1");
InstalledPlugin installedGit = createInstalled("scm-git-plugin");
when(loader.getInstalledPlugins()).thenReturn(ImmutableList.of(installedGit));
AvailablePlugin git = createAvailable("scm-git-plugin", "1");
AvailablePlugin git = createAvailable("scm-git-plugin");
when(center.getAvailable()).thenReturn(ImmutableSet.of(git));
Optional<AvailablePlugin> available = manager.getAvailable("scm-git-plugin");
@@ -169,7 +158,7 @@ class DefaultPluginManagerTest {
@Test
void shouldInstallThePlugin() {
AvailablePlugin git = createAvailable("scm-git-plugin", "1");
AvailablePlugin git = createAvailable("scm-git-plugin");
when(center.getAvailable()).thenReturn(ImmutableSet.of(git));
manager.install("scm-git-plugin", false);
@@ -178,36 +167,11 @@ class DefaultPluginManagerTest {
verify(eventBus, never()).post(any());
}
@Test
void shouldUpdateNormalPlugin() {
AvailablePlugin available = createAvailable("scm-git-plugin", "2");
InstalledPlugin installed = createInstalled("scm-git-plugin", "1");
when(installed.isCore()).thenReturn(false);
lenient().when(center.getAvailable()).thenReturn(ImmutableSet.of(available));
when(loader.getInstalledPlugins()).thenReturn(ImmutableSet.of(installed));
manager.install("scm-git-plugin", false);
verify(installer).install(available);
verify(eventBus, never()).post(any());
}
@Test
void shouldNotUpdateCorePlugin() {
AvailablePlugin available = createAvailable("scm-git-plugin", "2");
InstalledPlugin installed = createInstalled("scm-git-plugin", "1");
when(installed.isCore()).thenReturn(true);
lenient().when(center.getAvailable()).thenReturn(ImmutableSet.of(available));
when(loader.getInstalledPlugins()).thenReturn(ImmutableSet.of(installed));
assertThrows(ScmConstraintViolationException.class, () -> manager.install("scm-git-plugin", false));
}
@Test
void shouldInstallDependingPlugins() {
AvailablePlugin review = createAvailable("scm-review-plugin", "1");
AvailablePlugin review = createAvailable("scm-review-plugin");
when(review.getDescriptor().getDependencies()).thenReturn(ImmutableSet.of("scm-mail-plugin"));
AvailablePlugin mail = createAvailable("scm-mail-plugin", "1");
AvailablePlugin mail = createAvailable("scm-mail-plugin");
when(center.getAvailable()).thenReturn(ImmutableSet.of(review, mail));
manager.install("scm-review-plugin", false);
@@ -218,12 +182,12 @@ class DefaultPluginManagerTest {
@Test
void shouldNotInstallAlreadyInstalledDependencies() {
AvailablePlugin review = createAvailable("scm-review-plugin", "1");
AvailablePlugin review = createAvailable("scm-review-plugin");
when(review.getDescriptor().getDependencies()).thenReturn(ImmutableSet.of("scm-mail-plugin"));
AvailablePlugin mail = createAvailable("scm-mail-plugin", "1");
AvailablePlugin mail = createAvailable("scm-mail-plugin");
when(center.getAvailable()).thenReturn(ImmutableSet.of(review, mail));
InstalledPlugin installedMail = createInstalled("scm-mail-plugin", "1");
InstalledPlugin installedMail = createInstalled("scm-mail-plugin");
when(loader.getInstalledPlugins()).thenReturn(ImmutableList.of(installedMail));
manager.install("scm-review-plugin", false);
@@ -236,11 +200,11 @@ class DefaultPluginManagerTest {
@Test
void shouldRollbackOnFailedInstallation() {
AvailablePlugin review = createAvailable("scm-review-plugin", "1");
AvailablePlugin review = createAvailable("scm-review-plugin");
when(review.getDescriptor().getDependencies()).thenReturn(ImmutableSet.of("scm-mail-plugin"));
AvailablePlugin mail = createAvailable("scm-mail-plugin", "1");
AvailablePlugin mail = createAvailable("scm-mail-plugin");
when(mail.getDescriptor().getDependencies()).thenReturn(ImmutableSet.of("scm-notification-plugin"));
AvailablePlugin notification = createAvailable("scm-notification-plugin", "1");
AvailablePlugin notification = createAvailable("scm-notification-plugin");
when(center.getAvailable()).thenReturn(ImmutableSet.of(review, mail, notification));
PendingPluginInstallation pendingNotification = mock(PendingPluginInstallation.class);
@@ -259,9 +223,9 @@ class DefaultPluginManagerTest {
@Test
void shouldInstallNothingIfOneOfTheDependenciesIsNotAvailable() {
AvailablePlugin review = createAvailable("scm-review-plugin", "1");
AvailablePlugin review = createAvailable("scm-review-plugin");
when(review.getDescriptor().getDependencies()).thenReturn(ImmutableSet.of("scm-mail-plugin"));
AvailablePlugin mail = createAvailable("scm-mail-plugin", "1");
AvailablePlugin mail = createAvailable("scm-mail-plugin");
when(mail.getDescriptor().getDependencies()).thenReturn(ImmutableSet.of("scm-notification-plugin"));
when(center.getAvailable()).thenReturn(ImmutableSet.of(review, mail));
@@ -272,7 +236,7 @@ class DefaultPluginManagerTest {
@Test
void shouldSendRestartEventAfterInstallation() {
AvailablePlugin git = createAvailable("scm-git-plugin", "1");
AvailablePlugin git = createAvailable("scm-git-plugin");
when(center.getAvailable()).thenReturn(ImmutableSet.of(git));
manager.install("scm-git-plugin", true);
@@ -283,7 +247,7 @@ class DefaultPluginManagerTest {
@Test
void shouldNotSendRestartEventIfNoPluginWasInstalled() {
InstalledPlugin gitInstalled = createInstalled("scm-git-plugin", "1");
InstalledPlugin gitInstalled = createInstalled("scm-git-plugin");
when(loader.getInstalledPlugins()).thenReturn(ImmutableList.of(gitInstalled));
manager.install("scm-git-plugin", true);
@@ -292,7 +256,7 @@ class DefaultPluginManagerTest {
@Test
void shouldNotInstallAlreadyPendingPlugins() {
AvailablePlugin review = createAvailable("scm-review-plugin", "1");
AvailablePlugin review = createAvailable("scm-review-plugin");
when(center.getAvailable()).thenReturn(ImmutableSet.of(review));
manager.install("scm-review-plugin", false);
@@ -303,7 +267,7 @@ class DefaultPluginManagerTest {
@Test
void shouldSendRestartEvent() {
AvailablePlugin review = createAvailable("scm-review-plugin", "1");
AvailablePlugin review = createAvailable("scm-review-plugin");
when(center.getAvailable()).thenReturn(ImmutableSet.of(review));
manager.install("scm-review-plugin", false);
@@ -321,7 +285,7 @@ class DefaultPluginManagerTest {
@Test
void shouldReturnSingleAvailableAsPending() {
AvailablePlugin review = createAvailable("scm-review-plugin", "1");
AvailablePlugin review = createAvailable("scm-review-plugin");
when(center.getAvailable()).thenReturn(ImmutableSet.of(review));
manager.install("scm-review-plugin", false);
@@ -332,7 +296,7 @@ class DefaultPluginManagerTest {
@Test
void shouldReturnAvailableAsPending() {
AvailablePlugin review = createAvailable("scm-review-plugin", "1");
AvailablePlugin review = createAvailable("scm-review-plugin");
when(center.getAvailable()).thenReturn(ImmutableSet.of(review));
manager.install("scm-review-plugin", false);
@@ -392,35 +356,4 @@ class DefaultPluginManagerTest {
}
}
private AvailablePlugin createAvailable(String name, String version) {
PluginInformation information = new PluginInformation();
information.setName(name);
information.setVersion(version);
return createAvailable(information);
}
private InstalledPlugin createInstalled(String name, String version) {
PluginInformation information = new PluginInformation();
information.setName(name);
information.setVersion(version);
return createInstalled(information);
}
private InstalledPlugin createInstalled(PluginInformation information) {
InstalledPlugin plugin = mock(InstalledPlugin.class, Answers.RETURNS_DEEP_STUBS);
returnInformation(plugin, information);
return plugin;
}
private AvailablePlugin createAvailable(PluginInformation information) {
AvailablePluginDescriptor descriptor = mock(AvailablePluginDescriptor.class);
lenient().when(descriptor.getInformation()).thenReturn(information);
return new AvailablePlugin(descriptor);
}
private void returnInformation(Plugin mockedPlugin, PluginInformation information) {
when(mockedPlugin.getDescriptor().getInformation()).thenReturn(information);
}
}

View File

@@ -0,0 +1,37 @@
package sonia.scm.plugin;
import org.mockito.Answers;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class PluginTestHelper {
public static AvailablePlugin createAvailable(String name) {
PluginInformation information = new PluginInformation();
information.setName(name);
return createAvailable(information);
}
public static InstalledPlugin createInstalled(String name) {
PluginInformation information = new PluginInformation();
information.setName(name);
return createInstalled(information);
}
public static InstalledPlugin createInstalled(PluginInformation information) {
InstalledPlugin plugin = mock(InstalledPlugin.class, Answers.RETURNS_DEEP_STUBS);
returnInformation(plugin, information);
return plugin;
}
public static AvailablePlugin createAvailable(PluginInformation information) {
AvailablePluginDescriptor descriptor = mock(AvailablePluginDescriptor.class);
lenient().when(descriptor.getInformation()).thenReturn(information);
return new AvailablePlugin(descriptor);
}
private static void returnInformation(Plugin mockedPlugin, PluginInformation information) {
when(mockedPlugin.getDescriptor().getInformation()).thenReturn(information);
}
}