Skip to content

Commit

Permalink
Add discord/discourse roles (#7258)
Browse files Browse the repository at this point in the history
* Add discord/discourse roles

* Fix test
  • Loading branch information
iHiD authored Jan 8, 2025
1 parent b588365 commit db292a1
Show file tree
Hide file tree
Showing 7 changed files with 191 additions and 134 deletions.
6 changes: 5 additions & 1 deletion app/commands/user/set_discord_roles.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ def call
[MAINTAINER_ROLE_ID, user.maintainer?],
[SUPERMENTOR_ROLE_ID, user.supermentor?],
[MENTOR_ROLE_ID, user.mentor?],
[INSIDERS_ROLE_ID, user.insider?]
[INSIDERS_ROLE_ID, user.insider?],
[BOOTCAMP_ATTENDEE_ROLE_ID, user.bootcamp_attendee?],
[BOOTCAMP_MENTOR_ROLE_ID, user.bootcamp_mentor?]
].each do |role_id, condition|
add_or_remove!(role_id, condition)
rescue RestClient::NotFound
Expand Down Expand Up @@ -47,6 +49,8 @@ def remove_role!(url)
SUPERMENTOR_ROLE_ID = "1085196488436633681".freeze
MENTOR_ROLE_ID = "1192435804602105966".freeze
INSIDERS_ROLE_ID = "1096024168639766578".freeze
BOOTCAMP_ATTENDEE_ROLE_ID = "1326564387284320276".freeze
BOOTCAMP_MENTOR_ROLE_ID = "1305143333433249867".freeze
AUTH_HEADER = "Bot #{Exercism.secrets.discord_bot_token}".freeze
private_constant :API_URL, :GUILD_ID, :MAINTAINER_ROLE_ID, :SUPERMENTOR_ROLE_ID, :AUTH_HEADER
end
20 changes: 20 additions & 0 deletions app/commands/user/set_discourse_groups.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ def call
set_trust_level!
set_pm_enabled!
set_insiders!
set_bootcamp_attendee!
set_bootcamp_mentor!
rescue DiscourseApi::NotFoundError
# If the external user can't be found, then the
# oauth didn't complete so there's nothing to do.
Expand All @@ -33,6 +35,22 @@ def set_insiders!
end
end

def set_bootcamp_attendee!
if user.bootcamp_attendee?
add_to_group!(BOOTCAMP_ATTENDEES_GROUP_NAME)
else
remove_from_group!(BOOTCAMP_ATTENDEES_GROUP_NAME)
end
end

def set_bootcamp_mentor!
if user.bootcamp_mentor?
add_to_group!(BOOTCAMP_MENTORS_GROUP_NAME)
else
remove_from_group!(BOOTCAMP_MENTORS_GROUP_NAME)
end
end

def add_to_group!(group_name)
client.group_add(group_id(group_name), user_id: [discourse_user_id])
rescue DiscourseApi::UnprocessableEntity
Expand Down Expand Up @@ -63,4 +81,6 @@ def client = Exercism.discourse_client

PM_ENABLED_GROUP_NAME = "pm-enabled".freeze
INSIDERS_GROUP_NAME = "insiders".freeze
BOOTCAMP_ATTENDEES_GROUP_NAME = "bootcamp_attendees".freeze
BOOTCAMP_MENTORS_GROUP_NAME = "bootcamp_mentors".freeze
end
8 changes: 8 additions & 0 deletions db/migrate/20250108145756_add_bootcamp_roles_to_user_data.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
class AddBootcampRolesToUserData < ActiveRecord::Migration[7.0]
def change
return if Rails.env.production?

