diff --git a/lib/gateway/command.ex b/lib/gateway/command.ex index 44e074e..f2eea55 100644 --- a/lib/gateway/command.ex +++ b/lib/gateway/command.ex @@ -98,8 +98,8 @@ defmodule Crux.Gateway.Command do Used to join, switch between, and leave voice channels and/or change self_mute or self_deaf states. """ @spec voice_state_update( - guild_id :: pos_integer(), - channel_id :: pos_integer() | nil, + guild_id :: Crux.Structs.Snowflake.t(), + channel_id :: Crux.Structs.Snowflake.t() | nil, states :: [{:self_mute, boolean()} | {:self_deaf, boolean()}] ) :: command() def voice_state_update(guild_id, channel_id \\ nil, states \\ []) do @@ -158,18 +158,38 @@ defmodule Crux.Gateway.Command do The gateway will respond with `:GUILD_MEMBER_CHUNK` packets until all appropriate members are received. """ @spec request_guild_members( - guild_id :: pos_integer(), - opts :: [{:query, String.t()} | {:limit, pos_integer()}] + guild_id :: Crux.Structs.Snowflake.t(), + opts :: + [ + {:query, String.t()} + | {:limit, non_neg_integer()} + | {:presences, boolean()} + | {:user_ids, Crux.Structs.Snowflake.t() | [Crux.Structs.Snowflake.t()]} + ] + | map() ) :: command() - def request_guild_members(guild_id, opts \\ []) do + def request_guild_members(guild_id, opts \\ []) + + def request_guild_members(guild_id, %{} = opts) do + other_opts = + case opts do + %{query: query, user_ids: user_ids} -> %{"query" => query, "user_ids" => user_ids} + %{query: query} -> %{"query" => query} + %{user_ids: user_ids} -> %{"user_ids" => user_ids} + %{} -> %{"query" => ""} + end + %{ "guild_id" => guild_id, - "query" => opts[:query] || "", - "limit" => opts[:limit] || 0 + "limit" => Map.get(opts, :limit, 0), + "presences" => Map.get(opts, :presences, false) } + |> Map.merge(other_opts) |> finalize(8) end + def request_guild_members(guild_id, opts), do: request_guild_members(guild_id, Map.new(opts)) + @doc """ Builds a [Resume](https://discordapp.com/developers/docs/topics/gateway#resume) command. diff --git a/test/command_test.exs b/test/command_test.exs new file mode 100644 index 0000000..8ac5439 --- /dev/null +++ b/test/command_test.exs @@ -0,0 +1,62 @@ +defmodule Crux.Gateway.CommandTest do + use ExUnit.Case + doctest Crux.Gateway.Command + + # Since the commands directly make it WebSocket friendly + defp unfinalize({:binary, data}) do + %{"d" => d} = :erlang.binary_to_term(data) + + d + end + + describe "request_guild_members/1,2" do + # Get the guild_id out of the way + def request_guild_members(opts \\ []) do + Crux.Gateway.Command.request_guild_members(1234, opts) + end + + # Builds the expected map, including defaults + defp build_expected(opts) do + opts = Map.new(opts, fn {k, v} -> {to_string(k), v} end) + + %{"guild_id" => 1234, "limit" => 0, "presences" => false} + |> Map.merge(opts) + end + + test "/1" do + received = request_guild_members() |> unfinalize() + # The default is all of them + expected = build_expected(query: "") + + assert received === expected + end + + test "all options" do + opts = %{query: "space", limit: 15, user_ids: [1, 2, 3], presences: true} + + received = request_guild_members(opts) |> unfinalize() + + expected = build_expected(query: "space", limit: 15, user_ids: [1, 2, 3], presences: true) + + assert received === expected + end + + test "query does not return user_ids" do + opts = [query: "space"] + + received = request_guild_members(opts) |> unfinalize() + expected = build_expected(query: "space") + + assert received === expected + end + + test "user_ids does not return query" do + opts = [user_ids: [1, 2, 3]] + + received = request_guild_members(opts) |> unfinalize() + expected = build_expected(user_ids: [1, 2, 3]) + + assert received === expected + end + end +end diff --git a/test/test_helper.exs b/test/test_helper.exs new file mode 100644 index 0000000..869559e --- /dev/null +++ b/test/test_helper.exs @@ -0,0 +1 @@ +ExUnit.start()