Skip to content

Commit

Permalink
Implement tests to TerminalClient.getFields method (#1)
Browse files Browse the repository at this point in the history
  • Loading branch information
Baraujo25 authored and rabelenda committed Apr 24, 2019
1 parent ac5e329 commit 0a96066
Show file tree
Hide file tree
Showing 3 changed files with 201 additions and 44 deletions.
10 changes: 9 additions & 1 deletion src/main/java/net/infordata/em/TerminalClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,8 @@ public void setFieldTextByLabel(String label, String text) {
*/
public void sendKeyEvent(int keyCode, int modifiers) {
emulator.processRawKeyEvent(
new KeyEvent(emulator, KeyEvent.KEY_PRESSED, 0, modifiers, keyCode, KeyEvent.CHAR_UNDEFINED));
new KeyEvent(emulator, KeyEvent.KEY_PRESSED, 0, modifiers, keyCode,
KeyEvent.CHAR_UNDEFINED));
}

/**
Expand All @@ -181,6 +182,13 @@ public String getScreenText() {
return screen.toString();
}

/**
* Gets the fields present on the current screen.
*
* @return fields of the screen. Take into consideration that this only returns fields that hold
* some information to be sent to the server. The screen is composed by its textual representation
* plus these fields.
*/
public List<XI5250Field> getFields() {
return emulator.getFields();
}
Expand Down
17 changes: 14 additions & 3 deletions src/main/java/net/infordata/em/crt5250/XI5250Field.java
Original file line number Diff line number Diff line change
Expand Up @@ -234,11 +234,21 @@ protected void processFieldPaintEvent(XI5250FieldPaintEvent e) {
break;
}
}


public int getAttr() {
return ivAttr;
}
public final XI5250Crt getCrt() {
return ivCrt;
}


public byte[] getFFW() {
return ivFFW;
}

public byte[] getFCW() {
return ivFCW;
}
/**
* Initializes the field. It is called after that the 5250 panel construction has ended to let the
* field refresh its color attribute.
Expand Down Expand Up @@ -316,10 +326,11 @@ public void setString(String aStr) {
*
* @return value of the field as String
*/

public String getString() {
return ivCrt.getString(ivCol, ivRow, ivLength);
}