add_column :user_data, :bootcamp_attendee, :boolean, null: false, default: false
add_column :user_data, :bootcamp_mentor, :boolean, null: false, default: false
end
end
4 changes: 3 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema[7.0].define(version: 2024_12_16_055937) do
ActiveRecord::Schema[7.0].define(version: 2025_01_08_145756) do
create_table "active_storage_attachments", charset: "utf8mb4", collation: "utf8mb4_unicode_ci", force: :cascade do |t|
t.string "name", null: false
t.string "record_type", null: false
Expand Down Expand Up @@ -1393,6 +1393,8 @@
t.integer "seniority", limit: 1
t.string "bootcamp_affiliate_coupon_code"
t.string "bootcamp_free_coupon_code"
t.boolean "bootcamp_attendee", default: false, null: false
t.boolean "bootcamp_mentor", default: false, null: false
t.index ["discord_uid"], name: "index_user_data_on_discord_uid", unique: true
t.index ["first_donated_at", "show_on_supporters_page", "user_id"], name: "index_user_data__supporters-page"
t.index ["first_donated_at"], name: "index_user_data_on_first_donated_at"
Expand Down
168 changes: 36 additions & 132 deletions test/commands/user/set_discord_roles_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ class User::SetDiscordRolesTest < ActiveSupport::TestCase
uid = '111'
user = create :user, :not_mentor, discord_uid: uid

RestClient.unstub(:delete)

RestClient.expects(:delete).with(
"https://discord.com/api/guilds/854117591135027261/members/#{uid}/roles/1085196376058646559",
Authorization: "Bot #{Exercism.secrets.discord_bot_token}"
Expand All @@ -21,6 +23,14 @@ class User::SetDiscordRolesTest < ActiveSupport::TestCase
"https://discord.com/api/guilds/854117591135027261/members/#{uid}/roles/1192435804602105966",
Authorization: "Bot #{Exercism.secrets.discord_bot_token}"
)
RestClient.expects(:delete).with(
"https://discord.com/api/guilds/854117591135027261/members/#{uid}/roles/1326564387284320276",
Authorization: "Bot #{Exercism.secrets.discord_bot_token}"
)
RestClient.expects(:delete).with(
"https://discord.com/api/guilds/854117591135027261/members/#{uid}/roles/1305143333433249867",
Authorization: "Bot #{Exercism.secrets.discord_bot_token}"
)

User::SetDiscordRoles.(user)
end
Expand All @@ -35,21 +45,11 @@ class User::SetDiscordRolesTest < ActiveSupport::TestCase
end

test "adds maintainer role when user is maintainer" do
RestClient.stubs(:delete)

uid = SecureRandom.hex
user = create :user, :not_mentor, :maintainer, discord_uid: uid

