From 678b3ed8e91d8b4269aaee4e97448ce4344a0729 Mon Sep 17 00:00:00 2001 From: Ricardo Pacheco Date: Tue, 30 Apr 2024 11:37:05 -0300 Subject: [PATCH] [AFA-5] Create API with Restful structure (#6) * Create API with Restful structure * Fix lint issues * Update pull request template * Upgrade core version --- .../pull_request_template.md | 32 +++++++++++++++++ .github/workflows/ci.yml | 8 +++-- Gemfile | 2 +- Gemfile.lock | 34 +++++-------------- Procfile | 3 +- app/controllers/v1/auctions_controller.rb | 18 ++++++++++ config/application.rb | 3 ++ config/environments/development.rb | 2 +- config/initializers/auction_fun_core.rb | 3 ++ config/routes.rb | 13 +++++-- .../v1/auctions_controller_spec.rb | 31 +++++++++++++++++ spec/rails_helper.rb | 14 +++----- spec/support/database_cleaner_sequel.rb | 3 ++ spec/support/requests.rb | 13 +++++++ 14 files changed, 135 insertions(+), 44 deletions(-) create mode 100644 .github/PULL_REQUEST_TEMPLATE/pull_request_template.md create mode 100644 app/controllers/v1/auctions_controller.rb create mode 100644 spec/controllers/v1/auctions_controller_spec.rb create mode 100644 spec/support/database_cleaner_sequel.rb create mode 100644 spec/support/requests.rb diff --git a/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md b/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md new file mode 100644 index 0000000..1c71aaf --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md @@ -0,0 +1,32 @@ +> [!CAUTION] +> Topics with :red_circle: are required. The rest are optional and can be removed. + +Issue number: resolves # + +## Summary :red_circle: + +## Proposed / Possible solution :red_circle: + +## how to test :policeman: + +Describe in details (preferred step by step). + +## Risks / Impacts :red_circle: + +Inform the risks/impacts that this PR is generating + +### Examples + +- Unavailability in API x/y/z +- Downtime of x seconds in y environment +- None anticipated + +## Requirements for deployment :red_circle: + +Provide the necessary requirements that are needed pre or post deployment. + +### Examples + +- Execute the deployment of changes in project X as a preliminary step before starting this deployment. +- Execute the migrate command before starting the deployment process. +- None anticipated diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1756313..ebd9795 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -49,7 +49,11 @@ jobs: with: ruby-version: "3.3.0" bundler-cache: true - - name: Create database - run: bundle exec rake auction_fun_core:db:create_database[postgres] + - name: Create database and running migrations + run: | + bundle exec rake auction_fun_core:db:create_database[postgres] + bundle exec rake auction_fun_core:db:migrate + - name: Run lint + run: bundle exec standardrb - name: Run suite run: bundle exec rspec --color --format progress diff --git a/Gemfile b/Gemfile index a3767f2..9dbcc74 100644 --- a/Gemfile +++ b/Gemfile @@ -21,7 +21,7 @@ gem "rack-cors", "2.0.2" gem "dotenv-rails", "3.1.0", require: "dotenv/load", groups: %i[development test] # AuctionFunCore -gem "auction_fun_core", "0.8.5" +gem "auction_fun_core", "0.8.10" # gem "auction_fun_core", path: "../auction_fun_core", require: "auction_fun_core" group :development, :test do diff --git a/Gemfile.lock b/Gemfile.lock index 8412925..b822ffc 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,26 +1,3 @@ -PATH - remote: ../auction_fun_core - specs: - auction_fun_core (0.8.5) - activesupport (= 7.1.3.2) - bcrypt (= 3.1.20) - dotenv (= 3.1.0) - dry-events (= 1.0.1) - dry-matcher (= 1.0.0) - dry-monads (= 1.6.0) - dry-system (= 1.0.1) - dry-validation (= 1.10.0) - idlemailer (= 2.2.0) - money (= 6.19.0) - pg (= 1.5.6) - phonelib (= 0.8.8) - rake (= 13.2.0) - rom (= 5.3.0) - rom-sql (= 3.6.2) - sidekiq (= 7.2.2) - yard (= 0.9.36) - zeitwerk (= 2.6.13) - GEM remote: https://rubygems.org/ specs: @@ -99,7 +76,7 @@ GEM mutex_m tzinfo (~> 2.0) ast (2.4.2) - auction_fun_core (0.8.5) + auction_fun_core (0.8.10) activesupport (= 7.1.3.2) bcrypt (= 3.1.20) dotenv (= 3.1.0) @@ -116,6 +93,7 @@ GEM rom (= 5.3.0) rom-sql (= 3.6.2) sidekiq (= 7.2.2) + sidekiq-unique-jobs (= 8.0.10) yard (= 0.9.36) zeitwerk (= 2.6.13) base64 (0.2.0) @@ -308,7 +286,7 @@ GEM rake (13.2.0) rdoc (6.6.2) psych (>= 4.0.0) - redis-client (0.21.1) + redis-client (0.22.1) connection_pool regexp_parser (2.9.0) reline (0.4.3) @@ -387,6 +365,10 @@ GEM connection_pool (>= 2.3.0) rack (>= 2.2.4) redis-client (>= 0.19.0) + sidekiq-unique-jobs (8.0.10) + concurrent-ruby (~> 1.0, >= 1.0.5) + sidekiq (>= 7.0.0, < 8.0.0) + thor (>= 1.0, < 3.0) standard (1.35.1) language_server-protocol (~> 3.17.0.2) lint_roller (~> 1.0) @@ -422,7 +404,7 @@ PLATFORMS x86_64-linux DEPENDENCIES - auction_fun_core (= 0.8.5) + auction_fun_core (= 0.8.10) bootsnap (= 1.18.3) database_cleaner-sequel (= 2.0.2) dotenv-rails (= 3.1.0) diff --git a/Procfile b/Procfile index 5e6b227..1ce33fa 100644 --- a/Procfile +++ b/Procfile @@ -1,4 +1,5 @@ +web: RUBYOPT="-W0" bundle exec rails s database: postgres redis: redis-server mailserver: maildev --hide-extensions STARTTLS -background: bundle exec sidekiq +background: RUBYOPT="-W0" bundle exec sidekiq diff --git a/app/controllers/v1/auctions_controller.rb b/app/controllers/v1/auctions_controller.rb new file mode 100644 index 0000000..06e3823 --- /dev/null +++ b/app/controllers/v1/auctions_controller.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +module V1 + # Main class (Add doc) + class AuctionsController < ApplicationController + def index + auctions = auction_relation.all(params[:page] || 1, params[:per_page] || 25).to_a + + render json: {auctions: auctions}, status: :ok + end + + private + + def auction_relation + AuctionFunCore::Application[:container].relations[:auctions] + end + end +end diff --git a/config/application.rb b/config/application.rb index ba95400..89a4289 100644 --- a/config/application.rb +++ b/config/application.rb @@ -41,6 +41,9 @@ class Application < Rails::Application # Skip views, helpers and assets when generating a new resource. config.api_only = true + # Configure default timezone + config.time_zone = "America/Sao_Paulo" + # Custom global configurations config.secret_key_base = ENV.fetch("SECRET_KEY_BASE") config.x.database_url = ENV.fetch("DATABASE_URL") diff --git a/config/environments/development.rb b/config/environments/development.rb index 7de8cd1..919d1c4 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -40,7 +40,7 @@ config.active_support.disallowed_deprecation_warnings = [] # Raise an error on page load if there are pending migrations. - config.active_record.migration_error = :page_load + config.active_record.migration_error = false # Highlight code that triggered database queries in logs. config.active_record.verbose_query_logs = true diff --git a/config/initializers/auction_fun_core.rb b/config/initializers/auction_fun_core.rb index 233cce2..48ac5a8 100644 --- a/config/initializers/auction_fun_core.rb +++ b/config/initializers/auction_fun_core.rb @@ -1,4 +1,7 @@ AuctionFunCore::Application[:settings].database_url = ENV.fetch("DATABASE_URL") AuctionFunCore::Application[:settings].redis_url = ENV.fetch("REDIS_URL") +# Import locales from gem +I18n.load_path += Dir[Gem.loaded_specs["auction_fun_core"].full_gem_path + "/i18n/**/*.{rb,yml}"] + AuctionFunCore::Application.finalize! diff --git a/config/routes.rb b/config/routes.rb index 9f768e5..5ffe5a6 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,10 +1,17 @@ Rails.application.routes.draw do - # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html + if Rails.env.development? + require "sidekiq/web" + + Sidekiq::Web.use ActionDispatch::Cookies + Sidekiq::Web.use ActionDispatch::Session::CookieStore, key: "_auctionfuncore_session" + mount Sidekiq::Web => "/sidekiq" + end # Reveal health status on /up that returns 200 if the app boots with no exceptions, otherwise 500. # Can be used by load balancers and uptime monitors to verify that the app is live. get "up" => "rails/health#show", :as => :rails_health_check - # Defines the root path route ("/") - # root "posts#index" + namespace :v1, defaults: {format: :json} do + resources :auctions, only: %i[index] + end end diff --git a/spec/controllers/v1/auctions_controller_spec.rb b/spec/controllers/v1/auctions_controller_spec.rb new file mode 100644 index 0000000..69324c4 --- /dev/null +++ b/spec/controllers/v1/auctions_controller_spec.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +require "rails_helper" + +describe V1::AuctionsController do + describe "Routes", type: :routing do + it { expect(get("/v1/auctions")).to route_to("v1/auctions#index", format: :json) } + end + + describe "GET #index", type: :controller do + context "when auctions are available" do + let!(:auction) { Factory[:auction, :default_running_standard] } + + it "expect return http status ok with auctions" do + get :index + + expect(response).to have_http_status(:ok) + expect(response.body).to include(auction.title) + end + end + + context "when there are no auctions available" do + it "expect return http status ok with empty results" do + get :index + + expect(response).to have_http_status(:ok) + expect(json_response["auctions"]).to be_blank + end + end + end +end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 013283f..f4dda25 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -8,12 +8,13 @@ require "rspec/rails" # Start auction fun core application, configure rom and load factories directly from auction core gem. +require "sidekiq/testing" require "rom-factory" require "database_cleaner/sequel" -AuctionCore::Application.start(:core) +AuctionFunCore::Application.start(:core) Factory = ROM::Factory.configure do |config| - config.rom = AuctionCore::Application[:container] + config.rom = AuctionFunCore::Application[:container] end Dir[AuctionFunCore::Application.root.join("spec", "support", "**", "*.rb")].each { |f| require f } @@ -33,15 +34,8 @@ # directory. Alternatively, in the individual `*_spec.rb` files, manually # require only the support files necessary. # -# Rails.root.glob('spec/support/**/*.rb').sort.each { |f| require f } +Rails.root.glob("spec/support/**/*.rb").sort.each { |f| require f } -# Checks for pending migrations and applies them before tests are run. -# If you are not using ActiveRecord, you can remove these lines. -begin - ActiveRecord::Migration.maintain_test_schema! -rescue ActiveRecord::PendingMigrationError => e - abort e.to_s.strip -end RSpec.configure do |config| config.add_setting :rom config.rom = Factory.rom diff --git a/spec/support/database_cleaner_sequel.rb b/spec/support/database_cleaner_sequel.rb new file mode 100644 index 0000000..4e1b3cb --- /dev/null +++ b/spec/support/database_cleaner_sequel.rb @@ -0,0 +1,3 @@ +# frozen_string_literal: true + +DatabaseCleaner.strategy = :truncation diff --git a/spec/support/requests.rb b/spec/support/requests.rb new file mode 100644 index 0000000..893d003 --- /dev/null +++ b/spec/support/requests.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +module ControllerHelpers + def json_response + return if response.body.blank? + + JSON.parse(response.body, symbolize_keys: true) + end +end + +RSpec.configure do |c| + c.include ControllerHelpers, type: :controller +end