diff --git a/scm-core/src/main/java/sonia/scm/BadRequestException.java b/scm-core/src/main/java/sonia/scm/BadRequestException.java index 544ed75a0b..3290e77521 100644 --- a/scm-core/src/main/java/sonia/scm/BadRequestException.java +++ b/scm-core/src/main/java/sonia/scm/BadRequestException.java @@ -6,4 +6,8 @@ public abstract class BadRequestException extends ExceptionWithContext { public BadRequestException(List context, String message) { super(context, message); } + + public BadRequestException(List context, String message, Exception cause) { + super(context, message, cause); + } } diff --git a/scm-core/src/main/java/sonia/scm/repository/spi/ModifyCommandRequest.java b/scm-core/src/main/java/sonia/scm/repository/spi/ModifyCommandRequest.java index a108a73546..d61e17c785 100644 --- a/scm-core/src/main/java/sonia/scm/repository/spi/ModifyCommandRequest.java +++ b/scm-core/src/main/java/sonia/scm/repository/spi/ModifyCommandRequest.java @@ -122,10 +122,12 @@ public class ModifyCommandRequest implements Resetable, Validateable { } void cleanup() { - try { - IOUtil.delete(content); - } catch (IOException e) { - LOG.warn("could not delete temporary file {}", content, e); + if (content.exists()) { + try { + IOUtil.delete(content); + } catch (IOException e) { + LOG.warn("could not delete temporary file {}", content, e); + } } } } diff --git a/scm-ui-components/packages/ui-components/src/Breadcrumb.js b/scm-ui-components/packages/ui-components/src/Breadcrumb.js index d2f3409af6..5b0f151c61 100644 --- a/scm-ui-components/packages/ui-components/src/Breadcrumb.js +++ b/scm-ui-components/packages/ui-components/src/Breadcrumb.js @@ -1,10 +1,9 @@ //@flow import React from "react"; -import { Link } from "react-router-dom"; -import type { Branch, Repository } from "@scm-manager/ui-types"; +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 { } render() { - const { classes, baseUrl, branch, defaultBranch, branches, revision, path, repository } = this.props; + const { + classes, + baseUrl, + branch, + defaultBranch, + branches, + revision, + path, + repository + } = this.props; return ( <>
-

