From 0d945d7c9052eb61d15789584fc8461b9dce82e0 Mon Sep 17 00:00:00 2001
From: felmer <felmer>
Date: Tue, 11 Nov 2008 09:46:47 +0000
Subject: [PATCH] LMS-633 framework extensions, clean ups, and Javadoc. Tests
 in GenericSampleViewerTest extended.

SVN: 8950
---
 .../generic/client/web/client/dto/Code.java   |   2 +-
 .../web/client/dto/CodeWithRegistration.java  |   2 +-
 .../client/web/client/dto/ICodeProvider.java} |  18 +-
 .../client/dto/IInvalidationProvider.java}    |  16 +-
 .../generic/client/web/client/dto/Sample.java |   2 +-
 .../testframework/AbstractProperty.java       | 167 ++++++++++++++++++
 .../testframework/CheckTableCommand.java      |  16 +-
 .../EntityPropertyAssertion.java              |  46 -----
 ...ractValueAssertion.java => IProperty.java} |  21 +--
 ...deAssertion.java => IPropertyChecker.java} |  35 ++--
 .../client/testframework/IValueAssertion.java |   7 +-
 .../PropertyCheckingManager.java              |  74 ++++++++
 .../client/web/client/testframework/Row.java  |   9 +-
 .../application/sample/CheckSample.java       |  42 +----
 .../sample/GenericSampleViewerTest.java       |  34 +++-
 .../client/application/sample/Property.java   |  66 +++----
 16 files changed, 373 insertions(+), 184 deletions(-)
 rename openbis/{sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/testframework/AsStringAssertion.java => source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/ICodeProvider.java} (57%)
 rename openbis/{sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/testframework/EqualsAssertion.java => source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/IInvalidationProvider.java} (60%)
 create mode 100644 openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/testframework/AbstractProperty.java
 delete mode 100644 openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/testframework/EntityPropertyAssertion.java
 rename openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/testframework/{AbstractValueAssertion.java => IProperty.java} (63%)
 rename openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/testframework/{CodeAssertion.java => IPropertyChecker.java} (54%)
 create mode 100644 openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/testframework/PropertyCheckingManager.java

diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/Code.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/Code.java
index 299ef9140d2..d81b91a9eee 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/Code.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/Code.java
@@ -23,7 +23,7 @@ import com.google.gwt.user.client.rpc.IsSerializable;
  * 
  * @author Christian Ribeaud
  */
