Files
JIMRI/java/test/jmri/server/json/oblock/JsonOblockHttpServiceTest.java
T
2026-06-17 14:00:51 +02:00

252 lines
13 KiB
Java

package jmri.server.json.oblock;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.NullNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import jmri.*;
import jmri.jmrit.logix.OBlock;
import jmri.jmrit.logix.OBlockManager;
import jmri.server.json.JSON;
import jmri.server.json.JsonException;
import jmri.server.json.JsonNamedBeanHttpServiceTestBase;
import jmri.server.json.JsonRequest;
//import jmri.server.json.reporter.JsonReporter;
import jmri.server.json.sensor.JsonSensor;
import jmri.util.JUnitUtil;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assumptions.assumeTrue;
/**
*
* @author Randall Wood Copyright 2018
* @author Egbert Broerse Copyright 2020
*/
public class JsonOblockHttpServiceTest extends JsonNamedBeanHttpServiceTestBase<OBlock, JsonOblockHttpService> {
@BeforeEach
@Override
public void setUp() throws Exception {
super.setUp();
service = new JsonOblockHttpService(mapper);
JUnitUtil.initInternalSensorManager();
JUnitUtil.initDebugPowerManager();
JUnitUtil.initReporterManager();
}
@AfterEach
@Override
public void tearDown() throws Exception {
JUnitUtil.deregisterBlockManagerShutdownTask();
super.tearDown();
}
@Test
@Override
public void testDoGet() throws JmriException, IOException, JsonException {
OBlockManager manager = InstanceManager.getDefault(OBlockManager.class);
OBlock oblock1 = manager.provideOBlock("OB1");
Sensor sensor1 = InstanceManager.getDefault(SensorManager.class).provide("IS1");
JsonNode result;
// test block with defaults
result = service.doGet(JsonOblock.OBLOCK, "OB1", NullNode.getInstance(), new JsonRequest(locale, JSON.V5, JSON.GET, 0));
validate(result);
assertEquals(JsonOblock.OBLOCK, result.path(JSON.TYPE).asText());
assertEquals("OB1", result.path(JSON.DATA).path(JSON.NAME).asText());
assertEquals(JSON.UNKNOWN, result.path(JSON.DATA).path(JsonOblock.STATUS).asInt());
assertTrue(result.path(JSON.DATA).path(JsonOblock.WARRANT).isNull());
assertTrue(result.path(JSON.ID).isMissingNode());
// set block state and value
oblock1.setState(OBlock.OCCUPIED);
oblock1.setValue("value is not empty");
JUnitUtil.waitFor(() -> {
return oblock1.getState() == Block.OCCUPIED;
}, "OBlock to become occupied");
result = service.doGet(JsonOblock.OBLOCK, "OB1", NullNode.getInstance(), new JsonRequest(locale, JSON.V5, JSON.GET, 0));
validate(result);
assertEquals(JSON.ACTIVE, result.path(JSON.DATA).path(JsonOblock.STATUS).asInt());
// change oblock state
oblock1.setState(Block.UNOCCUPIED);
result = service.doGet(JsonOblock.OBLOCK, "OB1", NullNode.getInstance(), new JsonRequest(locale, JSON.V5, JSON.GET, 0));
validate(result);
assertEquals(JSON.INACTIVE, result.path(JSON.DATA).path(JsonOblock.STATUS).asInt());
// add a sensor and reporter to the oblock
oblock1.setSensor(sensor1.getSystemName());
result = service.doGet(JsonOblock.OBLOCK, "OB1", NullNode.getInstance(), new JsonRequest(locale, JSON.V5, JSON.GET, 0));
validate(result);
assertEquals(sensor1.getSystemName(), result.path(JSON.DATA).path(JsonSensor.SENSOR).asText());
JsonException ex = assertThrows( JsonException.class, () -> {
// add an invalid oblock by using a turnout name instead of an oblock name
assertNull(manager.getOBlock("IT1"));
service.doGet(JsonOblock.OBLOCK, "IT1", NullNode.getInstance(), new JsonRequest(locale, JSON.V5, JSON.GET, 0));
},"Expected exception not thrown.");
assertEquals(404, ex.getCode());
}
@Test
public void testDoPost() throws JmriException, IOException, JsonException {
OBlockManager manager = InstanceManager.getDefault(OBlockManager.class);
OBlock oblock1 = manager.provideOBlock("OB1");
// set off
JsonNode message = mapper.createObjectNode().put(JSON.NAME, "OB1").put(JsonOblock.STATUS, JSON.INACTIVE);
JsonNode result = service.doPost(JsonOblock.OBLOCK, "OB1", message, new JsonRequest(locale, JSON.V5, JSON.GET, 0));
assertEquals(Block.UNOCCUPIED, oblock1.getState());
validate(result);
assertEquals(JSON.INACTIVE, result.path(JSON.DATA).path(JsonOblock.STATUS).asInt());
// set on
message = mapper.createObjectNode().put(JSON.NAME, "OB1").put(JsonOblock.STATUS, JSON.ACTIVE);
result = service.doPost(JsonOblock.OBLOCK, "OB1", message, new JsonRequest(locale, JSON.V5, JSON.GET, 0));
assertEquals(Block.OCCUPIED, oblock1.getState());
validate(result);
assertEquals(JSON.ACTIVE, result.path(JSON.DATA).path(JsonOblock.STATUS).asInt());
// set unknown - remains on
message = mapper.createObjectNode().put(JSON.NAME, "OB1").put(JsonOblock.STATUS, JSON.UNKNOWN);
result = service.doPost(JsonOblock.OBLOCK, "OB1", message, new JsonRequest(locale, JSON.V5, JSON.GET, 0));
assertEquals(Block.OCCUPIED, oblock1.getState());
validate(result);
assertEquals(JSON.ACTIVE, result.path(JSON.DATA).path(JsonOblock.STATUS).asInt());
// set invalid state
JsonNode messageEx = mapper.createObjectNode().put(JSON.NAME, "OB1").put(JsonOblock.STATUS, 111); // Invalid value
JsonException ex = assertThrows( JsonException.class, () ->
service.doPost(JsonOblock.OBLOCK, "OB1", messageEx,
new JsonRequest(locale, JSON.V5, JSON.GET, 0)),
"Expected exception not thrown.");
assertEquals(400, ex.getCode());
assertEquals(Block.OCCUPIED, oblock1.getState());
// set value
message = mapper.createObjectNode().put(JSON.NAME, "OB1").put(JSON.VALUE, "some value");
assertNull( oblock1.getValue(), "Null block value");
service.doPost(JsonOblock.OBLOCK, "OB1", message, new JsonRequest(locale, JSON.V5, JSON.GET, 0));
assertEquals( "some value", oblock1.getValue(), "Non-null block value");
// set null value
message = mapper.createObjectNode().put(JSON.NAME, "OB1").putNull(JSON.VALUE);
assertNotNull( oblock1.getValue(), "Non-null block value");
service.doPost(JsonOblock.OBLOCK, "OB1", message, new JsonRequest(locale, JSON.V5, JSON.GET, 0));
assertNull( oblock1.getValue(), "Null block value");
// set non-existing sensor
JsonNode messageEx2 = mapper.createObjectNode().put(JSON.NAME, "OB1").put(JsonSensor.SENSOR, "IS1");
assertNull( oblock1.getSensor(), "No sensor");
ex = assertThrows( JsonException.class, () ->
service.doPost(JsonOblock.OBLOCK, "OB1", messageEx2, new JsonRequest(locale, JSON.V5, JSON.GET, 0)),
"Expected exception not thrown");
assertEquals( 404, ex.getCode(), "404 Not Found");
// set existing sensor
Sensor sensor1 = InstanceManager.getDefault(SensorManager.class).provide("IS1");
service.doPost(JsonOblock.OBLOCK, "OB1", messageEx2, new JsonRequest(locale, JSON.V5, JSON.GET, 0));
assertEquals( sensor1, oblock1.getSensor(), "Block has sensor");
// set null sensor
message = mapper.createObjectNode().put(JSON.NAME, "OB1").putNull(JsonSensor.SENSOR);
service.doPost(JsonOblock.OBLOCK, "OB1", message, new JsonRequest(locale, JSON.V5, JSON.GET, 0));
assertNull( oblock1.getSensor(), "Oblock has no sensor");
// reporters not copied from JsonBlockHttpServiceTest since they are not used in OBlocks
ex = assertThrows( JsonException.class, () -> {
// add an invalid oblock by using a turnout name instead of a oblock name
assertNull(manager.getOBlock("IT1"));
JsonNode messageEx3 = mapper.createObjectNode().put(JSON.NAME, "II1").put(JsonOblock.STATUS, Block.UNOCCUPIED);
service.doPost(JsonOblock.OBLOCK, "IT1", messageEx3, new JsonRequest(locale, JSON.V5, JSON.GET, 0));
}, "Expected exception not thrown.");
assertEquals(404, ex.getCode());
}
@Test
public void testDoPut() throws IOException, JsonException {
OBlockManager manager = InstanceManager.getDefault(OBlockManager.class);
// add a Oblock
assertNull(manager.getOBlock("OB1"));
JsonNode message = mapper.createObjectNode().put(JSON.NAME, "OB1").put(JsonOblock.STATUS, Block.UNOCCUPIED);
JsonNode result = service.doPut(JsonOblock.OBLOCK, "OB1", message, new JsonRequest(locale, JSON.V5, JSON.GET, 0));
validate(result);
assertNotNull(manager.getOBlock("OB1"));
JsonException ex = assertThrows( JsonException.class, () -> {
// add an invalid Oblock by using a turnout name instead of a Oblock name
assertNull(manager.getOBlock("IT1"));
JsonNode messageEx = mapper.createObjectNode().put(JSON.NAME, "II1").put(JsonOblock.STATUS, Block.UNOCCUPIED);
service.doPut(JsonOblock.OBLOCK, "", messageEx, new JsonRequest(locale, JSON.V5, JSON.GET, 0)); // use an empty name to trigger exception
}, "Expected exception not thrown.");
assertEquals(400, ex.getCode());
}
@Test
@Override
public void testDoDelete() throws JsonException {
assumeTrue(service != null, "protect against JUnit tests in Eclipse that test this class directly");
OBlockManager manager = InstanceManager.getDefault(OBlockManager.class);
ObjectNode message = mapper.createObjectNode();
// delete non-existent bean
JsonException ex = assertThrows( JsonException.class, () ->
service.doDelete(service.getType(), "non-existant", message, new JsonRequest(locale, JSON.V5, JSON.GET, 42)),
"Expected exception not thrown.");
assertEquals( 404, ex.getCode(), "Code is HTTP NOT FOUND");
assertEquals( "Object type oblock named \"non-existant\" not found.", ex.getMessage(), "Message");
assertEquals( 42, ex.getId(), "ID is 42");
manager.createNewOBlock("OB1", null);
// delete existing bean (no named listener)
assertNotNull(manager.getBySystemName("OB1"));
service.doDelete(service.getType(), "OB1", message, new JsonRequest(locale, JSON.V5, JSON.GET, 42));
assertNull(manager.getBySystemName("OB1"));
OBlock oblock = manager.createNewOBlock("OB1", null);
assertNotNull(oblock);
oblock.addPropertyChangeListener(evt -> {
// do nothing
}, "OB1", "Test Listener");
// delete existing bean (with named listener)
ex = assertThrows( JsonException.class, () ->
service.doDelete(service.getType(), "OB1", message,
new JsonRequest(locale, JSON.V5, JSON.GET, 42)),
"Expected exception not thrown.");
assertEquals(409, ex.getCode());
assertEquals(1, ex.getAdditionalData().path(JSON.CONFLICT).size());
assertEquals("Test Listener", ex.getAdditionalData().path(JSON.CONFLICT).path(0).asText());
ObjectNode message2 = message.put(JSON.FORCE_DELETE, ex.getAdditionalData().path(JSON.FORCE_DELETE).asText());
assertNotNull(manager.getBySystemName("OB1"));
// will throw if prior catch failed
service.doDelete(service.getType(), "OB1", message2, new JsonRequest(locale, JSON.V5, JSON.GET, 0));
assertNull(manager.getBySystemName("OB1"));
ex = assertThrows( JsonException.class, () ->
// deleting again should throw an exception
service.doDelete(service.getType(), "OB1", NullNode.getInstance(),
new JsonRequest(locale, JSON.V5, JSON.GET, 0)),
"Expected exception not thrown.");
assertEquals(404, ex.getCode());
}
/**
* Test of doGetList method, of class JsonOblockHttpService.
* @throws JsonException rethrows any JsonExceptions from instance.doGetList()
*/
@Test
public void testDoGetList() throws JsonException {
InstanceManager.getDefault(OBlockManager.class).createNewOBlock("OB9", null);
JsonOblockHttpService instance = new JsonOblockHttpService(mapper);
JsonNode result = instance.doGetList(JsonOblock.OBLOCK, mapper.createObjectNode(), new JsonRequest(locale, JSON.V5, JSON.GET, 0));
assertEquals(1, result.size());
validate(result);
}
/**
* Test of doSchema method, of class JsonOblockHttpService.
*
* @throws JsonException if something goes wrong
*/
@Override
@Test
public void testDoSchema() throws JsonException {
testDoSchema(JsonOblock.OBLOCK, JsonOblock.OBLOCKS);
}
}