/**
* Returns value of the field as String, all trailing nulls and blanks are cut off. NOTE: signed
* numeric are followed by sign char
Expand Down
218 changes: 178 additions & 40 deletions src/test/java/net/infordata/em/TerminalClientTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.google.common.base.Charsets;
import com.google.common.io.Resources;
import net.infordata.em.crt5250.XI5250Field;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
Expand All @@ -24,10 +25,13 @@
import java.security.GeneralSecurityException;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import java.util.Optional;
import java.util.List;
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Collectors;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals;

public class TerminalClientTest {

Expand All @@ -36,12 +40,6 @@ public class TerminalClientTest {
private static final String SERVICE_HOST = "localhost";
private static final String TERMINAL_TYPE = "IBM-3477-FC";

private VirtualTcpService service = new VirtualTcpService();
private TerminalClient client;
private ExceptionWaiter exceptionWaiter;
private ScheduledExecutorService stableTimeoutExecutor = Executors
.newSingleThreadScheduledExecutor();

@Rule
public TestRule watchman = new TestWatcher() {
@Override
Expand All @@ -54,6 +52,11 @@ public void finished(Description description) {
LOG.debug("Finished {}", description.getMethodName());
}
};
private VirtualTcpService service = new VirtualTcpService();
private TerminalClient client;
private ExceptionWaiter exceptionWaiter;
private ScheduledExecutorService stableTimeoutExecutor = Executors
.newSingleThreadScheduledExecutor();

@Before
public void setup() throws IOException {
Expand All @@ -72,31 +75,6 @@ private String getResourceFilePath(String resourcePath) {
return getClass().getResource(resourcePath).getFile();
}

private static class ExceptionWaiter implements ExceptionHandler {

private CountDownLatch exceptionLatch = new CountDownLatch(1);
private CountDownLatch closeLatch = new CountDownLatch(1);

@Override
public void onException(Throwable ex) {
exceptionLatch.countDown();
}

@Override
public void onConnectionClosed() {
closeLatch.countDown();
}

private void awaitException() throws InterruptedException {
assertThat(exceptionLatch.await(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)).isTrue();
}

private void awaitClose() throws InterruptedException {
assertThat(closeLatch.await(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)).isTrue();
}

}

@After
public void teardown() throws Exception {
client.disconnect();
Expand Down Expand Up @@ -153,16 +131,16 @@ private SSLContext buildSslContext() throws GeneralSecurityException {
SSLContext sslContext = SSLContext.getInstance("TLS");
TrustManager trustManager = new X509TrustManager() {

public java.security.cert.X509Certificate[] getAcceptedIssuers() {
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}

public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
X509Certificate[] certs, String authType) {
}

public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
X509Certificate[] certs, String authType) {
}
};
sslContext.init(null, new TrustManager[]{trustManager},
Expand Down Expand Up @@ -195,8 +173,8 @@ private void loginByCoord() {
}

private void loginByLabel() {
client.setFieldTextByLabel("User","TESTUSR");
client.setFieldTextByLabel("Password","TESTPSW");
client.setFieldTextByLabel("User", "TESTUSR");
client.setFieldTextByLabel("Password", "TESTPSW");
client.sendKeyEvent(KeyEvent.VK_ENTER, 0);
}

Expand Down Expand Up @@ -264,7 +242,7 @@ public void shouldThrowIllegalArgumentExceptionWhenSendIncorrectFieldPosition()
public void shouldThrowIllegalArgumentExceptionWhenSendIncorrectFieldLabel()
throws Exception {
awaitKeyboardUnlock();
client.setFieldTextByLabel("test","test");
client.setFieldTextByLabel("test", "test");
}

@Test
Expand All @@ -275,19 +253,179 @@ public void shouldSendCloseToExceptionHandlerWhenServerDown() throws Exception {
}

@Test
public void shouldSendExceptionToExceptionHandlerWhenLoginAndServerDownByCoord() throws Exception {
public void shouldSendExceptionToExceptionHandlerWhenLoginAndServerDownByCoord()
throws Exception {
awaitKeyboardUnlock();
service.stop(TIMEOUT_MILLIS);
loginByCoord();
exceptionWaiter.awaitException();
}

@Test
public void shouldSendExceptionToExceptionHandlerWhenLoginAndServerDownByLabel() throws Exception {
public void shouldSendExceptionToExceptionHandlerWhenLoginAndServerDownByLabel()
throws Exception {
awaitKeyboardUnlock();
service.stop(TIMEOUT_MILLIS);
loginByLabel();
exceptionWaiter.awaitException();
}

@Test
public void shouldGetCorrectFieldsWhenGetFields() throws Exception {
awaitKeyboardUnlock();
List<TestField> actualFields = client.getFields().stream()
.map(TestField::new)
.collect(Collectors.toList());
assertEquals(buildExpectedFields(), actualFields);
}

private List<TestField> buildExpectedFields() {
List<TestField> testFieldList = new ArrayList<>();
int fieldsColumn = 52;
String fieldsText = "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000";
testFieldList.add(new TestField.Builder(5, fieldsColumn, fieldsText).withMonocase().build());
testFieldList.add(
new TestField.Builder(6, fieldsColumn, fieldsText).withMonocase().withHighIntensity()
.withReverseImage()
.build());
testFieldList.add(new TestField.Builder(7, fieldsColumn, fieldsText).build());
testFieldList.add(new TestField.Builder(8, fieldsColumn, fieldsText).build());
testFieldList.add(new TestField.Builder(9, fieldsColumn, fieldsText).build());
return testFieldList;
}

private static class TestField {

private static final byte FIELD_FORMAT_MASK = 0x40;
private static final byte MONOCASE_MASK = 0x20;
private static final byte SCREEN_ATTRIBUTE_MASK = 0x20;
private static final byte UNDERSCORE_MASK = 0x04;
private static final byte HIGH_INTENSITY_MASK = 0x02;
private static final byte REVERSE_IMAGE_MASK = 0x01;

private final int row;
private final int column;
private final String text;
private final byte[] ffw;
private final byte[] fcw;
private final int attr;

private TestField(Builder builder) {
row = builder.row;
column = builder.column;
attr = builder.attr;
text = builder.text;
ffw = builder.ffw;
fcw = builder.fcw;
}

private TestField(XI5250Field field) {
column = field.getCol();
row = field.getRow();
attr = field.getAttr();
text = field.getString();
ffw = field.getFFW();
fcw = field.getFCW();
}

private static final class Builder {

private final int row;
private final int column;
private final String text;
private final byte[] fcw = {0, 0};
private byte[] ffw = {FIELD_FORMAT_MASK, 0};
private byte attr = SCREEN_ATTRIBUTE_MASK | UNDERSCORE_MASK;

private Builder(int row, int column, String text) {
this.row = row;
this.column = column;
this.text = text;
}

private Builder withMonocase() {
ffw[1] |= MONOCASE_MASK;
return this;
}

private Builder withHighIntensity() {
attr |= HIGH_INTENSITY_MASK;
return this;
}

private Builder withReverseImage() {
attr |= REVERSE_IMAGE_MASK;
return this;
}

private TestField build() {
return new TestField(this);
}

}

@Override
public String toString() {
return "TestField{" +
"row=" + row +
", column=" + column +
", ffw=" + Arrays.toString(ffw) +
", fcw=" + Arrays.toString(fcw) +
", attr=" + attr +
", text='" + text + '\'' +
'}';
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
TestField testField = (TestField) o;
return row == testField.row &&
column == testField.column &&
attr == testField.attr &&
Arrays.equals(ffw, testField.ffw) &&
Arrays.equals(fcw, testField.fcw) &&
Objects.equals(text, testField.text);
}

@Override
public int hashCode() {
int result = Objects.hash(row, column, attr, text);
result = 31 * result + Arrays.hashCode(ffw);
result = 31 * result + Arrays.hashCode(fcw);
return result;
}

}

private static class ExceptionWaiter implements ExceptionHandler {

private CountDownLatch exceptionLatch = new CountDownLatch(1);
private CountDownLatch closeLatch = new CountDownLatch(1);

@Override
public void onException(Throwable ex) {
exceptionLatch.countDown();
}

@Override
public void onConnectionClosed() {
closeLatch.countDown();
}

private void awaitException() throws InterruptedException {
assertThat(exceptionLatch.await(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)).isTrue();
}

private void awaitClose() throws InterruptedException {
assertThat(closeLatch.await(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)).isTrue();
}

}

}

0 comments on commit 0a96066

Please sign in to comment.