-public class Code implements IsSerializable
+public class Code implements IsSerializable, ICodeProvider
 {
     private String code;
 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/CodeWithRegistration.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/CodeWithRegistration.java
index 28a85c1afa3..3aa775c91d5 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/CodeWithRegistration.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/CodeWithRegistration.java
@@ -21,7 +21,7 @@ package ch.systemsx.cisd.openbis.generic.client.web.client.dto;
  * 
  * @author Christian Ribeaud
  */
-public class CodeWithRegistration extends AbstractRegistrationHolder
+public class CodeWithRegistration extends AbstractRegistrationHolder implements ICodeProvider
 {
     private String code;
 
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/testframework/AsStringAssertion.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/ICodeProvider.java
similarity index 57%
rename from openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/testframework/AsStringAssertion.java
rename to openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/ICodeProvider.java
index 385221af69a..c7ff4f762a4 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/testframework/AsStringAssertion.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/ICodeProvider.java
@@ -14,26 +14,16 @@
  * limitations under the License.
  */
 
-package ch.systemsx.cisd.openbis.generic.client.web.client.testframework;
-
-import junit.framework.Assert;
+package ch.systemsx.cisd.openbis.generic.client.web.client.dto;
 
 /**
  * 
  *
  * @author Franz-Josef Elmer
  */
-public class AsStringAssertion<T> extends AbstractValueAssertion<T>
+public interface ICodeProvider
 {
 
-    public AsStringAssertion(String failureMessagePrefix, T expectedValue)
-    {
-        super(failureMessagePrefix, expectedValue);
-    }
-    
-    public void assertValue(T value)
-    {
-        Assert.assertEquals(failureMessagePrefix, String.valueOf(expectedValue), String.valueOf(value));
-    }
+    public String getCode();
 
-}
+}
\ No newline at end of file
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/testframework/EqualsAssertion.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/IInvalidationProvider.java
similarity index 60%
rename from openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/testframework/EqualsAssertion.java
rename to openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/IInvalidationProvider.java
index 85f33f40992..71f2fdc1537 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/testframework/EqualsAssertion.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/IInvalidationProvider.java
@@ -14,25 +14,15 @@
  * limitations under the License.
  */
 
-package ch.systemsx.cisd.openbis.generic.client.web.client.testframework;
-
-import junit.framework.Assert;
+package ch.systemsx.cisd.openbis.generic.client.web.client.dto;
 
 /**
  * 
  *
  * @author Franz-Josef Elmer
  */
-public class EqualsAssertion<T> extends AbstractValueAssertion<T>
+public interface IInvalidationProvider
 {
-    public EqualsAssertion(String failureMessagePrefix, T expectedValue)
-    {
-        super(failureMessagePrefix, expectedValue);
-    }
-
-    public void assertValue(T value)
-    {
-        Assert.assertEquals(failureMessagePrefix, expectedValue, value);
-    }
+    public Invalidation getInvalidation();
 
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/Sample.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/Sample.java
index 83adc1d44ae..1a5e67f09ed 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/Sample.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/Sample.java
@@ -26,7 +26,7 @@ import ch.systemsx.cisd.common.annotation.CollectionMapping;
  * 
  * @author Izabela Adamczyk
  */
-public class Sample extends CodeWithRegistration
+public class Sample extends CodeWithRegistration implements IInvalidationProvider
 {
     public static final Sample[] EMPTY_ARRAY = new Sample[0];
 
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/testframework/AbstractProperty.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/testframework/AbstractProperty.java
new file mode 100644
index 00000000000..38afee0daad
--- /dev/null
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/testframework/AbstractProperty.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.client.web.client.testframework;
+
+import junit.framework.Assert;
+
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.EntityProperty;
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ICodeProvider;
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.IInvalidationProvider;
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.Invalidation;
+
+
+/**
+ * Abstract superclass of a generic {@link IProperty} which implements convenient
+ * property value expectations.
+ * It uses a fluent API approach for its methods to prepare expectations.
+ *
+ * @author Franz-Josef Elmer
+ */
+public abstract class AbstractProperty<C extends IPropertyChecker<?>> implements IProperty<C>
+{
+    private final String key;
+    protected final C checker;
+    protected final String message;
+
+    /**
+     * Creates an instance with the specified property name for the specified checker.
+     */
+    protected AbstractProperty(String key, C checker)
+    {
+        this.key = key;
+        this.checker = checker;
+        message = "Property '" + key + "':";
+    }
+
+    public C by(IValueAssertion<?> valueAssertion)
+    {
+        checker.property(key, valueAssertion);
+        return checker;
+    }
+
+    /**
+     * Sets assertion that the toString()ed property value equals the specified string.
+     */
+    public C asString(final String expectedValue)
+    {
+        return by(new IValueAssertion<Object>()
+            {
+                public void assertValue(Object value)
+                {
+                    Assert.assertEquals(message, expectedValue, String.valueOf(value));        
+                }
+            });
+    }
+    
+    /**
+     * Sets assertion that the toString()ed property value matches the specified regular
+     * expression.
+     */
+    public C matchingPattern(final String pattern)
+    {
+        return by(new IValueAssertion<Object>()
+            {
+                public void assertValue(Object value)
+                {
+                    String valueAsString = String.valueOf(value);
+                    if (valueAsString.matches(pattern) == false)
+                    {
+                        Assert.fail(message + " expected pattern <" + pattern + "> but was <"
+                                + value + ">");
+                    }
+                }
+            });
+    }
+
+    /**
+     * Sets assertion that the property value equals the specified object.
+     */
+    public C asObject(final Object expectedValue)
+    {
+        return by(new IValueAssertion<Object>()
+            {
+                public void assertValue(Object value)
+                {
+                    Assert.assertEquals(message, expectedValue, value);
+                }
+            });
+    }
+    
+    /**
+     * Sets assertion that the property value is of type {@link ICodeProvider} with a code
+     * equals the specified code.
+     */
+    public C asCode(final String expectedCode)
+    {
+        return by(new IValueAssertion<ICodeProvider>()
+            {
+                public void assertValue(ICodeProvider code)
+                {
+                    Assert.assertEquals(message, expectedCode, code.getCode());
+                }
+            });
+    }
+    
+    /**
+     * Sets assertion that the property value is of type {@link IInvalidationProvider} with 
+     * no {@link Invalidation} object.
+     */
+    public C asValidEntity()
+    {
+        return by(new IValueAssertion<IInvalidationProvider>()
+            {
+                public void assertValue(IInvalidationProvider provider)
+                {
+                    Invalidation invalidation = provider.getInvalidation();
+                    Assert.assertNull(message + " expected to be a valid entity.", invalidation);
+                }
+            });
+    }
+
+    /**
+     * Sets assertion that the property value is of type {@link IInvalidationProvider} with 
+     * an {@link Invalidation} object.
+     */
+    public C asInvalidEntity()
+    {
+        return by(new IValueAssertion<IInvalidationProvider>()
+            {
+                public void assertValue(IInvalidationProvider provider)
+                {
+                    Invalidation invalidation = provider.getInvalidation();
+                    Assert.assertNotNull(message + " expected to be an invalid entity.",
+                            invalidation);
+                }
+            });
+    }
+    
+    /**
+     * Sets assertion that the property value is of type {@link EntityProperty} with a value
+     * equals the specified string.
+     */
+    public C asProperty(final String expectedValue)
+    {
+        return by(new IValueAssertion<EntityProperty<?, ?>>()
+            {
+                public void assertValue(EntityProperty<?, ?> value)
+                {
+                    Assert.assertEquals(message, expectedValue, value.getValue());
+                }
+            });
+    }
+    
+}
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/testframework/CheckTableCommand.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/testframework/CheckTableCommand.java
index 107056057f6..d3be061c642 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/testframework/CheckTableCommand.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/testframework/CheckTableCommand.java
@@ -27,7 +27,8 @@ import com.google.gwt.user.client.rpc.AsyncCallback;
 import com.google.gwt.user.client.ui.Widget;
 
 /**
- * 
+ * Command for checking the content (i.e. <code>ListStore</code>) of a table (i.e. <code>Grid</code>).
+ * It uses a fluent API approach for its methods to prepare expectations.
  *
  * @author Franz-Josef Elmer
  */
@@ -38,24 +39,37 @@ public class CheckTableCommand extends AbstractDefaultTestCommand
     private int expectedNumberOfRows = -1;
     private List<Row> expectedRows = new ArrayList<Row>();
 
+    /**
+     * Creates an instance for the specified table or grid ID.
+     */
     public CheckTableCommand(String tableID)
     {
         super();
         this.tableID = tableID;
     }
 
+    /**
+     * Creates an instance for the specified table or grid ID and the specified class
+     * of the triggering call-back object.
+     */
     public CheckTableCommand(String tableID, Class<? extends AsyncCallback<?>> callbackClass)
     {
         super(callbackClass);
         this.tableID = tableID;
     }
     
+    /**
+     * Prepares this with the expectation upon the number of table rows.
+     */
     public CheckTableCommand expectedSize(int numberOfRows)
     {
         this.expectedNumberOfRows = numberOfRows;
         return this;
     }
     
+    /**
+     * Prepares this with the expectation upon a certain row to be appear in the table.
+     */
     public CheckTableCommand expectedRow(Row row)
     {
         expectedRows.add(row);
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/testframework/EntityPropertyAssertion.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/testframework/EntityPropertyAssertion.java
deleted file mode 100644
index 90f9ed55e26..00000000000
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/testframework/EntityPropertyAssertion.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2008 ETH Zuerich, CISD
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package ch.systemsx.cisd.openbis.generic.client.web.client.testframework;
-
-import junit.framework.Assert;
-
-import ch.systemsx.cisd.openbis.generic.client.web.client.dto.EntityProperty;
-
-/**
- * 
- *
- * @author Franz-Josef Elmer
- */
-public class EntityPropertyAssertion<T, P> implements IValueAssertion<EntityProperty<T, P>>
-{
-
-    private final String failureMessagePrefix;
-    private final String expectedValue;
-
-    public EntityPropertyAssertion(String failureMessagePrefix, String expectedValue)
-    {
-        this.failureMessagePrefix = failureMessagePrefix;
-        this.expectedValue = expectedValue;
-    }
-
-    @SuppressWarnings("unchecked")
-    public void assertValue(EntityProperty value)
-    {
-        Assert.assertEquals(failureMessagePrefix, expectedValue, value.getValue());
-    }
-
-}
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/testframework/AbstractValueAssertion.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/testframework/IProperty.java
similarity index 63%
rename from openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/testframework/AbstractValueAssertion.java
rename to openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/testframework/IProperty.java
index a54d0a1e7a7..ff6b1404e79 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/testframework/AbstractValueAssertion.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/testframework/IProperty.java
@@ -16,21 +16,18 @@
 
 package ch.systemsx.cisd.openbis.generic.client.web.client.testframework;
 
+
 /**
- * 
+ * Interface of an assertion preparation for a property checked by a
+ * {@link IPropertyChecker} of type <code>C</code>.
+ * It uses a fluent API approach for its methods to prepare expectations.
  *
  * @author Franz-Josef Elmer
  */
-public abstract class AbstractValueAssertion<T> implements IValueAssertion<T>
+public interface IProperty<C extends IPropertyChecker<?>>
 {
-    protected final T expectedValue;
-
-    protected final String failureMessagePrefix;
-
-    public AbstractValueAssertion(String failureMessagePrefix, T expectedValue)
-    {
-        this.failureMessagePrefix = failureMessagePrefix;
-        this.expectedValue = expectedValue;
-    }
-
+    /**
+     * Prepares this property with the specified value assertion and returns the checker.
+     */
+    public C by(IValueAssertion<?> valueAssertion);
 }
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/testframework/CodeAssertion.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/testframework/IPropertyChecker.java
similarity index 54%
rename from openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/testframework/CodeAssertion.java
rename to openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/testframework/IPropertyChecker.java
index 3cc02b857c1..0b8f3d806e7 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/testframework/CodeAssertion.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/testframework/IPropertyChecker.java
@@ -16,29 +16,24 @@
 
 package ch.systemsx.cisd.openbis.generic.client.web.client.testframework;
 
-import junit.framework.Assert;
-
-import ch.systemsx.cisd.openbis.generic.client.web.client.dto.Code;
-
 /**
- * 
+ * Interface for preparing expectation on a property checking class.
+ * It uses a fluent API approach for its methods to prepare expectations.
  *
  * @author Franz-Josef Elmer
  */
-public class CodeAssertion implements IValueAssertion<Code>
+public interface IPropertyChecker<C extends IPropertyChecker<?>>
 {
-    private final String failureMessagePrefix;
-    private final String expectedCode;
-
-    public CodeAssertion(String failureMessagePrefix, String expectedCode)
-    {
-        this.failureMessagePrefix = failureMessagePrefix;
-        this.expectedCode = expectedCode;
-    }
-
-    public void assertValue(Code code)
-    {
-        Assert.assertEquals(failureMessagePrefix, expectedCode, code.getCode());
-    }
-
+    /**
+     * Creates an expectation for the property of specified name.
+     */
+    public IProperty<C> property(String name);
+    
+    /**
+     * Adds an expectation of a property with specified name and specified
+     * assertion object which checks the property value.
+     * 
+     * @return this checker.
+     */
+    public C property(String name, IValueAssertion<?> valueAssertion);
 }
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/testframework/IValueAssertion.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/testframework/IValueAssertion.java
index a8025f7df45..65dea03fd0c 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/testframework/IValueAssertion.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/testframework/IValueAssertion.java
@@ -17,11 +17,16 @@
 package ch.systemsx.cisd.openbis.generic.client.web.client.testframework;
 
 /**
- * 
+ * Interface checking a value of type <code>T</code>.
  *
  * @author Franz-Josef Elmer
  */
 public interface IValueAssertion<T>
 {
+    /**
+     * Asserts that the specified value is as expected.
+     * 
+     * @throws AssertionError if assertion isn't fulfilled.
+     */
     public void assertValue(T value);
 }
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/testframework/PropertyCheckingManager.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/testframework/PropertyCheckingManager.java
new file mode 100644
index 00000000000..18c18351e29
--- /dev/null
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/testframework/PropertyCheckingManager.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.client.web.client.testframework;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import junit.framework.Assert;
+
+import com.extjs.gxt.ui.client.widget.WidgetComponent;
+import com.google.gwt.user.client.ui.Widget;
+
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.property.PropertyGrid;
+
+/**
+ * 
+ *
+ * @author Franz-Josef Elmer
+ */
+public class PropertyCheckingManager extends Assert
+{
+    @SuppressWarnings("unchecked")
+    private Map<String, IValueAssertion> expectedProperties =
+            new HashMap<String, IValueAssertion>();
+
+    public void addExcpectedProperty(String name, IValueAssertion<?> valueAssertion)
+    {
+        expectedProperties.put(name, valueAssertion);
+    }
+    
+    public void assertPropertiesOf(String widgetID)
+    {
+        Widget widget = GWTTestUtil.getWidgetWithID(widgetID);
+        assertTrue("Expected WidgetComponent instead of " + widget.getClass(),
+                widget instanceof WidgetComponent);
+        Widget wrappedWidget = ((WidgetComponent) widget).getWidget();
+        assertTrue("Expected PropertyGrid instead of " + wrappedWidget.getClass(),
+                wrappedWidget instanceof PropertyGrid);
+        assertProperties(((PropertyGrid) wrappedWidget).getProperties());
+    }
+
+    @SuppressWarnings("unchecked")
+    public void assertProperties(Map<String, ?> actualProperties)
+    {
+        for (Map.Entry<String, IValueAssertion> expectedProperty : expectedProperties.entrySet())
+        {
+            String key = expectedProperty.getKey();
+            assertTrue("Expected property not found: " + key, actualProperties.containsKey(key));
+            Object value = actualProperties.get(key);
+            try
+            {
+                expectedProperty.getValue().assertValue(value);
+            } catch (ClassCastException e)
+            {
+                throw new IllegalArgumentException("Property '" + key
+                        + "' is not of expected type: " + value);
+            }
+        }
+    }
+}
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/testframework/Row.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/testframework/Row.java
index 620d2656bb5..f66755b4ec0 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/testframework/Row.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/testframework/Row.java
@@ -20,7 +20,8 @@ import java.util.HashMap;
 import java.util.Map;
 
 /**
- * 
+ * Class which contains all expected cell values to be checked by {@link CheckTableCommand}.
+ * It uses a fluent API approach for its methods to prepare expectations.
  *
  * @author Franz-Josef Elmer
  */
@@ -28,6 +29,12 @@ public class Row
 {
     private final Map<String, Object> columnIDValuesMap = new HashMap<String, Object>();
     
+    /**
+     * Prepares this with an expected cell value.
+     * 
+     * @param columnID ID of the column to which the cell belongs.
+     * @param value Expected value.
+     */
     public Row withCell(String columnID, Object value)
     {
         columnIDValuesMap.put(columnID, value);
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/sample/CheckSample.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/sample/CheckSample.java
index 3fae9c2c6df..d59a0fe36fb 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/sample/CheckSample.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/sample/CheckSample.java
@@ -21,17 +21,11 @@ import static ch.systemsx.cisd.openbis.plugin.generic.client.web.client.applicat
 import static ch.systemsx.cisd.openbis.plugin.generic.client.web.client.application.sample.GenericSampleViewer.ID_PREFIX;
 import static ch.systemsx.cisd.openbis.plugin.generic.client.web.client.application.sample.GenericSampleViewer.PROPERTIES_ID_PREFIX;
 
-import java.util.HashMap;
-import java.util.Map;
-
-import com.extjs.gxt.ui.client.widget.WidgetComponent;
-import com.google.gwt.user.client.ui.Widget;
-
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.property.PropertyGrid;
 import ch.systemsx.cisd.openbis.generic.client.web.client.testframework.AbstractDefaultTestCommand;
 import ch.systemsx.cisd.openbis.generic.client.web.client.testframework.CheckTableCommand;
-import ch.systemsx.cisd.openbis.generic.client.web.client.testframework.GWTTestUtil;
+import ch.systemsx.cisd.openbis.generic.client.web.client.testframework.IPropertyChecker;
 import ch.systemsx.cisd.openbis.generic.client.web.client.testframework.IValueAssertion;
+import ch.systemsx.cisd.openbis.generic.client.web.client.testframework.PropertyCheckingManager;
 import ch.systemsx.cisd.openbis.plugin.generic.client.web.client.application.sample.GenericSampleViewer.SampleGenerationInfoCallback;
 
 /**
@@ -39,20 +33,19 @@ import ch.systemsx.cisd.openbis.plugin.generic.client.web.client.application.sam
  *
  * @author Franz-Josef Elmer
  */
-public class CheckSample extends AbstractDefaultTestCommand
+public class CheckSample extends AbstractDefaultTestCommand implements IPropertyChecker<CheckSample>
 {
 
     private final String identifier;
-
-    @SuppressWarnings("unchecked")
-    private Map<String, IValueAssertion> expectedProperties =
-            new HashMap<String, IValueAssertion>();
+    private final PropertyCheckingManager propertyCheckingManager;
+    
     private CheckTableCommand componentsTableCheck;
     private CheckTableCommand dataTableCheck;
 
     public CheckSample(String identifierPrefix, String code)
     {
         this.identifier = identifierPrefix + "/" + code;
+        propertyCheckingManager = new PropertyCheckingManager();
         addCallbackClass(SampleGenerationInfoCallback.class);
         addCallbackClass(GenericSampleViewer.ListSamplesCallback.class);
         addCallbackClass(GenericSampleViewer.ListExternalDataCallback.class);
@@ -63,10 +56,9 @@ public class CheckSample extends AbstractDefaultTestCommand
         return new Property(name, this);
     }
     
-    @SuppressWarnings("unchecked")
-    public CheckSample property(String name, IValueAssertion valueAssertion)
+    public CheckSample property(String name, IValueAssertion<?> valueAssertion)
     {
-        expectedProperties.put(name, valueAssertion);
+        propertyCheckingManager.addExcpectedProperty(name, valueAssertion);
         return this;
     }
     
@@ -84,7 +76,7 @@ public class CheckSample extends AbstractDefaultTestCommand
 
     public void execute()
     {
-        checkProperties();
+        propertyCheckingManager.assertPropertiesOf(PROPERTIES_ID_PREFIX + identifier);
         if (componentsTableCheck != null)
         {
             componentsTableCheck.execute();
@@ -95,20 +87,4 @@ public class CheckSample extends AbstractDefaultTestCommand
         }
     }
 
-    @SuppressWarnings("unchecked")
-    private void checkProperties()
-    {
-        Widget widget = GWTTestUtil.getWidgetWithID(PROPERTIES_ID_PREFIX + identifier);
-        assertEquals(true, widget instanceof WidgetComponent);
-        PropertyGrid grid = (PropertyGrid) ((WidgetComponent) widget).getWidget();
-        Map<String, ?> actualProperties = grid.getProperties();
-        for (Map.Entry<String, IValueAssertion> expectedProperty : expectedProperties.entrySet())
-        {
-            String key = expectedProperty.getKey();
-            assertTrue("Expected property not found: " + key, actualProperties.containsKey(key));
-            Object value = actualProperties.get(key);
-            expectedProperty.getValue().assertValue(value);
-        }
-    }
-
 }
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/sample/GenericSampleViewerTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/sample/GenericSampleViewerTest.java
index 22698987414..a50373379c5 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/sample/GenericSampleViewerTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/sample/GenericSampleViewerTest.java
@@ -17,14 +17,18 @@
 package ch.systemsx.cisd.openbis.plugin.generic.client.web.client.application.sample;
 
 import static ch.systemsx.cisd.openbis.generic.client.web.client.application.model.ModelDataPropertyNames.CODE;
+import static ch.systemsx.cisd.openbis.generic.client.web.client.application.model.ModelDataPropertyNames.FILE_FORMAT_TYPE;
+import static ch.systemsx.cisd.openbis.generic.client.web.client.application.model.ModelDataPropertyNames.LOCATION;
 
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.CategoriesBuilder;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.Login;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.OpenTab;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.sample_browser.ListSamples;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.sample_browser.ShowSample;
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.Invalidation;
 import ch.systemsx.cisd.openbis.generic.client.web.client.testframework.AbstractGWTTestCase;
 import ch.systemsx.cisd.openbis.generic.client.web.client.testframework.CheckTableCommand;
+import ch.systemsx.cisd.openbis.generic.client.web.client.testframework.IValueAssertion;
 import ch.systemsx.cisd.openbis.generic.client.web.client.testframework.Row;
 
 /**
@@ -48,10 +52,10 @@ public class GenericSampleViewerTest extends AbstractGWTTestCase
         CheckSample checkSample = new CheckSample(GROUP_IDENTIFIER, MASTER_PLATE_EXAMPLE);
         checkSample.property("Sample").asString(MASTER_PLATE_EXAMPLE);
         checkSample.property("Sample Type").asCode("MASTER_PLATE");
+        checkSample.property("Registrator").asPerson("Doe, John");
+        checkSample.property("Generated Samples").asGeneratedSamples("DP1-A [DILUTION_PLATE]",
+                "DP1-B [DILUTION_PLATE]");
         checkSample.property("Plate Geometry").asProperty("384_WELLS_16X24");
-//        assertEquals("Doe, John", grid.getText(2, 1));
-//        assertEquals("DP1-A [DILUTION_PLATE]\nDP1-B [DILUTION_PLATE]", grid.getText(4, 1)
-//                .replaceAll("\r\n", "\n"));
 
         
         CheckTableCommand componentsTable = checkSample.componentsTable().expectedSize(4);
@@ -77,14 +81,28 @@ public class GenericSampleViewerTest extends AbstractGWTTestCase
         CheckSample checkSample = new CheckSample(GROUP_IDENTIFIER, CELL_PLATE_EXAMPLE);
         checkSample.property("Sample").asString(CELL_PLATE_EXAMPLE);
         checkSample.property("Sample Type").asCode("CELL_PLATE");
-//        checkSample.property("Diluation Plate").asCode("3V-123");
-//        checkSample.property("Master Plate").asCode("MP001-1");
+        checkSample.property("Generated Samples").asGeneratedSamples("3VRP1A [REINFECT_PLATE]",
+                "3VRP1B [REINFECT_PLATE]");
+        checkSample.property("Invalidation").by(new IValueAssertion<Invalidation>()
+            {
+                public void assertValue(Invalidation invalidation)
+                {
+                    assertEquals("Doe", invalidation.getRegistrator().getLastName());
+                    assertEquals("wrong-code", invalidation.getReason());
+                }
+            });
+        checkSample.property("Dilution Plate").asCode("3V-123");
+        checkSample.property("Dilution Plate").asInvalidEntity();
+        checkSample.property("Master Plate").asCode("MP001-1");
+        checkSample.property("Master Plate").asInvalidEntity();
         
         
-        CheckTableCommand componentsTable = checkSample.componentsTable().expectedSize(0);
+        checkSample.componentsTable().expectedSize(0);
         CheckTableCommand dataTable = checkSample.dataTable().expectedSize(2);
-        dataTable.expectedRow(new Row().withCell(CODE, "20081105092158673-1"));
-        dataTable.expectedRow(new Row().withCell(CODE, "20081105092159188-3"));
+        dataTable.expectedRow(new Row().withCell(CODE, "20081105092158673-1").withCell(
+                FILE_FORMAT_TYPE, "TIFF"));
+        dataTable.expectedRow(new Row().withCell(CODE, "20081105092159188-3").withCell(LOCATION,
+                "analysis/result"));
         remoteConsole.prepare(checkSample);
         
         remoteConsole.finish(60000);
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/sample/Property.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/sample/Property.java
index 1590d72671f..367cefce038 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/sample/Property.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/sample/Property.java
@@ -16,52 +16,54 @@
 
 package ch.systemsx.cisd.openbis.plugin.generic.client.web.client.application.sample;
 
-import ch.systemsx.cisd.openbis.generic.client.web.client.testframework.AsStringAssertion;
-import ch.systemsx.cisd.openbis.generic.client.web.client.testframework.CodeAssertion;
-import ch.systemsx.cisd.openbis.generic.client.web.client.testframework.EntityPropertyAssertion;
-import ch.systemsx.cisd.openbis.generic.client.web.client.testframework.EqualsAssertion;
+import junit.framework.Assert;
+
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.Person;
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.Sample;
+import ch.systemsx.cisd.openbis.generic.client.web.client.testframework.AbstractProperty;
+import ch.systemsx.cisd.openbis.generic.client.web.client.testframework.IValueAssertion;
 
 /**
+ * Extends {@link AbstractProperty} with methods for {@link Person} and arrays of generated
+ * {@link Sample}.
  * 
- *
  * @author Franz-Josef Elmer
  */
-public class Property
+public class Property extends AbstractProperty<CheckSample> 
 {
-    private final String key;
-    private final CheckSample checker;
-    private final String message;
-
     public Property(String key, CheckSample checker)
     {
-        this.key = key;
-        this.checker = checker;
-        message = "Property '" + key + "':";
-    }
-    
-    public CheckSample asString(Object value)
-    {
-        checker.property(key, new AsStringAssertion<Object>(message, value));
-        return checker;
-    }
-
-    public CheckSample asObject(Object value)
-    {
-        checker.property(key, new EqualsAssertion<Object>(message, value));
-        return checker;
+        super(key, checker);
     }
     
-    public CheckSample asCode(String code)
+    public CheckSample asPerson(final String personAsString)
     {
-        checker.property(key, new CodeAssertion(message, code));
-        return checker;
+        return by(new IValueAssertion<Person>()
+            {
+                public void assertValue(Person value)
+                {
+                    String actualName = value.getLastName() + ", " + value.getFirstName();
+                    Assert.assertEquals(message, personAsString, actualName);
+                }
+            });
     }
     
-    @SuppressWarnings("unchecked")
-    public CheckSample asProperty(String value)
+    public CheckSample asGeneratedSamples(final String... samples)
     {
-        checker.property(key, new EntityPropertyAssertion(message, value));
-        return checker;
+        return by(new IValueAssertion<Sample[]>()
+            {
+                public void assertValue(Sample[] actualSamples)
+                {
+                    for (int i = 0, n = Math.min(samples.length, actualSamples.length); i < n; i++)
+                    {
+                        Sample actualSample = actualSamples[i];
+                        String code = actualSample.getCode();
+                        String type = actualSample.getSampleType().getCode();
+                        Assert.assertEquals(message + (i + 1) + ". sample", samples[i], code + " [" + type
+                                + "]");
+                    }
+                }
+            });
     }
     
 }
-- 
GitLab