Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add command to add a custom alias. #327

Merged
merged 1 commit into from
Aug 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions app/services/commands/alias/add.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# frozen_string_literal: true

module Commands
module Alias
class Add < Base
argument shortcut: 0
argument command: (1..)

# Determine if the argument matches this command.
#
# @return [Boolean]
def self.match?(arguments)
arguments.first == I18n.t("commands.lookup.alias.arguments.add")
end

private

# Returns the command, ensuring a forward slash is present.
#
# @return [String]
def command
value = parameters[:command]

unless value.start_with?("/")
value = "/#{value}"
end

value
end

# Return the handler for a successful command execution.
#
# @return [Success]
def success
Success.new(character: character, command: command, shortcut: parameters[:shortcut])
end

# Validate if the command is valid.
#
# @return [Boolean] If the alias exists or not.
def validate_command
parsed = Command::Parser.call(command)

if parsed == Commands::Unknown
InvalidCommand.new(command: command)
end
end
end
end
end
18 changes: 18 additions & 0 deletions app/services/commands/alias/add/invalid_command.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# frozen_string_literal: true

module Commands
module Alias
class Add < Base
class InvalidCommand < Result
locals :command

# Initialize an alias add invalid command result.
#
# @return [void]
def initialize(command:)
@command = command
end
end
end
end
end
33 changes: 33 additions & 0 deletions app/services/commands/alias/add/success.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# frozen_string_literal: true

module Commands
module Alias
class Add < Base
class Success < Result
locals :account, :command, :shortcut

# Initialize an alias add success result.
#
# @return [void]
def initialize(character:, command:, shortcut:)
@character = character
@command = command
@shortcut = shortcut
end

# Add the alias to the character's account.
#
# @return [void]
def call
account.update!(aliases: account.aliases.merge(shortcut => command))
end

private

attr_reader :character, :command, :shortcut

delegate :account, to: :character
end
end
end
end
7 changes: 7 additions & 0 deletions app/views/commands/alias/add/_invalid_command.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<%# locals: (command:) %>
<tr data-chat-target="message">
<td class="message-alias-add-invalid-command"></td>
<td class="message-alias-add-invalid-command">
<%= t(".message", command: command) %>
</td>
</tr>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<%# locals: (command:) %>
<%= turbo_stream.append("messages", partial: "commands/alias/add/invalid_command", locals: { command: command }) %>
9 changes: 9 additions & 0 deletions app/views/commands/alias/add/_success.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<%# locals: (account:, command:, shortcut:) %>
<tr data-chat-target="message">
<td class="message-alias-add"></td>
<td class="message-alias-add">
<%= t(".message", command: command, shortcut: shortcut) %></td>
</td>
</tr>

<script>window.Miroha.Settings.aliases = <%== account.aliases.to_json %>;</script>
2 changes: 2 additions & 0 deletions app/views/commands/alias/add/_success.turbo_stream.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<%# locals: (account:, command:, shortcut:) %>
<%= turbo_stream.append("messages", partial: "commands/alias/add/success", locals: { account: account, command: command, shortcut: shortcut }) %>
6 changes: 6 additions & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ en:

commands:
alias:
add:
invalid_command:
message: "There is no \"%{command}\" command."
success:
message: "The alias \"%{shortcut}\" has been added for the \"%{command}\" command."
list:
success:
header:
Expand Down Expand Up @@ -147,6 +152,7 @@ en:
alias:
name: "alias"
arguments:
add: "add"
list: "list"
remove: "remove"
show: "show"
Expand Down
75 changes: 75 additions & 0 deletions spec/features/commands/alias/add_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# frozen_string_literal: true

require "rails_helper"

describe "Sending the alias add command", :js do
let(:character) { create(:character) }
let(:command) { "/alias add #{shortcut} #{name}" }
let(:name) { "/emote" }
let(:shortcut) { "/e" }

before do
sign_in_as_character character
end

it "displays the alias add command message to the sender" do
send_text(command)

expect(page).to have_alias_add_command_message(command: name, shortcut: shortcut)
end

it "does not broadcast the message to the room" do
using_session(:nearby_character) do
sign_in_as_character create(:character, room: character.room)
end

send_text(command)

wait_for(have_alias_add_command_message(command: name, shortcut: shortcut)) do
using_session(:nearby_character) do
expect(page).not_to have_alias_add_command_message(command: name, shortcut: shortcut)
end
end
end

context "with an invalid command" do
let(:command) { "/alias add /f #{name}" }
let(:name) { "/fake" }

it "displays invalid command message to the sender" do
send_text(command)

expect(page).to have_invalid_command_message(command: name)
end

it "does not broadcast the message to the room" do
using_session(:nearby_character) do
sign_in_as_character create(:character, room: character.room)
end