RestClient.expects(:delete).with(
"https://discord.com/api/guilds/854117591135027261/members/#{uid}/roles/1085196488436633681",
Authorization: "Bot #{Exercism.secrets.discord_bot_token}"
)
RestClient.expects(:delete).with(
"https://discord.com/api/guilds/854117591135027261/members/#{uid}/roles/1096024168639766578",
Authorization: "Bot #{Exercism.secrets.discord_bot_token}"
)
RestClient.expects(:delete).with(
"https://discord.com/api/guilds/854117591135027261/members/#{uid}/roles/1192435804602105966",
Authorization: "Bot #{Exercism.secrets.discord_bot_token}"
)
RestClient.expects(:put).with(
"https://discord.com/api/guilds/854117591135027261/members/#{uid}/roles/1085196376058646559",
{},
Expand All @@ -59,47 +59,13 @@ class User::SetDiscordRolesTest < ActiveSupport::TestCase
User::SetDiscordRoles.(user)
end

test "removes maintainer role when user is not a maintainer" do
uid = SecureRandom.hex
user = create :user, :not_mentor, discord_uid: uid

RestClient.expects(:delete).with(
"https://discord.com/api/guilds/854117591135027261/members/#{uid}/roles/1085196488436633681",
Authorization: "Bot #{Exercism.secrets.discord_bot_token}"
)
RestClient.expects(:delete).with(
"https://discord.com/api/guilds/854117591135027261/members/#{uid}/roles/1096024168639766578",
Authorization: "Bot #{Exercism.secrets.discord_bot_token}"
)
RestClient.expects(:delete).with(
"https://discord.com/api/guilds/854117591135027261/members/#{uid}/roles/1085196376058646559",
Authorization: "Bot #{Exercism.secrets.discord_bot_token}"
)
RestClient.expects(:delete).with(
"https://discord.com/api/guilds/854117591135027261/members/#{uid}/roles/1192435804602105966",
Authorization: "Bot #{Exercism.secrets.discord_bot_token}"
)

User::SetDiscordRoles.(user)
end

test "adds mentor role when user is mentor" do
RestClient.stubs(:delete)

uid = SecureRandom.hex
user = create :user, discord_uid: uid
create(:user_track_mentorship, user:)

RestClient.expects(:delete).with(
"https://discord.com/api/guilds/854117591135027261/members/#{uid}/roles/1085196488436633681",
Authorization: "Bot #{Exercism.secrets.discord_bot_token}"
)
RestClient.expects(:delete).with(
"https://discord.com/api/guilds/854117591135027261/members/#{uid}/roles/1096024168639766578",
Authorization: "Bot #{Exercism.secrets.discord_bot_token}"
)
RestClient.expects(:delete).with(
"https://discord.com/api/guilds/854117591135027261/members/#{uid}/roles/1085196376058646559",
Authorization: "Bot #{Exercism.secrets.discord_bot_token}"
)
RestClient.expects(:put).with(
"https://discord.com/api/guilds/854117591135027261/members/#{uid}/roles/1192435804602105966",
{},
Expand All @@ -109,47 +75,12 @@ class User::SetDiscordRolesTest < ActiveSupport::TestCase
User::SetDiscordRoles.(user)
end

test "removes mentor role when user is not a mentor" do
uid = SecureRandom.hex
user = create :user, :not_mentor, discord_uid: uid

RestClient.expects(:delete).with(
"https://discord.com/api/guilds/854117591135027261/members/#{uid}/roles/1085196488436633681",
Authorization: "Bot #{Exercism.secrets.discord_bot_token}"
)
RestClient.expects(:delete).with(
"https://discord.com/api/guilds/854117591135027261/members/#{uid}/roles/1096024168639766578",
Authorization: "Bot #{Exercism.secrets.discord_bot_token}"
)
RestClient.expects(:delete).with(
"https://discord.com/api/guilds/854117591135027261/members/#{uid}/roles/1085196376058646559",
Authorization: "Bot #{Exercism.secrets.discord_bot_token}"
)
RestClient.expects(:delete).with(
"https://discord.com/api/guilds/854117591135027261/members/#{uid}/roles/1192435804602105966",
Authorization: "Bot #{Exercism.secrets.discord_bot_token}"
)

User::SetDiscordRoles.(user)
end

test "add supermentor role when user is supermentor" do
RestClient.stubs(:delete)

uid = SecureRandom.hex
user = create :user, :not_mentor, :supermentor, discord_uid: uid

RestClient.expects(:delete).with(
"https://discord.com/api/guilds/854117591135027261/members/#{uid}/roles/1085196376058646559",
Authorization: "Bot #{Exercism.secrets.discord_bot_token}"
)
RestClient.expects(:delete).with(
"https://discord.com/api/guilds/854117591135027261/members/#{uid}/roles/1096024168639766578",
Authorization: "Bot #{Exercism.secrets.discord_bot_token}"
)
RestClient.expects(:delete).with(
"https://discord.com/api/guilds/854117591135027261/members/#{uid}/roles/1192435804602105966",
Authorization: "Bot #{Exercism.secrets.discord_bot_token}"
)

RestClient.expects(:put).with(
"https://discord.com/api/guilds/854117591135027261/members/#{uid}/roles/1085196488436633681",
{},
Expand All @@ -159,74 +90,47 @@ class User::SetDiscordRolesTest < ActiveSupport::TestCase
User::SetDiscordRoles.(user)
end

test "removes supermentor role when user is not a supermentor" do
test "adds insiders role when user is insider" do
RestClient.stubs(:delete)

uid = SecureRandom.hex
user = create :user, :not_mentor, discord_uid: uid
user = create :user, :not_mentor, :insider, discord_uid: uid

RestClient.expects(:delete).with(
"https://discord.com/api/guilds/854117591135027261/members/#{uid}/roles/1085196376058646559",
Authorization: "Bot #{Exercism.secrets.discord_bot_token}"
)
RestClient.expects(:delete).with(
RestClient.expects(:put).with(
"https://discord.com/api/guilds/854117591135027261/members/#{uid}/roles/1096024168639766578",
Authorization: "Bot #{Exercism.secrets.discord_bot_token}"
)
RestClient.expects(:delete).with(
"https://discord.com/api/guilds/854117591135027261/members/#{uid}/roles/1192435804602105966",
Authorization: "Bot #{Exercism.secrets.discord_bot_token}"
)

RestClient.expects(:delete).with(
"https://discord.com/api/guilds/854117591135027261/members/#{uid}/roles/1085196488436633681",
{},
Authorization: "Bot #{Exercism.secrets.discord_bot_token}"
)

User::SetDiscordRoles.(user)
end

test "adds insiders role when user is insider" do
test "adds bootcamp attendee role when user is bootcamp attendee" do
RestClient.stubs(:delete)

uid = SecureRandom.hex
user = create :user, :not_mentor, :insider, discord_uid: uid
user = create :user, :not_mentor, discord_uid: uid
user.update!(bootcamp_attendee: true)

RestClient.expects(:delete).with(
"https://discord.com/api/guilds/854117591135027261/members/#{uid}/roles/1085196376058646559",
Authorization: "Bot #{Exercism.secrets.discord_bot_token}"
)
RestClient.expects(:delete).with(
"https://discord.com/api/guilds/854117591135027261/members/#{uid}/roles/1085196488436633681",
Authorization: "Bot #{Exercism.secrets.discord_bot_token}"
)
RestClient.expects(:delete).with(
"https://discord.com/api/guilds/854117591135027261/members/#{uid}/roles/1192435804602105966",
Authorization: "Bot #{Exercism.secrets.discord_bot_token}"
)
RestClient.expects(:put).with(
"https://discord.com/api/guilds/854117591135027261/members/#{uid}/roles/1096024168639766578",
"https://discord.com/api/guilds/854117591135027261/members/#{uid}/roles/1326564387284320276",
{},
Authorization: "Bot #{Exercism.secrets.discord_bot_token}"
)

User::SetDiscordRoles.(user)
end

test "removes insiders role when user is not an insider" do
test "adds bootcamp mentor role when user is bootcamp attendee" do
RestClient.stubs(:delete)

uid = SecureRandom.hex
user = create :user, :not_mentor, discord_uid: uid
user.update!(bootcamp_mentor: true)

RestClient.expects(:delete).with(
"https://discord.com/api/guilds/854117591135027261/members/#{uid}/roles/1085196376058646559",
Authorization: "Bot #{Exercism.secrets.discord_bot_token}"
)
RestClient.expects(:delete).with(
"https://discord.com/api/guilds/854117591135027261/members/#{uid}/roles/1085196488436633681",
Authorization: "Bot #{Exercism.secrets.discord_bot_token}"
)
RestClient.expects(:delete).with(
"https://discord.com/api/guilds/854117591135027261/members/#{uid}/roles/1192435804602105966",
Authorization: "Bot #{Exercism.secrets.discord_bot_token}"
)
RestClient.expects(:delete).with(
"https://discord.com/api/guilds/854117591135027261/members/#{uid}/roles/1096024168639766578",
RestClient.expects(:put).with(
"https://discord.com/api/guilds/854117591135027261/members/#{uid}/roles/1305143333433249867",
{},
Authorization: "Bot #{Exercism.secrets.discord_bot_token}"
)

Expand All @@ -237,7 +141,7 @@ class User::SetDiscordRolesTest < ActiveSupport::TestCase
uid = SecureRandom.hex
user = create :user, :not_mentor, :insider, discord_uid: uid

RestClient.expects(:delete).raises(RestClient::NotFound).times(3)
RestClient.expects(:delete).raises(RestClient::NotFound).times(5)
RestClient.expects(:put).raises(RestClient::NotFound)

User::SetDiscordRoles.(user)
Expand Down
Loading

0 comments on commit db292a1

Please sign in to comment.