api-surface #1
3 changed files with 144 additions and 0 deletions
feat(model): Role, RoleColors, RoleTags (presence booleans), Overwrite
commit
0c22758260
11
lib/dexcord/model/overwrite.ex
Normal file
11
lib/dexcord/model/overwrite.ex
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
defmodule Dexcord.Overwrite do
|
||||
@moduledoc "A channel permission overwrite."
|
||||
use Dexcord.Struct
|
||||
|
||||
discord_struct do
|
||||
field :id, :snowflake
|
||||
field :type, {:enum, Dexcord.OverwriteType}
|
||||
field :allow, {:flags, Dexcord.Permissions}, wire_string: true
|
||||
field :deny, {:flags, Dexcord.Permissions}, wire_string: true
|
||||
end
|
||||
end
|
||||
49
lib/dexcord/model/role.ex
Normal file
49
lib/dexcord/model/role.ex
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
defmodule Dexcord.Role do
|
||||
@moduledoc "A guild role. https://docs.discord.com/developers/topics/permissions"
|
||||
use Dexcord.Struct
|
||||
|
||||
discord_struct do
|
||||
field :id, :snowflake
|
||||
field :name, :string
|
||||
field :color, :integer
|
||||
field :colors, {:struct, Dexcord.RoleColors}
|
||||
field :hoist, :boolean
|
||||
field :icon, :string
|
||||
field :unicode_emoji, :string
|
||||
field :position, :integer
|
||||
field :permissions, {:flags, Dexcord.Permissions}, wire_string: true
|
||||
field :managed, :boolean
|
||||
field :mentionable, :boolean
|
||||
field :tags, {:struct, Dexcord.RoleTags}
|
||||
field :flags, {:flags, Dexcord.RoleFlags}
|
||||
end
|
||||
end
|
||||
|
||||
defmodule Dexcord.RoleColors do
|
||||
@moduledoc false
|
||||
use Dexcord.Struct
|
||||
|
||||
discord_struct do
|
||||
field :primary_color, :integer
|
||||
field :secondary_color, :integer
|
||||
field :tertiary_color, :integer
|
||||
end
|
||||
end
|
||||
|
||||
defmodule Dexcord.RoleTags do
|
||||
@moduledoc """
|
||||
Role tags. Docs: "Tags with type null represent booleans. They will be
|
||||
present and set to null if they are 'true', and will be not present if
|
||||
they are 'false'." — the three `:presence` fields below.
|
||||
"""
|
||||
use Dexcord.Struct
|
||||
|
||||
discord_struct do
|
||||
field :bot_id, :snowflake
|
||||
field :integration_id, :snowflake
|
||||
field :premium_subscriber, :presence
|
||||
field :subscription_listing_id, :snowflake
|
||||
field :available_for_purchase, :presence
|
||||
field :guild_connections, :presence
|
||||
end
|
||||
end
|
||||
84
test/dexcord/model_role_test.exs
Normal file
84
test/dexcord/model_role_test.exs
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
defmodule Dexcord.ModelRoleTest do
|
||||
use ExUnit.Case, async: true
|
||||
|
||||
describe "Role.from_map/1 — RoleTags presence booleans (api-surface.AC2.7)" do
|
||||
test "premium_subscriber present-null is true, absent tag is false" do
|
||||
map = %{
|
||||
"id" => "1",
|
||||
"name" => "Booster",
|
||||
"permissions" => "0",
|
||||
"tags" => %{"bot_id" => "2", "premium_subscriber" => nil}
|
||||
}
|
||||
|
||||
role = Dexcord.Role.from_map(map)
|
||||
|
||||
assert %Dexcord.RoleTags{} = role.tags
|
||||
assert role.tags.premium_subscriber == true
|
||||
assert role.tags.available_for_purchase == false
|
||||
assert role.tags.guild_connections == false
|
||||
assert role.tags.bot_id == 2
|
||||
end
|
||||
end
|
||||
|
||||
describe "Role.from_map/1 — string permission bitfields (wire_string)" do
|
||||
test "a >2^31 permission string decodes to an integer" do
|
||||
role = Dexcord.Role.from_map(%{"id" => "1", "name" => "r", "permissions" => "2147483648"})
|
||||
assert role.permissions == 2_147_483_648
|
||||
end
|
||||
|
||||
test "permission bits are queryable after decode" do
|
||||
role = Dexcord.Role.from_map(%{"id" => "1", "name" => "r", "permissions" => "8"})
|
||||
assert Dexcord.Permissions.has?(role.permissions, :administrator)
|
||||
end
|
||||
end
|
||||
|
||||
describe "Role.to_map/1" do
|
||||
test "re-encodes permissions as a decimal string and premium_subscriber as present-null" do
|
||||
map = %{
|
||||
"id" => "1",
|
||||
"name" => "Booster",
|
||||
"permissions" => "8",
|
||||
"tags" => %{"premium_subscriber" => nil}
|
||||
}
|
||||
|
||||
out = map |> Dexcord.Role.from_map() |> Dexcord.Role.to_map()
|
||||
|
||||
assert out["permissions"] == "8"
|
||||
assert Map.has_key?(out["tags"], "premium_subscriber")
|
||||
assert out["tags"]["premium_subscriber"] == nil
|
||||
end
|
||||
end
|
||||
|
||||
describe "Role colors" do
|
||||
test "colors struct decodes nested" do
|
||||
map = %{
|
||||
"id" => "1",
|
||||
"name" => "r",
|
||||
"colors" => %{"primary_color" => 1, "secondary_color" => 2, "tertiary_color" => 3}
|
||||
}
|
||||
|
||||
role = Dexcord.Role.from_map(map)
|
||||
assert %Dexcord.RoleColors{} = role.colors
|
||||
assert role.colors.primary_color == 1
|
||||
assert role.colors.secondary_color == 2
|
||||
assert role.colors.tertiary_color == 3
|
||||
end
|
||||
end
|
||||
|
||||
describe "Overwrite" do
|
||||
test "allow/deny round-trip as decimal strings" do
|
||||
map = %{"id" => "1", "type" => 0, "allow" => "1024", "deny" => "0"}
|
||||
|
||||
ow = Dexcord.Overwrite.from_map(map)
|
||||
assert ow.id == 1
|
||||
assert ow.type == :role
|
||||
assert ow.allow == 1024
|
||||
assert ow.deny == 0
|
||||
|
||||
out = Dexcord.Overwrite.to_map(ow)
|
||||
assert out["allow"] == "1024"
|
||||
assert out["deny"] == "0"
|
||||
assert out["type"] == 0
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue