From 3129cd856b006c4c654cc93b06fdce1be783487d Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Fri, 1 Jul 2016 22:47:54 +0700 Subject: [PATCH 1/7] #400: add tests and change config --- horta.properties.example | 2 ++ .../horta/plugins/pet/PetPluginSpec.scala | 33 +++++++++++++++++++ .../codingteam/horta/test/TestKitSpec.scala | 16 +++++---- 3 files changed, 44 insertions(+), 7 deletions(-) create mode 100644 src/test/scala/ru/org/codingteam/horta/plugins/pet/PetPluginSpec.scala diff --git a/horta.properties.example b/horta.properties.example index 6a9c87f..3fe1107 100644 --- a/horta.properties.example +++ b/horta.properties.example @@ -32,4 +32,6 @@ twitter.auth.consumerSecret=aa twitter.auth.token=aa twitter.auth.tokenSecret=aa +pet.rooms=room1,room3 + loglist.url = https://loglist.net diff --git a/src/test/scala/ru/org/codingteam/horta/plugins/pet/PetPluginSpec.scala b/src/test/scala/ru/org/codingteam/horta/plugins/pet/PetPluginSpec.scala new file mode 100644 index 0000000..ad9d7ff --- /dev/null +++ b/src/test/scala/ru/org/codingteam/horta/plugins/pet/PetPluginSpec.scala @@ -0,0 +1,33 @@ +package ru.org.codingteam.horta.plugins.pet + +import ru.org.codingteam.horta.configuration.Configuration +import ru.org.codingteam.horta.core.Clock +import ru.org.codingteam.horta.test.TestKitSpec + +class PetPluginSpec extends TestKitSpec { + Configuration.initialize(configuration + + """ + | + |rooms=room1,room2,room3 + |room1.room=foo@example.com + |room2.room=bar@example.com + |room3.room=baz@example.com + |pet.rooms=room1,room2 + """.stripMargin) + + "PetPlugin" should { + "create a pet for room included in config" in { + val plugin = new PetPlugin() + val room = "bar@example.com" + plugin.processRoomJoin(Clock.now, room, testActor) + plugin.pets should contain key room + } + + "not create a pet for room excluded from config" in { + val plugin = new PetPlugin() + val room = "baz@example.com" + plugin.processRoomJoin(Clock.now, room, testActor) + plugin.pets shouldNot contain key room + } + } +} diff --git a/src/test/scala/ru/org/codingteam/horta/test/TestKitSpec.scala b/src/test/scala/ru/org/codingteam/horta/test/TestKitSpec.scala index ecca651..1c3008f 100644 --- a/src/test/scala/ru/org/codingteam/horta/test/TestKitSpec.scala +++ b/src/test/scala/ru/org/codingteam/horta/test/TestKitSpec.scala @@ -20,19 +20,21 @@ abstract class TestKitSpec extends TestKit(ActorSystem("TestSystem", ConfigFacto |akka.actor.deployment { |} """.stripMargin))) -with ImplicitSender -with WordSpecLike -with Matchers -with OptionValues -with Eventually { + with ImplicitSender + with WordSpecLike + with Matchers + with OptionValues + with Eventually { implicit val timeout = Timeout(15.seconds) - Configuration.initialize( + val configuration = """ |storage.url=jdbc:h2:hell_test;DB_CLOSE_DELAY=-1 |storage.user=sa |storage.password= - |""".stripMargin) + |""".stripMargin + + Configuration.initialize(configuration) val pluginProps = List[Props]() val core = system.actorOf(Props(new Core(List(Props[LogPlugin]), List())), "core") From f5d3891c5f6e30258ef294d042531ef8fde245fe Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Fri, 1 Jul 2016 23:18:05 +0700 Subject: [PATCH 2/7] #400: refactor Configuration.roomDescriptions to map --- .../codingteam/horta/configuration/Configuration.scala | 8 ++++---- .../ru/org/codingteam/horta/plugins/TwitterPlugin.scala | 2 +- .../codingteam/horta/plugins/markov/MarkovPlugin.scala | 2 +- .../codingteam/horta/protocol/jabber/JabberProtocol.scala | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/scala/ru/org/codingteam/horta/configuration/Configuration.scala b/src/main/scala/ru/org/codingteam/horta/configuration/Configuration.scala index 0162141..f5da5c1 100644 --- a/src/main/scala/ru/org/codingteam/horta/configuration/Configuration.scala +++ b/src/main/scala/ru/org/codingteam/horta/configuration/Configuration.scala @@ -46,15 +46,15 @@ object Configuration { lazy val dftMessage = properties.getProperty("message") lazy val roomIds = Option(properties.getProperty("rooms")).map(_.split(",")).getOrElse(Array()) - lazy val roomDescriptors = roomIds map { - case rid => RoomDescriptor( + lazy val roomDescriptors = roomIds.map({ + case rid => (rid, RoomDescriptor( rid, properties.getProperty(rid + ".room"), LocaleDefinition(properties.getProperty(rid + ".locale", defaultLocalization.name)), properties.getProperty(rid + ".nickname", dftName), properties.getProperty(rid + ".message", dftMessage), - properties.getProperty(rid + ".events", "")) - } + properties.getProperty(rid + ".events", ""))) + }).toMap lazy val markovMessagesPerMinute = properties.getProperty("markov_messages_per_minute", "5").toInt lazy val markovMessageWordLimit = properties.getProperty("markov_message_word_limit", "30").toInt diff --git a/src/main/scala/ru/org/codingteam/horta/plugins/TwitterPlugin.scala b/src/main/scala/ru/org/codingteam/horta/plugins/TwitterPlugin.scala index dadbc21..fa8a514 100644 --- a/src/main/scala/ru/org/codingteam/horta/plugins/TwitterPlugin.scala +++ b/src/main/scala/ru/org/codingteam/horta/plugins/TwitterPlugin.scala @@ -56,7 +56,7 @@ class TwitterPlugin extends EventProcessor with RoomProcessor with ActorLogging * @param actor actor representing the room. */ override protected def processRoomJoin(time: DateTime, roomJID: String, actor: ActorRef): Unit = { - Configuration.roomDescriptors find { rd => roomJID.equals(rd.room) } filter { + Configuration.roomDescriptors.values find { rd => roomJID.equals(rd.room) } filter { _.isEventEnabled("twitter") } match { case Some(_) => diff --git a/src/main/scala/ru/org/codingteam/horta/plugins/markov/MarkovPlugin.scala b/src/main/scala/ru/org/codingteam/horta/plugins/markov/MarkovPlugin.scala index e603eb4..23c7d08 100644 --- a/src/main/scala/ru/org/codingteam/horta/plugins/markov/MarkovPlugin.scala +++ b/src/main/scala/ru/org/codingteam/horta/plugins/markov/MarkovPlugin.scala @@ -69,7 +69,7 @@ class MarkovPlugin() extends BasePlugin } def isMyself(credential: Credential): Boolean = { - (Configuration.roomDescriptors find { rd => rd.room == credential.roomId.getOrElse("") } map { rd => rd.nickname } getOrElse (Configuration.dftName)) == credential.name + (Configuration.roomDescriptors.values find { rd => rd.room == credential.roomId.getOrElse("") } map { rd => rd.nickname } getOrElse (Configuration.dftName)) == credential.name } def generatePhrase(credential: Credential, arguments: Array[String]) { diff --git a/src/main/scala/ru/org/codingteam/horta/protocol/jabber/JabberProtocol.scala b/src/main/scala/ru/org/codingteam/horta/protocol/jabber/JabberProtocol.scala index 6410d86..4caae8d 100644 --- a/src/main/scala/ru/org/codingteam/horta/protocol/jabber/JabberProtocol.scala +++ b/src/main/scala/ru/org/codingteam/horta/protocol/jabber/JabberProtocol.scala @@ -166,7 +166,7 @@ class JabberProtocol() extends Actor with ActorLogging { connection.login(Configuration.login, Configuration.password) log.info("Login succeed") - Configuration.roomDescriptors foreach { + Configuration.roomDescriptors.values foreach { case rd => if (rd.room != null) self ! JoinRoom(rd.room, rd.locale, rd.nickname, Option(rd.message)) else log.warning(s"No JID given for room ${rd.id}") From dd65772771bca3311b815d7e877779688d33109a Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Fri, 1 Jul 2016 23:20:11 +0700 Subject: [PATCH 3/7] #400: update tests to properly reconfigure horta --- .../horta/plugins/pet/PetPluginSpec.scala | 29 ++++++++++++------- .../codingteam/horta/test/TestKitSpec.scala | 6 +++- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/test/scala/ru/org/codingteam/horta/plugins/pet/PetPluginSpec.scala b/src/test/scala/ru/org/codingteam/horta/plugins/pet/PetPluginSpec.scala index ad9d7ff..dcd1c69 100644 --- a/src/test/scala/ru/org/codingteam/horta/plugins/pet/PetPluginSpec.scala +++ b/src/test/scala/ru/org/codingteam/horta/plugins/pet/PetPluginSpec.scala @@ -1,30 +1,37 @@ package ru.org.codingteam.horta.plugins.pet +import akka.testkit.TestActorRef import ru.org.codingteam.horta.configuration.Configuration import ru.org.codingteam.horta.core.Clock import ru.org.codingteam.horta.test.TestKitSpec class PetPluginSpec extends TestKitSpec { - Configuration.initialize(configuration + - """ - | - |rooms=room1,room2,room3 - |room1.room=foo@example.com - |room2.room=bar@example.com - |room3.room=baz@example.com - |pet.rooms=room1,room2 - """.stripMargin) + + override def configure(): Unit = { + val content = configuration + + """ + | + |rooms=room1,room2,room3 + |room1.room=foo@example.com + |room2.room=bar@example.com + |room3.room=baz@example.com + |pet.rooms=room1,room2 + """.stripMargin + Configuration.initialize(content) + } + + def createPlugin() = TestActorRef[PetPlugin].underlyingActor "PetPlugin" should { "create a pet for room included in config" in { - val plugin = new PetPlugin() + val plugin = createPlugin() val room = "bar@example.com" plugin.processRoomJoin(Clock.now, room, testActor) plugin.pets should contain key room } "not create a pet for room excluded from config" in { - val plugin = new PetPlugin() + val plugin = createPlugin() val room = "baz@example.com" plugin.processRoomJoin(Clock.now, room, testActor) plugin.pets shouldNot contain key room diff --git a/src/test/scala/ru/org/codingteam/horta/test/TestKitSpec.scala b/src/test/scala/ru/org/codingteam/horta/test/TestKitSpec.scala index 1c3008f..2067246 100644 --- a/src/test/scala/ru/org/codingteam/horta/test/TestKitSpec.scala +++ b/src/test/scala/ru/org/codingteam/horta/test/TestKitSpec.scala @@ -34,7 +34,11 @@ abstract class TestKitSpec extends TestKit(ActorSystem("TestSystem", ConfigFacto |storage.password= |""".stripMargin - Configuration.initialize(configuration) + def configure(): Unit = { + Configuration.initialize(configuration) + } + + configure() val pluginProps = List[Props]() val core = system.actorOf(Props(new Core(List(Props[LogPlugin]), List())), "core") From 50af28af598d476e5d8405dfbd69498b38749fec Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Fri, 1 Jul 2016 23:20:37 +0700 Subject: [PATCH 4/7] #400: check configuration when initializing pet --- .../org/codingteam/horta/configuration/Configuration.scala | 3 +++ .../ru/org/codingteam/horta/plugins/pet/PetPlugin.scala | 5 ++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/scala/ru/org/codingteam/horta/configuration/Configuration.scala b/src/main/scala/ru/org/codingteam/horta/configuration/Configuration.scala index f5da5c1..84f6acc 100644 --- a/src/main/scala/ru/org/codingteam/horta/configuration/Configuration.scala +++ b/src/main/scala/ru/org/codingteam/horta/configuration/Configuration.scala @@ -67,6 +67,9 @@ object Configuration { lazy val loglistUrl = properties.getProperty("loglist.url", "https://loglist.net") + lazy val petRoomNames = properties.getProperty("pet.rooms", "").split(',').map(_.trim) + lazy val petRoomIds = petRoomNames.map(roomDescriptors).map(_.room).toSet + def apply(key: String): String = { properties.getProperty(key) } diff --git a/src/main/scala/ru/org/codingteam/horta/plugins/pet/PetPlugin.scala b/src/main/scala/ru/org/codingteam/horta/plugins/pet/PetPlugin.scala index 7028cd5..222507d 100644 --- a/src/main/scala/ru/org/codingteam/horta/plugins/pet/PetPlugin.scala +++ b/src/main/scala/ru/org/codingteam/horta/plugins/pet/PetPlugin.scala @@ -4,6 +4,7 @@ import akka.actor.{ActorRef, Props} import akka.pattern.ask import akka.util.Timeout import org.joda.time.DateTime +import ru.org.codingteam.horta.configuration.Configuration import ru.org.codingteam.horta.localization.Localization import ru.org.codingteam.horta.plugins._ import ru.org.codingteam.horta.plugins.pet.commands._ @@ -82,7 +83,9 @@ class PetPlugin extends BasePlugin with CommandProcessor with RoomProcessor with } override def processRoomJoin(time: DateTime, roomJID: String, actor: ActorRef) { - initializePet(roomJID, actor) + if (Configuration.petRoomIds.contains(roomJID)) { + initializePet(roomJID, actor) + } } override def processRoomLeave(time: DateTime, roomJID: String) { From 1473a4f6c297c0d5c2633d9024e3d5e41a2c8fb8 Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Fri, 1 Jul 2016 23:52:18 +0700 Subject: [PATCH 5/7] #400: replace all cases of initializePet --- .../horta/plugins/pet/PetPlugin.scala | 57 ++++++++++--------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/src/main/scala/ru/org/codingteam/horta/plugins/pet/PetPlugin.scala b/src/main/scala/ru/org/codingteam/horta/plugins/pet/PetPlugin.scala index 222507d..9f84415 100644 --- a/src/main/scala/ru/org/codingteam/horta/plugins/pet/PetPlugin.scala +++ b/src/main/scala/ru/org/codingteam/horta/plugins/pet/PetPlugin.scala @@ -59,33 +59,33 @@ class PetPlugin extends BasePlugin with CommandProcessor with RoomProcessor with credential.roomId match { case Some(room) => - val pet = initializePet(room, location) - - // (isPrivate, text): - val responseF: Future[(Boolean, String)] = arguments match { - case Array(PetCommandMatcher(command), args@_*) => - (pet ? Pet.ExecuteCommand(command, credential, args.toArray)).mapTo[String].map(s => (false, s)) - case Array("transactions") => - withDatabase(_.readTransactions(credential.roomId.get, credential.name)) map { case transactions => - (true, transactions.mkString("\n")) + initializePet(room, location) match { + case Some(pet) => + // (isPrivate, text): + val responseF: Future[(Boolean, String)] = arguments match { + case Array(PetCommandMatcher(command), args@_*) => + (pet ? Pet.ExecuteCommand(command, credential, args.toArray)).mapTo[String].map(s => (false, s)) + case Array("transactions") => + withDatabase(_.readTransactions(credential.roomId.get, credential.name)) map { case transactions => + (true, transactions.mkString("\n")) + } + case _ => Future.successful((false, Localization.localize("Try $pet help.")(credential))) } - case _ => Future.successful((false, Localization.localize("Try $pet help.")(credential))) - } - for (response <- responseF) { - response match { - case (true, message) => Protocol.sendPrivateResponse(location, credential, message) - case (false, message) => Protocol.sendResponse(location, credential, message) - } + for (response <- responseF) { + response match { + case (true, message) => Protocol.sendPrivateResponse(location, credential, message) + case (false, message) => Protocol.sendResponse(location, credential, message) + } + } + case None => } case None => } } override def processRoomJoin(time: DateTime, roomJID: String, actor: ActorRef) { - if (Configuration.petRoomIds.contains(roomJID)) { - initializePet(roomJID, actor) - } + initializePet(roomJID, actor) } override def processRoomLeave(time: DateTime, roomJID: String) { @@ -97,16 +97,19 @@ class PetPlugin extends BasePlugin with CommandProcessor with RoomProcessor with } } - private def initializePet(roomId: String, location: ActorRef): ActorRef = { - pets.get(roomId) match { - case Some(actor) => actor - case None => - val actor = context.actorOf(Props(classOf[Pet], roomId, location)) - pets = pets.updated(roomId, actor) - actor + private def initializePet(roomId: String, location: ActorRef): Option[ActorRef] = { + if (!Configuration.petRoomIds.contains(roomId)) { + None + } else { + pets.get(roomId) match { + case Some(actor) => Some(actor) + case None => + val actor = context.actorOf(Props(classOf[Pet], roomId, location)) + pets = pets.updated(roomId, actor) + Some(actor) + } } } - } object PetPlugin { From f67102cca8e2f693a15f7ebadb061bbe75cc578a Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Sat, 2 Jul 2016 12:22:05 +0700 Subject: [PATCH 6/7] #400: move plugin-specific configuration to TestKitSpec --- .../horta/plugins/pet/PetPluginSpec.scala | 13 ------------- .../org/codingteam/horta/test/TestKitSpec.scala | 17 +++++++++-------- 2 files changed, 9 insertions(+), 21 deletions(-) diff --git a/src/test/scala/ru/org/codingteam/horta/plugins/pet/PetPluginSpec.scala b/src/test/scala/ru/org/codingteam/horta/plugins/pet/PetPluginSpec.scala index dcd1c69..10a3dd1 100644 --- a/src/test/scala/ru/org/codingteam/horta/plugins/pet/PetPluginSpec.scala +++ b/src/test/scala/ru/org/codingteam/horta/plugins/pet/PetPluginSpec.scala @@ -7,19 +7,6 @@ import ru.org.codingteam.horta.test.TestKitSpec class PetPluginSpec extends TestKitSpec { - override def configure(): Unit = { - val content = configuration + - """ - | - |rooms=room1,room2,room3 - |room1.room=foo@example.com - |room2.room=bar@example.com - |room3.room=baz@example.com - |pet.rooms=room1,room2 - """.stripMargin - Configuration.initialize(content) - } - def createPlugin() = TestActorRef[PetPlugin].underlyingActor "PetPlugin" should { diff --git a/src/test/scala/ru/org/codingteam/horta/test/TestKitSpec.scala b/src/test/scala/ru/org/codingteam/horta/test/TestKitSpec.scala index 2067246..cb5e350 100644 --- a/src/test/scala/ru/org/codingteam/horta/test/TestKitSpec.scala +++ b/src/test/scala/ru/org/codingteam/horta/test/TestKitSpec.scala @@ -27,18 +27,19 @@ abstract class TestKitSpec extends TestKit(ActorSystem("TestSystem", ConfigFacto with Eventually { implicit val timeout = Timeout(15.seconds) - val configuration = + Configuration.initialize( """ |storage.url=jdbc:h2:hell_test;DB_CLOSE_DELAY=-1 |storage.user=sa |storage.password= - |""".stripMargin - - def configure(): Unit = { - Configuration.initialize(configuration) - } - - configure() + | + |rooms=room1,room2,room3 + |room1.room=foo@example.com + |room2.room=bar@example.com + |room3.room=baz@example.com + | + |pet.rooms=room1,room2 + """.stripMargin) val pluginProps = List[Props]() val core = system.actorOf(Props(new Core(List(Props[LogPlugin]), List())), "core") From 85680f365a89d0a359f3d880f76a1adb3426c330 Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Sat, 2 Jul 2016 15:50:38 +0700 Subject: [PATCH 7/7] #400: drop unused import --- .../ru/org/codingteam/horta/plugins/pet/PetPluginSpec.scala | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/scala/ru/org/codingteam/horta/plugins/pet/PetPluginSpec.scala b/src/test/scala/ru/org/codingteam/horta/plugins/pet/PetPluginSpec.scala index 10a3dd1..e74bc59 100644 --- a/src/test/scala/ru/org/codingteam/horta/plugins/pet/PetPluginSpec.scala +++ b/src/test/scala/ru/org/codingteam/horta/plugins/pet/PetPluginSpec.scala @@ -1,7 +1,6 @@ package ru.org.codingteam.horta.plugins.pet import akka.testkit.TestActorRef -import ru.org.codingteam.horta.configuration.Configuration import ru.org.codingteam.horta.core.Clock import ru.org.codingteam.horta.test.TestKitSpec