Skip to content

Commit

Permalink
Fix leave detection (#18)
Browse files Browse the repository at this point in the history
  • Loading branch information
ForNeVeR committed Sep 8, 2019
1 parent 641eb5a commit acf2096
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 8 deletions.
12 changes: 6 additions & 6 deletions Emulsion.Tests/Xmpp/XmppClientTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ let private createPresenceFor (roomJid: JID) nickname =
presence.SetAttributeValue(From, participantJid.FullJid)
presence

let private createSelfPresence roomJid nickname =
let private createSelfPresence roomJid nickname (statusCode: int) =
let presence = createPresenceFor roomJid nickname
let x = XElement X
let status = XElement Status
status.SetAttributeValue(Code, "110")
status.SetAttributeValue(Code, statusCode)
x.Add status
presence.Add x
presence
Expand All @@ -40,7 +40,7 @@ let private createErrorPresence roomJid nickname errorXml =
presence

let private createLeavePresence roomJid nickname =
let presence = createSelfPresence roomJid nickname
let presence = createSelfPresence roomJid nickname 307
presence.SetAttributeValue(Type, "unavailable")
presence

Expand Down Expand Up @@ -84,7 +84,7 @@ let ``enterRoom function calls JoinMultiUserChat``(): unit =
addPresenceHandler = (fun _ h -> presenceHandlers.Add h),
joinMultiUserChat = fun roomJid nickname ->
called <- true
Seq.iter (fun h -> h (createSelfPresence roomJid nickname)) presenceHandlers
Seq.iter (fun h -> h (createSelfPresence roomJid nickname 110)) presenceHandlers
)
let roomInfo = { RoomJid = JID("room@conference.example.org"); Nickname = "testuser" }
Lifetime.Using(fun lt ->
Expand Down Expand Up @@ -117,7 +117,7 @@ let ``Lifetime returned from enterRoom terminates by a room leave presence``():
XmppClientFactory.create(
addPresenceHandler = (fun _ h -> presenceHandlers.Add h),
joinMultiUserChat = fun roomJid nickname ->
sendPresence (createSelfPresence roomJid nickname) presenceHandlers
sendPresence (createSelfPresence roomJid nickname 110) presenceHandlers
)
let roomInfo = { RoomJid = JID("room@conference.example.org"); Nickname = "testuser" }
Lifetime.Using(fun lt ->
Expand All @@ -134,7 +134,7 @@ let ``Lifetime returned from enterRoom terminates by an external lifetime termin
XmppClientFactory.create(
addPresenceHandler = (fun _ h -> presenceHandlers.Add h),
joinMultiUserChat = fun roomJid nickname ->
sendPresence (createSelfPresence roomJid nickname) presenceHandlers
sendPresence (createSelfPresence roomJid nickname 110) presenceHandlers
)
let roomInfo = { RoomJid = JID("room@conference.example.org"); Nickname = "testuser" }
use ld = Lifetime.Define()
Expand Down
7 changes: 6 additions & 1 deletion Emulsion/Xmpp/SharpXmppHelper.fs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ module Elements =
let Delay = XName.Get("delay", "urn:xmpp:delay")
let Error = XName.Get "error"
let Nick = XName.Get("nick", Namespaces.StorageBookmarks)
let Status = XName.Get "status"
let Status = XName.Get("status", Namespaces.MucUser)
let X = XName.Get("x", Namespaces.MucUser)

open Elements
Expand Down Expand Up @@ -84,6 +84,11 @@ let isGroupChatMessage(message: XMPPMessage): bool =
let isEmptyMessage(message: XMPPMessage): bool =
String.IsNullOrWhiteSpace message.Text

/// See https://xmpp.org/registrar/mucstatus.html
let private removalCodes = Set.ofArray [| 301; 307; 321; 322; 332 |]
let hasRemovalCode(states: int[]): bool =
states |> Array.exists (fun x -> Set.contains x removalCodes)

let getMessageId(message: XMPPMessage): string option =
getAttributeValue message Id

Expand Down
2 changes: 1 addition & 1 deletion Emulsion/Xmpp/XmppClient.fs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ let private isSelfPresence (roomInfo: RoomInfo) (presence: XMPPPresence) =
let private isLeavePresence (roomInfo: RoomInfo) (presence: XMPPPresence) =
let presence = SharpXmppHelper.parsePresence presence
let expectedJid = sprintf "%s/%s" roomInfo.RoomJid.BareJid roomInfo.Nickname
presence.From = expectedJid && Array.contains 110 presence.States && presence.Type = Some "unavailable"
presence.From = expectedJid && presence.Type = Some "unavailable" && SharpXmppHelper.hasRemovalCode presence.States

let private extractPresenceException (roomInfo: RoomInfo) (presence: XMPPPresence) =
let presence = SharpXmppHelper.parsePresence presence
Expand Down

0 comments on commit acf2096

Please sign in to comment.