diff --git a/Gemfile b/Gemfile index 11023bb..b127663 100644 --- a/Gemfile +++ b/Gemfile @@ -13,10 +13,13 @@ ruby ENV["CUSTOM_RUBY_VERSION"] || File.read( RAILS_VERSION = Gem::Version.new( ENV["RAILS_VERSION"] || File.read(File.expand_path(".rails-version", __dir__)).strip, ) + +gem "puma" gem "rails", "~> #{RAILS_VERSION}" gem "rake" gem "sqlite3", RAILS_VERSION >= Gem::Version.new("8") ? ">= 2" : "~> 1.4" -gem "puma" + +gem "faker" gem "rack-cors" # Only Rails >=7 gems. diff --git a/Gemfile.lock b/Gemfile.lock index c6025fb..04fa7db 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -113,6 +113,8 @@ GEM erubi (1.13.0) et-orbi (1.2.11) tzinfo + faker (3.5.1) + i18n (>= 1.8.11, < 2) foreman (0.88.1) fugit (1.11.1) et-orbi (~> 1, >= 1.2.11) @@ -335,6 +337,7 @@ DEPENDENCIES binding_of_caller byebug cloudflare-rails + faker foreman httparty kamal diff --git a/test/app/controllers/api/test/users_without_rescue_unknown_format_controller.rb b/test/app/controllers/api/test/no_rescue_unknown_format_controller.rb similarity index 63% rename from test/app/controllers/api/test/users_without_rescue_unknown_format_controller.rb rename to test/app/controllers/api/test/no_rescue_unknown_format_controller.rb index a0fdb80..8c49b32 100644 --- a/test/app/controllers/api/test/users_without_rescue_unknown_format_controller.rb +++ b/test/app/controllers/api/test/no_rescue_unknown_format_controller.rb @@ -1,4 +1,4 @@ -class Api::Test::UsersWithoutRescueUnknownFormatController < Api::TestController +class Api::Test::NoRescueUnknownFormatController < Api::TestController include RESTFramework::ModelControllerMixin self.fields = %w(id login) diff --git a/test/config/routes.rb b/test/config/routes.rb index befce6c..ec9cad9 100644 --- a/test/config/routes.rb +++ b/test/config/routes.rb @@ -43,14 +43,15 @@ rest_root :test namespace :test do rest_resources :users + rest_resources :added_select rest_resources :bare_create, force_plural: true, only: [:create] rest_resources :fields_hash_exclude rest_resources :fields_hash_only_except + rest_resources :no_rescue_unknown_format + rest_resources :read_only rest_resources :users_with_string_serializer rest_resources :users_with_sub_fields - rest_resources :users_without_rescue_unknown_format - rest_resources :read_only rest_route :network diff --git a/test/db/migrate/20240906180000_test_app_tables.rb b/test/db/migrate/20240906180000_test_app_tables.rb index 79805cd..d55a9d0 100644 --- a/test/db/migrate/20240906180000_test_app_tables.rb +++ b/test/db/migrate/20240906180000_test_app_tables.rb @@ -2,12 +2,20 @@ class TestAppTables < ActiveRecord::Migration[6.0] def change create_table(:users) do |t| t.string(:login, null: false, default: "", index: {unique: true}) - t.boolean(:is_admin, default: false) + t.string(:legal_name, null: false, default: "") + t.string(:short_name, null: false, default: "") t.integer(:age) + + t.boolean(:is_admin, null: false, default: false) + t.decimal(:balance, precision: 8, scale: 2) + t.integer(:state, null: false, default: 0) t.string(:status, null: false, default: "") + t.time(:day_start) + t.date(:last_reviewed_on) + t.references(:manager, foreign_key: {on_delete: :nullify, to_table: :users}) t.timestamps(null: true) diff --git a/test/db/schema.rb b/test/db/schema.rb index cc1a476..df2e600 100644 --- a/test/db/schema.rb +++ b/test/db/schema.rb @@ -103,11 +103,15 @@ create_table "users", force: :cascade do |t| t.string "login", default: "", null: false - t.boolean "is_admin", default: false + t.string "legal_name", default: "", null: false + t.string "short_name", default: "", null: false t.integer "age" + t.boolean "is_admin", default: false, null: false t.decimal "balance", precision: 8, scale: 2 t.integer "state", default: 0, null: false t.string "status", default: "", null: false + t.time "day_start" + t.date "last_reviewed_on" t.integer "manager_id" t.datetime "created_at" t.datetime "updated_at" diff --git a/test/db/seeds.rb b/test/db/seeds.rb index bfcb5ba..2a55023 100644 --- a/test/db/seeds.rb +++ b/test/db/seeds.rb @@ -1,4 +1,6 @@ -# Seed data is used for controller tests which need data to be useful, and also for the Demo API. +# Seed data is used for the Demo API. + +Faker::Config.random = Random.new(42) example = User.create!( login: "example", @@ -15,20 +17,62 @@ ) example.update!(manager: admin) -action = Genre.create!(name: "Action", description: "Action movies are fast-paced and exciting.") -_comedy = Genre.create!(name: "Comedy", description: "Comedy movies are funny.") -_drama = Genre.create!(name: "Drama", description: "Drama movies are serious.") -fantasy = Genre.create!(name: "Fantasy", description: "Fantasy movies are magical.") -adventure = Genre.create!(name: "Adventure", description: "Adventure movies are exciting.") +1000.times do |_| + # Create with faker data: + legal_name = Faker::Name.name_with_middle + short_name = legal_name.split(" ").first + begin + User.create!( + login: Faker::Internet.username, + legal_name: legal_name, + short_name: short_name, + age: rand(18..65), + is_admin: rand < 0.2, + balance: rand(0.0..10000.0), + state: [0, 0, 0, 0, User.states.keys.sample].sample, + status: User::STATUS_OPTS.keys.sample, + day_start: ["7:30", "8:00", "8:30", "9:00", "9:30"].sample, + last_reviewed_on: Time.zone.today - rand(0..365).days, + manager: [nil, example, admin, User.first(10).sample].sample, + ) + rescue ActiveRecord::RecordInvalid + end +end -star_wars = Movie.create!(name: "Star Wars IV: A New Hope", price: 14.99, main_genre: action) -dark_knight = Movie.create!(name: "The Dark Knight", price: 13.99, main_genre: action) -fellowship = Movie.create!( - name: "The Lord of the Rings: The Fellowship of the Ring", price: 12.99, main_genre: adventure, -) -matrix = Movie.create!(name: "The Matrix", price: 14.50, main_genre: action) -_avengers = Movie.create!(name: "The Avengers", price: 7.00, main_genre: action) -_inception = Movie.create!(name: "Inception", price: 15.99, main_genre: fantasy) +# Created by copilot: +Genre.create!(name: "Action", description: "Action movies are fast-paced and exciting.") +Genre.create!(name: "Comedy", description: "Comedy movies are funny.") +Genre.create!(name: "Drama", description: "Drama movies are serious.") +Genre.create!(name: "Fantasy", description: "Fantasy movies are magical.") +Genre.create!(name: "Adventure", description: "Adventure movies are exciting.") +Genre.create!(name: "Sci-Fi", description: "Sci-Fi movies are futuristic.") +Genre.create!(name: "Horror", description: "Horror movies are scary.") +Genre.create!(name: "Thriller", description: "Thriller movies are suspenseful.") +Genre.create!(name: "Mystery", description: "Mystery movies are puzzling.") +Genre.create!(name: "Romance", description: "Romance movies are about love.") +Genre.create!(name: "Musical", description: "Musical movies have singing and dancing.") +Genre.create!(name: "Documentary", description: "Documentary movies are non-fiction.") +Genre.create!(name: "Animation", description: "Animation movies are animated.") +Genre.create!(name: "Family", description: "Family movies are for all ages.") +Genre.create!(name: "Western", description: "Western movies are about the American West.") +Genre.create!(name: "War", description: "War movies are about military conflict.") +Genre.create!(name: "History", description: "History movies are about the past.") +Genre.create!(name: "Biography", description: "Biography movies are about real people.") +Genre.create!(name: "Sport", description: "Sport movies are about athletics.") +Genre.create!(name: "Music", description: "Music movies are about musicians.") +Genre.create!(name: "Crime", description: "Crime movies are about criminals.") +Genre.create!(name: "Noir", description: "Noir movies are dark and cynical.") +Genre.create!(name: "Superhero", description: "Superhero movies are about heroes.") +Genre.create!(name: "Spy", description: "Spy movies are about espionage.") + +50.times do |_| + Movie.create!( + name: Faker::Movie.title, + price: rand(5.0..20.0), + main_genre: Genre.all.sample, + ) +rescue ActiveRecord::RecordInvalid +end -example.movies += [star_wars, dark_knight] -admin.movies += [star_wars, fellowship, matrix] +example.movies += Movie.all.sample(5) +admin.movies += Movie.all.sample(20) diff --git a/test/test/controllers/api/demo/base.rb b/test/test/controllers/api/demo/base.rb index e693717..05d293c 100644 --- a/test/test/controllers/api/demo/base.rb +++ b/test/test/controllers/api/demo/base.rb @@ -6,7 +6,6 @@ module Api::Demo::Base def self.included(base) base.class_attribute(:create_params) base.class_attribute(:update_params) - base.setup { Rails.application.load_seed } end def test_index_with_filtering diff --git a/test/test/controllers/api/demo/movies_controller_test.rb b/test/test/controllers/api/demo/movies_controller_test.rb index e0962ed..9560343 100644 --- a/test/test/controllers/api/demo/movies_controller_test.rb +++ b/test/test/controllers/api/demo/movies_controller_test.rb @@ -8,9 +8,9 @@ class Api::Demo::MoviesControllerTest < ActionController::TestCase if defined?(Ransack) def test_ransack_simple - get(:index, as: :json, params: {q: {price_gt: 15}}) + get(:index, as: :json, params: {q: {price_gt: 9}}) assert_response(:success) - assert_equal(1, @response.parsed_body["results"].length) + assert_equal(2, @response.parsed_body["results"].length) end end diff --git a/test/test/controllers/api/plain/base.rb b/test/test/controllers/api/plain/base.rb index fd1912c..7fd00b4 100644 --- a/test/test/controllers/api/plain/base.rb +++ b/test/test/controllers/api/plain/base.rb @@ -6,7 +6,6 @@ module Api::Plain::Base def self.included(base) base.class_attribute(:create_params) base.class_attribute(:update_params) - base.setup { Rails.application.load_seed } end def test_index_with_filtering diff --git a/test/test/controllers/api/test/added_select_controller_test.rb b/test/test/controllers/api/test/added_select_controller_test.rb index e817eac..fae1eaf 100644 --- a/test/test/controllers/api/test/added_select_controller_test.rb +++ b/test/test/controllers/api/test/added_select_controller_test.rb @@ -1,8 +1,6 @@ -require_relative "base" +require "test_helper" class Api::Test::AddedSelectControllerTest < ActionController::TestCase - include BaseApi::TestControllerTests - def test_only_works get(:index, as: :json, params: {only: "id,selected_value"}) assert_response(:success) diff --git a/test/test/controllers/api/test/bare_create_controller_test.rb b/test/test/controllers/api/test/bare_create_controller_test.rb index 70ebfda..00f4f36 100644 --- a/test/test/controllers/api/test/bare_create_controller_test.rb +++ b/test/test/controllers/api/test/bare_create_controller_test.rb @@ -1,8 +1,6 @@ -require_relative "base" +require "test_helper" class Api::Test::BareCreateControllerTest < ActionController::TestCase - include BaseApi::TestControllerTests - def test_bare_create post(:create, as: :json, params: {name: "Test Bare Create"}) assert_response(:success) diff --git a/test/test/controllers/api/test/base.rb b/test/test/controllers/api/test/base.rb deleted file mode 100644 index b26afb0..0000000 --- a/test/test/controllers/api/test/base.rb +++ /dev/null @@ -1,9 +0,0 @@ -require "test_helper" - -module BaseApi - module TestControllerTests - def self.included(base) - base.setup { Rails.application.load_seed } - end - end -end diff --git a/test/test/controllers/api/test/fields_hash_only_except_controller_test.rb b/test/test/controllers/api/test/fields_hash_only_except_controller_test.rb index f3bdd5d..e66dd86 100644 --- a/test/test/controllers/api/test/fields_hash_only_except_controller_test.rb +++ b/test/test/controllers/api/test/fields_hash_only_except_controller_test.rb @@ -1,8 +1,6 @@ -require_relative "base" +require "test_helper" class Api::Test::FieldsHashOnlyExceptControllerTest < ActionController::TestCase - include BaseApi::TestControllerTests - def test_list get(:index, as: :json) assert_response(:success) diff --git a/test/test/controllers/api/test/network_controller_test.rb b/test/test/controllers/api/test/network_controller_test.rb index e531d5c..7a7458b 100644 --- a/test/test/controllers/api/test/network_controller_test.rb +++ b/test/test/controllers/api/test/network_controller_test.rb @@ -1,8 +1,6 @@ -require_relative "base" +require "test_helper" class Api::Test::NetworkControllerTest < ActionController::TestCase - include BaseApi::TestControllerTests - def test_cannot_list assert_raises(ActionController::UrlGenerationError) do get(:index) diff --git a/test/test/controllers/api/test/read_only_controller_test.rb b/test/test/controllers/api/test/read_only_controller_test.rb index a827b80..fe5386b 100644 --- a/test/test/controllers/api/test/read_only_controller_test.rb +++ b/test/test/controllers/api/test/read_only_controller_test.rb @@ -1,8 +1,6 @@ -require_relative "base" +require "test_helper" class Api::Test::ReadOnlyControllerTest < ActionController::TestCase - include BaseApi::TestControllerTests - def test_list get(:index, as: :json) assert_response(:success) diff --git a/test/test/controllers/api/test/users_with_string_serializer_controller_test.rb b/test/test/controllers/api/test/users_with_string_serializer_controller_test.rb index 420a37e..420cb32 100644 --- a/test/test/controllers/api/test/users_with_string_serializer_controller_test.rb +++ b/test/test/controllers/api/test/users_with_string_serializer_controller_test.rb @@ -1,5 +1,4 @@ -require_relative "base" +require "test_helper" class Api::Test::UsersWithStringSerializerControllerTest < ActionController::TestCase - include BaseApi::TestControllerTests end diff --git a/test/test/controllers/render_json_controller_test.rb b/test/test/controllers/render_json_controller_test.rb index a421ecc..1aa15ae 100644 --- a/test/test/controllers/render_json_controller_test.rb +++ b/test/test/controllers/render_json_controller_test.rb @@ -2,8 +2,6 @@ if defined?(ActiveModel::Serializer) class RenderJsonControllerTest < ActionController::TestCase - setup { Rails.application.load_seed } - def test_list_rest_serializer get(:list_rest_serializer) assert_response(:success) diff --git a/test/test/fixtures/genres.yml b/test/test/fixtures/genres.yml new file mode 100644 index 0000000..5237092 --- /dev/null +++ b/test/test/fixtures/genres.yml @@ -0,0 +1,15 @@ +action: + name: Action + description: Action movies are fast-paced and exciting. +comedy: + name: Comedy + description: Comedy movies are funny. +drama: + name: Drama + description: Drama movies are serious. +fantasy: + name: Fantasy + description: Fantasy movies are magical. +adventure: + name: Adventure + description: Adventure movies are exciting. diff --git a/test/test/fixtures/movies.yml b/test/test/fixtures/movies.yml new file mode 100644 index 0000000..67af4f8 --- /dev/null +++ b/test/test/fixtures/movies.yml @@ -0,0 +1,16 @@ +dark_knight: + name: The Dark Knight + price: 10.0 + main_genre: action +inception: + name: Inception + price: 12.0 + main_genre: action +the_hangover: + name: The Hangover + price: 8.0 + main_genre: comedy +the_shawshank_redemption: + name: The Shawshank Redemption + price: 9.0 + main_genre: drama diff --git a/test/test/fixtures/users.yml b/test/test/fixtures/users.yml new file mode 100644 index 0000000..dbc3c53 --- /dev/null +++ b/test/test/fixtures/users.yml @@ -0,0 +1,19 @@ +example: + login: example + age: 23 + balance: 20.34 + state: 0 + status: online + manager: admin + movies: + - dark_knight + - inception +admin: + login: admin + is_admin: true + age: 34 + balance: 230.34 + state: 0 + status: offline + movies: + - the_shawshank_redemption diff --git a/test/test/integration/api/demo_routing_test.rb b/test/test/integration/api/demo_routing_test.rb index 7077a33..845252f 100644 --- a/test/test/integration/api/demo_routing_test.rb +++ b/test/test/integration/api/demo_routing_test.rb @@ -16,13 +16,10 @@ def test_can_get_users assert_response(:success) end - # TODO: Disabled because test is broken in Rails 8, but behavior tested manually and working. - def _test_can_not_get_network_resourceful_routes - assert_raises(ActionController::RoutingError) do - get("/api/demo/network.json") - end - assert_raises(ActionController::RoutingError) do - get("/api/demo/network") - end + def test_can_not_get_network_resourceful_routes + get("/api/demo/network.json") + assert_response(:not_found) + get("/api/demo/network") + assert_response(:not_found) end end diff --git a/test/test/integration/api/test_routing_test.rb b/test/test/integration/api/test_routing_test.rb index 45a24ed..ca2df81 100644 --- a/test/test/integration/api/test_routing_test.rb +++ b/test/test/integration/api/test_routing_test.rb @@ -2,8 +2,6 @@ # The goal of this test is to ensure that the proper routes are defined for API2. class Api::TestRoutingTest < ActionDispatch::IntegrationTest - setup { Rails.application.load_seed } - def test_can_get_root get("/api/test") assert_response(:success) diff --git a/test/test/integration/rescuing_unknown_formats_test.rb b/test/test/integration/rescuing_unknown_formats_test.rb index acfdb4f..9622fcd 100644 --- a/test/test/integration/rescuing_unknown_formats_test.rb +++ b/test/test/integration/rescuing_unknown_formats_test.rb @@ -2,14 +2,10 @@ # The goal of this test is to ensure unknown formats are rescued, when configured. class RescuingUnknownFormatsTest < ActionDispatch::IntegrationTest - setup { Rails.application.load_seed } - # Test that an invalid format raises an uncaught exception. - # TODO: Disabled because test is broken in Rails 8, but behavior tested manually and working. - def _test_raise_unknown_format - assert_raises(ActionController::UnknownFormat) do - get("/api/test/users_without_rescue_unknown_format.jsom") - end + def test_raise_unknown_format + get("/api/test/no_rescue_unknown_format.jsom") + assert_response(:not_acceptable) end # Test that we rescue an unknown format and also that it defaults to :json. diff --git a/test/test/models/base.rb b/test/test/models/base.rb index 362ea58..f5b4eba 100644 --- a/test/test/models/base.rb +++ b/test/test/models/base.rb @@ -8,8 +8,6 @@ def self.included(base) base.setup do @model ||= self.class.name.match(/(.*)Test$/)[1].constantize @title_field ||= TITLE_FIELDS.select { |f| f.to_s.in?(@model.column_names) }[0] - - Rails.application.load_seed end end diff --git a/test/test/test_helper.rb b/test/test/test_helper.rb index ed0ef51..6ea552d 100644 --- a/test/test/test_helper.rb +++ b/test/test/test_helper.rb @@ -23,3 +23,7 @@ # end require "rails/test_help" + +class ActiveSupport::TestCase + fixtures :all +end