{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# OPTIONS_GHC -Wno-overlapping-patterns #-}
-- | basic stuff like connecting to a room and sending messages
module RoomSpec where
import Network.XMPP.XML
import Network.XMPP.XEP.MUC
import Data.Text(Text)
import Control.Exception
import Test.Hspec
import Network.XMPP.Types
import Network.XMPP.Helpers
import Network.XMPP.Core
import Control.Monad.IO.Class
import Control.Monad
import Network.XMPP.Stream
import Network.XMPP.Ejabberd
import Network.XMPP.Types
import Network.XMPP.Concurrent
import Data.Traversable
deriving instance Exception XmppError
spec :: Spec
spec = describe "ejabbered server tests" $ do
it "gets a connection" $ do
handle <- liftIO $ connectViaTcp "localhost" 5222
registerNewUser localEjabberdHost (EUser "jappie" "pass") (VHost "localhost")
(result, stream) <- runXmppMonad $ initStream handle "localhost" "jappie" "pass" "someResource"
nodeResource <- either throwIO pure result
void $ runXmppMonad' stream closeStream
it "can connect to a room" $ do
handle <- liftIO $ connectViaTcp "localhost" 5222
registerNewUser localEjabberdHost (EUser "jappie" "pass") (VHost "localhost")
registerNewUser localEjabberdHost (EUser "jesiska" "pass") (VHost "localhost")
(result, stream) <- runXmppMonad $ do
jappie <- either (error "init failure") id <$> initStream handle "localhost" "jappie" "pass" "someResource"
xmppSend =<< withUUID (createRoomStanza jappie (mkParticipantJIDForRoom "jappie" someRoom))
xmppSend =<< withUUID (createRoomStanza jappie (mkParticipantJIDForRoom "jesiska" someRoom))
pure $! seq result -- no lazy
void $ runXmppMonad' stream closeStream
it "can exchange messages" $ do
handle <- liftIO $ connectViaTcp "localhost" 5222
registerNewUser localEjabberdHost (EUser "jappie" "pass") (VHost "localhost")
registerNewUser localEjabberdHost (EUser "jesiska" "pass") (VHost "localhost")
void $ runXmppMonad $ do
jappie <- either (error "init failure") id <$> initStream handle "localhost" "jappie" "pass" "someResource"
xmppSend =<< withUUID (createRoomStanza jappie (mkParticipantJIDForRoom "jappie" someRoom))
xmppSend =<< withUUID (createRoomStanza jappie (mkParticipantJIDForRoom "jesiska" someRoom ))
let
expectedMsg = "some-msg"
stanza <- withUUID (roomMessageStanza jappie someRoom expectedMsg)
xmppSend $ stanza
stanze <- replicateM 10 parseM -- the order appears to be random
-- liftIO $ print stanze
for stanze $ \selected ->
case selected of
Left x -> liftIO $ throwIO x
Right msg -> case msg :: SomeStanza MUCPayload of
SomeStanza (MkMessage {mBody,mFrom, mPurpose = SIncoming}) -> do
liftIO $ unless (mBody == "") $ mBody `shouldBe` "some-msg"
unkown -> do
pure () -- skip
closeStream
someRoom :: JID 'Node
someRoom = mkRoomJID "localhost" "blah"
mkRoomJID :: Server -> Text -> JID 'Node
mkRoomJID srv roomId = NodeJID (NodeID roomId) $ DomainID $ "conference." <> srv
mkParticipantJIDForRoom :: Username -> RoomJID -> RoomMemberJID
mkParticipantJIDForRoom username NodeJID {..} =
NodeResourceJID nNode nDomain $ ResourceID username