nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: Kraigie/nostrum
Pull request #362 (2021-11-15 04:02:32)

fix: Parse role permissions if they're a string
Noticed when trying to get guild permissions for a user that permissions where being given as a string for some reason, resulting in an arithmetic error with the function using `:erlang.bor`, and sure enough listing roles and their permissions gives a list of strings:
```elixir
iex(3)> Nostrum.Cache.GuildCache.get!(441529557691006977).roles |> Enum.map(fn {_, role} -> role.permissions end)
["1071698533952", "6546644544", "8559918328"]
```

This adds an extra step in `Role.to_struct` that parses permissions if its a string, and corresponding test to make sure it works properly.


Patch:
diff --git a/lib/nostrum/struct/guild/role.ex b/lib/nostrum/struct/guild/role.ex
index 8c1027dc..0dd8d946 100644
--- a/lib/nostrum/struct/guild/role.ex
+++ b/lib/nostrum/struct/guild/role.ex
@@ -95,6 +95,10 @@ defmodule Nostrum.Struct.Guild.Role do
       map
       |> Map.new(fn {k, v} -> {Util.maybe_to_atom(k), v} end)
       |> Map.update(:id, nil, &Util.cast(&1, Snowflake))
+      |> Map.update(:permissions, nil, fn
+        perm when is_binary(perm) -> String.to_integer(perm)
+        x -> x
+      end)
 
     struct(__MODULE__, new)
   end


Test patch:
diff --git a/test/nostrum/struct/guild/role_test.exs b/test/nostrum/struct/guild/role_test.exs
index 66eac5ef..0d76c9f2 100644
--- a/test/nostrum/struct/guild/role_test.exs
+++ b/test/nostrum/struct/guild/role_test.exs
@@ -12,4 +12,34 @@ defmodule Nostrum.Struct.Guild.RoleTest do
       assert(to_string(role) === Role.mention(role))
     end
   end
+
+  describe "Role.to_struct\1" do
+    setup do
+      etf_role = %{
+        "id" => "431884023535632398",
+        "name" => "cool people",
+        "color" => 0x00FEED,
+        "hoist" => true,
+        "position" => 1,
+        "permissions" => "8559918328",
+        "managed" => false,
+        "mentionable" => true
+      }
+
+      role = Role.to_struct(etf_role)
+
+      {:ok, %{etf_role: etf_role, role: role}}
+    end
+
+    test "decodes to t:Role.t/0", context do
+      assert(%Role{} = context.role)
+    end
+
+    test "decodes string permissions correctly", context do
+      expected = String.to_integer(context.etf_role["permissions"])
+
+      assert(is_integer(context.role.permissions))
+      assert(expected === context.role.permissions)
+    end
+  end
 end