send_text(command)

wait_for(have_invalid_command_message(command: name)) do
using_session(:nearby_character) do
expect(page).not_to have_invalid_command_message(command: name)
end
end
end
end

protected

def have_alias_add_command_message(command:, shortcut:)
have_css(
"#messages .message-alias-add",
text: t("commands.alias.add.success.message", command: command, shortcut: shortcut)
)
end

def have_invalid_command_message(command:)
have_css(
"#messages .message-alias-add-invalid-command",
text: t("commands.alias.add.invalid_command.message", command: command)
)
end
end
20 changes: 20 additions & 0 deletions spec/services/commands/alias/add/invalid_command_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# frozen_string_literal: true

require "rails_helper"

describe Commands::Alias::Add::InvalidCommand, type: :service do
describe "class" do
it "inherits from command result" do
expect(described_class.superclass).to eq(Commands::Result)
end
end

describe "#locals" do
subject { instance.locals }

let(:command) { double }
let(:instance) { described_class.new(command: command) }

it { is_expected.to eq(command: command) }
end
end
38 changes: 38 additions & 0 deletions spec/services/commands/alias/add/success_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# frozen_string_literal: true

require "rails_helper"

describe Commands::Alias::Add::Success, type: :service do
describe "class" do
it "inherits from command result" do
expect(described_class.superclass).to eq(Commands::Result)
end
end

describe "#call" do
subject(:call) { instance.call }

let(:account) { character.account }
let(:character) { create(:character) }
let(:command) { "/emote" }
let(:instance) { described_class.new(character: character, command: command, shortcut: shortcut) }
let(:shortcut) { "/e" }

it "adds the alias to the character's account" do
call

expect(account.aliases).to have_key(shortcut)
end
end

describe "#locals" do
subject { instance.locals }

let(:character) { build_stubbed(:character) }
let(:command) { double }
let(:instance) { described_class.new(character: character, command: command, shortcut: shortcut) }
let(:shortcut) { double }

it { is_expected.to eq(account: character.account, command: command, shortcut: shortcut) }
end
end
92 changes: 92 additions & 0 deletions spec/services/commands/alias/add_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# frozen_string_literal: true

require "rails_helper"

describe Commands::Alias::Add, type: :service do
describe ".match?" do
subject { described_class.match?(arguments) }

context "with no arguments" do
let(:arguments) { [] }

it { is_expected.to be(false) }
end

context "with add argument" do
let(:arguments) { [t("commands.lookup.alias.arguments.add")] }

it { is_expected.to be(true) }
end

context "with other arguments" do
let(:arguments) { %w(fake list) }

it { is_expected.to be(false) }
end
end

describe "#call" do
subject(:call) { instance.call }

let(:character) { build_stubbed(:character) }
let(:instance) { described_class.new("/alias add #{shortcut} #{command}", character: character) }

context "with a valid shortcut and command" do
let(:command) { "/emote" }
let(:result) { instance_double(described_class::Success) }
let(:shortcut) { "/e" }

before do
allow(result).to receive(:call)
allow(described_class::Success).to receive(:new)
.with(character: character, command: command, shortcut: shortcut)
.and_return(result)
end

it "delegates to success handler" do
call

expect(result).to have_received(:call).with(no_args)
end
end

context "with a valid shortcut and command, without slashes" do
let(:command) { "emote" }
let(:result) { instance_double(described_class::Success) }
let(:shortcut) { "e" }

before do
allow(result).to receive(:call)
allow(described_class::Success).to receive(:new)
.with(character: character, command: "/#{command}", shortcut: shortcut)
.and_return(result)
end

it "delegates to success handler" do
call

expect(result).to have_received(:call).with(no_args)
end
end

context "with an invalid command" do
let(:command) { "/fake" }
let(:result) { instance_double(described_class::InvalidCommand) }
let(:shortcut) { "/f" }

before do
allow(described_class::InvalidCommand).to receive(:new)
.with(command: command)
.and_return(result)
end

it "delegates to invalid command handler" do
allow(result).to receive(:call)

call

expect(result).to have_received(:call).with(no_args)
end
end
end
end
21 changes: 21 additions & 0 deletions spec/views/commands/alias/add/_invalid_command.html.erb_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# frozen_string_literal: true

require "rails_helper"

describe "commands/alias/add/_invalid_command.html.erb" do
subject(:html) do
render partial: "commands/alias/add/invalid_command",
locals: { command: command }

rendered
end

let(:command) { "/unknown" }

it "renders the unknown alias message" do
expect(html).to have_message_row(
"td:nth-child(2)",
text: t("commands.alias.add.invalid_command.message", command: command)
)
end
end
Loading