diff --git a/scm-ui-components/packages/ui-components/src/modals/Modal.js b/scm-ui-components/packages/ui-components/src/modals/Modal.js index d0d96977c6..960f8277f0 100644 --- a/scm-ui-components/packages/ui-components/src/modals/Modal.js +++ b/scm-ui-components/packages/ui-components/src/modals/Modal.js @@ -8,13 +8,12 @@ type Props = { body: any, footer?: any, active: boolean, + className?: string }; - - class Modal extends React.Component { 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 { } return ( -
+
diff --git a/scm-ui-components/packages/ui-components/src/validation.js b/scm-ui-components/packages/ui-components/src/validation.js index fcfffcee45..98a36c6f0e 100644 --- a/scm-ui-components/packages/ui-components/src/validation.js +++ b/scm-ui-components/packages/ui-components/src/validation.js @@ -5,7 +5,7 @@ export const isNameValid = (name: string) => { return nameRegex.test(name); }; -const mailRegex = /^[ -~]+@[A-Za-z0-9][\w\-.]*\.[A-Za-z0-9][A-Za-z0-9-]+$/; +const mailRegex = /^[ -~]+@[A-Za-z0-9][\w\-.]*\.[A-Za-z0-9][A-Za-z0-9-]+$/; export const isMailValid = (mail: string) => { return mailRegex.test(mail); @@ -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); +}; diff --git a/scm-ui-components/packages/ui-components/src/validation.test.js b/scm-ui-components/packages/ui-components/src/validation.test.js index d50996ff2b..4af5d755d0 100644 --- a/scm-ui-components/packages/ui-components/src/validation.test.js +++ b/scm-ui-components/packages/ui-components/src/validation.test.js @@ -2,102 +2,117 @@ import * as validator from "./validation"; describe("test name validation", () => { - it("should return false", () => { - // invalid names taken from ValidationUtilTest.java - const invalidNames = [ - "@test", - " test 123", - " test 123 ", - "test 123 ", - "test/123", - "test%123", - "test:123", - "t ", - " t", - " t ", - "", + // invalid names taken from ValidationUtilTest.java + const invalidNames = [ + "@test", + " test 123", + " test 123 ", + "test 123 ", + "test/123", + "test%123", + "test:123", + "t ", + " t", + " t ", + "", - " invalid_name", - "another%one", - "!!!", - "!_!" - ]; - for (let name of invalidNames) { + " invalid_name", + "another%one", + "!!!", + "!_!" + ]; + 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", - "test.git", - "Test123.git", - "Test123-git", - "Test_user-123.git", - "test@scm-manager.de", - "test123", - "tt", - "t", - "valid_name", - "another1", - "stillValid", - "this.one_as-well", - "and@this" - ]; - for (let name of validNames) { + // valid names taken from ValidationUtilTest.java + const validNames = [ + "test", + "test.git", + "Test123.git", + "Test123-git", + "Test_user-123.git", + "test@scm-manager.de", + "test123", + "tt", + "t", + "valid_name", + "another1", + "stillValid", + "this.one_as-well", + "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", - "@ostfalia.de", - "s.sdorra@", - "s.sdorra@ostfalia", - "s.sdorra@ ostfalia.de", - "s.sdorra@[ostfalia.de" - ]; - for (let mail of invalid) { + // invalid taken from ValidationUtilTest.java + const invalid = [ + "ostfalia.de", + "@ostfalia.de", + "s.sdorra@", + "s.sdorra@ostfalia", + "s.sdorra@ ostfalia.de", + "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", - "sdorra@ostfalia.de", - "s.sdorra@hbk-bs.de", - "s.sdorra@gmail.com", - "s.sdorra@t.co", - "s.sdorra@ucla.college", - "s.sdorra@example.xn--p1ai", - "s.sdorra@scm.solutions", - "s'sdorra@scm.solutions", - "\"S Sdorra\"@scm.solutions" - ]; - for (let mail of valid) { + // valid taken from ValidationUtilTest.java + const valid = [ + "s.sdorra@ostfalia.de", + "sdorra@ostfalia.de", + "s.sdorra@hbk-bs.de", + "s.sdorra@gmail.com", + "s.sdorra@t.co", + "s.sdorra@ucla.college", + "s.sdorra@example.xn--p1ai", + "s.sdorra@scm.solutions", + "s'sdorra@scm.solutions", + "\"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) { - expect(validator.isNumberValid(number)).toBe(false); - } - }); - it("should return true", () => { - const valid = ["1", "35", "2", "235", "34.4"]; - for (let number of valid) { + 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); + }); + } + 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); + }); + } }); diff --git a/scm-ui/src/repos/sources/containers/Content.js b/scm-ui/src/repos/sources/containers/Content.js index b9032ae681..4d297c05bc 100644 --- a/scm-ui/src/repos/sources/containers/Content.js +++ b/scm-ui/src/repos/sources/containers/Content.js @@ -106,17 +106,15 @@ class Content extends React.Component {
{selector}
- - - +
diff --git a/scm-ui/src/users/components/userValidation.js b/scm-ui/src/users/components/userValidation.js index c9460fdd50..e53dce229c 100644 --- a/scm-ui/src/users/components/userValidation.js +++ b/scm-ui/src/users/components/userValidation.js @@ -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) { diff --git a/scm-ui/styles/scm.scss b/scm-ui/styles/scm.scss index 48d66e9768..1409e29caf 100644 --- a/scm-ui/styles/scm.scss +++ b/scm-ui/styles/scm.scss @@ -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, diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/InstalledPluginResourceTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/InstalledPluginResourceTest.java index d231bc2cef..e2a23f0d52 100644 --- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/InstalledPluginResourceTest.java +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/InstalledPluginResourceTest.java @@ -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 { diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/PluginDtoMapperTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/PluginDtoMapperTest.java index 1dc5e3d135..5bd7c1199e 100644 --- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/PluginDtoMapperTest.java +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/PluginDtoMapperTest.java @@ -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); - } - } diff --git a/scm-webapp/src/test/java/sonia/scm/plugin/DefaultPluginManagerTest.java b/scm-webapp/src/test/java/sonia/scm/plugin/DefaultPluginManagerTest.java index 6551b7d51d..16e1e2d73a 100644 --- a/scm-webapp/src/test/java/sonia/scm/plugin/DefaultPluginManagerTest.java +++ b/scm-webapp/src/test/java/sonia/scm/plugin/DefaultPluginManagerTest.java @@ -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 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 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 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 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 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); - } - } diff --git a/scm-webapp/src/test/java/sonia/scm/plugin/PluginTestHelper.java b/scm-webapp/src/test/java/sonia/scm/plugin/PluginTestHelper.java new file mode 100644 index 0000000000..7e3577d775 --- /dev/null +++ b/scm-webapp/src/test/java/sonia/scm/plugin/PluginTestHelper.java @@ -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); + } +}