diff --git a/Gemfile.lock b/Gemfile.lock index 83564d12..c8942e38 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -209,15 +209,15 @@ GEM mini_portile2 (~> 2.8.2) racc (~> 1.4) open3 (0.2.1) - parallel (1.27.0) - parser (3.3.10.0) + parallel (1.28.0) + parser (3.3.11.1) ast (~> 2.4.1) racc pg (1.6.3) pp (0.6.3) prettyprint prettyprint (0.2.0) - prism (1.4.0) + prism (1.9.0) proc_to_ast (0.2.0) parser rouge @@ -281,7 +281,7 @@ GEM erb psych (>= 4.0.0) tsort - regexp_parser (2.10.0) + regexp_parser (2.12.0) reline (0.6.3) io-console (~> 0.5) request_store (1.5.1) @@ -324,20 +324,20 @@ GEM rspec-support (3.13.7) rspec_junit_formatter (0.6.0) rspec-core (>= 2, < 4, != 2.12.0) - rubocop (1.75.8) + rubocop (1.86.1) json (~> 2.3) language_server-protocol (~> 3.17.0.2) lint_roller (~> 1.1.0) - parallel (~> 1.10) + parallel (>= 1.10) parser (>= 3.3.0.2) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 2.9.3, < 3.0) - rubocop-ast (>= 1.44.0, < 2.0) + rubocop-ast (>= 1.49.0, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 4.0) - rubocop-ast (1.44.1) + rubocop-ast (1.49.1) parser (>= 3.3.7.2) - prism (~> 1.4) + prism (~> 1.7) rubocop-factory_bot (2.27.1) lint_roller (~> 1.1) rubocop (~> 1.72, >= 1.72.1) @@ -350,9 +350,9 @@ GEM rack (>= 1.1) rubocop (>= 1.75.0, < 2.0) rubocop-ast (>= 1.44.0, < 2.0) - rubocop-rspec (3.6.0) + rubocop-rspec (3.9.0) lint_roller (~> 1.1) - rubocop (~> 1.72, >= 1.72.1) + rubocop (~> 1.81) rubocop-rspec_rails (2.31.0) lint_roller (~> 1.1) rubocop (~> 1.72, >= 1.72.1) diff --git a/app/graphql/types/base_interface.rb b/app/graphql/types/base_interface.rb index 14ea542f..8ad09de8 100644 --- a/app/graphql/types/base_interface.rb +++ b/app/graphql/types/base_interface.rb @@ -3,6 +3,7 @@ module Types module BaseInterface include GraphQL::Schema::Interface + edge_type_class(Types::BaseEdge) connection_type_class(Types::CountableConnectionType) diff --git a/app/graphql/types/base_object.rb b/app/graphql/types/base_object.rb index 6f7ae007..fe4cf814 100644 --- a/app/graphql/types/base_object.rb +++ b/app/graphql/types/base_object.rb @@ -3,6 +3,7 @@ module Types class BaseObject < GraphQL::Schema::Object include Sagittarius::Graphql::HasMarkdownDocumentation + edge_type_class(Types::BaseEdge) connection_type_class(Types::CountableConnectionType) field_class Types::BaseField diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb index 43551c0c..c29321de 100644 --- a/app/models/application_setting.rb +++ b/app/models/application_setting.rb @@ -4,8 +4,11 @@ class ApplicationSetting < ApplicationRecord include Code0::ZeroTrack::Loggable # Custom class used for policy association - ApplicationSettings = Class.new(ActiveSupport::HashWithIndifferentAccess) - MissingApplicationSettings = Class.new(StandardError) + class ApplicationSettings < ActiveSupport::HashWithIndifferentAccess + end + + class MissingApplicationSettings < StandardError + end SETTINGS = { user_registration_enabled: 1, diff --git a/app/models/concerns/has_translation.rb b/app/models/concerns/has_translation.rb index 85f8cf1b..7a30bf91 100644 --- a/app/models/concerns/has_translation.rb +++ b/app/models/concerns/has_translation.rb @@ -4,7 +4,7 @@ module HasTranslation extend ActiveSupport::Concern class_methods do - # rubocop:disable Naming/PredicateName -- this is like has_many from rails rather than a boolean predicate + # rubocop:disable Naming/PredicatePrefix -- this is an association macro, not a predicate def has_translation(relation, purpose: nil) has_many relation, -> { by_purpose(purpose) }, class_name: 'Translation', @@ -13,6 +13,6 @@ def has_translation(relation, purpose: nil) autosave: true, dependent: :destroy end - # rubocop:enable Naming/PredicateName + # rubocop:enable Naming/PredicatePrefix end end diff --git a/app/models/namespace.rb b/app/models/namespace.rb index 633f7514..10e4c953 100644 --- a/app/models/namespace.rb +++ b/app/models/namespace.rb @@ -20,11 +20,9 @@ def user_type? parent_type == User.name end - # rubocop:disable Naming/PredicateName - def has_owner? + def owner? user_type? end - # rubocop:enable Naming/PredicateName def member?(user) return false if user.nil? diff --git a/app/models/user.rb b/app/models/user.rb index e71a9afb..a98fc596 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -2,6 +2,7 @@ class User < ApplicationRecord include NamespaceParent + has_secure_password validates :username, length: { maximum: 50 }, @@ -46,9 +47,9 @@ def validate_mfa!(mfa) case mfa_type when :backup_code backup_code = BackupCode.where(user: self, token: mfa_value) - mfa_passed = backup_code.count.positive? + mfa_passed = backup_code.any? backup_code.delete_all - mfa_passed = false unless backup_code.count.zero? + mfa_passed = false unless backup_code.none? when :totp totp = ROTP::TOTP.new(totp_secret) mfa_passed = totp.verify(mfa_value) diff --git a/app/policies/base_policy.rb b/app/policies/base_policy.rb index 77f265ee..e385784e 100644 --- a/app/policies/base_policy.rb +++ b/app/policies/base_policy.rb @@ -1,7 +1,8 @@ # frozen_string_literal: true class BasePolicy < DeclarativePolicy::Base - InvalidUserError = Class.new(StandardError) + class InvalidUserError < StandardError + end def initialize(user, subject, opts = {}) super diff --git a/app/services/error_code.rb b/app/services/error_code.rb index db3e21f1..b3604896 100644 --- a/app/services/error_code.rb +++ b/app/services/error_code.rb @@ -1,7 +1,8 @@ # frozen_string_literal: true class ErrorCode - InvalidErrorCode = Class.new(StandardError) + class InvalidErrorCode < StandardError + end def self.validate_error_code!(error_code) return unless error_code.is_a?(Symbol) diff --git a/app/services/namespaces/members/assign_roles_service.rb b/app/services/namespaces/members/assign_roles_service.rb index 3e87a81e..ca9dd7b0 100644 --- a/app/services/namespaces/members/assign_roles_service.rb +++ b/app/services/namespaces/members/assign_roles_service.rb @@ -71,7 +71,7 @@ def create_audit_event(new_roles, old_roles_for_audit_event, namespace) end def check_last_admin_user(t) - return if member.namespace.has_owner? + return if member.namespace.owner? unless member.namespace.roles .joins(:abilities, :member_roles) diff --git a/app/services/namespaces/members/delete_service.rb b/app/services/namespaces/members/delete_service.rb index f89e9a2e..d4b63604 100644 --- a/app/services/namespaces/members/delete_service.rb +++ b/app/services/namespaces/members/delete_service.rb @@ -43,7 +43,7 @@ def execute private def check_last_administrator(t) - return if namespace_member.namespace.has_owner? + return if namespace_member.namespace.owner? unless namespace_member.namespace.roles .joins(:abilities, :member_roles) diff --git a/app/services/namespaces/roles/assign_abilities_service.rb b/app/services/namespaces/roles/assign_abilities_service.rb index 326bec64..dca7a585 100644 --- a/app/services/namespaces/roles/assign_abilities_service.rb +++ b/app/services/namespaces/roles/assign_abilities_service.rb @@ -59,7 +59,7 @@ def execute private def check_admin_existing(t) - return if role.namespace.has_owner? + return if role.namespace.owner? unless role.namespace.roles.where.not(id: role.id) .joins(:abilities) diff --git a/app/services/namespaces/roles/delete_service.rb b/app/services/namespaces/roles/delete_service.rb index 10477130..c11ed160 100644 --- a/app/services/namespaces/roles/delete_service.rb +++ b/app/services/namespaces/roles/delete_service.rb @@ -17,7 +17,7 @@ def execute return ServiceResponse.error(message: 'Missing permissions', error_code: :missing_permission) end - if !namespace_role.namespace.has_owner? && + if !namespace_role.namespace.owner? && !namespace_role.namespace.roles.where.not(id: namespace_role.id) .joins(:abilities) .joins(:member_roles) diff --git a/app/services/runtimes/check_runtime_compatibility_service.rb b/app/services/runtimes/check_runtime_compatibility_service.rb index 1f7c0b85..582422a7 100644 --- a/app/services/runtimes/check_runtime_compatibility_service.rb +++ b/app/services/runtimes/check_runtime_compatibility_service.rb @@ -41,7 +41,7 @@ def check_versions(model, identifier_field = :identifier) error_code: :missing_definition) end - result = compare_version(curr_type.parsed_version, to_check.parsed_version) + result = compatible_version?(curr_type.parsed_version, to_check.parsed_version) unless result return ServiceResponse.error(message: "#{model} is outdated", @@ -53,7 +53,7 @@ def check_versions(model, identifier_field = :identifier) # true: compatible # false: not compatible - def compare_version(primary_version, to_check_version) + def compatible_version?(primary_version, to_check_version) return false if primary_version.segments[0] != to_check_version.segments[0] return false if primary_version.segments[1] > to_check_version.segments[1] diff --git a/app/services/users/mfa/backup_codes/rotate_service.rb b/app/services/users/mfa/backup_codes/rotate_service.rb index 37e27164..d1739b6d 100644 --- a/app/services/users/mfa/backup_codes/rotate_service.rb +++ b/app/services/users/mfa/backup_codes/rotate_service.rb @@ -21,7 +21,7 @@ def execute transactional do |t| old_codes = BackupCode.where(user: current_user) old_codes.delete_all - unless old_codes.count.zero? + unless old_codes.none? t.rollback_and_return! ServiceResponse.error(message: 'Failed to delete old backup codes', error_code: :failed_to_invalidate_old_backup_codes) end diff --git a/db/fixtures/production/01_users.rb b/db/fixtures/production/01_users.rb index 81b285fa..cee5f412 100644 --- a/db/fixtures/production/01_users.rb +++ b/db/fixtures/production/01_users.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -return unless User.count.zero? +return unless User.none? initial_root_email = ENV.fetch('INITIAL_ROOT_MAIL', nil) initial_root_password = ENV.fetch('INITIAL_ROOT_PASSWORD', SecureRandom.hex) diff --git a/db/fixtures/production/02_runtimes.rb b/db/fixtures/production/02_runtimes.rb index 4947aaa3..7c2cdabf 100644 --- a/db/fixtures/production/02_runtimes.rb +++ b/db/fixtures/production/02_runtimes.rb @@ -3,7 +3,7 @@ initial_runtime_token = ENV.fetch('INITIAL_RUNTIME_TOKEN', nil) return if initial_runtime_token.blank? -return unless Runtime.count.zero? +return unless Runtime.none? runtime = Runtime.new( name: 'Initial Runtime', diff --git a/lib/sagittarius/graphql/stable_connection.rb b/lib/sagittarius/graphql/stable_connection.rb index ffc96cbd..ca5259fd 100644 --- a/lib/sagittarius/graphql/stable_connection.rb +++ b/lib/sagittarius/graphql/stable_connection.rb @@ -56,7 +56,7 @@ def nodes results.slice(0, page_size) end - # rubocop:disable Naming/PredicateName -- this is required by graphql-ruby + # rubocop:disable Naming/PredicateMethod, Naming/PredicatePrefix -- these method names are required by graphql-ruby def has_next_page !backward? && results.size > page_size end @@ -64,7 +64,7 @@ def has_next_page def has_previous_page backward? && results.size > page_size end - # rubocop:enable Naming/PredicateName + # rubocop:enable Naming/PredicateMethod, Naming/PredicatePrefix end # rubocop:enable GraphQL/ObjectDescription end diff --git a/lib/sagittarius/override.rb b/lib/sagittarius/override.rb index f61fd94e..34051edb 100644 --- a/lib/sagittarius/override.rb +++ b/lib/sagittarius/override.rb @@ -4,8 +4,11 @@ module Sagittarius module Override extend ActiveSupport::Concern - InvalidMethodError = Class.new(StandardError) - MissingOverrideError = Class.new(StandardError) + class InvalidMethodError < StandardError + end + + class MissingOverrideError < StandardError + end class_methods do def override(method) @@ -23,7 +26,7 @@ def self.verify!(clazz) def self.verify_existence!(clazz) Override.extensions[clazz].each do |method| - unless clazz.instance_methods.include?(method) + unless clazz.method_defined?(method) raise_error! InvalidMethodError, "Method #{method} is not defined on #{clazz}" end end @@ -40,7 +43,7 @@ def self.verify_overrides!(clazz) end Override.extensions[clazz].each do |method| - unless valid_sources.any? { |src| src.instance_methods(false).include?(method) } + unless valid_sources.any? { |src| src.method_defined?(method, false) } raise_error! MissingOverrideError, "Method #{method} is not defined on #{core_class} or a lower extension" end end @@ -68,7 +71,7 @@ def self.verify_missing_overrides!(clazz, extended_modules) lower_sources = [clazz] + extended_modules[0...index] ext.instance_methods(false).each do |method| - source = lower_sources.find { |src| src.instance_methods(false).include?(method) } + source = lower_sources.find { |src| src.method_defined?(method, false) } next unless source overrides = Override.extensions[ext] diff --git a/lib/sagittarius/validators/json_schema_validator.rb b/lib/sagittarius/validators/json_schema_validator.rb index ad00ddbc..49374adf 100644 --- a/lib/sagittarius/validators/json_schema_validator.rb +++ b/lib/sagittarius/validators/json_schema_validator.rb @@ -9,7 +9,8 @@ module Sagittarius module Validators class JsonSchemaValidator < ActiveModel::EachValidator - FilenameError = Class.new(StandardError) + class FilenameError < StandardError + end BASE_DIRECTORY = %w[app models json_schemas].freeze def initialize(options) diff --git a/spec/models/flow_spec.rb b/spec/models/flow_spec.rb index 8b0b0fa0..140a4ee2 100644 --- a/spec/models/flow_spec.rb +++ b/spec/models/flow_spec.rb @@ -121,13 +121,15 @@ ], starting_node_id: starting_node.id, settings: [ - database_id: flow.flow_settings.first.id, - flow_setting_id: flow.flow_settings.first.flow_setting_id, - value: { - struct_value: { - fields: { - 'url' => { - string_value: flow.flow_settings.first.object['url'], + { + database_id: flow.flow_settings.first.id, + flow_setting_id: flow.flow_settings.first.flow_setting_id, + value: { + struct_value: { + fields: { + 'url' => { + string_value: flow.flow_settings.first.object['url'], + }, }, }, }, diff --git a/spec/requests/graphql/mutation/namespace/projects/flows/create_mutation_spec.rb b/spec/requests/graphql/mutation/namespace/projects/flows/create_mutation_spec.rb index 9d135be1..5b927b3c 100644 --- a/spec/requests/graphql/mutation/namespace/projects/flows/create_mutation_spec.rb +++ b/spec/requests/graphql/mutation/namespace/projects/flows/create_mutation_spec.rb @@ -102,8 +102,10 @@ id: 'gid://sagittarius/NodeFunction/1000', functionDefinitionId: function_definition.to_global_id.to_s, parameters: [ - value: { - nodeFunctionId: 'gid://sagittarius/NodeFunction/2000', + { + value: { + nodeFunctionId: 'gid://sagittarius/NodeFunction/2000', + }, } ], nextNodeId: 'gid://sagittarius/NodeFunction/1001', @@ -112,15 +114,17 @@ id: 'gid://sagittarius/NodeFunction/1001', functionDefinitionId: function_definition.to_global_id.to_s, parameters: [ - value: { - referenceValue: { - referencePath: [ - { - arrayIndex: 0, - path: 'some.path', - } - ], - nodeFunctionId: 'gid://sagittarius/NodeFunction/2000', + { + value: { + referenceValue: { + referencePath: [ + { + arrayIndex: 0, + path: 'some.path', + } + ], + nodeFunctionId: 'gid://sagittarius/NodeFunction/2000', + }, }, } ], diff --git a/spec/requests/graphql/mutation/namespace/projects/flows/update_mutation_spec.rb b/spec/requests/graphql/mutation/namespace/projects/flows/update_mutation_spec.rb index 5bb68b43..5538f286 100644 --- a/spec/requests/graphql/mutation/namespace/projects/flows/update_mutation_spec.rb +++ b/spec/requests/graphql/mutation/namespace/projects/flows/update_mutation_spec.rb @@ -108,8 +108,10 @@ id: 'gid://sagittarius/NodeFunction/1000', functionDefinitionId: function_definition.to_global_id.to_s, parameters: [ - value: { - nodeFunctionId: 'gid://sagittarius/NodeFunction/2000', + { + value: { + nodeFunctionId: 'gid://sagittarius/NodeFunction/2000', + }, } ], nextNodeId: 'gid://sagittarius/NodeFunction/1001', diff --git a/spec/support/helpers/stub_ability.rb b/spec/support/helpers/stub_ability.rb index 5608aa0c..3e61e481 100644 --- a/spec/support/helpers/stub_ability.rb +++ b/spec/support/helpers/stub_ability.rb @@ -1,7 +1,8 @@ # frozen_string_literal: true module StubAbility - InvalidAbility = Class.new(StandardError) + class InvalidAbility < StandardError + end def stub_allowed_ability(policy_class, ability, user: nil, subject: nil) raise InvalidAbility, "Ability #{ability} does not exist" unless NamespaceRoleAbility::ABILITIES.key?(ability) diff --git a/spec/support/matchers/exceed_query_limit_matchers.rb b/spec/support/matchers/exceed_query_limit_matchers.rb index d6f9f1fb..07dc9081 100644 --- a/spec/support/matchers/exceed_query_limit_matchers.rb +++ b/spec/support/matchers/exceed_query_limit_matchers.rb @@ -138,7 +138,7 @@ def query_log(query_recorder) end def recorder - @recorder ||= ActiveRecord::QueryRecorder.new(skip_cached: skip_cached, &@subject_block) + @recorder ||= ActiveRecord::QueryRecorder.new(skip_cached: skip_cached?, &@subject_block) end # Take a query recorder and tabulate the frequencies of suffixes for each prefix. @@ -207,11 +207,11 @@ def log_message end end - def skip_cached + def skip_cached? true end - def verify_count(&block) + def count_verified?(&block) @subject_block = block actual_count > maximum end @@ -248,7 +248,7 @@ def expected_count control_recorder.count end - def verify_count(&block) + def count_verified?(&block) @subject_block = block # These blocks need to be evaluated in an expected order, in case @@ -260,7 +260,7 @@ def verify_count(&block) end match do |block| - verify_count(&block) + count_verified?(&block) end def failure_message @@ -304,7 +304,7 @@ def expected_count end end - def verify_count(&block) + def count_verified?(&block) @subject_block = block # These blocks need to be evaluated in an expected order, in case @@ -320,7 +320,7 @@ def verify_count(&block) end match do |block| - verify_count(&block) + count_verified?(&block) end def failure_message @@ -346,7 +346,7 @@ def expected_count_message [expected_count.to_s, or_fewer_msg, threshold_msg].compact.join(' ') end - def skip_cached + def skip_cached? @skip_cached || false end end @@ -357,14 +357,14 @@ def skip_cached include ExceedQueryLimitHelpers match do |block| - verify_count(&block) + count_verified?(&block) end failure_message_when_negated do |actual| failure_message end - def skip_cached + def skip_cached? false end end @@ -378,9 +378,9 @@ def skip_cached match do |block| if block.is_a?(ActiveRecord::QueryRecorder) @recorder = block - verify_count + count_verified? else - verify_count(&block) + count_verified?(&block) end end @@ -394,7 +394,7 @@ def skip_cached include ExceedQueryLimitHelpers - def verify_count(&block) + def count_verified?(&block) @subject_block = block actual_count == maximum end @@ -405,12 +405,12 @@ def failure_message "Expected exactly #{counts} queries, got #{actual_count}:\n\n#{log_message}" end - def skip_cached + def skip_cached? false end match do |block| - verify_count(&block) + count_verified?(&block) end failure_message_when_negated do |actual| diff --git a/tooling/graphql/docs/parser.rb b/tooling/graphql/docs/parser.rb index 6c070ace..33623cc3 100644 --- a/tooling/graphql/docs/parser.rb +++ b/tooling/graphql/docs/parser.rb @@ -4,7 +4,8 @@ module Tooling module Graphql module Docs class Parser # rubocop:disable GraphQL/ObjectDescription -- this is not a graphql object - ViolatedAssumption = Class.new(StandardError) + class ViolatedAssumption < StandardError # rubocop:disable GraphQL/ObjectDescription -- this is an exception, not a GraphQL object + end SLUGIFY_PRETTY_REGEXP = Regexp.new("[^[:alnum:]._~!$&'()+,;=@]+").freeze GQL_CONTEXT = { visibility_profile: :docs }.freeze