add collection update link if atleast one plugin is updatable

This commit is contained in:
Eduard Heimbuch
2019-09-27 16:07:25 +02:00
parent 2acad5936b
commit e1dd393cce
4 changed files with 41 additions and 11 deletions

View File

@@ -73,6 +73,13 @@ public interface PluginManager {
*/ */
List<AvailablePlugin> getAvailable(); List<AvailablePlugin> getAvailable();
/**
* Returns all updatable plugins.
*
* @return a list of updatable plugins.
*/
List<InstalledPlugin> getUpdatable();
/** /**
* Installs the plugin with the given name from the list of available plugins. * Installs the plugin with the given name from the list of available plugins.
* *

View File

@@ -3,16 +3,15 @@ package sonia.scm.api.v2.resources;
import com.google.inject.Inject; import com.google.inject.Inject;
import de.otto.edison.hal.Embedded; import de.otto.edison.hal.Embedded;
import de.otto.edison.hal.HalRepresentation; import de.otto.edison.hal.HalRepresentation;
import de.otto.edison.hal.Link;
import de.otto.edison.hal.Links; import de.otto.edison.hal.Links;
import sonia.scm.plugin.AvailablePlugin; import sonia.scm.plugin.AvailablePlugin;
import sonia.scm.plugin.InstalledPlugin; import sonia.scm.plugin.InstalledPlugin;
import sonia.scm.plugin.PluginPermissions; import sonia.scm.plugin.PluginManager;
import java.util.List; import java.util.List;
import static de.otto.edison.hal.Embedded.embeddedBuilder; import static de.otto.edison.hal.Embedded.embeddedBuilder;
import static de.otto.edison.hal.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;
import static java.util.stream.Collectors.toList; import static java.util.stream.Collectors.toList;
@@ -20,11 +19,13 @@ public class PluginDtoCollectionMapper {
private final ResourceLinks resourceLinks; private final ResourceLinks resourceLinks;
private final PluginDtoMapper mapper; private final PluginDtoMapper mapper;
private final PluginManager manager;
@Inject @Inject
public PluginDtoCollectionMapper(ResourceLinks resourceLinks, PluginDtoMapper mapper) { public PluginDtoCollectionMapper(ResourceLinks resourceLinks, PluginDtoMapper mapper, PluginManager manager) {
this.resourceLinks = resourceLinks; this.resourceLinks = resourceLinks;
this.mapper = mapper; this.mapper = mapper;
this.manager = manager;
} }
public HalRepresentation mapInstalled(List<InstalledPlugin> plugins, List<AvailablePlugin> availablePlugins) { public HalRepresentation mapInstalled(List<InstalledPlugin> plugins, List<AvailablePlugin> availablePlugins) {
@@ -46,7 +47,9 @@ public class PluginDtoCollectionMapper {
Links.Builder linksBuilder = linkingTo() Links.Builder linksBuilder = linkingTo()
.with(Links.linkingTo().self(baseUrl).build()); .with(Links.linkingTo().self(baseUrl).build());
if (!manager.getUpdatable().isEmpty()) {
linksBuilder.single(link("update", resourceLinks.installedPluginCollection().update())); linksBuilder.single(link("update", resourceLinks.installedPluginCollection().update()));
}
return linksBuilder.build(); return linksBuilder.build();
} }

View File

@@ -139,6 +139,14 @@ public class DefaultPluginManager implements PluginManager {
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
@Override
public List<InstalledPlugin> getUpdatable() {
return getInstalled()
.stream()
.filter(p -> isUpdatable(p.getDescriptor().getInformation().getName()))
.collect(Collectors.toList());
}
private <T extends Plugin> Predicate<T> filterByName(String name) { private <T extends Plugin> Predicate<T> filterByName(String name) {
return plugin -> name.equals(plugin.getDescriptor().getInformation().getName()); return plugin -> name.equals(plugin.getDescriptor().getInformation().getName());
} }

View File

@@ -10,15 +10,19 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks; import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.junit.jupiter.MockitoExtension;
import sonia.scm.plugin.AvailablePlugin; import sonia.scm.plugin.AvailablePlugin;
import sonia.scm.plugin.AvailablePluginDescriptor; import sonia.scm.plugin.AvailablePluginDescriptor;
import sonia.scm.plugin.InstalledPlugin; import sonia.scm.plugin.InstalledPlugin;
import sonia.scm.plugin.InstalledPluginDescriptor; import sonia.scm.plugin.InstalledPluginDescriptor;
import sonia.scm.plugin.PluginInformation; import sonia.scm.plugin.PluginInformation;
import sonia.scm.plugin.PluginManager;
import java.net.URI; import java.net.URI;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
import static java.util.Collections.singletonList; import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
@@ -34,6 +38,9 @@ class PluginDtoCollectionMapperTest {
@InjectMocks @InjectMocks
PluginDtoMapperImpl pluginDtoMapper; PluginDtoMapperImpl pluginDtoMapper;
@Mock
PluginManager manager;
Subject subject = mock(Subject.class); Subject subject = mock(Subject.class);
ThreadState subjectThreadState = new SubjectThreadState(subject); ThreadState subjectThreadState = new SubjectThreadState(subject);
@@ -43,6 +50,11 @@ class PluginDtoCollectionMapperTest {
ThreadContext.bind(subject); ThreadContext.bind(subject);
} }
@BeforeEach
void mockPluginManager() {
lenient().when(manager.getUpdatable()).thenReturn(new ArrayList<>());
}
@AfterEach @AfterEach
public void unbindSubject() { public void unbindSubject() {
ThreadContext.unbindSubject(); ThreadContext.unbindSubject();
@@ -51,7 +63,7 @@ class PluginDtoCollectionMapperTest {
@Test @Test
void shouldMapInstalledPluginsWithoutUpdateWhenNoNewerVersionIsAvailable() { void shouldMapInstalledPluginsWithoutUpdateWhenNoNewerVersionIsAvailable() {
PluginDtoCollectionMapper mapper = new PluginDtoCollectionMapper(resourceLinks, pluginDtoMapper); PluginDtoCollectionMapper mapper = new PluginDtoCollectionMapper(resourceLinks, pluginDtoMapper, manager);
HalRepresentation result = mapper.mapInstalled( HalRepresentation result = mapper.mapInstalled(
singletonList(createInstalledPlugin("scm-some-plugin", "1")), singletonList(createInstalledPlugin("scm-some-plugin", "1")),
@@ -66,7 +78,7 @@ class PluginDtoCollectionMapperTest {
@Test @Test
void shouldSetNewVersionInInstalledPluginWhenAvailableVersionIsNewer() { void shouldSetNewVersionInInstalledPluginWhenAvailableVersionIsNewer() {
PluginDtoCollectionMapper mapper = new PluginDtoCollectionMapper(resourceLinks, pluginDtoMapper); PluginDtoCollectionMapper mapper = new PluginDtoCollectionMapper(resourceLinks, pluginDtoMapper,manager);
HalRepresentation result = mapper.mapInstalled( HalRepresentation result = mapper.mapInstalled(
singletonList(createInstalledPlugin("scm-some-plugin", "1")), singletonList(createInstalledPlugin("scm-some-plugin", "1")),
@@ -80,7 +92,7 @@ class PluginDtoCollectionMapperTest {
@Test @Test
void shouldNotAddInstallLinkForNewVersionWhenNotPermitted() { void shouldNotAddInstallLinkForNewVersionWhenNotPermitted() {
when(subject.isPermitted("plugin:manage")).thenReturn(false); when(subject.isPermitted("plugin:manage")).thenReturn(false);
PluginDtoCollectionMapper mapper = new PluginDtoCollectionMapper(resourceLinks, pluginDtoMapper); PluginDtoCollectionMapper mapper = new PluginDtoCollectionMapper(resourceLinks, pluginDtoMapper, manager);
HalRepresentation result = mapper.mapInstalled( HalRepresentation result = mapper.mapInstalled(
singletonList(createInstalledPlugin("scm-some-plugin", "1")), singletonList(createInstalledPlugin("scm-some-plugin", "1")),
@@ -93,7 +105,7 @@ class PluginDtoCollectionMapperTest {
@Test @Test
void shouldNotAddInstallLinkForNewVersionWhenInstallationIsPending() { void shouldNotAddInstallLinkForNewVersionWhenInstallationIsPending() {
when(subject.isPermitted("plugin:manage")).thenReturn(true); when(subject.isPermitted("plugin:manage")).thenReturn(true);
PluginDtoCollectionMapper mapper = new PluginDtoCollectionMapper(resourceLinks, pluginDtoMapper); PluginDtoCollectionMapper mapper = new PluginDtoCollectionMapper(resourceLinks, pluginDtoMapper, manager);
AvailablePlugin availablePlugin = createAvailablePlugin("scm-some-plugin", "2"); AvailablePlugin availablePlugin = createAvailablePlugin("scm-some-plugin", "2");
when(availablePlugin.isPending()).thenReturn(true); when(availablePlugin.isPending()).thenReturn(true);
@@ -108,7 +120,7 @@ class PluginDtoCollectionMapperTest {
@Test @Test
void shouldAddInstallLinkForNewVersionWhenPermitted() { void shouldAddInstallLinkForNewVersionWhenPermitted() {
when(subject.isPermitted("plugin:manage")).thenReturn(true); when(subject.isPermitted("plugin:manage")).thenReturn(true);
PluginDtoCollectionMapper mapper = new PluginDtoCollectionMapper(resourceLinks, pluginDtoMapper); PluginDtoCollectionMapper mapper = new PluginDtoCollectionMapper(resourceLinks, pluginDtoMapper, manager);
HalRepresentation result = mapper.mapInstalled( HalRepresentation result = mapper.mapInstalled(
singletonList(createInstalledPlugin("scm-some-plugin", "1")), singletonList(createInstalledPlugin("scm-some-plugin", "1")),
@@ -121,7 +133,7 @@ class PluginDtoCollectionMapperTest {
@Test @Test
void shouldSetInstalledPluginPendingWhenCorrespondingAvailablePluginIsPending() { void shouldSetInstalledPluginPendingWhenCorrespondingAvailablePluginIsPending() {
when(subject.isPermitted("plugin:manage")).thenReturn(true); when(subject.isPermitted("plugin:manage")).thenReturn(true);
PluginDtoCollectionMapper mapper = new PluginDtoCollectionMapper(resourceLinks, pluginDtoMapper); PluginDtoCollectionMapper mapper = new PluginDtoCollectionMapper(resourceLinks, pluginDtoMapper, manager);
AvailablePlugin availablePlugin = createAvailablePlugin("scm-some-plugin", "2"); AvailablePlugin availablePlugin = createAvailablePlugin("scm-some-plugin", "2");
when(availablePlugin.isPending()).thenReturn(true); when(availablePlugin.isPending()).thenReturn(true);