api-surface #1
4 changed files with 293 additions and 0 deletions
feat(model): User, AvatarDecorationData, PrimaryGuild, Emoji, PartialEmoji, Sticker, StickerItem
commit
5570609adb
30
lib/dexcord/model/emoji.ex
Normal file
30
lib/dexcord/model/emoji.ex
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
defmodule Dexcord.Emoji do
|
||||
@moduledoc "A guild emoji. https://docs.discord.com/developers/resources/emoji"
|
||||
use Dexcord.Struct
|
||||
|
||||
discord_struct do
|
||||
field :id, :snowflake
|
||||
field :name, :string
|
||||
field :roles, {:list, :snowflake}, default: []
|
||||
field :user, {:struct, Dexcord.User}
|
||||
field :require_colons, :boolean
|
||||
field :managed, :boolean
|
||||
field :animated, :boolean, default: false
|
||||
field :available, :boolean
|
||||
end
|
||||
end
|
||||
|
||||
defmodule Dexcord.PartialEmoji do
|
||||
@moduledoc """
|
||||
The minimal emoji shape used in reactions, components, and poll media.
|
||||
Unicode emoji: `id` nil, `name` the character. Custom: `id` set; `name`
|
||||
may be nil when the emoji's data is unavailable (deleted custom emoji).
|
||||
"""
|
||||
use Dexcord.Struct
|
||||
|
||||
discord_struct do
|
||||
field :id, :snowflake
|
||||
field :name, :string
|
||||
field :animated, :boolean, default: false
|
||||
end
|
||||
end
|
||||
29
lib/dexcord/model/sticker.ex
Normal file
29
lib/dexcord/model/sticker.ex
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
defmodule Dexcord.Sticker do
|
||||
@moduledoc "A message sticker. https://docs.discord.com/developers/resources/sticker"
|
||||
use Dexcord.Struct
|
||||
|
||||
discord_struct do
|
||||
field :id, :snowflake
|
||||
field :pack_id, :snowflake
|
||||
field :name, :string
|
||||
field :description, :string
|
||||
field :tags, :string
|
||||
field :type, {:enum, Dexcord.StickerType}
|
||||
field :format_type, {:enum, Dexcord.StickerFormatType}
|
||||
field :available, :boolean
|
||||
field :guild_id, :snowflake
|
||||
field :user, {:struct, Dexcord.User}
|
||||
field :sort_value, :integer
|
||||
end
|
||||
end
|
||||
|
||||
defmodule Dexcord.StickerItem do
|
||||
@moduledoc "The smallest amount of data required to render a sticker."
|
||||
use Dexcord.Struct
|
||||
|
||||
discord_struct do
|
||||
field :id, :snowflake
|
||||
field :name, :string
|
||||
field :format_type, {:enum, Dexcord.StickerFormatType}
|
||||
end
|
||||
end
|
||||
48
lib/dexcord/model/user.ex
Normal file
48
lib/dexcord/model/user.ex
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
defmodule Dexcord.User do
|
||||
@moduledoc "A Discord user. https://docs.discord.com/developers/resources/user"
|
||||
use Dexcord.Struct
|
||||
|
||||
discord_struct do
|
||||
field :id, :snowflake
|
||||
field :username, :string
|
||||
field :discriminator, :string
|
||||
field :global_name, :string
|
||||
field :avatar, :string
|
||||
field :bot, :boolean, default: false
|
||||
field :system, :boolean, default: false
|
||||
field :mfa_enabled, :boolean
|
||||
field :banner, :string
|
||||
field :accent_color, :integer
|
||||
field :locale, :string
|
||||
field :verified, :boolean
|
||||
field :email, :string
|
||||
field :flags, {:flags, Dexcord.UserFlags}
|
||||
field :premium_type, {:enum, Dexcord.PremiumType}
|
||||
field :public_flags, {:flags, Dexcord.UserFlags}
|
||||
field :avatar_decoration_data, {:struct, Dexcord.AvatarDecorationData}
|
||||
field :collectibles, :raw
|
||||
field :primary_guild, {:struct, Dexcord.PrimaryGuild}
|
||||
end
|
||||
end
|
||||
|
||||
defmodule Dexcord.AvatarDecorationData do
|
||||
@moduledoc false
|
||||
use Dexcord.Struct
|
||||
|
||||
discord_struct do
|
||||
field :asset, :string
|
||||
field :sku_id, :snowflake
|
||||
end
|
||||
end
|
||||
|
||||
defmodule Dexcord.PrimaryGuild do
|
||||
@moduledoc "A user's primary-guild (server tag) identity."
|
||||
use Dexcord.Struct
|
||||
|
||||
discord_struct do
|
||||
field :identity_guild_id, :snowflake
|
||||
field :identity_enabled, :boolean
|
||||
field :tag, :string
|
||||
field :badge, :string
|
||||
end
|
||||
end
|
||||
186
test/dexcord/model_user_test.exs
Normal file
186
test/dexcord/model_user_test.exs
Normal file
|
|
@ -0,0 +1,186 @@
|
|||
defmodule Dexcord.ModelUserTest do
|
||||
use ExUnit.Case, async: true
|
||||
|
||||
describe "User.from_map/1" do
|
||||
test "full user map decodes field-correct with snowflake normalized to integer" do
|
||||
map = %{
|
||||
"id" => "80351110224678912",
|
||||
"username" => "Nelly",
|
||||
"discriminator" => "1337",
|
||||
"global_name" => "Nelly",
|
||||
"avatar" => "8342729096ea3675442027381ff50dfe",
|
||||
"bot" => false,
|
||||
"system" => false,
|
||||
"mfa_enabled" => true,
|
||||
"banner" => "06c16474723fe537c283b8efa61a30c8",
|
||||
"accent_color" => 16_711_680,
|
||||
"locale" => "en-US",
|
||||
"verified" => true,
|
||||
"email" => "nelly@discord.com",
|
||||
"flags" => 64,
|
||||
"premium_type" => 1,
|
||||
"public_flags" => 64,
|
||||
"avatar_decoration_data" => %{
|
||||
"asset" => "a_fb5bc2b3625390fd53a5e6ecb268e5ba",
|
||||
"sku_id" => "1144058844004233369"
|
||||
},
|
||||
"collectibles" => %{"nameplate" => %{"sku_id" => "x"}},
|
||||
"primary_guild" => %{
|
||||
"identity_guild_id" => "123456789",
|
||||
"identity_enabled" => true,
|
||||
"tag" => "PONY",
|
||||
"badge" => "abc123"
|
||||
}
|
||||
}
|
||||
|
||||
user = Dexcord.User.from_map(map)
|
||||
|
||||
assert user.id == 80_351_110_224_678_912
|
||||
assert user.username == "Nelly"
|
||||
assert user.discriminator == "1337"
|
||||
assert user.global_name == "Nelly"
|
||||
assert user.avatar == "8342729096ea3675442027381ff50dfe"
|
||||
assert user.bot == false
|
||||
assert user.system == false
|
||||
assert user.mfa_enabled == true
|
||||
assert user.banner == "06c16474723fe537c283b8efa61a30c8"
|
||||
assert user.accent_color == 16_711_680
|
||||
assert user.locale == "en-US"
|
||||
assert user.verified == true
|
||||
assert user.email == "nelly@discord.com"
|
||||
assert user.flags == 64
|
||||
assert user.premium_type == :nitro_classic
|
||||
assert user.public_flags == 64
|
||||
assert user.collectibles == %{"nameplate" => %{"sku_id" => "x"}}
|
||||
|
||||
assert %Dexcord.AvatarDecorationData{} = user.avatar_decoration_data
|
||||
assert user.avatar_decoration_data.asset == "a_fb5bc2b3625390fd53a5e6ecb268e5ba"
|
||||
assert user.avatar_decoration_data.sku_id == 1_144_058_844_004_233_369
|
||||
|
||||
assert %Dexcord.PrimaryGuild{} = user.primary_guild
|
||||
assert user.primary_guild.identity_guild_id == 123_456_789
|
||||
assert user.primary_guild.identity_enabled == true
|
||||
assert user.primary_guild.tag == "PONY"
|
||||
assert user.primary_guild.badge == "abc123"
|
||||
end
|
||||
|
||||
test "minimal user map defaults other fields to nil and bot to false" do
|
||||
map = %{
|
||||
"id" => "1",
|
||||
"username" => "min",
|
||||
"discriminator" => "0",
|
||||
"global_name" => "min",
|
||||
"avatar" => nil
|
||||
}
|
||||
|
||||
user = Dexcord.User.from_map(map)
|
||||
|
||||
assert user.id == 1
|
||||
assert user.username == "min"
|
||||
assert user.avatar == nil
|
||||
assert user.bot == false
|
||||
assert user.system == false
|
||||
assert user.mfa_enabled == nil
|
||||
assert user.flags == nil
|
||||
assert user.premium_type == nil
|
||||
assert user.avatar_decoration_data == nil
|
||||
assert user.primary_guild == nil
|
||||
end
|
||||
|
||||
test "round-trip re-encodes id as a string" do
|
||||
map = %{"id" => "80351110224678912", "username" => "Nelly", "discriminator" => "1337"}
|
||||
out = map |> Dexcord.User.from_map() |> Dexcord.User.to_map()
|
||||
assert out["id"] == "80351110224678912"
|
||||
assert out["username"] == "Nelly"
|
||||
end
|
||||
end
|
||||
|
||||
describe "PartialEmoji.from_map/1" do
|
||||
test "unicode emoji decodes with nil id and the character as name" do
|
||||
emoji = Dexcord.PartialEmoji.from_map(%{"id" => nil, "name" => "🔥"})
|
||||
assert emoji.id == nil
|
||||
assert emoji.name == "🔥"
|
||||
assert emoji.animated == false
|
||||
end
|
||||
|
||||
test "custom emoji decodes id, name, and animated" do
|
||||
emoji = Dexcord.PartialEmoji.from_map(%{"id" => "123", "name" => "blob", "animated" => true})
|
||||
assert emoji.id == 123
|
||||
assert emoji.name == "blob"
|
||||
assert emoji.animated == true
|
||||
end
|
||||
|
||||
test "deleted custom emoji with null name decodes name to nil" do
|
||||
emoji = Dexcord.PartialEmoji.from_map(%{"id" => "123", "name" => nil})
|
||||
assert emoji.id == 123
|
||||
assert emoji.name == nil
|
||||
end
|
||||
end
|
||||
|
||||
describe "Emoji.from_map/1" do
|
||||
test "guild emoji decodes with roles and nested user" do
|
||||
map = %{
|
||||
"id" => "41771983429993937",
|
||||
"name" => "LUL",
|
||||
"roles" => ["41771983429993000"],
|
||||
"user" => %{"id" => "96008815106887111", "username" => "Cool", "discriminator" => "0001"},
|
||||
"require_colons" => true,
|
||||
"managed" => false,
|
||||
"animated" => false,
|
||||
"available" => true
|
||||
}
|
||||
|
||||
emoji = Dexcord.Emoji.from_map(map)
|
||||
|
||||
assert emoji.id == 41_771_983_429_993_937
|
||||
assert emoji.name == "LUL"
|
||||
assert emoji.roles == [41_771_983_429_993_000]
|
||||
assert %Dexcord.User{} = emoji.user
|
||||
assert emoji.user.id == 96_008_815_106_887_111
|
||||
assert emoji.require_colons == true
|
||||
assert emoji.animated == false
|
||||
assert emoji.available == true
|
||||
end
|
||||
|
||||
test "roles defaults to empty list when absent" do
|
||||
emoji = Dexcord.Emoji.from_map(%{"id" => "1", "name" => "x"})
|
||||
assert emoji.roles == []
|
||||
end
|
||||
end
|
||||
|
||||
describe "Sticker.from_map/1 and StickerItem.from_map/1" do
|
||||
test "sticker decodes type and format_type enums and nested user" do
|
||||
map = %{
|
||||
"id" => "749054660769218631",
|
||||
"pack_id" => "847199849233514549",
|
||||
"name" => "Wave",
|
||||
"description" => "Wumpus waves hello",
|
||||
"tags" => "wumpus, hello, sup, hi, oh, greeting, wave, welcome",
|
||||
"type" => 1,
|
||||
"format_type" => 3,
|
||||
"available" => true,
|
||||
"guild_id" => "1",
|
||||
"user" => %{"id" => "2", "username" => "u", "discriminator" => "0"},
|
||||
"sort_value" => 12
|
||||
}
|
||||
|
||||
sticker = Dexcord.Sticker.from_map(map)
|
||||
|
||||
assert sticker.id == 749_054_660_769_218_631
|
||||
assert sticker.pack_id == 847_199_849_233_514_549
|
||||
assert sticker.name == "Wave"
|
||||
assert sticker.type == :standard
|
||||
assert sticker.format_type == :lottie
|
||||
assert sticker.available == true
|
||||
assert %Dexcord.User{} = sticker.user
|
||||
assert sticker.sort_value == 12
|
||||
end
|
||||
|
||||
test "sticker item decodes minimal shape" do
|
||||
item = Dexcord.StickerItem.from_map(%{"id" => "1", "name" => "Wave", "format_type" => 1})
|
||||
assert item.id == 1
|
||||
assert item.name == "Wave"
|
||||
assert item.format_type == :png
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue