Show updatable plugins

This commit is contained in:
Rene Pfeuffer
2019-09-11 14:51:38 +02:00
parent df78c90510
commit 202a638a0f
9 changed files with 277 additions and 51 deletions

View File

@@ -3,8 +3,8 @@ 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 sonia.scm.plugin.AvailablePlugin;
import sonia.scm.plugin.InstalledPlugin; import sonia.scm.plugin.InstalledPlugin;
import sonia.scm.plugin.InstalledPluginDescriptor;
import sonia.scm.plugin.PluginManager; import sonia.scm.plugin.PluginManager;
import sonia.scm.plugin.PluginPermissions; import sonia.scm.plugin.PluginPermissions;
import sonia.scm.web.VndMediaType; import sonia.scm.web.VndMediaType;
@@ -50,7 +50,8 @@ public class InstalledPluginResource {
public Response getInstalledPlugins() { public Response getInstalledPlugins() {
PluginPermissions.read().check(); PluginPermissions.read().check();
List<InstalledPlugin> plugins = pluginManager.getInstalled(); List<InstalledPlugin> plugins = pluginManager.getInstalled();
return Response.ok(collectionMapper.mapInstalled(plugins)).build(); List<AvailablePlugin> available = pluginManager.getAvailable();
return Response.ok(collectionMapper.mapInstalled(plugins, available)).build();
} }
/** /**
@@ -72,8 +73,9 @@ public class InstalledPluginResource {
public Response getInstalledPlugin(@PathParam("name") String name) { public Response getInstalledPlugin(@PathParam("name") String name) {
PluginPermissions.read().check(); PluginPermissions.read().check();
Optional<InstalledPlugin> pluginDto = pluginManager.getInstalled(name); Optional<InstalledPlugin> pluginDto = pluginManager.getInstalled(name);
List<AvailablePlugin> available = pluginManager.getAvailable();
if (pluginDto.isPresent()) { if (pluginDto.isPresent()) {
return Response.ok(mapper.mapInstalled(pluginDto.get())).build(); return Response.ok(mapper.mapInstalled(pluginDto.get(), available)).build();
} else { } else {
throw notFound(entity("Plugin", name)); throw notFound(entity("Plugin", name));
} }

View File

@@ -1,5 +1,6 @@
package sonia.scm.api.v2.resources; package sonia.scm.api.v2.resources;
import com.fasterxml.jackson.annotation.JsonInclude;
import de.otto.edison.hal.HalRepresentation; import de.otto.edison.hal.HalRepresentation;
import de.otto.edison.hal.Links; import de.otto.edison.hal.Links;
import lombok.Getter; import lombok.Getter;
@@ -16,6 +17,8 @@ public class PluginDto extends HalRepresentation {
private String name; private String name;
private String version; private String version;
@JsonInclude(JsonInclude.Include.NON_NULL)
private String newVersion;
private String displayName; private String displayName;
private String description; private String description;
private String author; private String author;

View File

@@ -26,8 +26,11 @@ public class PluginDtoCollectionMapper {
this.mapper = mapper; this.mapper = mapper;
} }
public HalRepresentation mapInstalled(List<InstalledPlugin> plugins) { public HalRepresentation mapInstalled(List<InstalledPlugin> plugins, List<AvailablePlugin> availablePlugins) {
List<PluginDto> dtos = plugins.stream().map(mapper::mapInstalled).collect(toList()); List<PluginDto> dtos = plugins
.stream()
.map(i -> mapper.mapInstalled(i, availablePlugins))
.collect(toList());
return new HalRepresentation(createInstalledPluginsLinks(), embedDtos(dtos)); return new HalRepresentation(createInstalledPluginsLinks(), embedDtos(dtos));
} }

View File

@@ -11,6 +11,9 @@ import sonia.scm.plugin.PluginPermissions;
import javax.inject.Inject; import javax.inject.Inject;
import java.util.List;
import java.util.Optional;
import static de.otto.edison.hal.Link.link; import static de.otto.edison.hal.Link.link;
import static de.otto.edison.hal.Links.linkingTo; import static de.otto.edison.hal.Links.linkingTo;
@@ -22,8 +25,8 @@ public abstract class PluginDtoMapper {
public abstract void map(PluginInformation plugin, @MappingTarget PluginDto dto); public abstract void map(PluginInformation plugin, @MappingTarget PluginDto dto);
public PluginDto mapInstalled(InstalledPlugin plugin) { public PluginDto mapInstalled(InstalledPlugin plugin, List<AvailablePlugin> availablePlugins) {
PluginDto dto = createDtoForInstalled(plugin); PluginDto dto = createDtoForInstalled(plugin, availablePlugins);
map(dto, plugin); map(dto, plugin);
return dto; return dto;
} }
@@ -57,13 +60,33 @@ public abstract class PluginDtoMapper {
return new PluginDto(links.build()); return new PluginDto(links.build());
} }
private PluginDto createDtoForInstalled(InstalledPlugin plugin) { private PluginDto createDtoForInstalled(InstalledPlugin plugin, List<AvailablePlugin> availablePlugins) {
PluginInformation information = plugin.getDescriptor().getInformation(); PluginInformation information = plugin.getDescriptor().getInformation();
Optional<AvailablePlugin> availablePlugin = checkForUpdates(plugin, availablePlugins);
Links.Builder links = linkingTo() Links.Builder links = linkingTo()
.self(resourceLinks.installedPlugin() .self(resourceLinks.installedPlugin()
.self(information.getName())); .self(information.getName()));
if (availablePlugin.isPresent()
&& !availablePlugin.get().isPending()
&& PluginPermissions.manage().isPermitted()
) {
links.single(link("update", resourceLinks.availablePlugin().install(information.getName())));
}
return new PluginDto(links.build()); PluginDto dto = new PluginDto(links.build());
availablePlugin.ifPresent(value -> {
dto.setNewVersion(value.getDescriptor().getInformation().getVersion());
dto.setPending(value.isPending());
});
return dto;
}
private Optional<AvailablePlugin> checkForUpdates(InstalledPlugin plugin, List<AvailablePlugin> availablePlugins) {
return availablePlugins.stream()
.filter(a -> a.getDescriptor().getInformation().getName().equals(plugin.getDescriptor().getInformation().getName()))
.findAny();
} }
} }

View File

@@ -42,6 +42,7 @@ import org.slf4j.LoggerFactory;
import sonia.scm.NotFoundException; import sonia.scm.NotFoundException;
import sonia.scm.event.ScmEventBus; import sonia.scm.event.ScmEventBus;
import sonia.scm.lifecycle.RestartEvent; import sonia.scm.lifecycle.RestartEvent;
import sonia.scm.version.Version;
//~--- JDK imports ------------------------------------------------------------ //~--- JDK imports ------------------------------------------------------------
import javax.inject.Inject; import javax.inject.Inject;
@@ -83,7 +84,7 @@ public class DefaultPluginManager implements PluginManager {
return center.getAvailable() return center.getAvailable()
.stream() .stream()
.filter(filterByName(name)) .filter(filterByName(name))
.filter(this::isNotInstalled) .filter(this::isNotInstalledOrMoreUpToDate)
.map(p -> getPending(name).orElse(p)) .map(p -> getPending(name).orElse(p))
.findFirst(); .findFirst();
} }
@@ -116,7 +117,7 @@ public class DefaultPluginManager implements PluginManager {
PluginPermissions.read().check(); PluginPermissions.read().check();
return center.getAvailable() return center.getAvailable()
.stream() .stream()
.filter(this::isNotInstalled) .filter(this::isNotInstalledOrMoreUpToDate)
.map(p -> getPending(p.getDescriptor().getInformation().getName()).orElse(p)) .map(p -> getPending(p.getDescriptor().getInformation().getName()).orElse(p))
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
@@ -125,8 +126,14 @@ public class DefaultPluginManager implements PluginManager {
return plugin -> name.equals(plugin.getDescriptor().getInformation().getName()); return plugin -> name.equals(plugin.getDescriptor().getInformation().getName());
} }
private boolean isNotInstalled(AvailablePlugin availablePlugin) { private boolean isNotInstalledOrMoreUpToDate(AvailablePlugin availablePlugin) {
return !getInstalled(availablePlugin.getDescriptor().getInformation().getName()).isPresent(); return getInstalled(availablePlugin.getDescriptor().getInformation().getName())
.map(installedPlugin -> availableIsMoreUpToDateThanInstalled(availablePlugin, installedPlugin))
.orElse(true);
}
private boolean availableIsMoreUpToDateThanInstalled(AvailablePlugin availablePlugin, InstalledPlugin installed) {
return Version.parse(availablePlugin.getDescriptor().getInformation().getVersion()).isNewer(installed.getDescriptor().getInformation().getVersion());
} }
@Override @Override

View File

@@ -29,6 +29,7 @@ import java.net.URISyntaxException;
import java.util.Collections; import java.util.Collections;
import java.util.Optional; import java.util.Optional;
import static java.util.Collections.emptyList;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
@@ -87,7 +88,7 @@ class InstalledPluginResourceTest {
void getInstalledPlugins() throws URISyntaxException, UnsupportedEncodingException { void getInstalledPlugins() throws URISyntaxException, UnsupportedEncodingException {
InstalledPlugin installedPlugin = createPlugin(); InstalledPlugin installedPlugin = createPlugin();
when(pluginManager.getInstalled()).thenReturn(Collections.singletonList(installedPlugin)); when(pluginManager.getInstalled()).thenReturn(Collections.singletonList(installedPlugin));
when(collectionMapper.mapInstalled(Collections.singletonList(installedPlugin))).thenReturn(new MockedResultDto()); when(collectionMapper.mapInstalled(Collections.singletonList(installedPlugin), Collections.emptyList())).thenReturn(new MockedResultDto());
MockHttpRequest request = MockHttpRequest.get("/v2/plugins/installed"); MockHttpRequest request = MockHttpRequest.get("/v2/plugins/installed");
request.accept(VndMediaType.PLUGIN_COLLECTION); request.accept(VndMediaType.PLUGIN_COLLECTION);
@@ -110,7 +111,7 @@ class InstalledPluginResourceTest {
PluginDto pluginDto = new PluginDto(); PluginDto pluginDto = new PluginDto();
pluginDto.setName("pluginName"); pluginDto.setName("pluginName");
when(mapper.mapInstalled(installedPlugin)).thenReturn(pluginDto); when(mapper.mapInstalled(installedPlugin, emptyList())).thenReturn(pluginDto);
MockHttpRequest request = MockHttpRequest.get("/v2/plugins/installed/pluginName"); MockHttpRequest request = MockHttpRequest.get("/v2/plugins/installed/pluginName");
request.accept(VndMediaType.PLUGIN); request.accept(VndMediaType.PLUGIN);

View File

@@ -0,0 +1,171 @@
package sonia.scm.api.v2.resources;
import de.otto.edison.hal.HalRepresentation;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.subject.support.SubjectThreadState;
import org.apache.shiro.util.ThreadContext;
import org.apache.shiro.util.ThreadState;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.junit.jupiter.MockitoExtension;
import sonia.scm.plugin.AvailablePlugin;
import sonia.scm.plugin.AvailablePluginDescriptor;
import sonia.scm.plugin.InstalledPlugin;
import sonia.scm.plugin.InstalledPluginDescriptor;
import sonia.scm.plugin.PluginInformation;
import java.net.URI;
import java.util.List;
import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class PluginDtoCollectionMapperTest {
ResourceLinks resourceLinks = ResourceLinksMock.createMock(URI.create("/"));
@InjectMocks
PluginDtoMapperImpl pluginDtoMapper;
Subject subject = mock(Subject.class);
ThreadState subjectThreadState = new SubjectThreadState(subject);
@BeforeEach
void bindSubject() {
subjectThreadState.bind();
ThreadContext.bind(subject);
}
@AfterEach
public void unbindSubject() {
ThreadContext.unbindSubject();
}
@Test
void shouldMapInstalledPluginsWithoutUpdateWhenNoNewerVersionIsAvailable() {
PluginDtoCollectionMapper mapper = new PluginDtoCollectionMapper(resourceLinks, pluginDtoMapper);
HalRepresentation result = mapper.mapInstalled(
singletonList(createInstalledPlugin("scm-some-plugin", "1")),
singletonList(createAvailablePlugin("scm-other-plugin", "2")));
List<HalRepresentation> plugins = result.getEmbedded().getItemsBy("plugins");
assertThat(plugins).hasSize(1);
PluginDto plugin = (PluginDto) plugins.get(0);
assertThat(plugin.getVersion()).isEqualTo("1");
assertThat(plugin.getNewVersion()).isNull();
}
@Test
void shouldSetNewVersionInInstalledPluginWhenAvailableVersionIsNewer() {
PluginDtoCollectionMapper mapper = new PluginDtoCollectionMapper(resourceLinks, pluginDtoMapper);
HalRepresentation result = mapper.mapInstalled(
singletonList(createInstalledPlugin("scm-some-plugin", "1")),
singletonList(createAvailablePlugin("scm-some-plugin", "2")));
PluginDto plugin = getPluginDtoFromResult(result);
assertThat(plugin.getVersion()).isEqualTo("1");
assertThat(plugin.getNewVersion()).isEqualTo("2");
}
@Test
void shouldNotAddInstallLinkForNewVersionWhenNotPermitted() {
when(subject.isPermitted("plugin:manage")).thenReturn(false);
PluginDtoCollectionMapper mapper = new PluginDtoCollectionMapper(resourceLinks, pluginDtoMapper);
HalRepresentation result = mapper.mapInstalled(
singletonList(createInstalledPlugin("scm-some-plugin", "1")),
singletonList(createAvailablePlugin("scm-some-plugin", "2")));
PluginDto plugin = getPluginDtoFromResult(result);
assertThat(plugin.getLinks().getLinkBy("update")).isEmpty();
}
@Test
void shouldNotAddInstallLinkForNewVersionWhenInstallationIsPending() {
when(subject.isPermitted("plugin:manage")).thenReturn(true);
PluginDtoCollectionMapper mapper = new PluginDtoCollectionMapper(resourceLinks, pluginDtoMapper);
AvailablePlugin availablePlugin = createAvailablePlugin("scm-some-plugin", "2");
when(availablePlugin.isPending()).thenReturn(true);
HalRepresentation result = mapper.mapInstalled(
singletonList(createInstalledPlugin("scm-some-plugin", "1")),
singletonList(availablePlugin));
PluginDto plugin = getPluginDtoFromResult(result);
assertThat(plugin.getLinks().getLinkBy("update")).isEmpty();
}
@Test
void shouldAddInstallLinkForNewVersionWhenPermitted() {
when(subject.isPermitted("plugin:manage")).thenReturn(true);
PluginDtoCollectionMapper mapper = new PluginDtoCollectionMapper(resourceLinks, pluginDtoMapper);
HalRepresentation result = mapper.mapInstalled(
singletonList(createInstalledPlugin("scm-some-plugin", "1")),
singletonList(createAvailablePlugin("scm-some-plugin", "2")));
PluginDto plugin = getPluginDtoFromResult(result);
assertThat(plugin.getLinks().getLinkBy("update")).isNotEmpty();
}
@Test
void shouldSetInstalledPluginPendingWhenCorrespondingAvailablePluginIsPending() {
when(subject.isPermitted("plugin:manage")).thenReturn(true);
PluginDtoCollectionMapper mapper = new PluginDtoCollectionMapper(resourceLinks, pluginDtoMapper);
AvailablePlugin availablePlugin = createAvailablePlugin("scm-some-plugin", "2");
when(availablePlugin.isPending()).thenReturn(true);
HalRepresentation result = mapper.mapInstalled(
singletonList(createInstalledPlugin("scm-some-plugin", "1")),
singletonList(availablePlugin));
PluginDto plugin = getPluginDtoFromResult(result);
assertThat(plugin.isPending()).isTrue();
}
private PluginDto getPluginDtoFromResult(HalRepresentation result) {
assertThat(result.getEmbedded().getItemsBy("plugins")).hasSize(1);
List<HalRepresentation> plugins = result.getEmbedded().getItemsBy("plugins");
return (PluginDto) plugins.get(0);
}
private InstalledPlugin createInstalledPlugin(String name, String version) {
PluginInformation information = new PluginInformation();
information.setName(name);
information.setVersion(version);
return createInstalledPlugin(information);
}
private InstalledPlugin createInstalledPlugin(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;
}
private AvailablePlugin createAvailablePlugin(String name, String version) {
PluginInformation information = new PluginInformation();
information.setName(name);
information.setVersion(version);
return createAvailablePlugin(information);
}
private AvailablePlugin createAvailablePlugin(PluginInformation information) {
AvailablePlugin plugin = mock(AvailablePlugin.class);
AvailablePluginDescriptor descriptor = mock(AvailablePluginDescriptor.class);
lenient().when(descriptor.getInformation()).thenReturn(information);
lenient().when(plugin.getDescriptor()).thenReturn(descriptor);
return plugin;
}
}

View File

@@ -17,7 +17,9 @@ import sonia.scm.plugin.InstalledPlugin;
import sonia.scm.plugin.PluginInformation; import sonia.scm.plugin.PluginInformation;
import java.net.URI; import java.net.URI;
import java.util.Collections;
import static java.util.Collections.emptyList;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
@@ -74,7 +76,7 @@ class PluginDtoMapperTest {
void shouldAppendInstalledSelfLink() { void shouldAppendInstalledSelfLink() {
InstalledPlugin plugin = createInstalled(); InstalledPlugin plugin = createInstalled();
PluginDto dto = mapper.mapInstalled(plugin); PluginDto dto = mapper.mapInstalled(plugin, emptyList());
assertThat(dto.getLinks().getLinkBy("self").get().getHref()) assertThat(dto.getLinks().getLinkBy("self").get().getHref())
.isEqualTo("https://hitchhiker.com/v2/plugins/installed/scm-cas-plugin"); .isEqualTo("https://hitchhiker.com/v2/plugins/installed/scm-cas-plugin");
} }

View File

@@ -23,7 +23,6 @@ import java.util.List;
import java.util.Optional; import java.util.Optional;
import static org.assertj.core.api.Assertions.assertThat; 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.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.*; import static org.mockito.Mockito.*;
@@ -71,8 +70,8 @@ class DefaultPluginManagerTest {
@Test @Test
void shouldReturnInstalledPlugins() { void shouldReturnInstalledPlugins() {
InstalledPlugin review = createInstalled("scm-review-plugin"); InstalledPlugin review = createInstalled("scm-review-plugin", "1");
InstalledPlugin git = createInstalled("scm-git-plugin"); InstalledPlugin git = createInstalled("scm-git-plugin", "1");
when(loader.getInstalledPlugins()).thenReturn(ImmutableList.of(review, git)); when(loader.getInstalledPlugins()).thenReturn(ImmutableList.of(review, git));
@@ -82,8 +81,8 @@ class DefaultPluginManagerTest {
@Test @Test
void shouldReturnReviewPlugin() { void shouldReturnReviewPlugin() {
InstalledPlugin review = createInstalled("scm-review-plugin"); InstalledPlugin review = createInstalled("scm-review-plugin", "1");
InstalledPlugin git = createInstalled("scm-git-plugin"); InstalledPlugin git = createInstalled("scm-git-plugin", "1");
when(loader.getInstalledPlugins()).thenReturn(ImmutableList.of(review, git)); when(loader.getInstalledPlugins()).thenReturn(ImmutableList.of(review, git));
@@ -101,8 +100,8 @@ class DefaultPluginManagerTest {
@Test @Test
void shouldReturnAvailablePlugins() { void shouldReturnAvailablePlugins() {
AvailablePlugin review = createAvailable("scm-review-plugin"); AvailablePlugin review = createAvailable("scm-review-plugin", "1");
AvailablePlugin git = createAvailable("scm-git-plugin"); AvailablePlugin git = createAvailable("scm-git-plugin", "1");
when(center.getAvailable()).thenReturn(ImmutableSet.of(review, git)); when(center.getAvailable()).thenReturn(ImmutableSet.of(review, git));
@@ -111,22 +110,35 @@ class DefaultPluginManagerTest {
} }
@Test @Test
void shouldFilterOutAllInstalled() { void shouldFilterOutAllInstalledWithSameVersion() {
InstalledPlugin installedGit = createInstalled("scm-git-plugin"); InstalledPlugin installedGit = createInstalled("scm-git-plugin", "1");
when(loader.getInstalledPlugins()).thenReturn(ImmutableList.of(installedGit)); when(loader.getInstalledPlugins()).thenReturn(ImmutableList.of(installedGit));
AvailablePlugin review = createAvailable("scm-review-plugin"); AvailablePlugin review = createAvailable("scm-review-plugin", "1");
AvailablePlugin git = createAvailable("scm-git-plugin"); AvailablePlugin git = createAvailable("scm-git-plugin", "1");
when(center.getAvailable()).thenReturn(ImmutableSet.of(review, git)); when(center.getAvailable()).thenReturn(ImmutableSet.of(review, git));
List<AvailablePlugin> available = manager.getAvailable(); List<AvailablePlugin> available = manager.getAvailable();
assertThat(available).containsOnly(review); 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 @Test
void shouldReturnAvailable() { void shouldReturnAvailable() {
AvailablePlugin review = createAvailable("scm-review-plugin"); AvailablePlugin review = createAvailable("scm-review-plugin", "1");
AvailablePlugin git = createAvailable("scm-git-plugin"); AvailablePlugin git = createAvailable("scm-git-plugin", "1");
when(center.getAvailable()).thenReturn(ImmutableSet.of(review, git)); when(center.getAvailable()).thenReturn(ImmutableSet.of(review, git));
Optional<AvailablePlugin> available = manager.getAvailable("scm-git-plugin"); Optional<AvailablePlugin> available = manager.getAvailable("scm-git-plugin");
@@ -135,7 +147,7 @@ class DefaultPluginManagerTest {
@Test @Test
void shouldReturnEmptyForNonExistingAvailable() { void shouldReturnEmptyForNonExistingAvailable() {
AvailablePlugin review = createAvailable("scm-review-plugin"); AvailablePlugin review = createAvailable("scm-review-plugin", "1");
when(center.getAvailable()).thenReturn(ImmutableSet.of(review)); when(center.getAvailable()).thenReturn(ImmutableSet.of(review));
Optional<AvailablePlugin> available = manager.getAvailable("scm-git-plugin"); Optional<AvailablePlugin> available = manager.getAvailable("scm-git-plugin");
@@ -144,10 +156,10 @@ class DefaultPluginManagerTest {
@Test @Test
void shouldReturnEmptyForInstalledPlugin() { void shouldReturnEmptyForInstalledPlugin() {
InstalledPlugin installedGit = createInstalled("scm-git-plugin"); InstalledPlugin installedGit = createInstalled("scm-git-plugin", "1");
when(loader.getInstalledPlugins()).thenReturn(ImmutableList.of(installedGit)); when(loader.getInstalledPlugins()).thenReturn(ImmutableList.of(installedGit));
AvailablePlugin git = createAvailable("scm-git-plugin"); AvailablePlugin git = createAvailable("scm-git-plugin", "1");
when(center.getAvailable()).thenReturn(ImmutableSet.of(git)); when(center.getAvailable()).thenReturn(ImmutableSet.of(git));
Optional<AvailablePlugin> available = manager.getAvailable("scm-git-plugin"); Optional<AvailablePlugin> available = manager.getAvailable("scm-git-plugin");
@@ -156,7 +168,7 @@ class DefaultPluginManagerTest {
@Test @Test
void shouldInstallThePlugin() { void shouldInstallThePlugin() {
AvailablePlugin git = createAvailable("scm-git-plugin"); AvailablePlugin git = createAvailable("scm-git-plugin", "1");
when(center.getAvailable()).thenReturn(ImmutableSet.of(git)); when(center.getAvailable()).thenReturn(ImmutableSet.of(git));
manager.install("scm-git-plugin", false); manager.install("scm-git-plugin", false);
@@ -167,9 +179,9 @@ class DefaultPluginManagerTest {
@Test @Test
void shouldInstallDependingPlugins() { void shouldInstallDependingPlugins() {
AvailablePlugin review = createAvailable("scm-review-plugin"); AvailablePlugin review = createAvailable("scm-review-plugin", "1");
when(review.getDescriptor().getDependencies()).thenReturn(ImmutableSet.of("scm-mail-plugin")); when(review.getDescriptor().getDependencies()).thenReturn(ImmutableSet.of("scm-mail-plugin"));
AvailablePlugin mail = createAvailable("scm-mail-plugin"); AvailablePlugin mail = createAvailable("scm-mail-plugin", "1");
when(center.getAvailable()).thenReturn(ImmutableSet.of(review, mail)); when(center.getAvailable()).thenReturn(ImmutableSet.of(review, mail));
manager.install("scm-review-plugin", false); manager.install("scm-review-plugin", false);
@@ -180,12 +192,12 @@ class DefaultPluginManagerTest {
@Test @Test
void shouldNotInstallAlreadyInstalledDependencies() { void shouldNotInstallAlreadyInstalledDependencies() {
AvailablePlugin review = createAvailable("scm-review-plugin"); AvailablePlugin review = createAvailable("scm-review-plugin", "1");
when(review.getDescriptor().getDependencies()).thenReturn(ImmutableSet.of("scm-mail-plugin")); when(review.getDescriptor().getDependencies()).thenReturn(ImmutableSet.of("scm-mail-plugin"));
AvailablePlugin mail = createAvailable("scm-mail-plugin"); AvailablePlugin mail = createAvailable("scm-mail-plugin", "1");
when(center.getAvailable()).thenReturn(ImmutableSet.of(review, mail)); when(center.getAvailable()).thenReturn(ImmutableSet.of(review, mail));
InstalledPlugin installedMail = createInstalled("scm-mail-plugin"); InstalledPlugin installedMail = createInstalled("scm-mail-plugin", "1");
when(loader.getInstalledPlugins()).thenReturn(ImmutableList.of(installedMail)); when(loader.getInstalledPlugins()).thenReturn(ImmutableList.of(installedMail));
manager.install("scm-review-plugin", false); manager.install("scm-review-plugin", false);
@@ -198,11 +210,11 @@ class DefaultPluginManagerTest {
@Test @Test
void shouldRollbackOnFailedInstallation() { void shouldRollbackOnFailedInstallation() {
AvailablePlugin review = createAvailable("scm-review-plugin"); AvailablePlugin review = createAvailable("scm-review-plugin", "1");
when(review.getDescriptor().getDependencies()).thenReturn(ImmutableSet.of("scm-mail-plugin")); when(review.getDescriptor().getDependencies()).thenReturn(ImmutableSet.of("scm-mail-plugin"));
AvailablePlugin mail = createAvailable("scm-mail-plugin"); AvailablePlugin mail = createAvailable("scm-mail-plugin", "1");
when(mail.getDescriptor().getDependencies()).thenReturn(ImmutableSet.of("scm-notification-plugin")); when(mail.getDescriptor().getDependencies()).thenReturn(ImmutableSet.of("scm-notification-plugin"));
AvailablePlugin notification = createAvailable("scm-notification-plugin"); AvailablePlugin notification = createAvailable("scm-notification-plugin", "1");
when(center.getAvailable()).thenReturn(ImmutableSet.of(review, mail, notification)); when(center.getAvailable()).thenReturn(ImmutableSet.of(review, mail, notification));
PendingPluginInstallation pendingNotification = mock(PendingPluginInstallation.class); PendingPluginInstallation pendingNotification = mock(PendingPluginInstallation.class);
@@ -221,9 +233,9 @@ class DefaultPluginManagerTest {
@Test @Test
void shouldInstallNothingIfOneOfTheDependenciesIsNotAvailable() { void shouldInstallNothingIfOneOfTheDependenciesIsNotAvailable() {
AvailablePlugin review = createAvailable("scm-review-plugin"); AvailablePlugin review = createAvailable("scm-review-plugin", "1");
when(review.getDescriptor().getDependencies()).thenReturn(ImmutableSet.of("scm-mail-plugin")); when(review.getDescriptor().getDependencies()).thenReturn(ImmutableSet.of("scm-mail-plugin"));
AvailablePlugin mail = createAvailable("scm-mail-plugin"); AvailablePlugin mail = createAvailable("scm-mail-plugin", "1");
when(mail.getDescriptor().getDependencies()).thenReturn(ImmutableSet.of("scm-notification-plugin")); when(mail.getDescriptor().getDependencies()).thenReturn(ImmutableSet.of("scm-notification-plugin"));
when(center.getAvailable()).thenReturn(ImmutableSet.of(review, mail)); when(center.getAvailable()).thenReturn(ImmutableSet.of(review, mail));
@@ -234,7 +246,7 @@ class DefaultPluginManagerTest {
@Test @Test
void shouldSendRestartEventAfterInstallation() { void shouldSendRestartEventAfterInstallation() {
AvailablePlugin git = createAvailable("scm-git-plugin"); AvailablePlugin git = createAvailable("scm-git-plugin", "1");
when(center.getAvailable()).thenReturn(ImmutableSet.of(git)); when(center.getAvailable()).thenReturn(ImmutableSet.of(git));
manager.install("scm-git-plugin", true); manager.install("scm-git-plugin", true);
@@ -245,7 +257,7 @@ class DefaultPluginManagerTest {
@Test @Test
void shouldNotSendRestartEventIfNoPluginWasInstalled() { void shouldNotSendRestartEventIfNoPluginWasInstalled() {
InstalledPlugin gitInstalled = createInstalled("scm-git-plugin"); InstalledPlugin gitInstalled = createInstalled("scm-git-plugin", "1");
when(loader.getInstalledPlugins()).thenReturn(ImmutableList.of(gitInstalled)); when(loader.getInstalledPlugins()).thenReturn(ImmutableList.of(gitInstalled));
manager.install("scm-git-plugin", true); manager.install("scm-git-plugin", true);
@@ -254,7 +266,7 @@ class DefaultPluginManagerTest {
@Test @Test
void shouldNotInstallAlreadyPendingPlugins() { void shouldNotInstallAlreadyPendingPlugins() {
AvailablePlugin review = createAvailable("scm-review-plugin"); AvailablePlugin review = createAvailable("scm-review-plugin", "1");
when(center.getAvailable()).thenReturn(ImmutableSet.of(review)); when(center.getAvailable()).thenReturn(ImmutableSet.of(review));
manager.install("scm-review-plugin", false); manager.install("scm-review-plugin", false);
@@ -265,7 +277,7 @@ class DefaultPluginManagerTest {
@Test @Test
void shouldSendRestartEvent() { void shouldSendRestartEvent() {
AvailablePlugin review = createAvailable("scm-review-plugin"); AvailablePlugin review = createAvailable("scm-review-plugin", "1");
when(center.getAvailable()).thenReturn(ImmutableSet.of(review)); when(center.getAvailable()).thenReturn(ImmutableSet.of(review));
manager.install("scm-review-plugin", false); manager.install("scm-review-plugin", false);
@@ -283,7 +295,7 @@ class DefaultPluginManagerTest {
@Test @Test
void shouldReturnSingleAvailableAsPending() { void shouldReturnSingleAvailableAsPending() {
AvailablePlugin review = createAvailable("scm-review-plugin"); AvailablePlugin review = createAvailable("scm-review-plugin", "1");
when(center.getAvailable()).thenReturn(ImmutableSet.of(review)); when(center.getAvailable()).thenReturn(ImmutableSet.of(review));
manager.install("scm-review-plugin", false); manager.install("scm-review-plugin", false);
@@ -294,7 +306,7 @@ class DefaultPluginManagerTest {
@Test @Test
void shouldReturnAvailableAsPending() { void shouldReturnAvailableAsPending() {
AvailablePlugin review = createAvailable("scm-review-plugin"); AvailablePlugin review = createAvailable("scm-review-plugin", "1");
when(center.getAvailable()).thenReturn(ImmutableSet.of(review)); when(center.getAvailable()).thenReturn(ImmutableSet.of(review));
manager.install("scm-review-plugin", false); manager.install("scm-review-plugin", false);
@@ -355,15 +367,17 @@ class DefaultPluginManagerTest {
} }
private AvailablePlugin createAvailable(String name) { private AvailablePlugin createAvailable(String name, String version) {
PluginInformation information = new PluginInformation(); PluginInformation information = new PluginInformation();
information.setName(name); information.setName(name);
information.setVersion(version);
return createAvailable(information); return createAvailable(information);
} }
private InstalledPlugin createInstalled(String name) { private InstalledPlugin createInstalled(String name, String version) {
PluginInformation information = new PluginInformation(); PluginInformation information = new PluginInformation();
information.setName(name); information.setName(name);
information.setVersion(version);
return createInstalled(information); return createInstalled(information);
} }