Skip to content

Commit

Permalink
Moved direct messages into core:
Browse files Browse the repository at this point in the history
- moved UsersStorage
- moved DirectMessageModel
- moved Test
  • Loading branch information
marioosh committed Jul 2, 2015
1 parent bc37cd6 commit 897dd9f
Show file tree
Hide file tree
Showing 3 changed files with 192 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package io.scalac.slack.common

import org.joda.time.DateTime
import akka.actor.ActorRef
import akka.pattern._
import akka.util.Timeout

import scala.annotation.tailrec
import scala.concurrent.ExecutionContext

/**
* Created on 08.02.15 22:04
Expand Down Expand Up @@ -54,11 +57,11 @@ case object Ping extends OutgoingMessage {
case class OutboundMessage(channel: String, text: String) extends OutgoingMessage {
override def toJson =
s"""{
|"id": ${MessageCounter.next},
|"type": "message",
|"channel": "$channel",
|"text": "$text"
|}""".stripMargin
|"id": ${MessageCounter.next},
|"type": "message",
|"channel": "$channel",
|"text": "$text"
|}""".stripMargin
}

sealed trait RichMessageElement
Expand Down Expand Up @@ -136,3 +139,20 @@ object Outgoing extends MessageEventType
* it's needed because of their similiarity
*/
case class MessageType(messageType: String, subType: Option[String])

/**
* Direct message is message send by the private channel
* userStorage try to find channel ID and if will
* message is translated into basic message and send to this channel.
*/
object DirectMessage extends {

def apply(key: String, message: String)(implicit context: ExecutionContext, userStorage: ActorRef, timeout: Timeout, forward: (OutboundMessage) => Unit): Unit = {

userStorage ? FindChannel(key) onSuccess {
case Some(channel: String) =>
forward(OutboundMessage(channel, message))
}

}
}
63 changes: 63 additions & 0 deletions src/main/scala/io/scalac/slack/common/UsersStorage.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package io.scalac.slack.common

import akka.actor.{Actor, ActorLogging}
import io.scalac.slack.api.Ok
import io.scalac.slack.models.{DirectChannel, Presence, SlackUser}

import scala.language.{implicitConversions, postfixOps}

/**
* Maintainer: @marioosh
*/
class UsersStorage extends Actor with ActorLogging {

var userCatalog = List.empty[UserInfo]
var channelCatalog = List.empty[DirectChannel]

implicit def convertUsers(su: SlackUser): UserInfo = UserInfo(su.id.trim, su.name.trim, su.presence)

override def receive: Receive = {
case RegisterUsers(users@_*) =>
users.filterNot(u => u.deleted).foreach(addUser(_))
sender ! Ok

case FindUser(key) => sender ! userCatalog.find { user =>
val matcher = key.trim.toLowerCase
matcher == user.id || matcher == user.name
}

case RegisterDirectChannels(channels@_*) =>
channels foreach addDirectChannel
sender ! Ok

case FindChannel(key) =>

val id = userCatalog.find(u => u.name == key.trim.toLowerCase) match {
case Some(user) => user.id
case None => key
}
sender ! channelCatalog.find(c => c.id == id || c.userId == id).map(_.id)

}

def addDirectChannel(channel: DirectChannel): Unit = {
channelCatalog = channel :: channelCatalog.filterNot(_.userId == channel.userId)
}

private def addUser(user: UserInfo): Unit = {
userCatalog = user :: userCatalog.filterNot(_.id == user.id)
}

}

case class UserInfo(id: String, name: String, presence: Presence) {
def userLink() = s"""<@$id|name>"""
}

case class RegisterUsers(slackUsers: SlackUser*)

case class RegisterDirectChannels(ims: DirectChannel*)

case class FindUser(key: String)

case class FindChannel(key: String)
103 changes: 103 additions & 0 deletions src/test/scala/io/scalac/slack/common/UsersStorageTest.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package io.scalac.slack.common

import akka.actor.{ActorSystem, Props}
import akka.testkit.{DefaultTimeout, ImplicitSender, TestKit}
import io.scalac.slack.api.Ok
import io.scalac.slack.models.{Active, DirectChannel, SlackUser}
import org.scalatest.{BeforeAndAfterAll, Matchers, WordSpecLike}

import scala.concurrent.duration._
import scala.language.postfixOps

/**
* Maintainer: @marioosh
*/
class UsersStorageTest(_system: ActorSystem) extends TestKit(_system) with DefaultTimeout with ImplicitSender with Matchers with WordSpecLike with BeforeAndAfterAll {

def this() = this(ActorSystem("UsersStorageTestActorSystem"))

override protected def afterAll(): Unit = TestKit.shutdownActorSystem(system)

"UserStorage" must {

"save incoming users" in {
val mario = SlackUser("1234", "mario", deleted = false, Some(false), None, None, None, None, None, None, Active)
val stefek = SlackUser("12345", "stefek", deleted = false, Some(false), None, None, None, None, None, None, Active)
val us = system.actorOf(Props[UsersStorage])

within(2 seconds) {
us ! RegisterUsers(mario)
expectMsg(Ok)
}

}

"find user from storage" in {
val mario = SlackUser("1234", "mario", deleted = false, Some(false), None, None, None, None, None, None, Active)
val stefek = SlackUser("12345", "stefek", deleted = false, Some(false), None, None, None, None, None, None, Active)
val us = system.actorOf(Props[UsersStorage])

within(1 second) {
us ! RegisterUsers(mario, stefek)
expectMsg(Ok)
us ! FindUser("mario")
expectMsg(Some(UserInfo("1234", "mario", Active)))
us ! FindUser("12345")
expectMsg(Some(UserInfo("12345", "stefek", Active)))
us ! FindUser("gitara")
expectMsg(None)

}
}
}


"Channel Catalog" must {
"be able to add new channel and find it" in {
val im1 = DirectChannel("D123", "U123")
val im2 = DirectChannel("D124", "U124")
val im3 = DirectChannel("D125", "U124")

val us = system.actorOf(Props[UsersStorage])

within(1 second) {
us ! RegisterDirectChannels(im1, im2)
expectMsg(Ok)
us ! RegisterDirectChannels(im3)
expectMsg(Ok)
us ! FindChannel("D12234")
expectMsg(None)
us ! FindChannel("D123")
expectMsg(Some("D123"))
us ! FindChannel("D125")
expectMsg(Some("D125"))
us ! FindChannel("U124")
expectMsg(Some("D125"))

}
}
"be able to find channel by username" in {
val im1 = DirectChannel("D123", "U123")
val mario = SlackUser("U123", "mario", deleted = false, Some(false), None, None, None, None, None, None, Active)

val us = system.actorOf(Props[UsersStorage])

within(1 second) {
us ! RegisterUsers(mario)
expectMsg(Ok)
us ! RegisterDirectChannels(im1)
expectMsg(Ok)
//find
us ! FindChannel("D123")
expectMsg(Some("D123"))
us ! FindChannel("U123")
expectMsg(Some("D123"))
us ! FindChannel("mario")
expectMsg(Some("D123"))

}

}
}

}

0 comments on commit 897dd9f

Please sign in to comment.