# frozen_string_literal: true
describe ESM::Command::Base do
include_context "connection"
describe "Properties" do
include_context "command" do
let!(:command_class) { ESM::Command::Test::BaseV1 }
end
it "has a valid name" do
expect(command.command_name).to eq("base_v1")
end
it "has a valid category" do
expect(command.category).to eq("test")
end
it "has #{ESM::Command::Test::BaseV1::ARGUMENT_COUNT} arguments" do
expect(command.arguments.size).to eq(ESM::Command::Test::BaseV1::ARGUMENT_COUNT)
end
it "has description" do
expect(command.description).to eq("A test command")
end
it "has a type" do
expect(command.type).to eq(:player)
end
it "has examples (hash)" do
expect(command.examples(raw: true)).to eq(
[{description: "A test example"}, {description: "An example with args", arguments: {target: "foo"}}]
)
end
it "has examples (string)" do
expect(command.examples).to eq(
<<~STRING
```
/test base_v1 community_id:<community> server_id:<server> target:<target>
```A test example
```
/test base_v1 community_id:<community> server_id:<server> target:foo
```An example with args
STRING
)
end
it "has defines" do
expect(command.attributes).not_to be_nil
expect(command.attributes.enabled.modifiable).to be(true)
expect(command.attributes.enabled.default).to be(true)
expect(command.attributes.allowlist_enabled.modifiable).to be(true)
expect(command.attributes.allowlist_enabled.default).to eq(false)
expect(command.attributes.allowlisted_role_ids.modifiable).to be(true)
expect(command.attributes.allowlisted_role_ids.default).to eq([])
expect(command.attributes.allowed_in_text_channels.modifiable).to be(true)
expect(command.attributes.allowed_in_text_channels.default).to be(true)
expect(command.attributes.cooldown_time.modifiable).to be(true)
expect(command.attributes.cooldown_time.default).to eq(2.seconds)
end
it "has requires" do
expect(command.requirements).not_to be_nil
expect(command.requirements).to contain_exactly(:registration)
end
it "has proper usage" do
expect(command.usage).to eq("/test base_v1")
expect(command.usage(use_placeholders: true)).to eq("/test base_v1 community_id:<community> server_id:<server> target:<target>")
end
end
describe "#create_user" do
include_context "command" do
let!(:command_class) { ESM::Command::Test::PlayerCommand }
end
it "creates an unregistered user" do
execute!
expect(ESM::User.all.size).to eq(1)
end
end
describe "#current_user" do
include_context "command" do
let!(:command_class) { ESM::Command::Test::PlayerCommand }
end
it "is defined" do
expect(command.respond_to?(:current_user)).to be(true)
end
it "has a valid user" do
execute!
expect(previous_command.current_user).not_to be_nil
expect(previous_command.current_user.discord_id).to eq(user.discord_id)
end
it "creates" do
discord_id = user.discord_id
user.destroy!
expect { execute! }.to raise_error(ESM::Exception::CheckFailure) do |error|
embed = error.data
expect(embed.description).to match("I'll need you to link your Steam account")
end
new_current_user = ESM::User.find_by_discord_id(discord_id)
expect(new_current_user).not_to be(nil)
expect(previous_command.current_user.discord_id).to eq(new_current_user.discord_id)
end
end
describe "#current_community" do
include_context "command" do
let!(:command_class) { ESM::Command::Test::CommunityCommand }
end
it "is defined" do
expect(command.respond_to?(:current_community)).to be(true)
end
it "is a valid community" do
execute!(community_id: community.community_id)
expect(previous_command.current_community).not_to be_nil
expect(previous_command.current_community.id).to eq(community.id)
end
end
describe "#target_server" do
include_context "command" do
let!(:command_class) { ESM::Command::Test::ServerCommand }
end
it "is defined" do
expect(command.respond_to?(:target_server)).to be(true)
end
it "is a valid server" do
expect { execute!(arguments: {server_id: server.server_id}) }.to raise_error(ESM::Exception::CheckFailure)
expect(previous_command.target_server).not_to be_nil
expect(previous_command.target_server.id).to eq(server.id)
expect(previous_command.arguments.server_id).to eq(server.server_id)
end
it "is invalid" do
expect { execute!(arguments: {server_id: "esm_ This Server Cannot Exist"}) }.to raise_error(ESM::Exception::CheckFailure)
end
end
describe "#target_community" do
include_context "command" do
let!(:command_class) { ESM::Command::Test::CommunityCommand }
end
it "is defined" do
expect(command.respond_to?(:target_community)).to be(true)
end
it "is a valid community" do
execute!(community_id: community.community_id)
expect(previous_command.target_community).not_to be_nil
expect(previous_command.target_community.id).to eq(community.id)
end
it "is invalid" do
expect { execute!(arguments: {community_id: "es"}) }.to raise_error(ESM::Exception::CheckFailure) do |error|
expect(error.to_embed.description).to match(/hey .+, i was unable to find a community with an ID of `.+`./i)
end
end
end
describe "#target_user" do
let!(:secondary_user) { create(:user) }
include_context "command" do
let!(:command_class) { ESM::Command::Test::TargetCommand }
end
it "is defined" do
expect(command.respond_to?(:target_user)).to be(true)
end
context "when the target is not steam uid, discord id, or discord mention" do
it "is invalid" do
expect { execute!(arguments: {target: "000000000000000000"}) }.to raise_error(ESM::Exception::CheckFailure)
end
end
context "when the target is a discord ID and the target exists in the DB" do
it "returns the database user" do
execute!(arguments: {target: secondary_user.discord_id})
expect(previous_command.target_user.discord_id).to eq(secondary_user.discord_id)
end
end
context "when the target is a discord ID and the target does not exist in the DB" do
it "creates a user and returns it" do
discord_id = secondary_user.discord_id
secondary_user.destroy
execute!(arguments: {target: discord_id})
new_target_user = ESM::User.find_by_discord_id(discord_id)
expect(previous_command.target_user.discord_id).to eq(new_target_user.discord_id)
end
end
context "when the target is a steam uid and the target exists in the DB" do
it "returns the database user" do
execute!(arguments: {target: secondary_user.steam_uid})
expect(previous_command.target_user.steam_uid).to eq(secondary_user.steam_uid)
end
end
context "when the target is a steam uid and the target does not exist in the DB" do
it "returns an ephemeral user" do
steam_uid = secondary_user.steam_uid
secondary_user.destroy
execute!(arguments: {target: steam_uid})
expect(previous_command.target_user).to be_kind_of(ESM::User::Ephemeral)
expect(previous_command.target_user.steam_uid).to eq(steam_uid)
end
end
context "when the target is a discord mention and the target does exist in the DB" do
it "returns the database user" do
execute!(arguments: {target: secondary_user.discord_mention})
expect(previous_command.target_user.id).to eq(secondary_user.id)
end
end
context "when the target is a discord mention and the target does not exist in the DB" do
it "creates a user and returns it" do
discord_mention = secondary_user.discord_mention
secondary_user.destroy
execute!(arguments: {target: discord_mention})
expect(previous_command.target_user.discord_mention).to eq(discord_mention)
end
end
end
describe "#target_uid" do
let!(:secondary_user) { create(:user) }
include_context "command" do
let!(:command_class) { ESM::Command::Test::TargetCommand }
end
it "from Steam UID" do
execute!(arguments: {target: secondary_user.steam_uid})
expect(previous_command.target_uid).to eq(secondary_user.steam_uid)
end
it "from mention" do
execute!(arguments: {target: secondary_user.mention})
expect(previous_command.target_uid).to eq(secondary_user.steam_uid)
end
it "from discord ID" do
execute!(arguments: {target: secondary_user.discord_id})
expect(previous_command.target_uid).to eq(secondary_user.steam_uid)
end
it "from unregistered" do
secondary_user.update(steam_uid: nil)
execute!(arguments: {target: secondary_user.mention})
expect(previous_command.target_uid).to eq(nil)
end
it "from gibberish" do
expect { execute!(arguments: {target: "000000000000000000"}) }.to raise_error(ESM::Exception::CheckFailure)
expect(previous_command.target_uid).to eq(nil)
end
end
describe "#registration_required?" do
include_context "command" do
let!(:command_class) { ESM::Command::Test::ServerCommand }
end
it "is defined" do
expect(command.respond_to?(:registration_required?)).to be(true)
end
it "requires registration" do
expect(command.registration_required?).to be(true)
end
it "does not require registration" do
command.requirements.unset(:registration)
expect(command.registration_required?).to be(false)
end
end
describe "#on_execute" do
include_context "command" do
let!(:command_class) { ESM::Command::Test::PlayerCommand }
end
it "is defined" do
expect(command.respond_to?(:on_execute)).to be(true)
end
it "is callable" do
expect(command.on_execute).to eq("on_execute")
end
end
describe "#on_response" do
include_context "command" do
let!(:command_class) { ESM::Command::Test::PlayerCommand }
end
it "is defined" do
expect(command.respond_to?(:on_response)).to be(true)
end
it "is callable" do
expect(command.on_response).to eq("on_response")
end
end
describe "#from_discord!" do
include_context "command" do
let!(:command_class) { ESM::Command::Test::ServerSuccessCommand }
end
it "is defined" do
expect(command.respond_to?(:from_discord!)).to be(true)
end
it "executes" do
expect {
execute!(arguments: {server_id: server.server_id}, nullable: true)
}.to raise_error(ESM::Exception::CheckFailure)
end
it "executes with nullable arguments" do
expect {
execute!(arguments: {server_id: server.server_id})
}.to raise_error(ESM::Exception::CheckFailure)
end
describe "Handles Errors" do
it "send error (CheckFailure)" do
execution_args = {command_class: ESM::Command::Test::DirectMessageCommand}
expect { execute!(**execution_args) }.to raise_error(ESM::Exception::CheckFailure) do |error|
embed = error.data
expect(embed.description).to eq(
"Hey #{user.mention}, this command can only be used in a **Direct Message** with me.\n\nJust right click my name, click **Message**, and send it there"
)
end
end
it "send error (StandardError)" do
execute!(command_class: ESM::Command::Test::ErrorCommand, handle_error: true)
ESM.discord_bot.test_outbox.await_size(1)
error = ESM.discord_bot.test_outbox.first.content
expect(error.description).to match(
/an error occurred while processing your request.[[:space:]]Will you please join my \[Discord\]\(https...esmbot.com.join\) and post the following error code in the `#get-help-here` channel so my developer can fix it for you\?[[:space:]]Thank you![[:space:]]```\w+```/i
)
end
it "handles errors from the server", :requires_connection do
execution_args = {
command_class: ESM::Command::Test::ServerErrorCommand,
arguments: {server_id: server.server_id}
}
expect { execute!(**execution_args) }.to raise_error(ESM::Exception::ExtensionError)
end
end
end
describe "#raise_error!" do
include_context "command" do
let!(:command_class) { ESM::Command::Test::BaseV1 }
end
before do
command.origin = ESM::Discord::Command::Origin.new(
user: user,
community: community,
channel: community.discord_server.channels.first
)
end
it "raises the translation" do
expect {
command.raise_error!(:text_only, user: user.mention, path_prefix: "command_errors")
}.to raise_error(ESM::Exception::CheckFailure) do |error|
embed = error.data
expect(embed.description).to match(/this command can only be used in a discord server's \*\*text channel\*\*/i)
end
end
it "raises the block" do
expect { command.raise_error! { "This will is the message" } }.to raise_error(ESM::Exception::CheckFailure) do |error|
expect(error.data).to match(/this will is the message/i)
end
end
end
describe "limit to" do
context "when limit_to is unset" do
include_context "command" do
let!(:command_class) { ESM::Command::Test::PlayerCommand }
end
it "is not limited" do
expect(command.limited_to).to be_nil
expect(command.dm_only?).to be(false)
expect(command.text_only?).to be(false)
end
it "executes in text channels" do
execute!
end
it "executes in DM channels" do
execute!(channel_type: :dm)
end
end
context "when limit_to is set to Direct Message" do
include_context "command" do
let!(:command_class) { ESM::Command::Test::DirectMessageCommand }
end
it "supports multiple variations" do
command_class.limit_to(:direct_message)
expect(command_class.limited_to).to eq(:dm)
command_class.limit_to(:dm)
expect(command_class.limited_to).to eq(:dm)
command_class.limit_to(:private_message)
expect(command_class.limited_to).to eq(:dm)
command_class.limit_to(:pm)
expect(command_class.limited_to).to eq(:dm)
end
it "is limited to direct messages" do
expect(command.limited_to).to eq(:dm)
expect(command.dm_only?).to be(true)
expect(command.text_only?).to be(false)
end
it "does not work in text channels" do
expect { execute! }.to raise_error(ESM::Exception::CheckFailure) do |error|
embed = error.data
expect(embed.description).to match(/this command can only be used in a \*\*direct message\*\* with me/i)
end
end
it "works in Direct Message channels" do
execute!(channel_type: :dm)
end
end
context "when limit_to is set to Text channel" do
include_context "command" do
let!(:command_class) { ESM::Command::Test::TextChannelCommand }
end
it "supports multiple variations" do
command_class.limit_to(:text)
expect(command_class.limited_to).to eq(:text)
command_class.limit_to(:text_channel)
expect(command_class.limited_to).to eq(:text)
end
it "is limited to text" do
expect(command.limited_to).to eq(:text)
expect(command.dm_only?).to be(false)
expect(command.text_only?).to be(true)
end
it "works in text channels" do
execute!
end
it "does not work in Direct Message channels" do
expect { execute!(channel_type: :dm) }.to raise_error(ESM::Exception::CheckFailure) do |error|
embed = error.data
expect(embed.description).to match(
/this command can only be used in a discord server's \*\*text channel\*\*\./i
)
end
end
end
end
describe "#create_or_update_cooldown" do
include_context "command" do
let!(:command_class) { ESM::Command::Test::CooldownCommand }
end
context "when there is no cooldown" do
it "creates one" do
expect(ESM::Cooldown.all.size).to eq(0)
execute!
expect(previous_command.current_cooldown).to be_kind_of(ESM::Cooldown)
expect(previous_command.current_cooldown.valid?).to be(true)
expect(previous_command.current_cooldown.persisted?).to be(true)
end
end
context "when there is a cooldown" do
it "updates it" do
cooldown = create(
:cooldown, :inactive,
steam_uid: user.steam_uid,
command_name: command.command_name
)
execute!(channel_type: :dm)
expect(previous_command.current_cooldown).to be_kind_of(ESM::Cooldown)
expect(previous_command.current_cooldown.valid?).to be(true)
expect(previous_command.current_cooldown.persisted?).to be(true)
expect(previous_command.current_cooldown.id).to eq(cooldown.id)
end
end
end
describe "#current_cooldown_query" do
include_context "command" do
let!(:command_class) { ESM::Command::Test::CooldownCommand }
end
let(:query_hash) { command.current_cooldown_query.where_values_hash.symbolize_keys }
let!(:target_community) { create(:community) }
before do
command.requirements.unset(:registration)
command.origin = ESM::Discord::Command::Origin.new(user: user)
end
context "when registration is not required" do
it "uses the user id" do
expect(query_hash).to include(
command_name: command.command_name, user_id: user.id
).and exclude(
:steam_uid, :server_id, :community_id
)
end
end
context "when registration is required" do
before do
command.requirements.set(:registration)
end
it "uses the steam uid" do
expect(query_hash).to include(
command_name: command.command_name, steam_uid: user.steam_uid
).and exclude(
:user_id, :server_id, :community_id
)
end
end
context "when there is a target community" do
before do
command.origin = ESM::Discord::Command::Origin.new(user: user, community: community)
command.instance_variable_set(:@target_community, target_community)
end
it "uses the target community's ID" do
expect(query_hash).to include(
command_name: command.command_name, user_id: user.id, community_id: target_community.id
).and exclude(
:steam_uid, :server_id
)
end
end
context "when there is a current community, but no target community" do
before do
command.origin = ESM::Discord::Command::Origin.new(user: user, community: community)
end
it "uses the current community's ID" do
expect(query_hash).to include(
command_name: command.command_name, user_id: user.id, community_id: community.id
).and exclude(
:steam_uid, :server_id
)
end
end
context "when there is a target server" do
before do
command.instance_variable_set(:@target_server, server)
end
it "uses the target server's ID" do
expect(query_hash).to include(
command_name: command.command_name, user_id: user.id, server_id: server.id
).and exclude(
:steam_uid
)
end
end
end
describe "#on_cooldown?" do
include_context "command" do
let!(:command_class) { ESM::Command::Test::CooldownCommand }
end
it "respond" do
expect(command.respond_to?(:on_cooldown?)).to be(true)
end
context "when the command is on cooldown" do
it "raises an exception" do
cooldown = create(
:cooldown, :active, user: user, community: community,
command_name: command.command_name
)
command.instance_variable_set(:@current_cooldown, cooldown)
expect(command.current_cooldown).to eq(cooldown)
expect(command.on_cooldown?).to be(true)
end
end
context "when the command is not on cooldown" do
it "does not raise an exception" do
cooldown = create(
:cooldown, :inactive, user: user, community: community,
command_name: command.command_name
)
command.instance_variable_set(:@current_cooldown, cooldown)
expect(command.current_cooldown).to eq(cooldown)
expect(command.on_cooldown?).to be(false)
end
end
end
# Truth table: https://docs.google.com/spreadsheets/d/1BDHVwhyvgbFPlXnAtFKzOcPtGhZ1zG5H-_1km3VXKr8/edit#gid=0
describe "Command Permissions" do
include_context "command" do
let!(:command_class) { ESM::Command::Test::CommunityCommand }
let(:discord_server) do
build(
:discord_server,
channels: %i[general logging commands],
roles: %i[allowlisted],
owner: user_is_owner ? discord_user : build(:discord_user)
)
end
end
let(:configuration) { ESM::CommandConfiguration.where(command_name: command.command_name).first }
let(:allowlisted_role_ids) { community.role_ids }
let(:allowlisted_role) { discord_server.roles.find { |role| role.name == "allowlisted" } }
let(:role_user) do
role_discord_user = build(:discord_user)
build(:discord_member, server: discord_server, user: role_discord_user, roles: [allowlisted_role])
create(:user, discord_user: role_discord_user)
end
describe "Text Channel" do
describe "Allowed" do
it "enabled: true, allowlist_enabled: false, allowlisted: false, allowed: true" do
configuration.update!(
enabled: true,
allowlist_enabled: false,
allowlisted_role_ids: [],
allowed_in_text_channels: true
)
execute!(arguments: {community_id: community.community_id})
end
it "enabled: true, allowlist_enabled: true, allowlisted: true, allowed: true" do
configuration.update!(
enabled: true,
allowlist_enabled: true,
allowlisted_role_ids: allowlisted_role_ids,
allowed_in_text_channels: true
)
# CHECK THAT user ACTUALLY HAS ROLE
execute!(user: role_user, arguments: {community_id: community.community_id})
end
end
describe "Denied" do
it "enabled: false, allowlist_enabled: false, allowlisted: false, allowed: false" do
configuration.update!(
enabled: false,
allowlist_enabled: false,
allowlisted_role_ids: [],
allowed_in_text_channels: false
)
expect {
execute!(arguments: {community_id: community.community_id})
}.to raise_error(ESM::Exception::CheckFailure, /not enabled/i)
end
it "enabled: false, notify_when_disabled: true" do
configuration.update!(
enabled: false,
notify_when_disabled: true
)
expect {
execute!(arguments: {community_id: community.community_id})
}.to raise_error(ESM::Exception::CheckFailure, /not enabled/i)
end
it "enabled: false, notify_when_disabled: false" do
configuration.update!(
enabled: false,
notify_when_disabled: false
)
expect {
execute!(arguments: {community_id: community.community_id})
}.to raise_error(ESM::Exception::CheckFailureNoMessage)
# It did not send a message
expect(ESM.discord_bot.test_outbox.size).to eq(0)
end
it "enabled: false, allowlist_enabled: false, allowlisted: false, allowed: true" do
configuration.update!(
enabled: false,
allowlist_enabled: false,
allowlisted_role_ids: [],
allowed_in_text_channels: true
)
expect {
execute!(arguments: {community_id: community.community_id})
}.to raise_error(ESM::Exception::CheckFailure, /not enabled/i)
end
it "enabled: false, allowlist_enabled: true, allowlisted: false, allowed: false" do
configuration.update!(
enabled: false,
allowlist_enabled: true,
allowlisted_role_ids: [],
allowed_in_text_channels: false
)
expect {
execute!(arguments: {community_id: community.community_id})
}.to raise_error(ESM::Exception::CheckFailure, /not enabled/i)
end
it "enabled: false, allowlist_enabled: true, allowlisted: true, allowed: false" do
configuration.update!(
enabled: false,
allowlist_enabled: true,
allowlisted_role_ids: allowlisted_role_ids,
allowed_in_text_channels: false
)
expect {
execute!(arguments: {community_id: community.community_id})
}.to raise_error(ESM::Exception::CheckFailure, /not enabled/i)
end
it "enabled: false, allowlist_enabled: true, allowlisted: true, allowed: true" do
configuration.update!(
enabled: false,
allowlist_enabled: true,
allowlisted_role_ids: allowlisted_role_ids,
allowed_in_text_channels: true
)
expect {
execute!(arguments: {community_id: community.community_id})
}.to raise_error(ESM::Exception::CheckFailure, /not enabled/i)
end
it "enabled: true, allowlist_enabled: false, allowlisted: false, allowed: false" do
configuration.update!(
enabled: true,
allowlist_enabled: false,
allowlisted_role_ids: [],
allowed_in_text_channels: false
)
expect {
execute!(arguments: {community_id: community.community_id})
}.to raise_error(ESM::Exception::CheckFailure, /not allowed/i)
end
it "enabled: true, allowlist_enabled: true, allowlisted: false, allowed: true" do
configuration.update!(
enabled: true,
allowlist_enabled: true,
allowlisted_role_ids: [],
allowed_in_text_channels: true
)
expect {
execute!(user: role_user, arguments: {community_id: community.community_id})
}.to raise_error(ESM::Exception::CheckFailure, /not have permission/i)
end
it "enabled: true, allowlist_enabled: true, allowlisted: true, allowed: false" do
configuration.update!(
enabled: true,
allowlist_enabled: true,
allowlisted_role_ids: allowlisted_role_ids,
allowed_in_text_channels: false
)
expect {
execute!(arguments: {community_id: community.community_id})
}.to raise_error(ESM::Exception::CheckFailure, /not have permission/i)
end
end
end
describe "Private Message" do
describe "Allowed" do
it "enabled: true, allowlist_enabled: false, allowlisted: false, allowed: true" do
configuration.update!(
enabled: true,
allowlist_enabled: false,
allowlisted_role_ids: [],
allowed_in_text_channels: true
)
execute!(channel_type: :pm, arguments: {community_id: community.community_id})
end
it "enabled: true, allowlist_enabled: true, allowlisted: true, allowed: true" do
configuration.update!(
enabled: true,
allowlist_enabled: true,
allowlisted_role_ids: allowlisted_role_ids,
allowed_in_text_channels: true
)
execute!(channel_type: :pm, user: role_user, arguments: {community_id: community.community_id})
end
it "enabled: true, allowlist_enabled: false, allowlisted: false, allowed: false" do
configuration.update!(
enabled: true,
allowlist_enabled: false,
allowlisted_role_ids: [],
allowed_in_text_channels: false
)
execute!(channel_type: :pm, arguments: {community_id: community.community_id})
end
it "enabled: true, allowlist_enabled: true, allowlisted: true, allowed: false" do
configuration.update!(
enabled: true,
allowlist_enabled: true,
allowlisted_role_ids: allowlisted_role_ids,
allowed_in_text_channels: false
)
execute!(channel_type: :pm, user: role_user, arguments: {community_id: community.community_id})
end
end
describe "Denied" do
it "enabled: false, notify_when_disabled: true" do
configuration.update!(
enabled: false,
notify_when_disabled: true
)
expect {
execute!(channel_type: :pm, arguments: {community_id: community.community_id})
}.to raise_error(ESM::Exception::CheckFailure, /not enabled/i)
end
it "enabled: false, notify_when_disabled: false" do
configuration.update!(
enabled: false,
notify_when_disabled: false
)
expect {
execute!(channel_type: :pm, arguments: {community_id: community.community_id})
}.to raise_error(ESM::Exception::CheckFailure, /not enabled/i)
end
it "enabled: false, allowlist_enabled: false, allowlisted: false, allowed: false" do
configuration.update!(
enabled: false,
allowlist_enabled: false,
allowlisted_role_ids: [],
allowed_in_text_channels: false
)
expect {
execute!(channel_type: :pm, arguments: {community_id: community.community_id})
}.to raise_error(ESM::Exception::CheckFailure, /not enabled/i)
end
it "enabled: false, allowlist_enabled: false, allowlisted: false, allowed: true" do
configuration.update!(
enabled: false,
allowlist_enabled: false,
allowlisted_role_ids: [],
allowed_in_text_channels: true
)
expect {
execute!(channel_type: :pm, arguments: {community_id: community.community_id})
}.to raise_error(ESM::Exception::CheckFailure, /not enabled/i)
end
it "enabled: false, allowlist_enabled: true, allowlisted: false, allowed: false" do
configuration.update!(
enabled: false,
allowlist_enabled: true,
allowlisted_role_ids: [],
allowed_in_text_channels: false
)
expect {
execute!(
channel_type: :pm,
user: user,
arguments: {
community_id: community.community_id
}
)
}.to raise_error(ESM::Exception::CheckFailure, /not enabled/i)
end
it "enabled: false, allowlist_enabled: true, allowlisted: true, allowed: false" do
configuration.update!(
enabled: false,
allowlist_enabled: true,
allowlisted_role_ids: community.role_ids,
allowed_in_text_channels: false
)
expect {
execute!(
channel_type: :pm,
user: user,
arguments: {
community_id: community.community_id
}
)
}.to raise_error(ESM::Exception::CheckFailure, /not enabled/i)
end
it "enabled: false, allowlist_enabled: true, allowlisted: true, allowed: true" do
configuration.update!(
enabled: false,
allowlist_enabled: true,
allowlisted_role_ids: allowlisted_role_ids,
allowed_in_text_channels: true
)
expect {
execute!(channel_type: :pm, arguments: {community_id: community.community_id})
}.to raise_error(ESM::Exception::CheckFailure, /not enabled/i)
end
it "enabled: true, allowlist_enabled: true, allowlisted: false, allowed: true" do
configuration.update!(
enabled: true,
allowlist_enabled: true,
allowlisted_role_ids: [],
allowed_in_text_channels: true
)
expect {
execute!(channel_type: :pm, user: role_user, arguments: {community_id: community.community_id})
}.to raise_error(ESM::Exception::CheckFailure, /not have permission/i)
end
end
end
end
# Features of player mode:
# Use DM commands in Text Channels
# Run commands for OTHER community servers in text channels
# Blocks admin commands from being used text channels
describe "Player Mode" do
include_context "command" do
let!(:command_class) { ESM::Command::Test::CommunityCommand }
end
let!(:player_community) { community }
let(:server_community) { create(:community) }
before do
player_community.update!(player_mode_enabled: true)
end
it "ensures server community and player community are not the same" do
expect(player_community.id).not_to eq(server_community.id)
end
it "is enabled" do
expect(player_community.player_mode_enabled?).to be(true)
end
it "is able to use DM only commands in text channel" do
execute!(command_class: ESM::Command::Test::DirectMessageCommand)
end
it "is able to run player command for other communities in text channel" do
# Ensure the command can still be used regardless of that communities permissions for "allowed_in_text_channels"
player_community.command_configurations
.where(command_name: command.command_name)
.first
.update!(allowed_in_text_channels: false)
execute!(community_id: server_community.community_id)
end
it "does not allow admin commands in text channel" do
expect {
execute!(
command_class: ESM::Command::Test::AdminCommand,
arguments: {
community_id: server_community.community_id
}
)
}.to raise_error(ESM::Exception::CheckFailure, /is not available in player mode/i)
end
it "does not allow running commands for other communities in another server community's text channels" do
expect {
execute!(
channel: server_community.discord_server.channels.first,
arguments: {
community_id: player_community.community_id
}
)
}.to raise_error(ESM::Exception::CheckFailure, /commands for other communities/i)
end
end
describe "#skip_action" do
include_context "command" do
let!(:command_class) { ESM::Command::Test::SkipServerCheckCommand }
end
it "skips #check_for_connected_server!" do
execute!(arguments: {server_id: server.server_id})
end
it "does not modify the class attribute" do
command.skip_action(:cooldown)
expect(command.skipped_actions.to_a).to eq([:connected_server, :cooldown])
expect(command_class.skipped_actions.to_a).to eq([:connected_server])
end
end
describe "#skip" do
include_context "command" do
let!(:command_class) { ESM::Command::Test::SkipCooldownCommand }
end
it "skips #create_or_update_cooldown" do
execute!(arguments: {server_id: server.server_id})
expect(previous_command.current_cooldown).to eq(nil)
end
end
describe "#add_request" do
include_context "command" do
let!(:command_class) { ESM::Command::Test::RequestCommand }
end
it "adds the request" do
execute!(arguments: {target: second_user.discord_id})
expect(ESM::Request.all.size).to eq(1)
expect(second_user.pending_requests.size).to eq(1)
end
end
describe "#from_request" do
include_context "command" do
let!(:command_class) { ESM::Command::Test::RequestCommand }
end
it "is accepted" do
execute!(arguments: {target: second_user.discord_id})
request = ESM::Request.first
request.respond(true)
ESM.discord_bot.test_outbox.await_size(2)
expect(ESM.discord_bot.test_outbox.first.content).to be_a(ESM::Embed)
expect(ESM.discord_bot.test_outbox.second.content).to eq("accepted")
end
it "is declined" do
execute!(arguments: {target: second_user.discord_id})
request = ESM::Request.first
request.respond(false)
ESM.discord_bot.test_outbox.await_size(2)
expect(ESM.discord_bot.test_outbox.first.content).to be_a(ESM::Embed)
expect(ESM.discord_bot.test_outbox.second.content).to eq("declined")
end
end
end