Add some more tests for FCP interface and refactor
authorDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Sun, 8 Jan 2017 12:54:42 +0000 (13:54 +0100)
committerDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Sun, 8 Jan 2017 12:54:42 +0000 (13:54 +0100)
src/main/java/net/pterodactylus/sone/fcp/FcpInterface.java
src/test/java/net/pterodactylus/sone/fcp/FcpInterfaceTest.kt

index 440cb4c..36e18e6 100644 (file)
@@ -153,41 +153,37 @@ public class FcpInterface {
         */
        public void handle(PluginReplySender pluginReplySender, SimpleFieldSet parameters, Bucket data, int accessType) {
                if (!active.get()) {
-                       try {
-                               sendReply(pluginReplySender, null, new ErrorResponse(400, "FCP Interface deactivated"));
-                       } catch (PluginNotFoundException pnfe1) {
-                               logger.log(Level.FINE, "Could not set error to plugin.", pnfe1);
-                       }
+                       sendErrorReply(pluginReplySender, null, 503, "FCP Interface deactivated");
                        return;
                }
                AbstractSoneCommand command = commands.get(parameters.get("Message"));
                if ((accessType == FredPluginFCP.ACCESS_FCP_RESTRICTED) && (((fullAccessRequired.get() == FullAccessRequired.WRITING) && command.requiresWriteAccess()) || (fullAccessRequired.get() == FullAccessRequired.ALWAYS))) {
-                       try {
-                               sendReply(pluginReplySender, null, new ErrorResponse(401, "Not authorized"));
-                       } catch (PluginNotFoundException pnfe1) {
-                               logger.log(Level.FINE, "Could not set error to plugin.", pnfe1);
-                       }
+                       sendErrorReply(pluginReplySender, null, 401, "Not authorized");
                        return;
                }
+               if (command == null) {
+                       sendErrorReply(pluginReplySender, null, 404, "Unrecognized Message: " + parameters.get("Message"));
+                       return;
+               }
+               String identifier = parameters.get("Identifier");
+               if ((identifier == null) || (identifier.length() == 0)) {
+                       sendErrorReply(pluginReplySender, null, 400, "Missing Identifier.");
+                       return;
+               }
+               try {
+                       Response response = command.execute(parameters, data, AccessType.values()[accessType]);
+                       sendReply(pluginReplySender, identifier, response);
+               } catch (Exception e1) {
+                       logger.log(Level.WARNING, "Could not process FCP command “%s”.", command);
+                       sendErrorReply(pluginReplySender, identifier, 500, "Error executing command: " + e1.getMessage());
+               }
+       }
+
+       private void sendErrorReply(PluginReplySender pluginReplySender, String identifier, int errorCode, String message) {
                try {
-                       if (command == null) {
-                               sendReply(pluginReplySender, null, new ErrorResponse("Unrecognized Message: " + parameters.get("Message")));
-                               return;
-                       }
-                       String identifier = parameters.get("Identifier");
-                       if ((identifier == null) || (identifier.length() == 0)) {
-                               sendReply(pluginReplySender, null, new ErrorResponse("Missing Identifier."));
-                               return;
-                       }
-                       try {
-                               Response response = command.execute(parameters, data, AccessType.values()[accessType]);
-                               sendReply(pluginReplySender, identifier, response);
-                       } catch (Exception e1) {
-                               logger.log(Level.WARNING, "Could not process FCP command “%s”.", command);
-                               sendReply(pluginReplySender, identifier, new ErrorResponse("Error executing command: " + e1.getMessage()));
-                       }
+                       sendReply(pluginReplySender, identifier, new ErrorResponse(errorCode, message));
                } catch (PluginNotFoundException pnfe1) {
-                       logger.log(Level.WARNING, "Could not find destination plugin: " + pluginReplySender);
+                       logger.log(Level.FINE, "Could not send error to plugin.", pnfe1);
                }
        }
 
index 1ec9473..9e9df16 100644 (file)
@@ -1,5 +1,10 @@
+@file:Suppress("DEPRECATION")
+
 package net.pterodactylus.sone.fcp
 
+import freenet.pluginmanager.PluginNotFoundException
+import freenet.pluginmanager.PluginReplySender
+import freenet.support.SimpleFieldSet
 import net.pterodactylus.sone.core.Core
 import net.pterodactylus.sone.fcp.FcpInterface.FullAccessRequired
 import net.pterodactylus.sone.fcp.FcpInterface.FullAccessRequired.ALWAYS
@@ -8,10 +13,17 @@ import net.pterodactylus.sone.fcp.FcpInterface.FullAccessRequired.WRITING
 import net.pterodactylus.sone.fcp.event.FcpInterfaceActivatedEvent
 import net.pterodactylus.sone.fcp.event.FcpInterfaceDeactivatedEvent
 import net.pterodactylus.sone.fcp.event.FullAccessRequiredChanged
+import net.pterodactylus.sone.freenet.fcp.Command.AccessType.FULL_FCP
+import net.pterodactylus.sone.freenet.fcp.Command.AccessType.RESTRICTED_FCP
+import net.pterodactylus.sone.main.SonePlugin
+import net.pterodactylus.sone.test.capture
 import net.pterodactylus.sone.test.mock
+import net.pterodactylus.sone.test.whenever
 import org.hamcrest.MatcherAssert.assertThat
 import org.hamcrest.Matchers.equalTo
 import org.junit.Test
+import org.mockito.ArgumentMatchers
+import org.mockito.Mockito.verify
 
 /**
  * Unit test for [FcpInterface] and its subclasses.
@@ -20,6 +32,9 @@ class FcpInterfaceTest {
 
        private val core = mock<Core>()
        private val fcpInterface = FcpInterface(core)
+       private val pluginReplySender = mock<PluginReplySender>()
+       private val parameters = SimpleFieldSet(true)
+       private val replyParameters = capture<SimpleFieldSet>()
 
        @Test
        fun `fcp interface can be activated`() {
@@ -53,4 +68,71 @@ class FcpInterfaceTest {
                setAndVerifyAccessRequired(ALWAYS)
        }
 
+       @Test
+       fun `sending command to inactive fcp interface results in 400 error reply`() {
+               fcpInterface.fcpInterfaceDeactivated(FcpInterfaceDeactivatedEvent())
+               fcpInterface.handle(pluginReplySender, parameters, null, 0)
+               verify(pluginReplySender).send(replyParameters.capture())
+               assertThat(replyParameters.value["Message"], equalTo("Error"))
+               assertThat(replyParameters.value["ErrorCode"], equalTo("503"))
+       }
+
+       @Test
+       fun `exception while sending reply does not result in exception`() {
+               fcpInterface.fcpInterfaceDeactivated(FcpInterfaceDeactivatedEvent())
+               whenever(pluginReplySender.send(ArgumentMatchers.any())).thenThrow(PluginNotFoundException::class.java)
+               fcpInterface.handle(pluginReplySender, parameters, null, 0)
+       }
+
+       @Test
+       fun `sending command over restricted fcp connection results in 401 error reply`() {
+               fcpInterface.fcpInterfaceActivated(FcpInterfaceActivatedEvent())
+               fcpInterface.handle(pluginReplySender, parameters, null, RESTRICTED_FCP.ordinal)
+               verify(pluginReplySender).send(replyParameters.capture())
+               assertThat(replyParameters.value["Message"], equalTo("Error"))
+               assertThat(replyParameters.value["ErrorCode"], equalTo("401"))
+       }
+
+       @Test
+       fun `sending unknown command over full access connection results in 404 error reply`() {
+               fcpInterface.fcpInterfaceActivated(FcpInterfaceActivatedEvent())
+               fcpInterface.handle(pluginReplySender, parameters, null, FULL_FCP.ordinal)
+               verify(pluginReplySender).send(replyParameters.capture())
+               assertThat(replyParameters.value["Message"], equalTo("Error"))
+               assertThat(replyParameters.value["ErrorCode"], equalTo("404"))
+       }
+
+       @Test
+       fun `sending version command without identifier results in 400 error code`() {
+               fcpInterface.fcpInterfaceActivated(FcpInterfaceActivatedEvent())
+               parameters.putSingle("Message", "Version")
+               fcpInterface.handle(pluginReplySender, parameters, null, FULL_FCP.ordinal)
+               verify(pluginReplySender).send(replyParameters.capture())
+               assertThat(replyParameters.value["Message"], equalTo("Error"))
+               assertThat(replyParameters.value["ErrorCode"], equalTo("400"))
+       }
+
+       @Test
+       fun `sending version command with empty identifier results in 400 error code`() {
+               fcpInterface.fcpInterfaceActivated(FcpInterfaceActivatedEvent())
+               parameters.putSingle("Message", "Version")
+               parameters.putSingle("Identifier", "")
+               fcpInterface.handle(pluginReplySender, parameters, null, FULL_FCP.ordinal)
+               verify(pluginReplySender).send(replyParameters.capture())
+               assertThat(replyParameters.value["Message"], equalTo("Error"))
+               assertThat(replyParameters.value["ErrorCode"], equalTo("400"))
+       }
+
+       @Test
+       fun `sending version command with identifier results in version reply`() {
+               fcpInterface.fcpInterfaceActivated(FcpInterfaceActivatedEvent())
+               parameters.putSingle("Message", "Version")
+               parameters.putSingle("Identifier", "Test")
+               fcpInterface.handle(pluginReplySender, parameters, null, FULL_FCP.ordinal)
+               verify(pluginReplySender).send(replyParameters.capture())
+               assertThat(replyParameters.value["Message"], equalTo("Version"))
+               assertThat(replyParameters.value["Version"], equalTo(SonePlugin.getPluginVersion()))
+               assertThat(replyParameters.value["ProtocolVersion"], equalTo("1"))
+       }
+
 }