Index: geniuswebcore/test/geniusweb/protocol/session/learn/LearnSettingsTest.py
===================================================================
--- geniuswebcore/test/geniusweb/protocol/session/learn/LearnSettingsTest.py	(revision 71)
+++ geniuswebcore/test/geniusweb/protocol/session/learn/LearnSettingsTest.py	(revision 71)
@@ -0,0 +1,154 @@
+import json
+from typing import List
+import unittest
+from unittest.mock import Mock
+
+from pyson.ObjectMapper import ObjectMapper
+from tudelft_utilities_logging.Reporter import Reporter
+from unitpy.GeneralTests import GeneralTests
+from uri.uri import URI
+
+from geniusweb.deadline.DeadlineRounds import DeadlineRounds
+from geniusweb.protocol.session.SessionSettings import SessionSettings
+from geniusweb.protocol.session.TeamInfo import TeamInfo
+from geniusweb.protocol.session.learn.LearnSettings import LearnSettings
+from geniusweb.references.Parameters import Parameters
+from geniusweb.references.PartyRef import PartyRef
+from geniusweb.references.PartyWithParameters import PartyWithParameters
+from geniusweb.references.PartyWithProfile import PartyWithProfile
+from geniusweb.references.ProfileRef import ProfileRef
+
+
+class LearnSettingsTest (unittest.TestCase, GeneralTests[LearnSettings]):
+	jackson = ObjectMapper()
+	
+	serialized = "{\"LearnSettings\":{\"participants\":[{\"TeamInfo\":{\"parties\":[{\"party\":{\"partyref\":\"party1\",\"parameters\":{\"persistentstate\":\"6bb5f909-0079-43ac-a8ac-a31794391074\",\"negotiationdata\":[\"12b5f909-0079-43ac-a8ac-a31794391012\"]}},\"profile\":\"http://prof1\"}]}}],\"deadline\":{\"DeadlineRounds\":{\"rounds\":10,\"durationms\":10000}}}}"
+
+	def setUp(self):
+		self.params = Parameters()
+		self.params = self.params.With("persistentstate",
+				"6bb5f909-0079-43ac-a8ac-a31794391074")
+		self.params = self.params.With("negotiationdata",
+				["12b5f909-0079-43ac-a8ac-a31794391012"])
+
+		# define participants
+		self.participants = self.createTeam(self.params, 1)
+
+		# participants2
+# 		ProfileRef profile2 = new ProfileRef("http://prof2");
+# 		PartyWithProfile partywithp2 = new PartyWithProfile(party1, profile2);
+# 		List<PartyWithProfile> team2pp = Arrays.asList(partywithp2);
+# 		TeamInfo team2 = new TeamInfo(team2pp);
+		self.participants2 = self.createTeam(self.params, 2)
+
+		self.deadline = DeadlineRounds(10, 10000)
+		self.deadline2 = DeadlineRounds(20, 10000)
+
+		self.settings1 =  LearnSettings(self.participants, self.deadline)
+		self.settings1a =  LearnSettings(self.participants, self.deadline)
+		self.settings2 =  LearnSettings(self.participants2, self.deadline)
+		self.settings3 =  LearnSettings(self.participants, self.deadline2)
+
+
+	def createTeam(self, params:Parameters,  partynr:int) -> List[TeamInfo] :
+		'''
+		@param params  the parameters for the party
+		@param partynr the serialnr for the party, eg 1 or 2.
+		@return a List of TeamInfo with just 1 team.
+		'''
+		party1ref = PartyRef(URI("party" + str(partynr)))
+		party1 = PartyWithParameters(party1ref, params)
+		profile1 = ProfileRef(URI("http://prof" + str(partynr)))
+		partywithp1 = PartyWithProfile(party1, profile1)
+		team1pp = [partywithp1]
+		team1 = TeamInfo(team1pp)
+		return [team1]
+
+	def getGeneralTestData(self) ->List[List[LearnSettings]]:
+		return [[self.settings1, self.settings1a],[self.settings2], [self.settings3]]
+
+	def getGeneralTestStrings(self)->List[str]:
+		return [
+				"LearnSettings.TeamInfo.*PartyWithProfile.*PartyRef.*party1.*persistentstate=6b.*, negotiationdata=\\[12.*..*ProfileRef.*prof1.*,DeadlineRounds.*10,10000.*",
+				"LearnSettings.TeamInfo.*PartyWithProfile.*PartyRef.*party2.*persistentstate=6b.*, negotiationdata=\\[12.*..*ProfileRef.*prof2.*,DeadlineRounds.*10,10000.*",
+				"LearnSettings.TeamInfo.*PartyWithProfile.*PartyRef.*party1.*persistentstate=6b.*, negotiationdata=\\[12.*..*ProfileRef.*prof1.*,DeadlineRounds.*20,10000.*"]
+
+	def testNullParticipants(self):
+		self.assertRaises(ValueError, lambda:LearnSettings(None, self.deadline))
+
+	def testNullDeadline(self):
+		self.assertRaises(ValueError, lambda:LearnSettings(self.participants, None))
+
+	def testgetMaxRuntimeTest(self):
+		self.assertEqual(10, self.settings1.getMaxRunTime(), 0.00000001)
+
+	def testgetProtocolTest(self):
+		# this will throw if not Learn protocol or another problem.
+		protocol = self.settings1.getProtocol(Mock(Reporter))
+
+
+	def testbadPersistentTest(self):
+		# hack. #1933.
+		newparams = self.params.With("persistentstate",
+				"\"notproperUUID\"")
+		participants = self.createTeam(newparams, 1)
+
+		self.assertRaises(ValueError, lambda:LearnSettings(participants, self.deadline))
+
+	def testpersistentNotStringTest(self):
+		newparams = self.params.With("persistentstate", 32)
+		participants = self.createTeam(newparams, 1)
+
+		self.assertRaises(ValueError, lambda: LearnSettings(participants, self.deadline))
+
+	def testpersistentWithoutQuotesTest(self) :
+		newparams = self.params.With("persistentstate",
+				"6bb5f909-0079-43ac-a8ac-a31794391074")
+		participants = self.createTeam(newparams, 1)
+
+		LearnSettings(participants, self.deadline)
+
+	def testpersistentExtraQuoteTest(self) :
+		newparams = self.params.With("persistentstate",
+				"\"6bb5f909-0079-43ac-a8ac-a31794391074\"")
+		participants = self.createTeam(newparams, 1)
+
+		self.assertRaises(ValueError, lambda:LearnSettings(participants, self.deadline))
+
+	def testnegotiationDataNotList(self):
+		newparams = self.params.With("negotiationdata",
+				"\"12b5f909-0079-43ac-a8ac-a31794391012\"")
+		participants = self.createTeam(newparams, 1)
+		self.assertRaises(ValueError, lambda:LearnSettings(participants, self.deadline))
+
+	def testnegotiationDataBadContents(self):
+		newparams = self.params.With("negotiationdata", "\"bad\"")
+		participants = self.createTeam(newparams, 1)
+		self.assertRaises(ValueError, lambda: LearnSettings(participants, self.deadline))
+
+	def testnegotiationDataNotString(self):
+		newparams = self.params.With("negotiationdata", 12)
+		participants = self.createTeam(newparams, 1)
+		self.assertRaises(ValueError, lambda:LearnSettings(participants,self.deadline))
+
+	def testgetTeamsTest(self):
+		self.assertEqual(self.participants, self.settings1.getTeams())
+		self.assertEqual(1, self.settings1.getTeamSize())
+
+	def testgetDeadlineTest(self):
+		self.assertEqual(self.deadline, self.settings1.getDeadline())
+
+	def testwithTeamTest(self):
+		newset = self.settings1.With(self.participants2[0])
+		self.assertEqual(2, len(newset.getTeams()))
+
+	def testDeserialize(self) :
+		obj = self.jackson.parse(json.loads(self.serialized), SessionSettings)
+		print(obj)
+		self.assertEqual(self.settings1, obj)
+
+	def testSerialize(self):
+		jsonobj = self.jackson.toJson(self.settings1);
+		print(jsonobj)
+		self.assertEqual(json.loads(self.serialized), jsonobj)
+
Index: geniuswebcore/test/geniusweb/protocol/session/learn/LearnStateTest.py
===================================================================
--- geniuswebcore/test/geniusweb/protocol/session/learn/LearnStateTest.py	(revision 71)
+++ geniuswebcore/test/geniusweb/protocol/session/learn/LearnStateTest.py	(revision 71)
@@ -0,0 +1,124 @@
+import unittest
+from unittest.mock import Mock
+
+from uri.uri import URI
+
+from geniusweb.actions.EndNegotiation import EndNegotiation
+from geniusweb.actions.LearningDone import LearningDone
+from geniusweb.actions.PartyId import PartyId
+from geniusweb.deadline.DeadlineTime import DeadlineTime
+from geniusweb.inform.Agreements import Agreements
+from geniusweb.progress.Progress import Progress
+from geniusweb.protocol.ProtocolException import ProtocolException
+from geniusweb.protocol.session.TeamInfo import TeamInfo
+from geniusweb.protocol.session.learn.LearnSettings import LearnSettings
+from geniusweb.protocol.session.learn.LearnState import LearnState
+from geniusweb.references.Parameters import Parameters
+from geniusweb.references.PartyRef import PartyRef
+from geniusweb.references.PartyWithParameters import PartyWithParameters
+from geniusweb.references.PartyWithProfile import PartyWithProfile
+from geniusweb.references.ProfileRef import ProfileRef
+
+
+class LearnStateTest(unittest.TestCase):
+
+	PARTY2 = "party2"
+	PARTY1 = "party1"
+	party1id =  PartyId(PARTY1)
+	party2id =  PartyId(PARTY2)
+	deadline =  DeadlineTime(10000)
+	partyprofile1 = Mock(PartyWithProfile)
+	partyprofile2 = Mock(PartyWithProfile)
+	progressnotdone = Mock(Progress)
+	progressdone = Mock(Progress);
+
+	def setUp(self):
+		self.params = Parameters()
+		self.params = self.params.With("persistentstate",
+				"6bb5f909-0079-43ac-a8ac-a31794391074")
+		self.params = self.params.With("negotiationdata",
+				["12b5f909-0079-43ac-a8ac-a31794391012"])
+
+		
+		self.progressnotdone.isPastDeadline=Mock(return_value=False)
+		self.progressdone.isPastDeadline=Mock(return_value=True)
+
+		# define team1
+		party1ref = PartyRef(URI(self.PARTY1))
+		party1 = PartyWithParameters(party1ref, self.params)
+		profile1 = ProfileRef(URI("http://prof1"))
+		partywithp1 = PartyWithProfile(party1, profile1)
+		team1pp = [partywithp1]
+		self.team1 = TeamInfo(team1pp)
+
+		# define team2
+		party2ref = PartyRef(URI(self.PARTY2))
+		party2 = PartyWithParameters(party2ref, self.params)
+		profile2 = ProfileRef(URI("http://prof2"))
+		partywithp2 = PartyWithProfile(party2, profile2)
+		team2pp = [partywithp2]
+		self.team2 = TeamInfo(team2pp)
+
+		participants = [self.team1, self.team2]
+		settings = LearnSettings(participants, self.deadline)
+		self.state =LearnState([],[],None, settings)
+
+		self.connectedstate = self.state.WithParty(self.party1id, self.partyprofile1)\
+				.WithParty(self.party2id, self.partyprofile2).WithProgress(self.progressnotdone)
+
+
+	def testsmokeTestNull(self):
+		self.assertRaises(ValueError, lambda:LearnState([],[],None, None))
+
+	def testsmokeTest(self):
+		settings = Mock(LearnSettings)
+		LearnState([],[],None,settings)
+
+	def testgetAgreementsTest(self):
+		self.assertEqual(Agreements(), self.state.getAgreements())
+
+	def testisFinalTest(self):
+		# initial state is false, because we check
+		# that there are no learningDone reports
+		self.assertFalse(self.state.isFinal(0))
+		# not final because there are connected parties not yet done.
+		self.assertFalse(self.connectedstate.isFinal(0))
+		finalstate = self.connectedstate.WithProgress(self.progressdone)
+		self.assertTrue(finalstate.isFinal(0))
+
+		errorstate = self.connectedstate\
+				.WithException(ProtocolException("test", self.party1id))
+		self.assertTrue(errorstate.isFinal(0))
+
+	def testcheckActionTest(self):
+		# check basic illegal actions in Learning
+		self.assertNotEqual(None, self.connectedstate.checkAction(self.party1id, None))
+		self.assertNotEqual(None, self.connectedstate.checkAction(PartyId("unknown"), None))
+		self.assertNotEqual(None, self.connectedstate.checkAction(self.party1id,
+				EndNegotiation(self.party1id)))
+		self.assertNotEqual(None,self.connectedstate.checkAction(self.party1id,
+				LearningDone(self.party2id)))
+
+		# check a good action is allowed
+		self.assertEqual(None,self.connectedstate.checkAction(self.party1id,
+				LearningDone(self.party1id)))
+
+		# no learning twice not ok
+		learned = self.connectedstate.WithAction(self.party1id,
+				LearningDone(self.party1id))
+		self.assertNotEqual(None, 
+				learned.checkAction(self.party1id, LearningDone(self.party1id)))
+
+	def testLearnDoneActionTest(self):
+		learned = self.connectedstate.WithAction(self.party1id,
+				LearningDone(self.party1id))
+
+	def testisFinalWhenAllLearned(self):
+		learned = self.connectedstate\
+			.WithAction(self.party1id, LearningDone(self.party1id))\
+			.WithAction(self.party2id, LearningDone(self.party2id))
+		self.assertTrue(learned.isFinal(0))
+
+	def testgetResultTest(self):
+		res = self.connectedstate.getResult()
+		self.assertEqual(0, len(res.getAgreements().getMap()))
Index: geniuswebcore/test/geniusweb/protocol/session/learn/LearnTest.py
===================================================================
--- geniuswebcore/test/geniusweb/protocol/session/learn/LearnTest.py	(revision 71)
+++ geniuswebcore/test/geniusweb/protocol/session/learn/LearnTest.py	(revision 71)
@@ -0,0 +1,137 @@
+from time import sleep, time
+from typing import cast
+import unittest
+from unittest.mock import Mock
+
+from tudelft_utilities_logging.Reporter import Reporter
+from uri.uri import URI
+
+from geniusweb.actions.EndNegotiation import EndNegotiation
+from geniusweb.actions.LearningDone import LearningDone
+from geniusweb.actions.PartyId import PartyId
+from geniusweb.deadline.DeadlineTime import DeadlineTime
+from geniusweb.inform.Finished import Finished
+from geniusweb.protocol.partyconnection.ProtocolToPartyConn import ProtocolToPartyConn
+from geniusweb.protocol.partyconnection.ProtocolToPartyConnFactory import ProtocolToPartyConnFactory
+from geniusweb.protocol.session.TeamInfo import TeamInfo
+from geniusweb.protocol.session.learn.Learn import Learn
+from geniusweb.protocol.session.learn.LearnSettings import LearnSettings
+from geniusweb.protocol.session.learn.LearnState import LearnState
+from geniusweb.references.Parameters import Parameters
+from geniusweb.references.PartyRef import PartyRef
+from geniusweb.references.PartyWithParameters import PartyWithParameters
+from geniusweb.references.PartyWithProfile import PartyWithProfile
+from geniusweb.references.ProfileRef import ProfileRef
+
+
+class LearnTest(unittest.TestCase):
+
+	reporter = Mock(Reporter)
+	params = Parameters()
+	deadline = DeadlineTime(1800)
+	party1id = PartyId("party1")
+	party2id = PartyId("party2")
+
+	def setUp(self):
+		self.conn1 = Mock(ProtocolToPartyConn)
+		self.conn2 = Mock(ProtocolToPartyConn)
+		self.params = self.params.With("persistentstate",
+				"6bb5f909-0079-43ac-a8ac-a31794391074")
+		self.params = self.params.With("negotiationdata",
+				["12b5f909-0079-43ac-a8ac-a31794391012"])
+
+	def testsmokeTest(self):
+		Learn(Mock(LearnState), Mock(Reporter))
+
+	def testgetDescrTest(self):
+		l = Learn(Mock(LearnState), Mock(Reporter))
+
+		self.assertNotEqual(None, l.getDescription())
+
+	def testgetStateTest(self) :
+		state = Mock(LearnState)
+		l = Learn(state, Mock(Reporter))
+		self.assertEqual(state, l.getState())
+
+	def testgetRefTest(self):
+		l = Learn(Mock(LearnState), Mock(Reporter))
+		self.assertEqual("Learn", str(l.getRef().getURI().getPath()))
+
+	def testfinalStateNotificationTest(self):
+		# check that listeners get notified when session ends.
+		pass
+
+	def testStartStopBasic(self) :
+		learn = self.createBasicLearn()
+		factory = self.createFactory()
+		learn.start(factory)
+		#extra, check if start worked ok
+		self.assertEqual(None, learn.getState().getError())
+		self.assertFalse(learn.getState().isFinal(time()*1000))
+		sleep(2.000)
+		self.assertTrue(learn.getState().isFinal(time()*1000))
+
+	def testStartStopLearn(self):
+		learn = self.createBasicLearn();
+		factory = self.createFactory()
+		learn.start(factory)
+		self.assertFalse(learn.getState().isFinal(time()*1000))
+
+		# Instead of mocking connectin we call actionRequest directly
+		learn._actionRequest(self.conn1, LearningDone(self.party1id))
+		self.assertFalse(learn.getState().isFinal(time()*1000))
+		learn._actionRequest(self.conn2, LearningDone(self.party2id))
+		self.assertTrue(learn.getState().isFinal(time()*1000))
+
+	def testAddParty(self):
+		l = Learn(Mock(LearnState), Mock(Reporter))
+		self.assertRaises(ValueError, lambda:l.addParticipant(Mock(PartyWithProfile)))
+	
+
+	def testisFinishSentNormally(self):
+		learn = self.createBasicLearn()
+		factory = self.createFactory()
+		learn.start(factory)
+		learn._actionRequest(self.conn1,  LearningDone(self.party1id))
+		learn._actionRequest(self.conn2, LearningDone(self.party2id))
+		
+		self.assertEqual(1, len([call for call in self.conn1.send.call_args_list \
+			if isinstance(call[0][0],Finished)]))
+		self.assertEqual(1, len([call for call in self.conn2.send.call_args_list \
+			if isinstance(call[0][0],Finished)]))
+
+	def testisFinishSentInError(self):
+		learn = self.createBasicLearn()
+		factory = self.createFactory()
+		learn.start(factory)
+		learn._actionRequest(self.conn1, EndNegotiation(self.party1id))
+		self.assertEqual(1, len([call for call in self.conn1.send.call_args_list \
+			if isinstance(call[0][0],Finished)]))
+		self.assertEqual(1, len([call for call in self.conn2.send.call_args_list \
+			if isinstance(call[0][0],Finished)]))
+
+	def createBasicLearn(self)->Learn:
+		team1 = self.createTeam(1)
+		team2 = self.createTeam(2)
+		settings = LearnSettings([team1, team2],self.deadline)
+		return cast(Learn, settings.getProtocol(self.reporter))
+
+	def createTeam( self, nr:int) -> TeamInfo :
+		party1ref = PartyRef(URI("party" + str(nr)))
+		party1 = PartyWithParameters(party1ref, self.params)
+		profile1 = ProfileRef(URI("prof" + str(nr)))
+		partywithp1 = PartyWithProfile(party1, profile1)
+		team1pp = [partywithp1]
+		team = TeamInfo(team1pp)
+		return team
+
+	def createFactory(self )->ProtocolToPartyConnFactory :
+		self.conn1.getParty=Mock(return_value=self.party1id)
+		self.conn2.getParty=Mock(return_value=self.party2id)
+
+		factory = Mock(	ProtocolToPartyConnFactory)
+		# connections = mock(List.class);
+		connections = [self.conn1, self.conn2]
+		factory.connectAll=Mock(return_value=connections)
+		return factory;
+
Index: geniuswebcore/test/geniusweb/protocol/tournament/TeamTest.py
===================================================================
--- geniuswebcore/test/geniusweb/protocol/tournament/TeamTest.py	(revision 71)
+++ geniuswebcore/test/geniusweb/protocol/tournament/TeamTest.py	(revision 71)
@@ -0,0 +1,33 @@
+import unittest
+from unitpy.GeneralTests import GeneralTests
+from geniusweb.protocol.tournament.Team import Team
+from geniusweb.references.PartyRef import PartyRef
+from geniusweb.references.Parameters import Parameters
+from geniusweb.references.PartyWithParameters import PartyWithParameters
+from typing import List
+from uri.uri import URI
+
+class TeamTest(unittest.TestCase, GeneralTests[Team]):
+    
+    def setUp(self):
+        self.partyref1 = PartyRef(URI("party1"))
+        self.partyref2 = PartyRef(URI("party2"))
+        self.params1 = Parameters().With("a", 1)
+        self.pwithp1 = PartyWithParameters(self.partyref1, self.params1)
+        self.pwithp2 = PartyWithParameters(self.partyref2, self.params1)
+        self.team1 = Team([self.pwithp1])
+        self.team1a = Team([self.pwithp1])
+        self.team2 = Team([self.pwithp2])
+
+        #@Override
+    def getGeneralTestData(self) -> List[List[Team]]:
+        return [[self.team1, self.team1a],[self.team2]]
+
+    #@Override
+    def getGeneralTestStrings(self) -> List[str]:
+        return [".PartyRef.party1..a=1..",".PartyRef.party2..a=1.."]
+
+    #@Test
+    def testGet(self):
+        self.assertEqual([self.pwithp1], self.team1.getParties())
+        
