diff --git a/app/controllers/account/join_codes_controller.rb b/app/controllers/account/join_codes_controller.rb index fba2ccfe9..217ee603c 100644 --- a/app/controllers/account/join_codes_controller.rb +++ b/app/controllers/account/join_codes_controller.rb @@ -9,8 +9,11 @@ class Account::JoinCodesController < ApplicationController end def update - @join_code.update!(join_code_params) - redirect_to account_join_code_path + if @join_code.update(join_code_params) + redirect_to account_join_code_path + else + render :edit, status: :unprocessable_entity + end end def destroy diff --git a/app/models/account/join_code.rb b/app/models/account/join_code.rb index 82283e4f6..79160cbaa 100644 --- a/app/models/account/join_code.rb +++ b/app/models/account/join_code.rb @@ -1,8 +1,11 @@ class Account::JoinCode < ApplicationRecord CODE_LENGTH = 12 + USAGE_LIMIT_MAX = 10_000_000_000 belongs_to :account + validates :usage_limit, numericality: { less_than_or_equal_to: USAGE_LIMIT_MAX, message: "cannot be larger than the population of the planet" } + scope :active, -> { where("usage_count < usage_limit") } before_create :generate_code, if: -> { code.blank? } diff --git a/app/views/account/join_codes/edit.html.erb b/app/views/account/join_codes/edit.html.erb index bca92e58f..8a65adca7 100644 --- a/app/views/account/join_codes/edit.html.erb +++ b/app/views/account/join_codes/edit.html.erb @@ -14,12 +14,21 @@ <%= form_with model: @join_code, url: account_join_code_path, method: :patch, data: { controller: "form" }, html: { class: "flex flex-column gap" } do |form| %> <%= form.number_field :usage_limit, - required: true, autofocus: true, min: @join_code.usage_count, + required: true, autofocus: true, + in: 0..Account::JoinCode::USAGE_LIMIT_MAX, class: "input center txt-large fit-content font-weight-black txt-align-center", style: "max-inline-size: 8ch", data: { action: "keydown.esc@document->form#cancel focus->form#select" } %> + <% if @join_code.errors.any? %> +
+ <% @join_code.errors.full_messages.each do |message| %> +

<%= message %>

+ <% end %> +
+ <% end %> +

- This code has been used <%= @join_code.usage_count %>/<%= @join_code.usage_limit %> times. + This code has been used <%= @join_code.usage_count %>/<%= @join_code.usage_limit_in_database %> times.

<%= form.button type: :submit, class: "btn btn--link center txt-medium", data: { form_target: "submit" } do %> diff --git a/test/controllers/accounts/join_codes_controller_test.rb b/test/controllers/accounts/join_codes_controller_test.rb index 33c118386..15d41b5ec 100644 --- a/test/controllers/accounts/join_codes_controller_test.rb +++ b/test/controllers/accounts/join_codes_controller_test.rb @@ -37,4 +37,14 @@ class Account::JoinCodesControllerTest < ActionDispatch::IntegrationTest delete account_join_code_path assert_response :forbidden end + + test "update with extremely large usage_limit" do + # A number larger than bigint max (2^63 - 1 = 9223372036854775807) + huge_number = "99999999999999999999999999999999999" + + put account_join_code_path, params: { account_join_code: { usage_limit: huge_number } } + + assert_response :unprocessable_entity + assert_select ".txt-negative", text: /cannot be larger than the population of the planet/ + end end