Index: geniuswebcore/test/geniusweb/inform/ActionDoneTest.py
===================================================================
--- geniuswebcore/test/geniusweb/inform/ActionDoneTest.py	(revision 66)
+++ geniuswebcore/test/geniusweb/inform/ActionDoneTest.py	(revision 67)
@@ -8,4 +8,6 @@
 from geniusweb.inform.Inform import Inform
 from geniusweb.inform.YourTurn import YourTurn
+from geniusweb.inform.Voting import Voting
+from unitpy.GeneralTests import GeneralTests
 
 
Index: geniuswebcore/test/geniusweb/inform/AgreementsTest.py
===================================================================
--- geniuswebcore/test/geniusweb/inform/AgreementsTest.py	(revision 66)
+++ geniuswebcore/test/geniusweb/inform/AgreementsTest.py	(revision 67)
@@ -46,5 +46,5 @@
         
     def testRepr(self):
-        self.assertEqual("Agreements{party1: Bid{'issue1': value1}}", repr(self.agrees))
+        self.assertEqual('Agreements{party1=Bid{issue1="value1"}}', repr(self.agrees))
         
     def testEqual(self):
Index: geniuswebcore/test/geniusweb/inform/FinishedTest.py
===================================================================
--- geniuswebcore/test/geniusweb/inform/FinishedTest.py	(revision 66)
+++ geniuswebcore/test/geniusweb/inform/FinishedTest.py	(revision 67)
@@ -38,5 +38,5 @@
     
     def testRepr(self):
-        self.assertEqual("Finished[Agreements{party1: Bid{}, party2: Bid{}}]", repr(self.finished))
+        self.assertEqual("Finished[Agreements{party1=Bid{}, party2=Bid{}}]", repr(self.finished))
         
     def testEqual(self):
Index: geniuswebcore/test/geniusweb/inform/OptInTest.py
===================================================================
--- geniuswebcore/test/geniusweb/inform/OptInTest.py	(revision 67)
+++ geniuswebcore/test/geniusweb/inform/OptInTest.py	(revision 67)
@@ -0,0 +1,55 @@
+from datetime import datetime
+import json
+import unittest
+
+from pyson.ObjectMapper import ObjectMapper
+from uri.uri import URI 
+
+from geniusweb.actions.PartyId import PartyId
+from geniusweb.actions.Vote import Vote
+from geniusweb.actions.Votes import Votes
+from geniusweb.inform.Inform import Inform
+from geniusweb.inform.OptIn import OptIn
+from geniusweb.issuevalue.Bid import Bid
+from geniusweb.issuevalue.DiscreteValue import DiscreteValue
+
+
+class OptInTest(unittest.TestCase):
+    maxDiff = None
+        
+    bid1 =  Bid({"iss":  DiscreteValue("val1")})
+    bid2 =  Bid({"iss":  DiscreteValue("val2")})
+    partyA =  PartyId("partyA")
+    partyB =  PartyId("partyB")
+    voteA1 = Vote(partyA, bid1, 2, 9)
+    voteB1 =  Vote(partyB, bid1, 2, 9)
+    voteB2 =  Vote(partyB, bid2, 2, 9)
+
+    votesA = Votes(partyA, set([voteA1]))
+    votesB = Votes(partyB,set([voteB1, voteB2]))
+
+    optIn1 = OptIn([votesA, votesB])
+    optIn1a = OptIn([votesA, votesB])
+    optIn2 = OptIn([votesA])
+    jackson = ObjectMapper();
+
+    asJson="{\"OptIn\":{\"votes\":[{\"Votes\":{\"actor\":\"partyA\",\"votes\":[{\"Vote\":{\"actor\":\"partyA\",\"bid\":{\"issuevalues\":{\"iss\":\"val1\"}},\"minPower\":2,\"maxPower\":9}}]}},{\"Votes\":{\"actor\":\"partyB\",\"votes\":[{\"Vote\":{\"actor\":\"partyB\",\"bid\":{\"issuevalues\":{\"iss\":\"val2\"}},\"minPower\":2,\"maxPower\":9}},{\"Vote\":{\"actor\":\"partyB\",\"bid\":{\"issuevalues\":{\"iss\":\"val1\"}},\"minPower\":2,\"maxPower\":9}}]}}]}}"
+
+    def testGeneralTestData(self) :
+        self.assertEqual(self.optIn1, self.optIn1a)
+        self.assertNotEqual(self.optIn1, self.optIn2)
+        self.assertEqual(hash(self.optIn1), hash(self.optIn1a))
+        self.assertNotEqual(hash(self.optIn1), hash(self.optIn2))
+
+
+    def testSerialize(self):
+        jsonstruct = self.jackson.toJson(self.optIn1)
+        print(jsonstruct)
+        # test does not work, python keeps changing the field order...
+#         self.assertEqual(self.bla, jsonstruct)
+
+    def testDeserialize(self):
+        p = self.jackson.parse(json.loads(self.asJson), Inform)
+        print(p);
+        self.assertEqual(self.optIn1, p)
+
Index: geniuswebcore/test/geniusweb/inform/SettingsTest.py
===================================================================
--- geniuswebcore/test/geniusweb/inform/SettingsTest.py	(revision 66)
+++ geniuswebcore/test/geniusweb/inform/SettingsTest.py	(revision 67)
@@ -1,62 +1,84 @@
+from typing import Dict, Any, List
+from geniusweb.inform.Settings import Settings
+from unitpy.GeneralTests import GeneralTests
+from geniusweb.actions.PartyId import PartyId
 from datetime import datetime
