diff --git a/lib/exirc/client.ex b/lib/exirc/client.ex index e9183ac..3cea999 100644 --- a/lib/exirc/client.ex +++ b/lib/exirc/client.ex @@ -24,6 +24,7 @@ defmodule ExIRC.Client do ssl?: false, connected?: false, logged_on?: false, + motd: "", autoping: true, channel_prefixes: "", network: "", @@ -585,8 +586,29 @@ defmodule ExIRC.Client do if state.debug?, do: debug "RECEIVING SERVER CAPABILITIES" {:noreply, Utils.isup(msg.args, state)} end - # Called when the client enters a channel + # Called on server sends RPL_MOTDSTART. Resets the MOTD to empty. + def handle_data(%ExIRC.Message{cmd: @rpl_motdstart} = msg, state) do + {:noreply, %{state | motd: ""}} + end + + # Called when server sends RPL_MOTD. Appends the line the current MOTD. + def handle_data(%ExIRC.Message{cmd: @rpl_motd, args: [_nick, "- " <> line]} = msg, state) do + motd = state.motd <> line <> "\n" + {:noreply, %{state | motd: motd}} + end + + # Called when server sends RPL_ENDOFMOTD. Trims the last newline char from the + # MOTD (because an extra was appended while handling the last RPL_MOTD line) + # and sends a :received_motd event. + def handle_data(%ExIRC.Message{cmd: @rpl_endofmotd} = msg, state) do + motd = String.slice(state.motd, 0..-2) + state = %{state | motd: motd} + send_event {:received_motd, motd}, state + {:noreply, state} + end + + # Called when the client enters a channel def handle_data(%ExIRC.Message{nick: nick, cmd: "JOIN"} = msg, %ClientState{nick: nick} = state) do channel = msg.args |> List.first |> String.trim if state.debug?, do: debug "JOINED A CHANNEL #{channel}" diff --git a/test/client_test.exs b/test/client_test.exs index b56de8b..34e15ca 100644 --- a/test/client_test.exs +++ b/test/client_test.exs @@ -50,6 +50,35 @@ defmodule ExIRC.ClientTest do assert_receive {:login_failed, :nick_in_use}, 10 end + test "receiving the whole MOTD sends an event to handler" do + motd = """ + I am a multi- + line motd + """ + state = %{get_state() | channels: []} + + {:noreply, state} = Client.handle_data(%ExIRC.Message{ + cmd: @rpl_motdstart, + args: [state.nick, "- " <> state.server <> " message of the day"] + }, state) + + state = motd + |> String.split("\n") + |> List.foldl(state, fn(line, new_state) -> + msg = %ExIRC.Message{cmd: @rpl_motd, args: [new_state.nick, "- " <> line]} + {:noreply, new_state} = Client.handle_data(msg, new_state) + new_state + end) + + {:noreply, state} = Client.handle_data(%ExIRC.Message{ + cmd: @rpl_endofmotd, + args: [state.nick, "End of MOTD command"] + }, state) + + assert state.motd == motd + assert_receive {:received_motd, motd}, 10 + end + test "own nick change sends event to handler" do state = get_state() msg = %ExIRC.Message{nick: state.nick, cmd: "NICK", args: ["new_nick"]}