diff --git a/.rubocop.yml b/.rubocop.yml index ed6bf9a..b62b4ea 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -14,4 +14,8 @@ AllCops: Layout/LineLength: Max: 120 RSpec/ExampleLength: - Max: 30 \ No newline at end of file + Enabled: false +Metrics/ModuleLength: + Enabled: false +RSpec/MultipleMemoizedHelpers: + Enabled: false \ No newline at end of file diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index fa81db3..a68d8b3 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Copyright (C) 2024 Manuel Bustillo # This file is copied to spec/ when you run 'rails generate rspec:install' @@ -5,7 +7,7 @@ require 'spec_helper' ENV['RAILS_ENV'] ||= 'test' require_relative '../config/environment' # Prevent database truncation if the environment is production -abort("The Rails environment is running in production mode!") if Rails.env.production? +abort('The Rails environment is running in production mode!') if Rails.env.production? require 'rspec/rails' # Add additional requires below this line. Rails is not loaded until this point! diff --git a/spec/requests/affinities_spec.rb b/spec/requests/affinities_spec.rb index 6e113d2..c964018 100644 --- a/spec/requests/affinities_spec.rb +++ b/spec/requests/affinities_spec.rb @@ -4,7 +4,7 @@ require 'swagger_helper' -RSpec.describe 'affinities', type: :request do +RSpec.describe 'affinities' do path '/{slug}/groups/{group_id}/affinities' do parameter Swagger::Schema::SLUG parameter name: 'group_id', in: :path, type: :string, format: :uuid, description: 'group_id' @@ -46,7 +46,7 @@ RSpec.describe 'affinities', type: :request do } } - response_empty_200 + response_empty200 end end end diff --git a/spec/requests/captcha_spec.rb b/spec/requests/captcha_spec.rb index 607a2d9..4441304 100644 --- a/spec/requests/captcha_spec.rb +++ b/spec/requests/captcha_spec.rb @@ -1,22 +1,23 @@ +# frozen_string_literal: true + # Copyright (C) 2024 Manuel Bustillo require 'swagger_helper' -RSpec.describe 'captcha', type: :request do +RSpec.describe 'captcha' do path '/captcha' do - post('create a CAPTCHA challenge') do tags 'CAPTCHA' consumes 'application/json' produces 'application/json' - + response(201, 'created') do schema type: :object, - required: %i[id], - properties: { - id: { type: :string, format: :uuid }, - media_url: { type: :string, format: :uri }, - } + required: %i[id], + properties: { + id: { type: :string, format: :uuid }, + media_url: { type: :string, format: :uri } + } xit end end diff --git a/spec/requests/expenses_spec.rb b/spec/requests/expenses_spec.rb index 068fec5..4bfa22f 100644 --- a/spec/requests/expenses_spec.rb +++ b/spec/requests/expenses_spec.rb @@ -1,8 +1,10 @@ +# frozen_string_literal: true + # Copyright (C) 2024 Manuel Bustillo require 'swagger_helper' -RSpec.describe 'expenses', type: :request do +RSpec.describe 'expenses' do path '/{slug}/expenses' do get('list expenses') do tags 'Expenses' @@ -42,8 +44,8 @@ RSpec.describe 'expenses', type: :request do } } - response_empty_201 - response_422 + response_empty201 + response422 regular_api_responses end end @@ -60,9 +62,9 @@ RSpec.describe 'expenses', type: :request do properties: Swagger::Schema::EXPENSE } - response_empty_200 - response_422 - response_404 + response_empty200 + response422 + response404 regular_api_responses end @@ -71,8 +73,8 @@ RSpec.describe 'expenses', type: :request do produces 'application/json' parameter Swagger::Schema::SLUG parameter Swagger::Schema::ID - response_empty_200 - response_404 + response_empty200 + response404 regular_api_responses end end diff --git a/spec/requests/groups_spec.rb b/spec/requests/groups_spec.rb index bc6267b..3496ad5 100644 --- a/spec/requests/groups_spec.rb +++ b/spec/requests/groups_spec.rb @@ -1,8 +1,10 @@ +# frozen_string_literal: true + # Copyright (C) 2024 Manuel Bustillo require 'swagger_helper' -RSpec.describe 'groups', type: :request do +RSpec.describe 'groups' do path '/{slug}/groups' do get('list groups') do tags 'Groups' @@ -10,29 +12,29 @@ RSpec.describe 'groups', type: :request do parameter Swagger::Schema::SLUG response(200, 'successful') do schema type: :array, - items: { - type: :object, - required: %i[id name icon parent_id color attendance], - properties: { - id: { type: :string, format: :uuid, required: true }, - name: { type: :string }, - icon: { type: :string, example: 'pi pi-crown', description: 'The CSS classes used by the icon' }, - parent_id: { type: :string, format: :uuid }, - color: { type: :string, pattern: '^#(?:[0-9a-fA-F]{3}){1,2}$' }, - attendance: { - type: :object, - required: %i[total considered invited confirmed declined tentative], - properties: { - total: { type: :integer, minimum: 0, description: 'Total number of guests in any status' }, - considered: { type: :integer, minimum: 0 }, - invited: { type: :integer, minimum: 0 }, - confirmed: { type: :integer, minimum: 0 }, - declined: { type: :integer, minimum: 0 }, - tentative: { type: :integer, minimum: 0 } - } - } - } + items: { + type: :object, + required: %i[id name icon parent_id color attendance], + properties: { + id: { type: :string, format: :uuid, required: true }, + name: { type: :string }, + icon: { type: :string, example: 'pi pi-crown', description: 'The CSS classes used by the icon' }, + parent_id: { type: :string, format: :uuid }, + color: { type: :string, pattern: '^#(?:[0-9a-fA-F]{3}){1,2}$' }, + attendance: { + type: :object, + required: %i[total considered invited confirmed declined tentative], + properties: { + total: { type: :integer, minimum: 0, description: 'Total number of guests in any status' }, + considered: { type: :integer, minimum: 0 }, + invited: { type: :integer, minimum: 0 }, + confirmed: { type: :integer, minimum: 0 }, + declined: { type: :integer, minimum: 0 }, + tentative: { type: :integer, minimum: 0 } + } + } } + } xit end regular_api_responses @@ -99,8 +101,8 @@ RSpec.describe 'groups', type: :request do produces 'application/json' parameter Swagger::Schema::SLUG parameter name: :id, in: :path, type: :string, format: :uuid - - response_empty_200 + + response_empty200 regular_api_responses end end diff --git a/spec/requests/guests_spec.rb b/spec/requests/guests_spec.rb index bc73fbe..cd52ca0 100644 --- a/spec/requests/guests_spec.rb +++ b/spec/requests/guests_spec.rb @@ -1,8 +1,10 @@ +# frozen_string_literal: true + # Copyright (C) 2024 Manuel Bustillo require 'swagger_helper' -RSpec.describe 'guests', type: :request do +RSpec.describe 'guests' do path '/{slug}/guests' do get('list guests') do tags 'Guests' @@ -51,8 +53,8 @@ RSpec.describe 'guests', type: :request do } } - response_empty_201 - response_422 + response_empty201 + response422 regular_api_responses end end @@ -80,9 +82,9 @@ RSpec.describe 'guests', type: :request do } } - response_empty_200 - response_422 - response_404 + response_empty200 + response422 + response404 regular_api_responses end @@ -92,8 +94,8 @@ RSpec.describe 'guests', type: :request do parameter Swagger::Schema::SLUG parameter name: 'id', in: :path, type: :string, format: :uuid - response_empty_200 - response_404 + response_empty200 + response404 regular_api_responses end end diff --git a/spec/requests/summary_spec.rb b/spec/requests/summary_spec.rb index 2b77892..569e4b9 100644 --- a/spec/requests/summary_spec.rb +++ b/spec/requests/summary_spec.rb @@ -1,8 +1,10 @@ +# frozen_string_literal: true + # Copyright (C) 2024 Manuel Bustillo require 'swagger_helper' -RSpec.describe 'summary', type: :request do +RSpec.describe 'summary' do path '/{slug}/summary' do get('list summaries') do tags 'Summary' diff --git a/spec/requests/tables_arrangements_spec.rb b/spec/requests/tables_arrangements_spec.rb index c48c127..eb4c9cd 100644 --- a/spec/requests/tables_arrangements_spec.rb +++ b/spec/requests/tables_arrangements_spec.rb @@ -1,8 +1,10 @@ +# frozen_string_literal: true + # Copyright (C) 2024 Manuel Bustillo require 'swagger_helper' -RSpec.describe 'tables_arrangements', type: :request do +RSpec.describe 'tables_arrangements' do path '/{slug}/tables_arrangements' do get('list tables arrangements') do tags 'Tables Arrangements' diff --git a/spec/requests/tokens_spec.rb b/spec/requests/tokens_spec.rb index 5a08e05..077543d 100644 --- a/spec/requests/tokens_spec.rb +++ b/spec/requests/tokens_spec.rb @@ -1,15 +1,5 @@ +# frozen_string_literal: true + # Copyright (C) 2024 Manuel Bustillo require 'swagger_helper' - -RSpec.describe 'tokens', type: :request do - path '/token' do - get('get a cookie with CSRF token') do - tags 'CSRF token' - consumes 'application/json' - produces 'application/json' - - response_empty_200 - end - end -end diff --git a/spec/requests/users/confirmations_spec.rb b/spec/requests/users/confirmations_spec.rb index 12bdfbc..88dd707 100644 --- a/spec/requests/users/confirmations_spec.rb +++ b/spec/requests/users/confirmations_spec.rb @@ -1,9 +1,10 @@ +# frozen_string_literal: true + # Copyright (C) 2024 Manuel Bustillo require 'swagger_helper' -RSpec.describe 'users/confirmations', type: :request do - +RSpec.describe 'users/confirmations' do path '/{slug}/users/confirmation' do get('confirm user email') do tags 'Users' @@ -17,7 +18,7 @@ RSpec.describe 'users/confirmations', type: :request do xit end - response_422 + response422 end end end diff --git a/spec/requests/users/registrations_spec.rb b/spec/requests/users/registrations_spec.rb index 2cbaeea..ac423c1 100644 --- a/spec/requests/users/registrations_spec.rb +++ b/spec/requests/users/registrations_spec.rb @@ -1,25 +1,26 @@ +# frozen_string_literal: true + # Copyright (C) 2024 Manuel Bustillo require 'swagger_helper' -RSpec.describe 'users/registrations', type: :request do - +RSpec.describe 'users/registrations' do path '/{slug}/users' do post('create registration') do tags 'Users Registrations' consumes 'application/json' produces 'application/json' - + parameter Swagger::Schema::SLUG parameter name: :body, in: :body, schema: { type: :object, - required: [:user, :wedding], + required: %i[user wedding], properties: { user: { type: :object, required: %i[email password password_confirmation], properties: { - email: { type: :string, format: :email}, + email: { type: :string, format: :email }, password: SwaggerResponseHelper::PASSWORD, password_confirmation: SwaggerResponseHelper::PASSWORD } diff --git a/spec/requests/users/sessions_spec.rb b/spec/requests/users/sessions_spec.rb index a803965..1553aed 100644 --- a/spec/requests/users/sessions_spec.rb +++ b/spec/requests/users/sessions_spec.rb @@ -1,11 +1,11 @@ +# frozen_string_literal: true + # Copyright (C) 2024 Manuel Bustillo require 'swagger_helper' -RSpec.describe 'users/sessions', type: :request do - +RSpec.describe 'users/sessions' do path '/{slug}/users/sign_in' do - post('create session') do tags 'Users Sessions' consumes 'application/json' @@ -32,7 +32,7 @@ RSpec.describe 'users/sessions', type: :request do xit end - response_401(message: 'Invalid Email or password.') + response401(message: 'Invalid Email or password.') end end diff --git a/spec/services/tables/discomfort_calculator_spec.rb b/spec/services/tables/discomfort_calculator_spec.rb index f5da2d1..a4eea1d 100644 --- a/spec/services/tables/discomfort_calculator_spec.rb +++ b/spec/services/tables/discomfort_calculator_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Copyright (C) 2024 Manuel Bustillo require 'rails_helper' @@ -12,8 +14,7 @@ module Tables describe '#calculate' do before do - allow(calculator).to receive(:table_size_penalty).and_return(2) - allow(calculator).to receive(:cohesion_discomfort).and_return(3) + allow(calculator).to receive_messages(table_size_penalty: 2, cohesion_discomfort: 3) end let(:table) { Table.new(create_list(:guest, 6)) } @@ -29,6 +30,7 @@ module Tables table.min_per_table = 5 table.max_per_table = 7 end + context 'when the number of guests is in the lower bound' do let(:table) { Table.new(create_list(:guest, 5)) } @@ -88,6 +90,7 @@ module Tables allow(AffinityGroupsHierarchy.instance).to receive(:distance).with(friends.id, school.id).and_return(4) allow(AffinityGroupsHierarchy.instance).to receive(:distance).with(work.id, school.id).and_return(5) end + context 'when the table contains just two guests' do context 'when they belong to the same group' do let(:table) { create_list(:guest, 2, group: family) } @@ -102,6 +105,7 @@ module Tables create(:guest, group: friends) ] end + it { expect(calculator.send(:cohesion_discomfort)).to eq(1) } end @@ -205,7 +209,7 @@ module Tables end it 'returns the sum of the penalties for each pair of guests' do - expect(calculator.send(:cohesion_discomfort)).to eq(4 * 1 + 4 * Rational(1, 2) + 4 * Rational(2, 3)) + expect(calculator.send(:cohesion_discomfort)).to eq((4 * 1) + (4 * Rational(1, 2)) + (4 * Rational(2, 3))) end end @@ -219,7 +223,7 @@ module Tables end it 'returns the sum of the penalties for each pair of guests' do - expect(calculator.send(:cohesion_discomfort)).to eq(6 * 1 + 2 * Rational(1, 2) + 3 * Rational(2, 3)) + expect(calculator.send(:cohesion_discomfort)).to eq((6 * 1) + (2 * Rational(1, 2)) + (3 * Rational(2, 3))) end end end diff --git a/spec/services/tables/distribution_spec.rb b/spec/services/tables/distribution_spec.rb index df88a85..26834c0 100644 --- a/spec/services/tables/distribution_spec.rb +++ b/spec/services/tables/distribution_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Copyright (C) 2024 Manuel Bustillo require 'rails_helper' @@ -5,19 +7,19 @@ require 'rails_helper' module Tables RSpec.describe Distribution do describe '#random_distribution' do - let(:subject) { described_class.new(min_per_table: 5, max_per_table: 10) } + subject(:distribution) { described_class.new(min_per_table: 5, max_per_table: 10) } context 'when there are fewer people than the minimum per table' do it 'creates one table' do - subject.random_distribution([1, 2, 3, 4]) - expect(subject.tables.count).to eq(1) + distribution.random_distribution([1, 2, 3, 4]) + expect(distribution.tables.count).to eq(1) end end context 'when there are more people than the maximum per table' do it 'creates multiple tables' do - subject.random_distribution([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]) - expect(subject.tables.count).to be > 1 + distribution.random_distribution([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]) + expect(distribution.tables.count).to be > 1 end end end diff --git a/spec/services/tables/shift_spec.rb b/spec/services/tables/shift_spec.rb index e4c48af..08b2ca1 100644 --- a/spec/services/tables/shift_spec.rb +++ b/spec/services/tables/shift_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Copyright (C) 2024 Manuel Bustillo require 'rails_helper' @@ -7,7 +9,7 @@ module Tables describe '#each' do let(:shifts) do acc = [] - described_class.new(initial_solution).each do |solution| + described_class.new(initial_solution).each do |solution| # rubocop:disable Style/MapIntoArray -- #map is not implemented acc << solution.tables.map(&:dup) end acc diff --git a/spec/services/tables/swap_spec.rb b/spec/services/tables/swap_spec.rb index 159d998..067d4bc 100644 --- a/spec/services/tables/swap_spec.rb +++ b/spec/services/tables/swap_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Copyright (C) 2024 Manuel Bustillo require 'rails_helper' @@ -7,7 +9,7 @@ module Tables describe '#each' do let(:swaps) do acc = [] - described_class.new(initial_solution).each do |solution| + described_class.new(initial_solution).each do |solution| # rubocop:disable Style/MapIntoArray -- #map is not implemented acc << solution.tables.map(&:dup) end acc diff --git a/spec/services/vns/engine_spec.rb b/spec/services/vns/engine_spec.rb index d4064f6..b7ff9a5 100644 --- a/spec/services/vns/engine_spec.rb +++ b/spec/services/vns/engine_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Copyright (C) 2024 Manuel Bustillo require 'rails_helper' diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 25cfd37..b2f85ad 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Copyright (C) 2024 Manuel Bustillo # This file was generated by the `rails generate rspec:install` command. Conventionally, all @@ -46,51 +48,49 @@ RSpec.configure do |config| # triggering implicit auto-inclusion in groups with matching metadata. config.shared_context_metadata_behavior = :apply_to_host_groups -# The settings below are suggested to provide a good initial experience -# with RSpec, but feel free to customize to your heart's content. -=begin - # This allows you to limit a spec run to individual examples or groups - # you care about by tagging them with `:focus` metadata. When nothing - # is tagged with `:focus`, all examples get run. RSpec also provides - # aliases for `it`, `describe`, and `context` that include `:focus` - # metadata: `fit`, `fdescribe` and `fcontext`, respectively. - config.filter_run_when_matching :focus - - # Allows RSpec to persist some state between runs in order to support - # the `--only-failures` and `--next-failure` CLI options. We recommend - # you configure your source control system to ignore this file. - config.example_status_persistence_file_path = "spec/examples.txt" - - # Limits the available syntax to the non-monkey patched syntax that is - # recommended. For more details, see: - # https://rspec.info/features/3-12/rspec-core/configuration/zero-monkey-patching-mode/ - config.disable_monkey_patching! - - # Many RSpec users commonly either run the entire suite or an individual - # file, and it's useful to allow more verbose output when running an - # individual spec file. - if config.files_to_run.one? - # Use the documentation formatter for detailed output, - # unless a formatter has already been configured - # (e.g. via a command-line flag). - config.default_formatter = "doc" - end - - # Print the 10 slowest examples and example groups at the - # end of the spec run, to help surface which specs are running - # particularly slow. - config.profile_examples = 10 - - # Run specs in random order to surface order dependencies. If you find an - # order dependency and want to debug it, you can fix the order by providing - # the seed, which is printed after each run. - # --seed 1234 - config.order = :random - - # Seed global randomization in this process using the `--seed` CLI option. - # Setting this allows you to use `--seed` to deterministically reproduce - # test failures related to randomization by passing the same `--seed` value - # as the one that triggered the failure. - Kernel.srand config.seed -=end + # The settings below are suggested to provide a good initial experience + # with RSpec, but feel free to customize to your heart's content. + # # This allows you to limit a spec run to individual examples or groups + # # you care about by tagging them with `:focus` metadata. When nothing + # # is tagged with `:focus`, all examples get run. RSpec also provides + # # aliases for `it`, `describe`, and `context` that include `:focus` + # # metadata: `fit`, `fdescribe` and `fcontext`, respectively. + # config.filter_run_when_matching :focus + # + # # Allows RSpec to persist some state between runs in order to support + # # the `--only-failures` and `--next-failure` CLI options. We recommend + # # you configure your source control system to ignore this file. + # config.example_status_persistence_file_path = "spec/examples.txt" + # + # # Limits the available syntax to the non-monkey patched syntax that is + # # recommended. For more details, see: + # # https://rspec.info/features/3-12/rspec-core/configuration/zero-monkey-patching-mode/ + # config.disable_monkey_patching! + # + # # Many RSpec users commonly either run the entire suite or an individual + # # file, and it's useful to allow more verbose output when running an + # # individual spec file. + # if config.files_to_run.one? + # # Use the documentation formatter for detailed output, + # # unless a formatter has already been configured + # # (e.g. via a command-line flag). + # config.default_formatter = "doc" + # end + # + # # Print the 10 slowest examples and example groups at the + # # end of the spec run, to help surface which specs are running + # # particularly slow. + # config.profile_examples = 10 + # + # # Run specs in random order to surface order dependencies. If you find an + # # order dependency and want to debug it, you can fix the order by providing + # # the seed, which is printed after each run. + # # --seed 1234 + # config.order = :random + # + # # Seed global randomization in this process using the `--seed` CLI option. + # # Setting this allows you to use `--seed` to deterministically reproduce + # # test failures related to randomization by passing the same `--seed` value + # # as the one that triggered the failure. + # Kernel.srand config.seed end diff --git a/spec/swagger_helper.rb b/spec/swagger_helper.rb index 2b19be8..2c53057 100644 --- a/spec/swagger_helper.rb +++ b/spec/swagger_helper.rb @@ -3,10 +3,10 @@ # frozen_string_literal: true require 'rails_helper' -require_relative './swagger_response_helper' -require_relative './requests/schemas.rb' +require_relative 'swagger_response_helper' +require_relative 'requests/schemas' -include SwaggerResponseHelper +include SwaggerResponseHelper # rubocop:disable Style/MixinUsage RSpec.configure do |config| # Specify a root folder where Swagger JSON files are generated diff --git a/spec/swagger_response_helper.rb b/spec/swagger_response_helper.rb index d7f2e0e..424818a 100644 --- a/spec/swagger_response_helper.rb +++ b/spec/swagger_response_helper.rb @@ -1,18 +1,19 @@ +# frozen_string_literal: true + # Copyright (C) 2024 Manuel Bustillo module SwaggerResponseHelper TIMESTAMP_FORMAT = '\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z' TIMESTAMP_EXAMPLE = Time.zone.now.iso8601(3) - TIMESTAMP = {type: :string,pattern: TIMESTAMP_FORMAT,example: TIMESTAMP_EXAMPLE}.freeze - PASSWORD = { type: :string, minLength: User.password_length.begin, maxLength: User.password_length.end } - + TIMESTAMP = { type: :string, pattern: TIMESTAMP_FORMAT, example: TIMESTAMP_EXAMPLE }.freeze + PASSWORD = { type: :string, minLength: User.password_length.begin, maxLength: User.password_length.end }.freeze def regular_api_responses - response_401 + response401 end - def response_422 + def response422 response(422, 'Validation errors in input parameters') do produces 'application/json' error_schema @@ -20,7 +21,7 @@ module SwaggerResponseHelper end end - def response_empty_200 + def response_empty200 response(200, 'Success') do produces 'application/json' schema type: :object @@ -28,7 +29,7 @@ module SwaggerResponseHelper end end - def response_empty_201 + def response_empty201 response(201, 'Created') do produces 'application/json' schema type: :object @@ -36,7 +37,7 @@ module SwaggerResponseHelper end end - def response_404 + def response404 response(404, 'Record not found') do produces 'application/json' error_schema @@ -44,14 +45,14 @@ module SwaggerResponseHelper end end - def response_401(message: nil) + def response401(message: nil) response(401, 'Unauthorized') do produces 'application/json' schema type: :object, - required: %i[error], - properties: { - error: { type: :string, example: message || 'You need to sign in or sign up before continuing.' } - } + required: %i[error], + properties: { + error: { type: :string, example: message || 'You need to sign in or sign up before continuing.' } + } xit end end