+from pyson.ObjectMapper import ObjectMapper
+from geniusweb.references.ProfileRef import ProfileRef
+from uri.uri import URI
+from geniusweb.references.ProtocolRef import ProtocolRef
+from geniusweb.progress.ProgressRounds import ProgressRounds
+from geniusweb.references.Parameters import Parameters
+from geniusweb.references.PartyRef import PartyRef
+import json
+from geniusweb.inform.Inform import Inform
 import unittest
 
-from pyson.ObjectMapper import ObjectMapper
-from uri import URI #type:ignore
+class SettingsTest(unittest.TestCase, GeneralTests[Settings]):
 
-from geniusweb.actions.PartyId import PartyId
-from geniusweb.inform.Inform import Inform
-from geniusweb.inform.Settings import Settings
-from geniusweb.progress.ProgressTime import ProgressTime
-from geniusweb.references.Parameters import Parameters
-from geniusweb.references.ProfileRef import ProfileRef
-from geniusweb.references.ProtocolRef import ProtocolRef
+    id = PartyId("party1")
+    id2 = PartyId("party2")
 
+    asJson = "{\"Settings\":"\
+            + "{\"id\":\"party1\",\"profile\":\"ws:profile1\","\
+            + "\"protocol\":\"ws:localhost/protocol1\","\
+            + "\"progress\":{\"ProgressRounds\":{\"duration\":10,\"currentRound\":0,\"endtime\":999}},"\
+            + "\"parameters\":{}}}"
 
-class SettingsTest(unittest.TestCase):
-    id1 = PartyId("party1")
-    id2 = PartyId("party2")
-    profileref1 = ProfileRef(URI("profile:1"))
-    profileref2 = ProfileRef(URI("profile:2"))
-    protocolref1 = ProtocolRef(URI("protocol:1"))
-    protocolref2 = ProtocolRef(URI("protocol:2"))
-    progress1=ProgressTime(1000, datetime.fromtimestamp(12345678))
-    progress2=ProgressTime(2000, datetime.fromtimestamp(12345678))
-    parameters1=Parameters()
-    parameters2=Parameters({'a':1})
+    date = datetime.fromtimestamp(999/1000.)
+    jackson = ObjectMapper()
 
