Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add custom websocket event type support #21

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 65 additions & 51 deletions modules/core/src/main/scala/muffin/model/websocket/domain.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package muffin.model.websocket

import scala.util._

import muffin.model.Post

object domain {
Expand All @@ -20,65 +22,77 @@ object domain {
data: A
)

enum EventType {
case Hello
case Posted
case AddedToTeam
case AuthenticationChallenge
case ChannelConverted
case ChannelCreated
case ChannelDeleted
case ChannelMemberUpdated
case ChannelUpdated
case ChannelViewed
case ConfigChanged
case DeleteTeam
case DirectAdded
case EmojiAdded
case EphemeralMessage
case GroupAdded
case LeaveTeam
case LicenseChanged
case MemberroleUpdated
case NewUser
case PluginDisabled
case PluginEnabled
case PluginStatusesChanged
case PostDeleted
case PostEdited
case PostUnread
case PreferenceChanged
case PreferencesChanged
case PreferencesDeleted
case ReactionAdded
case ReactionRemoved
case Response
case RoleUpdated
case StatusChange
case Typing
case UpdateTeam
case UserAdded
case UserRemoved
case UserRoleUpdated
case UserUpdated
case DialogOpened
case ThreadUpdated
case ThreadFollowChanged
case ThreadReadChanged
sealed trait EventType {
def repr: String
}

object EventType {

enum KnownEventType extends EventType {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DefaultEventType

case Hello
case Posted
case AddedToTeam
case AuthenticationChallenge
case ChannelConverted
case ChannelCreated
case ChannelDeleted
case ChannelMemberUpdated
case ChannelUpdated
case ChannelViewed
case ConfigChanged
case DeleteTeam
case DirectAdded
case EmojiAdded
case EphemeralMessage
case GroupAdded
case LeaveTeam
case LicenseChanged
case MemberroleUpdated
case NewUser
case PluginDisabled
case PluginEnabled
case PluginStatusesChanged
case PostDeleted
case PostEdited
case PostUnread
case PreferenceChanged
case PreferencesChanged
case PreferencesDeleted
case ReactionAdded
case ReactionRemoved
case Response
case RoleUpdated
case StatusChange
case Typing
case UpdateTeam
case UserAdded
case UserRemoved
case UserRoleUpdated
case UserUpdated
case DialogOpened
case ThreadUpdated
case ThreadFollowChanged
case ThreadReadChanged

def repr: String = this.toString
}

def fromSnakeCase(s: String): EventType = {
val tokens = s.split("_").toList.map(_.capitalize)
EventType.valueOf(
tokens.foldLeft(new StringBuilder(tokens.length)) {
(builder, token) => builder.addAll(token)
}
.toString()
)
Try(
KnownEventType.valueOf(
tokens.foldLeft(new StringBuilder(tokens.length)) {
(builder, token) => builder.addAll(token)
}
.result()
)
) match {
case Success(tpe) => tpe
case Failure(_) => CustomEventType(s)
}
}

case class CustomEventType(repr: String) extends EventType
}

case class PostedEventData(channelName: String, channelType: ChannelType, senderName: String, post: Post)
Expand Down
8 changes: 4 additions & 4 deletions modules/core/src/test/scala/muffin/api/ApiTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ trait ApiTest[To[_], From[_]](integration: String, codecSupport: CodecSupport[To
.websocket()
.flatMap(
_.addListener[domain.TestObject](
EventType.Hello,
EventType.KnownEventType.Hello,
event => listenedEvent.complete(event).void
)
.connect()
Expand All @@ -310,7 +310,7 @@ trait ApiTest[To[_], From[_]](integration: String, codecSupport: CodecSupport[To
.websocket()
.flatMap(
_.addListener[String](
EventType.Hello,
EventType.KnownEventType.Hello,
event =>
listenedEvents.offer(domain.TestObject.default)
)
Expand All @@ -325,7 +325,7 @@ trait ApiTest[To[_], From[_]](integration: String, codecSupport: CodecSupport[To
.websocket()
.flatMap(
_.addListener[domain.TestObject](
EventType.Hello,
EventType.KnownEventType.Hello,
event => listenedEvents.offer(event)
)
.connect()
Expand All @@ -347,7 +347,7 @@ trait ApiTest[To[_], From[_]](integration: String, codecSupport: CodecSupport[To
.websocket()
.flatMap(
_.addListener[PostedEventData](
EventType.Posted,
EventType.KnownEventType.Posted,
event => listenedEvent.complete(event).void
)
.connect()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package muffin.model.websocket

import scala.concurrent.Future
import scala.util.Try

import muffin.api.ApiTestSupport
import muffin.model.websocket.domain.*
Expand Down Expand Up @@ -61,16 +60,19 @@ class EntityTypeParsingTest() extends ApiTestSupport {

val result: List[EventType] = rawTypes.map(EventType.fromSnakeCase)

Future.successful(assert(result.length == EventType.values.length))
Future.successful(assert(result.length == EventType.KnownEventType.values.length))
}
Scenario(s"Parse from snake case, incorrect kebab case raw types $integration") {
val rawTypes = List(
"added-to-team"
)
Scenario(s"Parse from snake case custom types $integration") {
val rawType = "everything you want here"

val result = rawTypes.map(tpe => Try(EventType.fromSnakeCase(tpe)))
val result = EventType.fromSnakeCase(rawType)

Future.successful(assert(result.head.isFailure))
Future.successful(
result match {
case _: EventType.KnownEventType => assert(false, "must be a custom type")
case EventType.CustomEventType(_) => assert(true)
}
)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,10 @@ class CirceApiTest extends ApiTest[Encoder, Decoder]("circe", codec) {
.map(postingEvent =>
List(
Event(
EventType.Hello,
EventType.KnownEventType.Hello,
RawJson.from(Encoder[domain.TestObject].apply(domain.TestObject.default).toString)
),
Event(EventType.Posted, RawJson.from(postingEvent))
Event(EventType.KnownEventType.Posted, RawJson.from(postingEvent))
)
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,10 @@ class ZioApiTest extends ApiTest[JsonEncoder, JsonDecoder]("zio", codec) {
private val events = loadResource("websockets/posting/postingWithFileIds.json").map(postingEvent =>
List(
Event(
EventType.Hello,
EventType.KnownEventType.Hello,
RawJson.from(domain.TestObject.default.toJson)
),
Event(EventType.Posted, RawJson.from(postingEvent))
Event(EventType.KnownEventType.Posted, RawJson.from(postingEvent))
)
)
}
Expand Down