Return pending plugins in endpoint

This commit is contained in:
Rene Pfeuffer
2019-09-13 14:44:32 +02:00
parent 0ceb1ad295
commit 2e42d8be91
2 changed files with 74 additions and 11 deletions

View File

@@ -6,6 +6,7 @@ import de.otto.edison.hal.Embedded;
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 sonia.scm.plugin.AvailablePlugin; import sonia.scm.plugin.AvailablePlugin;
import sonia.scm.plugin.InstalledPlugin;
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;
@@ -16,7 +17,9 @@ import javax.ws.rs.POST;
import javax.ws.rs.Path; import javax.ws.rs.Path;
import javax.ws.rs.Produces; import javax.ws.rs.Produces;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.stream.Stream;
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;
@@ -50,6 +53,14 @@ public class PendingPluginResource {
.stream() .stream()
.filter(AvailablePlugin::isPending) .filter(AvailablePlugin::isPending)
.collect(toList()); .collect(toList());
List<InstalledPlugin> installed = pluginManager.getInstalled();
Stream<AvailablePlugin> newPlugins = pending
.stream()
.filter(a -> !contains(installed, a));
Stream<InstalledPlugin> updatePlugins = installed
.stream()
.filter(i -> contains(pending, i));
Links.Builder linksBuilder = linkingTo().self(resourceLinks.pendingPluginCollection().self()); Links.Builder linksBuilder = linkingTo().self(resourceLinks.pendingPluginCollection().self());
@@ -58,11 +69,28 @@ public class PendingPluginResource {
} }
Embedded.Builder embedded = Embedded.embeddedBuilder(); Embedded.Builder embedded = Embedded.embeddedBuilder();
embedded.with("available", pending.stream().map(mapper::mapAvailable).collect(toList())); embedded.with("new", newPlugins.map(mapper::mapAvailable).collect(toList()));
embedded.with("update", updatePlugins.map(i -> mapper.mapInstalled(i, pending)).collect(toList()));
return Response.ok(new HalRepresentation(linksBuilder.build(), embedded.build())).build(); return Response.ok(new HalRepresentation(linksBuilder.build(), embedded.build())).build();
} }
private boolean contains(Collection<InstalledPlugin> installedPlugins, AvailablePlugin availablePlugin) {
return installedPlugins
.stream()
.anyMatch(installedPlugin -> haveSameName(installedPlugin, availablePlugin));
}
private boolean contains(Collection<AvailablePlugin> availablePlugins, InstalledPlugin installedPlugin) {
return availablePlugins
.stream()
.anyMatch(availablePlugin -> haveSameName(installedPlugin, availablePlugin));
}
private boolean haveSameName(InstalledPlugin installedPlugin, AvailablePlugin availablePlugin) {
return installedPlugin.getDescriptor().getInformation().getName().equals(availablePlugin.getDescriptor().getInformation().getName());
}
@POST @POST
@Path("/install") @Path("/install")
@StatusCodes({ @StatusCodes({

View File

@@ -18,7 +18,8 @@ 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.PluginCondition; import sonia.scm.plugin.InstalledPlugin;
import sonia.scm.plugin.InstalledPluginDescriptor;
import sonia.scm.plugin.PluginInformation; import sonia.scm.plugin.PluginInformation;
import sonia.scm.plugin.PluginManager; import sonia.scm.plugin.PluginManager;
@@ -27,7 +28,6 @@ import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper; import javax.ws.rs.ext.ExceptionMapper;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.util.Collections;
import static java.net.URI.create; import static java.net.URI.create;
import static java.util.Collections.singletonList; import static java.util.Collections.singletonList;
@@ -76,6 +76,11 @@ class PendingPluginResourceTest {
dto.setName(((AvailablePlugin)invocation.getArgument(0)).getDescriptor().getInformation().getName()); dto.setName(((AvailablePlugin)invocation.getArgument(0)).getDescriptor().getInformation().getName());
return dto; return dto;
}); });
lenient().when(mapper.mapInstalled(any(), any())).thenAnswer(invocation -> {
PluginDto dto = new PluginDto();
dto.setName(((InstalledPlugin)invocation.getArgument(0)).getDescriptor().getInformation().getName());
return dto;
});
} }
@Nested @Nested
@@ -94,7 +99,7 @@ class PendingPluginResourceTest {
@Test @Test
void shouldGetEmptyPluginListsWithoutInstallLinkWhenNoPendingPluginsPresent() throws URISyntaxException, UnsupportedEncodingException { void shouldGetEmptyPluginListsWithoutInstallLinkWhenNoPendingPluginsPresent() throws URISyntaxException, UnsupportedEncodingException {
AvailablePlugin availablePlugin = createAvailablePlugin("not-available-plugin"); AvailablePlugin availablePlugin = createAvailablePlugin("not-pending-plugin");
when(availablePlugin.isPending()).thenReturn(false); when(availablePlugin.isPending()).thenReturn(false);
when(pluginManager.getAvailable()).thenReturn(singletonList(availablePlugin)); when(pluginManager.getAvailable()).thenReturn(singletonList(availablePlugin));
@@ -103,12 +108,12 @@ class PendingPluginResourceTest {
assertThat(response.getStatus()).isEqualTo(HttpServletResponse.SC_OK); assertThat(response.getStatus()).isEqualTo(HttpServletResponse.SC_OK);
assertThat(response.getContentAsString()).contains("\"_links\":{\"self\":{\"href\":\"/v2/plugins/pending\"}}"); assertThat(response.getContentAsString()).contains("\"_links\":{\"self\":{\"href\":\"/v2/plugins/pending\"}}");
assertThat(response.getContentAsString()).doesNotContain("not-available-plugin"); assertThat(response.getContentAsString()).doesNotContain("not-pending-plugin");
} }
@Test @Test
void shouldGetPendingAvailablePluginListsWithInstallLink() throws URISyntaxException, UnsupportedEncodingException { void shouldGetPendingAvailablePluginListWithInstallLink() throws URISyntaxException, UnsupportedEncodingException {
AvailablePlugin availablePlugin = createAvailablePlugin("available-plugin"); AvailablePlugin availablePlugin = createAvailablePlugin("pending-available-plugin");
when(availablePlugin.isPending()).thenReturn(true); when(availablePlugin.isPending()).thenReturn(true);
when(pluginManager.getAvailable()).thenReturn(singletonList(availablePlugin)); when(pluginManager.getAvailable()).thenReturn(singletonList(availablePlugin));
@@ -116,7 +121,24 @@ class PendingPluginResourceTest {
dispatcher.invoke(request, response); dispatcher.invoke(request, response);
assertThat(response.getStatus()).isEqualTo(HttpServletResponse.SC_OK); assertThat(response.getStatus()).isEqualTo(HttpServletResponse.SC_OK);
assertThat(response.getContentAsString()).contains("\"_embedded\":{\"available\":[{\"name\":\"available-plugin\""); assertThat(response.getContentAsString()).contains("\"new\":[{\"name\":\"pending-available-plugin\"");
assertThat(response.getContentAsString()).contains("\"install\":{\"href\":\"/v2/plugins/pending/install\"}");
System.out.println(response.getContentAsString());
}
@Test
void shouldGetPendingUpdatePluginListWithInstallLink() throws URISyntaxException, UnsupportedEncodingException {
AvailablePlugin availablePlugin = createAvailablePlugin("available-plugin");
when(availablePlugin.isPending()).thenReturn(true);
when(pluginManager.getAvailable()).thenReturn(singletonList(availablePlugin));
InstalledPlugin installedPlugin = createInstalledPlugin("available-plugin");
when(pluginManager.getInstalled()).thenReturn(singletonList(installedPlugin));
MockHttpRequest request = MockHttpRequest.get("/v2/plugins/pending");
dispatcher.invoke(request, response);
assertThat(response.getStatus()).isEqualTo(HttpServletResponse.SC_OK);
assertThat(response.getContentAsString()).contains("\"update\":[{\"name\":\"available-plugin\"");
assertThat(response.getContentAsString()).contains("\"install\":{\"href\":\"/v2/plugins/pending/install\"}"); assertThat(response.getContentAsString()).contains("\"install\":{\"href\":\"/v2/plugins/pending/install\"}");
System.out.println(response.getContentAsString()); System.out.println(response.getContentAsString());
} }
@@ -182,11 +204,24 @@ class PendingPluginResourceTest {
} }
private AvailablePlugin createAvailablePlugin(PluginInformation pluginInformation) { private AvailablePlugin createAvailablePlugin(PluginInformation pluginInformation) {
AvailablePluginDescriptor descriptor = new AvailablePluginDescriptor( AvailablePluginDescriptor descriptor = mock(AvailablePluginDescriptor.class);
pluginInformation, new PluginCondition(), Collections.emptySet(), "https://download.hitchhiker.com", null lenient().when(descriptor.getInformation()).thenReturn(pluginInformation);
);
AvailablePlugin availablePlugin = mock(AvailablePlugin.class); AvailablePlugin availablePlugin = mock(AvailablePlugin.class);
lenient().when(availablePlugin.getDescriptor()).thenReturn(descriptor); lenient().when(availablePlugin.getDescriptor()).thenReturn(descriptor);
return availablePlugin; return availablePlugin;
} }
private InstalledPlugin createInstalledPlugin(String name) {
PluginInformation pluginInformation = new PluginInformation();
pluginInformation.setName(name);
return createInstalledPlugin(pluginInformation);
}
private InstalledPlugin createInstalledPlugin(PluginInformation pluginInformation) {
InstalledPluginDescriptor descriptor = mock(InstalledPluginDescriptor.class);
lenient().when(descriptor.getInformation()).thenReturn(pluginInformation);
InstalledPlugin installedPlugin = mock(InstalledPlugin.class);
lenient().when(installedPlugin.getDescriptor()).thenReturn(descriptor);
return installedPlugin;
}
} }