-    settings  = Settings(id1, profileref1, protocolref1, progress1, parameters1 )
-    settings1  = Settings(id1, profileref1, protocolref1, progress1, parameters1 )
-    settings2  = Settings(id2, profileref1, protocolref1, progress1, parameters1 )
-    settings3  = Settings(id1, profileref2, protocolref1, progress1, parameters1 )
-    settings4  = Settings(id1, profileref1, protocolref2, progress1, parameters1 )
-    settings5  = Settings(id1, profileref1, protocolref1, progress2, parameters1 )
+    # we can't mock because we want to test the serializer
+    profile1 = ProfileRef( URI("ws:profile1"))
+    # jackson.readValue(serialized, Profile.class);
 
-    settings1json={'Settings': {'id': 'party1', 'profile': 'profile:1', 'protocol': 'protocol:1', 'progress': {'ProgressTime': {'duration': 1000, 'start': 12345678000}}, 'parameters': {}}}
+    protocol1 = ProtocolRef(URI("ws:localhost/protocol1"))
+    protocol1a = ProtocolRef(URI("ws:localhost/protocol1"))
+    protocol2 = ProtocolRef(URI("ws:localhost/protocol2"))
+    progress1 = ProgressRounds(10, 0, date)
+    progress1a = ProgressRounds(10, 0, date)
+    progress2 = ProgressRounds(12, 0, date)
 
+    settings1 = Parameters()
+    settings2 = Parameters().With("a", 1)
 
+    negoinfo1 = Settings(id, profile1, protocol1, progress1, settings1)
+    negoinfo1a = Settings(id, profile1, protocol1a, progress1a,settings1)
+    negoinfo2 = Settings(id, profile1, protocol2, progress1, settings1)
+    negoinfo3 = Settings(id, profile1, protocol1, progress2, settings1)
+    negoinfo4 = Settings(id2, profile1, protocol1, progress2, settings1)
+    negoinfo5 = Settings(id, profile1, protocol1, progress1, settings2)
+
+    def getGeneralTestData(self)-> List[List[Settings]] :
+        return [[self.negoinfo1, self.negoinfo1a],
+                [self.negoinfo2], [self.negoinfo3],
+                [self.negoinfo4], [self.negoinfo5]]
+
+    def getGeneralTestStrings(self) -> List[str]:
+        return [
+                "Settings.*party1.*ProtocolRef.*protocol1.*ProgressRounds.*0.*10.*",
+                "Settings.*party1.*ProtocolRef.*protocol2.*ProgressRounds.*0.*10.*",
+                "Settings.*party1.*ProtocolRef.*protocol1.*ProgressRounds.*0.*12.*",
+                "Settings.*party2.*ProtocolRef.*protocol1.*ProgressRounds.*0.*12.*",
+                "Settings.*party1.*ProtocolRef.*protocol1.*ProgressRounds.*0.*10.*"]
+
+    def testSmoke(self): 
+        PartyRef(URI("ws:localhost"))
+    
+    def testNull(self):
+        self.assertRaises(ValueError,lambda: PartyRef(None))
+  
     def testSerialize(self):
-        pyson=ObjectMapper()
-        print(str(pyson.toJson(self.settings1)))
-        self.assertEqual(self.settings1json, pyson.toJson(self.settings1))
+        json1 = self.jackson.toJson(self.negoinfo1)
+        print(json1)
+        self.assertEqual(json.loads(self.asJson), json1)
         
     def testDeserialize(self):
-        pyson=ObjectMapper()
-        self.assertEqual(self.settings1, pyson.parse(self.settings1json, Inform))
-        
-    def testRepr(self):
-        self.assertEqual("Settings[party1,ProfileRef[profile:1],ProtocolRef[protocol:1],ProgressTime[12345678.0 , 1000ms],{}]", repr(self.settings))
-        
-    def testEqual(self):
-        self.assertEqual(self.settings, self.settings1)
-        self.assertNotEqual(self.settings, self.settings2)
-        self.assertNotEqual(self.settings, self.settings3)
-        self.assertNotEqual(self.settings, self.settings4)
-        self.assertNotEqual(self.settings, self.settings5)
-        self.assertEqual(hash(self.settings), hash(self.settings1))
-        self.assertNotEqual(hash(self.settings), hash(self.settings2))
-        self.assertNotEqual(hash(self.settings), hash(self.settings3))
-        self.assertNotEqual(hash(self.settings), hash(self.settings4))
-        self.assertNotEqual(hash(self.settings), hash(self.settings5))
-        
-        
+        p = self.jackson.parse(json.loads(self.asJson), Inform)
+        print(p)
+        self.assertEqual(self.negoinfo1, p)
+
+    def testGeneralDict(self):
+        val = self.jackson.parse(json.loads("{\"a\":0.3,\"b\":{\"x\":3},\"c\":[1,2,3]}"), 
+                                 Dict[str,Any])
+        print(val)
Index: geniuswebcore/test/geniusweb/inform/VotingTest.py
===================================================================
--- geniuswebcore/test/geniusweb/inform/VotingTest.py	(revision 67)
+++ geniuswebcore/test/geniusweb/inform/VotingTest.py	(revision 67)
@@ -0,0 +1,61 @@
+import json
+import unittest
+
+from pyson.ObjectMapper import ObjectMapper
+
+from geniusweb.actions.Offer import Offer
+from geniusweb.actions.PartyId import PartyId
+from geniusweb.inform.Inform import Inform
+from geniusweb.inform.Voting import Voting
+from geniusweb.issuevalue.Bid import Bid
+from geniusweb.issuevalue.DiscreteValue import DiscreteValue
+from typing import List
+from unitpy.GeneralTests import GeneralTests
+
+
+class VotingTest(unittest.TestCase,GeneralTests[Voting]):
+    maxDiff = None
+
+    jackson = ObjectMapper();
+    party1 = PartyId("party1");
+    bid1 = Bid({"iss": DiscreteValue("val1")})
+    bid2 =  Bid({"iss": DiscreteValue("val2")})
+    
+    powers1 = {party1: 2}
+    powers2 = {party1: 3}
+    
+    voting1 = Voting([Offer(party1, bid1)], powers1)
+    voting1a = Voting([Offer(party1, bid1)], powers1)
+    voting2 = Voting([ Offer(party1, bid2)], powers1)
+    voting3 = Voting([ Offer(party1, bid1)], powers2);
+    
+    asJson="{\"Voting\":{\"offers\":[{\"Offer\":{\"actor\":\"party1\",\"bid\":{\"issuevalues\":{\"iss\":\"val1\"}}}}],\"powers\":{\"party1\":2}}}"
+
+    def getGeneralTestData(self)-> List[List[Voting]]:
+        return [[self.voting1, self.voting1a], [self.voting2], [self.voting3]]
+    
+
+    def getGeneralTestStrings(self)-> List[str]:
+        return ["Voting.*Bid.*iss.*val1.*party1.*2.*",
+                "Voting.*Bid.*iss.*val2.*party1.*2.*",
+                "Voting.*Bid.*iss.*val1.*party1.*3.*"]
+    
+
+    
+    def testGeneralTestData(self):
+        self.assertEqual(self.voting1, self.voting1a)
+        self.assertEqual(hash(self.voting1), hash(self.voting1a))
+        self.assertNotEqual(self.voting1, self.voting2)
+        self.assertNotEqual(hash(self.voting1), hash(self.voting2))
+
+    
+    def testSerialize(self) :
+        jsondict = self.jackson.toJson(self.voting1);
+        print(jsondict);
+        self.assertEqual(json.loads(self.asJson), jsondict);
+    
+    def testDeserialize(self):
+        p = self.jackson.parse(json.loads(self.asJson), Inform)
+        print(p)
+        self.assertEqual(self.voting1, p)
+    
Index: geniuswebcore/test/geniusweb/inform/YourTurnTest.py
===================================================================
--- geniuswebcore/test/geniusweb/inform/YourTurnTest.py	(revision 66)
+++ geniuswebcore/test/geniusweb/inform/YourTurnTest.py	(revision 67)
@@ -11,5 +11,5 @@
     pyson=ObjectMapper()
     yourturn  = YourTurn()
-    yourturnjson= {'YourTurn': {}}
+    yourturnjson:dict= {'YourTurn': {}}
     
 
