From 5536045d31f4bba597fc6bc86dfbe6d050995d70 Mon Sep 17 00:00:00 2001 From: Leandro Machado Pereira Date: Wed, 17 Jan 2024 22:59:27 -0300 Subject: [PATCH 01/23] feat: improve specs for lib --- lib/calculos.rb | 4 +++- lib/resultados.rb | 23 ++++++++++++++++++----- spec/lib/calculos_spec.rb | 10 +++++++--- spec/lib/resultados_spec.rb | 24 +++++++++++++++++++----- spec/lib/validadores_spec.rb | 34 ++++++++++++++++++++++++++-------- 5 files changed, 73 insertions(+), 22 deletions(-) diff --git a/lib/calculos.rb b/lib/calculos.rb index f48c09c..4fe07a7 100644 --- a/lib/calculos.rb +++ b/lib/calculos.rb @@ -1,5 +1,7 @@ class Calculos def self.performance(valor_meta, valor_realizado) - (valor_realizado / valor_meta) + return 0 if valor_meta.to_i.zero? + + (BigDecimal(valor_realizado, 9) / BigDecimal(valor_meta, 9)).to_f end end diff --git a/lib/resultados.rb b/lib/resultados.rb index 0eb7f6a..f2f2c83 100644 --- a/lib/resultados.rb +++ b/lib/resultados.rb @@ -1,19 +1,32 @@ class Resultados - attr_accessor :valor_meta, :valor_realizado + attr_accessor :valor_meta, :valor_realizado, :valor_performance def initialize() @valor_meta = valor_meta @valor_realizado = valor_realizado - # @valor_performance = valor_performance + @valor_performance = valor_performance end def calcula_performance - return 0 if valor_meta.zero? + return 0 if invalido_valor_meta? + valor_realizado / valor_meta end def calcula_realizado - return 0 if valor_realizado.zero? - valor_meta * valor_peformance + return 0 if invalido_valor_performance? + return 0 if invalido_valor_meta? + + valor_meta * valor_performance + end + + private + + def invalido_valor_performance? + valor_performance.nil? || valor_performance.zero? + end + + def invalido_valor_meta? + valor_meta.nil? || valor_meta.zero? end end diff --git a/spec/lib/calculos_spec.rb b/spec/lib/calculos_spec.rb index 87a5478..75c2920 100644 --- a/spec/lib/calculos_spec.rb +++ b/spec/lib/calculos_spec.rb @@ -6,7 +6,7 @@ it "com atributos validos" do valor_performance = Calculos.performance(100.5, 150.5) - expect(valor_performance).to eq(1.1682242990654206) + expect(valor_performance).to eq(1.4975124378109452) end it "com valor realizado valido e meta zero" do @@ -16,11 +16,15 @@ end it "com valor realizado valido e meta null" do - skip("escreva testes para esses casos") + valor_performance = Calculos.performance(nil, 150.5) + + expect(valor_performance).to eq(0) end it "com valor meta valido e realizado zero" do - skip("escreva testes para esses casos") + valor_performance = Calculos.performance(100.5, 0) + + expect(valor_performance).to eq(0) end end end diff --git a/spec/lib/resultados_spec.rb b/spec/lib/resultados_spec.rb index 717400f..0109f43 100644 --- a/spec/lib/resultados_spec.rb +++ b/spec/lib/resultados_spec.rb @@ -16,7 +16,7 @@ resultado.valor_meta = 0 resultado.valor_realizado = 20 - expect(resultado.calcula_performance).to eq(nil) + expect(resultado.calcula_performance).to eq(0) end it "com valor realizado valido e meta null" do @@ -30,7 +30,7 @@ it "com valor meta valido e realizado zero" do resultado = Resultados.new resultado.valor_meta = 10 - resultado.valor_realizado = 0 + resultado.valor_realizado = 10 expect(resultado.calcula_performance).to eq(1) end @@ -39,12 +39,26 @@ describe "Calcular realizado" do it "com valor realizado valido" do resultado = Resultados.new - resultado.valor_performance = 0 - resultado.valor_neta = 0 + resultado.valor_performance = 1 + resultado.valor_meta = 1 expect(resultado.calcula_realizado).to eq(1) end - # @TODO CRIE MAIS TESTES + it "com valor realizado invalido" do + resultado = Resultados.new + resultado.valor_performance = 0 + resultado.valor_meta = 1 + + expect(resultado.calcula_realizado).to eq(0) + end + + it "com valor meta invalido" do + resultado = Resultados.new + resultado.valor_performance = 1 + resultado.valor_meta = 0 + + expect(resultado.calcula_realizado).to eq(0) + end end end diff --git a/spec/lib/validadores_spec.rb b/spec/lib/validadores_spec.rb index 24229ac..d557ec7 100644 --- a/spec/lib/validadores_spec.rb +++ b/spec/lib/validadores_spec.rb @@ -5,37 +5,55 @@ describe "Validadores" do context "data" do it "validador data (YYYY-MM-DD)" do - data = Validadores.data('2019-31-12') + data = Validadores.data('2019-12-12') expect(data).to eq(true) end it "validador data (YYYY-MM)" do - skip("escreva testes para esses casos") + data = Validadores.data('2019-12') + + expect(data).to eq(false) end it "validador para data (DD/MM/YYYY)" do - skip("escreva testes para esses casos") + data = Validadores.data('01-12-2019') + + expect(data).to eq(false) end end context "número" do it "validador número inteiro" do - skip("escreva testes para esses casos") + inteiro = Validadores.valor('20') + + expect(inteiro).to eq(true) end it "validador número decimal" do - skip("escreva testes para esses casos") + decimal = Validadores.valor('20.5') + + expect(decimal).to eq(true) end it "validador número percentual" do - skip("escreva testes para esses casos") + percentual = Validadores.valor('20%') + + expect(percentual).to eq(true) end end context "diversos" do - it "validador e-mail" do - skip("escreva testes para esses casos") + it "validador e-mail errado" do + errado = Validadores.email('email.text') + + expect(errado).to eq(false) + end + + it "validador e-mail correto" do + valido = Validadores.email('email@gmail.com') + + expect(valido).to eq(true) end end end From 69a712a0ab4aead77a94679d6383733d30c32826 Mon Sep 17 00:00:00 2001 From: Leandro Machado Pereira Date: Wed, 17 Jan 2024 23:05:17 -0300 Subject: [PATCH 02/23] feat: implement show action and remove unused actions --- app/controllers/clientes_controller.rb | 8 ++------ app/controllers/resultados_controller.rb | 12 ++++-------- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/app/controllers/clientes_controller.rb b/app/controllers/clientes_controller.rb index 749252f..77fb2a7 100644 --- a/app/controllers/clientes_controller.rb +++ b/app/controllers/clientes_controller.rb @@ -6,13 +6,9 @@ def index end def show - end - - def new - @cliente = Cliente.new - end + set_cliente - def edit + render json: @cliente end def create diff --git a/app/controllers/resultados_controller.rb b/app/controllers/resultados_controller.rb index b4bd3ad..d84a764 100644 --- a/app/controllers/resultados_controller.rb +++ b/app/controllers/resultados_controller.rb @@ -1,18 +1,14 @@ class ResultadosController < ApplicationController - before_action :set_resultado, only: [:show, :edit, :update, :destroy] + before_action :set_resultado, only: [:show, :update, :destroy] def index @resultados = Resultado.all end def show - end - - def new - @resultado = Resultado.new - end + set_resultado - def edit + render json: @resultado end def create @@ -46,6 +42,6 @@ def set_resultado # Never trust parameters from the scary internet, only allow the white list through. def resultado_params - params.require(:resultado).permit(:periodo, :valor_meta, :valor_realizado) + params.require(:resultado).permit(:cliente_id, :periodo, :valor_meta, :valor_realizado) end end From c919d64be051c2f41ac7c95fc4b5d29c0b37f89c Mon Sep 17 00:00:00 2001 From: Leandro Machado Pereira Date: Wed, 17 Jan 2024 23:52:20 -0300 Subject: [PATCH 03/23] feat: refactor of importa arquivos and fix specs --- lib/importa_arquivos.rb | 14 ++++++++ spec/controllers/clientes_controller_spec.rb | 12 ++++--- .../controllers/resultados_controller_spec.rb | 32 ++++++++++--------- .../fixtures/{ => files}/arquivo_invalido.csv | 0 spec/fixtures/{ => files}/arquivo_valido.csv | 0 spec/lib/importa_arquivos_spec.rb | 30 ++++++++--------- 6 files changed, 52 insertions(+), 36 deletions(-) create mode 100644 lib/importa_arquivos.rb rename spec/fixtures/{ => files}/arquivo_invalido.csv (100%) rename spec/fixtures/{ => files}/arquivo_valido.csv (100%) diff --git a/lib/importa_arquivos.rb b/lib/importa_arquivos.rb new file mode 100644 index 0000000..16c124c --- /dev/null +++ b/lib/importa_arquivos.rb @@ -0,0 +1,14 @@ +class ImportaArquivos + def self.importa_arquivo(arquivo) + @arquivo = arquivo + importa_dados + end + + def self.importa_dados + CSV.foreach(@arquivo, headers: true, header_converters: :symbol, col_sep: ';') do |row| + next unless Validadores.data(row[:periodo]) + cliente = Cliente.create_or_find_by(nome: row[:cliente]) + cliente.resultado.create(periodo: row[:periodo], valor_meta: row[:valor_meta], valor_realizado: row[:valor_realizado]) + end + end +end diff --git a/spec/controllers/clientes_controller_spec.rb b/spec/controllers/clientes_controller_spec.rb index 839765f..c5bd827 100644 --- a/spec/controllers/clientes_controller_spec.rb +++ b/spec/controllers/clientes_controller_spec.rb @@ -37,22 +37,24 @@ describe "PUT #update" do context "with valid params" do let(:new_attributes) { - skip("Add a hash of attributes valid for your model") + { nome: "AchieveMore updated" } } it "updates the requested cliente" do cliente = Cliente.create! valid_attributes put :update, params: {id: cliente.to_param, cliente: new_attributes}, session: valid_session cliente.reload - skip("Add assertions for updated state") + + expect(cliente.nome).to eq("AchieveMore updated") end it "renders a JSON response with the cliente" do cliente = Cliente.create! valid_attributes put :update, params: {id: cliente.to_param, cliente: valid_attributes}, session: valid_session + expect(response).to have_http_status(:ok) - expect(response.content_type).to eq('application/json') + expect(response.content_type).to include('application/json') end end end @@ -60,10 +62,10 @@ describe "DELETE #destroy" do it "destroys the requested cliente" do cliente = Cliente.create! valid_attributes + expect { - delete :destroy, params: {id: cliente.to_param}, session: valid_session + delete :destroy, params: {id: cliente.to_param} }.to change(Cliente, :count).by(-1) end end - end diff --git a/spec/controllers/resultados_controller_spec.rb b/spec/controllers/resultados_controller_spec.rb index c80f268..7870f28 100644 --- a/spec/controllers/resultados_controller_spec.rb +++ b/spec/controllers/resultados_controller_spec.rb @@ -1,8 +1,6 @@ require 'rails_helper' RSpec.describe ResultadosController, type: :controller do - let(:arquivo_valido) { { file: fixture_file_upload('metas_validas.csv', 'text/csv') } } - let(:cliente) { create(:cliente) } @@ -11,20 +9,22 @@ { cliente_id: cliente.id, periodo: Date.today, valor_meta: 10, valor_realizado: 12 } } + let(:resultado) { Resultado.create! valid_attributes } + let(:valid_session) { {} } describe "GET #index" do it "returns a success response" do - resultado = Resultado.create! valid_attributes - get :index, params: {}, session: valid_session + get :index, params: {} + expect(response).to be_successful end end describe "GET #show" do it "returns a success response" do - resultado = Resultado.create! valid_attributes - get :show, params: {id: resultado.to_param}, session: valid_session + get :show, params: {id: resultado.to_param} + expect(response).to be_successful end end @@ -42,22 +42,23 @@ describe "PUT #update" do context "with valid params" do let(:new_attributes) { - skip("Add a hash of attributes valid for your model") + { valor_meta: 10.5, valor_realizado: 12.7 } } - it "updates the requested resultado" do - resultado = Resultado.create! valid_attributes + it "updates the requested resultado", :aggregate_failures do put :update, params: {id: resultado.to_param, resultado: new_attributes}, session: valid_session + resultado.reload - skip("Add assertions for updated state") + + expect(resultado.valor_meta).to eq(10.5) + expect(resultado.valor_realizado).to eq(12.7) end it "renders a JSON response with the resultado" do - resultado = Resultado.create! valid_attributes + put :update, params: {id: resultado.to_param, resultado: valid_attributes} - put :update, params: {id: resultado.to_param, resultado: valid_attributes}, session: valid_session expect(response).to have_http_status(:ok) - expect(response.content_type).to eq('application/json') + expect(response.content_type).to include('application/json') end end end @@ -65,15 +66,16 @@ describe "DELETE #destroy" do it "destroys the requested resultado" do resultado = Resultado.create! valid_attributes + expect { - delete :destroy, params: {id: resultado.to_param}, session: valid_session + delete :destroy, params: {id: resultado.to_param} }.to change(Resultado, :count).by(-1) end end describe "Teste final!" do it "qual a resposta para a vida o universo e tudo mais?" do - resposta = Base64.encode64("ESCREVA AQUI A RESPOSTA") + resposta = Base64.encode64("42") expect("NDI=\n").to eq(resposta) end end diff --git a/spec/fixtures/arquivo_invalido.csv b/spec/fixtures/files/arquivo_invalido.csv similarity index 100% rename from spec/fixtures/arquivo_invalido.csv rename to spec/fixtures/files/arquivo_invalido.csv diff --git a/spec/fixtures/arquivo_valido.csv b/spec/fixtures/files/arquivo_valido.csv similarity index 100% rename from spec/fixtures/arquivo_valido.csv rename to spec/fixtures/files/arquivo_valido.csv diff --git a/spec/lib/importa_arquivos_spec.rb b/spec/lib/importa_arquivos_spec.rb index 55d4300..1805d2a 100644 --- a/spec/lib/importa_arquivos_spec.rb +++ b/spec/lib/importa_arquivos_spec.rb @@ -1,11 +1,9 @@ require 'rails_helper' require 'csv' -require 'validadores' -require 'resultados' include ActionDispatch::TestProcess::FixtureFile -RSpec.describe Validadores, type: :lib do +RSpec.describe ImportaArquivos, type: :lib do describe "Importando arquivos" do let(:arquivo_valido) { { file: fixture_file_upload('arquivo_valido.csv', 'text/csv') } } let(:arquivo_invalido) { { file: fixture_file_upload('arquivo_invalido.csv', 'text/csv') } } @@ -14,34 +12,34 @@ it "validando datas" do @file = File.open(arquivo_valido[:file]) - CSV.foreach(@file, {headers: true, header_converters: :symbol, col_sep: ';'}) do |row| - break unless Validadores.data(row[:periodo]) - cliente = Cliente.create!(nome: row[:cliente]) - cliente.resultado.create!(periodo: row[:periodo], valor_meta: row[:valor_meta], valor_realizado: row[:valor_realizado]) - end + ImportaArquivos.importa_arquivo(@file) expect(Cliente.all.size).to eq(3) end it "salva arquivo na base e calcula performance total" do - # @file = File.open(arquivo_valido[:file]) + @file = File.open(arquivo_valido[:file]) - # CSV.foreach(@file, {headers: true, header_converters: :symbol, col_sep: ';'}) do |row| - # cliente = Cliente.create!(nome: row[:cliente]) - # cliente.resultado.create!(periodo: row[:periodo], valor_meta: row[:valor_meta], valor_realizado: row[:valor_realizado]) - # end + ImportaArquivos.importa_arquivo(@file) - skip("escreva testes para esses casos") + expect(Resultado.all.size).to eq(3) end end context "Arquivo invalido" do it "validando datas" do - skip("escreva testes para esses casos") + @file = File.open(arquivo_invalido[:file]) + + expect do + ImportaArquivos.importa_arquivo(@file) + end.to change(Resultado, :count).by(1) end it "inserindo linhas na base somente se arquivo valido" do - skip("escreva testes para esses casos") + @file = File.open(arquivo_invalido[:file]) + expect do + ImportaArquivos.importa_arquivo(@file) + end.to change(Resultado, :count).by(1) end end end From 34672cce30b9bfd7b4b5af3ff1b25addf5ffe303 Mon Sep 17 00:00:00 2001 From: Leandro Machado Pereira Date: Thu, 18 Jan 2024 00:04:09 -0300 Subject: [PATCH 04/23] feat: improve autoload --- app/controllers/calculos_controller.rb | 10 +++++++--- config/application.rb | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/app/controllers/calculos_controller.rb b/app/controllers/calculos_controller.rb index 9df91cc..f994439 100644 --- a/app/controllers/calculos_controller.rb +++ b/app/controllers/calculos_controller.rb @@ -1,9 +1,13 @@ -require 'calculos' - class CalculosController < ApplicationController def performance - valor_performance = Calculos.performance(params[:valor_meta], params[:valor_realizado]) + valor_performance = Calculos.performance(calculos_params[:valor_meta], calculos_params[:valor_realizado]) render json: { valor_performance: valor_performance } end + + private + + def calculos_params + params.permit(:valor_meta, :valor_realizado) + end end diff --git a/config/application.rb b/config/application.rb index 600f2c3..e3a0d59 100644 --- a/config/application.rb +++ b/config/application.rb @@ -20,7 +20,7 @@ module ApiAppName class Application < Rails::Application # Initialize configuration defaults for originally generated Rails version. - config.load_defaults 5.2 + config.autoload_paths += Dir["#{config.root}/lib/**/"] # Settings in config/environments/* take precedence over those specified here. # Application configuration can go into files in config/initializers From 0b002ea1ba91bc16d6eed31510fa5172b4830bab Mon Sep 17 00:00:00 2001 From: Leandro Machado Pereira Date: Thu, 18 Jan 2024 00:09:32 -0300 Subject: [PATCH 05/23] feat: improve autoload of lib folder --- config/application.rb | 1 + config/routes.rb | 2 -- spec/controllers/calculos_controller_spec.rb | 4 ++++ spec/controllers/clientes_controller_spec.rb | 5 +++++ 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/config/application.rb b/config/application.rb index e3a0d59..dc0a4d6 100644 --- a/config/application.rb +++ b/config/application.rb @@ -20,6 +20,7 @@ module ApiAppName class Application < Rails::Application # Initialize configuration defaults for originally generated Rails version. + config.load_defaults 5.2 config.autoload_paths += Dir["#{config.root}/lib/**/"] # Settings in config/environments/* take precedence over those specified here. diff --git a/config/routes.rb b/config/routes.rb index 87ace09..7ed5355 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,6 +1,4 @@ Rails.application.routes.draw do - # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html - resources :clientes resources :resultados diff --git a/spec/controllers/calculos_controller_spec.rb b/spec/controllers/calculos_controller_spec.rb index 6a607f1..e03e7da 100644 --- a/spec/controllers/calculos_controller_spec.rb +++ b/spec/controllers/calculos_controller_spec.rb @@ -18,13 +18,17 @@ describe "GET #performance" do it "com atributos validos" do resultado = Resultado.create! valid_attributes + get :performance, params: {valor_meta: resultado.valor_meta, valor_realizado: resultado.valor_realizado}, session: valid_session + expect(response).to be_successful end it "com atributos inválidos" do resultado = Resultado.create! valid_attributes + get :performance, params: {valor_meta: resultado.valor_meta, valor_realizado: resultado.valor_realizado}, session: valid_session + expect(response).to be_successful end end diff --git a/spec/controllers/clientes_controller_spec.rb b/spec/controllers/clientes_controller_spec.rb index c5bd827..ac6aab6 100644 --- a/spec/controllers/clientes_controller_spec.rb +++ b/spec/controllers/clientes_controller_spec.rb @@ -11,7 +11,9 @@ describe "GET #index" do it "returns a success response" do cliente = Cliente.create! valid_attributes + get :index, params: {}, session: valid_session + expect(response).to be_successful end end @@ -19,7 +21,9 @@ describe "GET #show" do it "returns a success response" do cliente = Cliente.create! valid_attributes + get :show, params: {id: cliente.to_param}, session: valid_session + expect(response).to be_successful end end @@ -42,6 +46,7 @@ it "updates the requested cliente" do cliente = Cliente.create! valid_attributes + put :update, params: {id: cliente.to_param, cliente: new_attributes}, session: valid_session cliente.reload From bcf199830e2065f8913b97c990dbedf3676de122 Mon Sep 17 00:00:00 2001 From: Leandro Machado Pereira Date: Thu, 18 Jan 2024 00:27:43 -0300 Subject: [PATCH 06/23] feat: upgrade ruby to 3.1 --- .github/workflows/deploy.yml | 4 ++-- .gitignore | 4 ++-- .ruby-version | 2 +- Dockerfile | 6 ++++-- Gemfile | 9 +-------- Gemfile.lock | 2 +- 6 files changed, 11 insertions(+), 16 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index e632423..acdf40e 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -17,7 +17,7 @@ jobs: ci_node_index: [0, 1] env: RAILS_ENV: test - GEMFILE_RUBY_VERSION: 2.6.9 + GEMFILE_RUBY_VERSION: 3.1.2 steps: - uses: actions/checkout@v2 @@ -26,7 +26,7 @@ jobs: uses: ruby/setup-ruby@v1 with: # Not needed with a .ruby-version file - ruby-version: 2.6.9 + ruby-version: 3.1.2 # runs 'bundle install' and caches installed gems automatically bundler-cache: true diff --git a/.gitignore b/.gitignore index 84af4c9..b6154ae 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ log/* tmp/* -db/development.sqlite3 -db/test.sqlite3 +db/development.sqlite3* +db/test.sqlite3* diff --git a/.ruby-version b/.ruby-version index e0e1b46..6ebad14 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.6.9 \ No newline at end of file +3.1.2 \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 75d4616..3b92cb6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ -FROM --platform=linux/x86_64 ruby:2.6-alpine +FROM --platform=linux/x86_64 ruby:3.1-alpine -LABEL Name=achievemore-ruby Version=2.6 +LABEL Name=achievemore-ruby Version=3.1 WORKDIR /app @@ -16,6 +16,8 @@ RUN apk --update add less COPY Gemfile /app/Gemfile COPY Gemfile.lock /app/Gemfile.lock +RUN gem install bundler +RUN gem update --system RUN bundle install COPY . /app diff --git a/Gemfile b/Gemfile index ff60935..f782dbd 100644 --- a/Gemfile +++ b/Gemfile @@ -1,14 +1,7 @@ source 'https://rubygems.org' git_source(:github) { |repo| "https://github.com/#{repo}.git" } -ruby '~> 2.6.9' - -# Bundle edge Rails instead: gem 'rails', github: 'rails/rails' -gem 'rails', '~> 5.2.4.5' -# Use sqlite3 as the database for Active Record -gem 'sqlite3' -# Use Puma as the app server -gem 'puma', '~> 4.3' +ruby '~> 3.1.2' gem 'active_model_serializers' diff --git a/Gemfile.lock b/Gemfile.lock index d790f4a..6fcd416 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -181,7 +181,7 @@ DEPENDENCIES tzinfo-data RUBY VERSION - ruby 2.6.9p207 + ruby 3.1.2p207 BUNDLED WITH 2.4.21 From 761e9a4d16d5a865735a3fa4109a4d14a3dd7a7e Mon Sep 17 00:00:00 2001 From: Leandro Machado Pereira Date: Thu, 18 Jan 2024 00:37:42 -0300 Subject: [PATCH 07/23] feat: upgrade rails to 7.0 --- Gemfile | 37 +---- Gemfile.lock | 339 +++++++++++++++++++++++++----------------- config/application.rb | 2 +- spec/rails_helper.rb | 2 +- 4 files changed, 213 insertions(+), 167 deletions(-) diff --git a/Gemfile b/Gemfile index f782dbd..81bfe78 100644 --- a/Gemfile +++ b/Gemfile @@ -4,48 +4,25 @@ git_source(:github) { |repo| "https://github.com/#{repo}.git" } ruby '~> 3.1.2' gem 'active_model_serializers' - -# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder -# gem 'jbuilder', '~> 2.5' -# Use Redis adapter to run Action Cable in production -# gem 'redis', '~> 4.0' -# Use ActiveModel has_secure_password -# gem 'bcrypt', '~> 3.1.7' - -# Use ActiveStorage variant -# gem 'mini_magick', '~> 4.8' - -# Use Capistrano for deployment -# gem 'capistrano-rails', group: :development - -# Reduces boot times through caching; required in config/boot.rb gem 'bootsnap', '>= 1.1.0', require: false - -# Use Rack CORS for handling Cross-Origin Resource Sharing (CORS), making cross-origin AJAX possible -# gem 'rack-cors' +gem 'puma' +gem 'rails', '~> 7.0' +gem 'sqlite3', platform: :ruby group :development, :test do - # Call 'byebug' anywhere in the code to stop execution and get a debugger console - gem 'byebug', platforms: [:mri, :mingw, :x64_mingw] + gem 'debug', '~> 1.0' end group :test do - gem 'rspec-rails', '~> 3.5' - - # Use Factory Girl for generating random test data + gem 'rspec-rails' gem 'factory_bot' - - # gem 'database_cleaner-active_record', git: 'https://github.com/DatabaseCleaner/database_cleaner-active_record' gem 'database_cleaner' end group :development do - gem 'listen', '>= 3.0.5', '< 3.2' - # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring + gem 'listen', '~> 3.5' gem 'spring' - gem 'spring-watcher-listen', '~> 2.0.0' + gem 'spring-watcher-listen' end - -# Windows does not include zoneinfo files, so bundle the tzinfo-data gem gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby] diff --git a/Gemfile.lock b/Gemfile.lock index 6fcd416..7c29214 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,166 +1,235 @@ GEM remote: https://rubygems.org/ specs: - actioncable (5.2.4.6) - actionpack (= 5.2.4.6) + actioncable (7.1.3) + actionpack (= 7.1.3) + activesupport (= 7.1.3) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailer (5.2.4.6) - actionpack (= 5.2.4.6) - actionview (= 5.2.4.6) - activejob (= 5.2.4.6) + zeitwerk (~> 2.6) + actionmailbox (7.1.3) + actionpack (= 7.1.3) + activejob (= 7.1.3) + activerecord (= 7.1.3) + activestorage (= 7.1.3) + activesupport (= 7.1.3) + mail (>= 2.7.1) + net-imap + net-pop + net-smtp + actionmailer (7.1.3) + actionpack (= 7.1.3) + actionview (= 7.1.3) + activejob (= 7.1.3) + activesupport (= 7.1.3) mail (~> 2.5, >= 2.5.4) - rails-dom-testing (~> 2.0) - actionpack (5.2.4.6) - actionview (= 5.2.4.6) - activesupport (= 5.2.4.6) - rack (~> 2.0, >= 2.0.8) + net-imap + net-pop + net-smtp + rails-dom-testing (~> 2.2) + actionpack (7.1.3) + actionview (= 7.1.3) + activesupport (= 7.1.3) + nokogiri (>= 1.8.5) + racc + rack (>= 2.2.4) + rack-session (>= 1.0.1) rack-test (>= 0.6.3) - rails-dom-testing (~> 2.0) - rails-html-sanitizer (~> 1.0, >= 1.0.2) - actionview (5.2.4.6) - activesupport (= 5.2.4.6) + rails-dom-testing (~> 2.2) + rails-html-sanitizer (~> 1.6) + actiontext (7.1.3) + actionpack (= 7.1.3) + activerecord (= 7.1.3) + activestorage (= 7.1.3) + activesupport (= 7.1.3) + globalid (>= 0.6.0) + nokogiri (>= 1.8.5) + actionview (7.1.3) + activesupport (= 7.1.3) builder (~> 3.1) - erubi (~> 1.4) - rails-dom-testing (~> 2.0) - rails-html-sanitizer (~> 1.0, >= 1.0.3) - active_model_serializers (0.10.10) - actionpack (>= 4.1, < 6.1) - activemodel (>= 4.1, < 6.1) + erubi (~> 1.11) + rails-dom-testing (~> 2.2) + rails-html-sanitizer (~> 1.6) + active_model_serializers (0.10.14) + actionpack (>= 4.1) + activemodel (>= 4.1) case_transform (>= 0.2) jsonapi-renderer (>= 0.1.1.beta1, < 0.3) - activejob (5.2.4.6) - activesupport (= 5.2.4.6) + activejob (7.1.3) + activesupport (= 7.1.3) globalid (>= 0.3.6) - activemodel (5.2.4.6) - activesupport (= 5.2.4.6) - activerecord (5.2.4.6) - activemodel (= 5.2.4.6) - activesupport (= 5.2.4.6) - arel (>= 9.0) - activestorage (5.2.4.6) - actionpack (= 5.2.4.6) - activerecord (= 5.2.4.6) - marcel (~> 0.3.1) - activesupport (5.2.4.6) + activemodel (7.1.3) + activesupport (= 7.1.3) + activerecord (7.1.3) + activemodel (= 7.1.3) + activesupport (= 7.1.3) + timeout (>= 0.4.0) + activestorage (7.1.3) + actionpack (= 7.1.3) + activejob (= 7.1.3) + activerecord (= 7.1.3) + activesupport (= 7.1.3) + marcel (~> 1.0) + activesupport (7.1.3) + base64 + bigdecimal concurrent-ruby (~> 1.0, >= 1.0.2) - i18n (>= 0.7, < 2) - minitest (~> 5.1) - tzinfo (~> 1.1) - arel (9.0.0) - bootsnap (1.16.0) + connection_pool (>= 2.2.5) + drb + i18n (>= 1.6, < 2) + minitest (>= 5.1) + mutex_m + tzinfo (~> 2.0) + base64 (0.2.0) + bigdecimal (3.1.5) + bootsnap (1.17.1) msgpack (~> 1.2) builder (3.2.4) - byebug (11.0.1) case_transform (0.2) activesupport - concurrent-ruby (1.1.9) + concurrent-ruby (1.2.3) + connection_pool (2.4.1) crass (1.0.6) - database_cleaner (1.7.0) - diff-lcs (1.3) - erubi (1.10.0) - factory_bot (5.0.2) - activesupport (>= 4.2.0) + database_cleaner (2.0.2) + database_cleaner-active_record (>= 2, < 3) + database_cleaner-active_record (2.1.0) + activerecord (>= 5.a) + database_cleaner-core (~> 2.0.0) + database_cleaner-core (2.0.1) + date (3.3.4) + debug (1.9.0) + irb (~> 1.10) + reline (>= 0.3.8) + diff-lcs (1.5.0) + drb (2.2.0) + ruby2_keywords + erubi (1.12.0) + factory_bot (6.4.5) + activesupport (>= 5.0.0) ffi (1.16.3) - globalid (1.0.0) - activesupport (>= 5.0) - i18n (1.8.11) + globalid (1.2.1) + activesupport (>= 6.1) + i18n (1.14.1) concurrent-ruby (~> 1.0) + io-console (0.7.1) + irb (1.11.1) + rdoc + reline (>= 0.4.2) jsonapi-renderer (0.2.2) - listen (3.1.5) - rb-fsevent (~> 0.9, >= 0.9.4) - rb-inotify (~> 0.9, >= 0.9.7) - ruby_dep (~> 1.2) - loofah (2.13.0) + listen (3.8.0) + rb-fsevent (~> 0.10, >= 0.10.3) + rb-inotify (~> 0.9, >= 0.9.10) + loofah (2.22.0) crass (~> 1.0.2) - nokogiri (>= 1.5.9) - mail (2.7.1) + nokogiri (>= 1.12.0) + mail (2.8.1) mini_mime (>= 0.1.1) - marcel (0.3.3) - mimemagic (~> 0.3.2) - method_source (1.0.0) - mimemagic (0.3.10) - nokogiri (~> 1) - rake - mini_mime (1.1.2) + net-imap + net-pop + net-smtp + marcel (1.0.2) + mini_mime (1.1.5) mini_portile2 (2.8.5) - minitest (5.15.0) + minitest (5.21.1) msgpack (1.7.2) - nio4r (2.5.8) - nokogiri (1.13.10) - mini_portile2 (~> 2.8.0) + mutex_m (0.2.0) + net-imap (0.4.9.1) + date + net-protocol + net-pop (0.1.2) + net-protocol + net-protocol (0.2.2) + timeout + net-smtp (0.4.0.1) + net-protocol + nio4r (2.7.0) + nokogiri (1.16.0) + mini_portile2 (~> 2.8.2) racc (~> 1.4) - puma (4.3.10) + psych (5.1.2) + stringio + puma (6.4.2) nio4r (~> 2.0) - racc (1.7.1) - rack (2.2.6.2) - rack-test (1.1.0) - rack (>= 1.0, < 3) - rails (5.2.4.6) - actioncable (= 5.2.4.6) - actionmailer (= 5.2.4.6) - actionpack (= 5.2.4.6) - actionview (= 5.2.4.6) - activejob (= 5.2.4.6) - activemodel (= 5.2.4.6) - activerecord (= 5.2.4.6) - activestorage (= 5.2.4.6) - activesupport (= 5.2.4.6) - bundler (>= 1.3.0) - railties (= 5.2.4.6) - sprockets-rails (>= 2.0.0) - rails-dom-testing (2.0.3) - activesupport (>= 4.2.0) + racc (1.7.3) + rack (3.0.8) + rack-session (2.0.0) + rack (>= 3.0.0) + rack-test (2.1.0) + rack (>= 1.3) + rackup (2.1.0) + rack (>= 3) + webrick (~> 1.8) + rails (7.1.3) + actioncable (= 7.1.3) + actionmailbox (= 7.1.3) + actionmailer (= 7.1.3) + actionpack (= 7.1.3) + actiontext (= 7.1.3) + actionview (= 7.1.3) + activejob (= 7.1.3) + activemodel (= 7.1.3) + activerecord (= 7.1.3) + activestorage (= 7.1.3) + activesupport (= 7.1.3) + bundler (>= 1.15.0) + railties (= 7.1.3) + rails-dom-testing (2.2.0) + activesupport (>= 5.0.0) + minitest nokogiri (>= 1.6) - rails-html-sanitizer (1.4.2) - loofah (~> 2.3) - railties (5.2.4.6) - actionpack (= 5.2.4.6) - activesupport (= 5.2.4.6) - method_source - rake (>= 0.8.7) - thor (>= 0.19.0, < 2.0) - rake (13.0.6) - rb-fsevent (0.10.3) - rb-inotify (0.10.0) + rails-html-sanitizer (1.6.0) + loofah (~> 2.21) + nokogiri (~> 1.14) + railties (7.1.3) + actionpack (= 7.1.3) + activesupport (= 7.1.3) + irb + rackup (>= 1.0.0) + rake (>= 12.2) + thor (~> 1.0, >= 1.2.2) + zeitwerk (~> 2.6) + rake (13.1.0) + rb-fsevent (0.11.2) + rb-inotify (0.10.1) ffi (~> 1.0) - rspec-core (3.8.2) - rspec-support (~> 3.8.0) - rspec-expectations (3.8.4) + rdoc (6.6.2) + psych (>= 4.0.0) + reline (0.4.2) + io-console (~> 0.5) + rspec-core (3.12.2) + rspec-support (~> 3.12.0) + rspec-expectations (3.12.3) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.8.0) - rspec-mocks (3.8.1) + rspec-support (~> 3.12.0) + rspec-mocks (3.12.6) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.8.0) - rspec-rails (3.8.2) - actionpack (>= 3.0) - activesupport (>= 3.0) - railties (>= 3.0) - rspec-core (~> 3.8.0) - rspec-expectations (~> 3.8.0) - rspec-mocks (~> 3.8.0) - rspec-support (~> 3.8.0) - rspec-support (3.8.2) - ruby_dep (1.5.0) - spring (2.1.0) - spring-watcher-listen (2.0.1) + rspec-support (~> 3.12.0) + rspec-rails (6.1.0) + actionpack (>= 6.1) + activesupport (>= 6.1) + railties (>= 6.1) + rspec-core (~> 3.12) + rspec-expectations (~> 3.12) + rspec-mocks (~> 3.12) + rspec-support (~> 3.12) + rspec-support (3.12.1) + ruby2_keywords (0.0.5) + spring (4.1.3) + spring-watcher-listen (2.1.0) listen (>= 2.7, < 4.0) - spring (>= 1.2, < 3.0) - sprockets (4.0.2) + spring (>= 4) + sqlite3 (1.7.0) + mini_portile2 (~> 2.8.0) + stringio (3.1.0) + thor (1.3.0) + timeout (0.4.1) + tzinfo (2.0.6) concurrent-ruby (~> 1.0) - rack (> 1, < 3) - sprockets-rails (3.4.2) - actionpack (>= 5.2) - activesupport (>= 5.2) - sprockets (>= 3.0.0) - sqlite3 (1.4.1) - thor (1.2.1) - thread_safe (0.3.6) - tzinfo (1.2.9) - thread_safe (~> 0.1) - websocket-driver (0.7.5) + webrick (1.8.1) + websocket-driver (0.7.6) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) + zeitwerk (2.6.12) PLATFORMS ruby @@ -168,15 +237,15 @@ PLATFORMS DEPENDENCIES active_model_serializers bootsnap (>= 1.1.0) - byebug database_cleaner + debug (~> 1.0) factory_bot - listen (>= 3.0.5, < 3.2) - puma (~> 4.3) - rails (~> 5.2.4.5) - rspec-rails (~> 3.5) + listen (~> 3.5) + puma + rails (~> 7.0) + rspec-rails spring - spring-watcher-listen (~> 2.0.0) + spring-watcher-listen sqlite3 tzinfo-data diff --git a/config/application.rb b/config/application.rb index dc0a4d6..db53b0f 100644 --- a/config/application.rb +++ b/config/application.rb @@ -20,7 +20,7 @@ module ApiAppName class Application < Rails::Application # Initialize configuration defaults for originally generated Rails version. - config.load_defaults 5.2 + config.load_defaults 7.0 config.autoload_paths += Dir["#{config.root}/lib/**/"] # Settings in config/environments/* take precedence over those specified here. diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 7fffc0b..29b3efc 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -39,7 +39,7 @@ config.include RequestSpecHelper, type: :request # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures - config.fixture_path = "#{::Rails.root}/spec/fixtures" + config.fixture_paths = ["#{::Rails.root}/spec/fixtures"] # If you're not using ActiveRecord, or you'd prefer not to run each of your # examples within a transaction, remove the following line or assign false From 5297b424960ecea67fd1b8eccd20cfcd3a29e544 Mon Sep 17 00:00:00 2001 From: Leandro Machado Pereira Date: Thu, 18 Jan 2024 00:41:40 -0300 Subject: [PATCH 08/23] fix: actions cache error --- config/environments/test.rb | 2 +- spec/lib/importa_arquivos_spec.rb | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/config/environments/test.rb b/config/environments/test.rb index 0a38fd3..1714a94 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -5,7 +5,7 @@ # test suite. You never need to work with it otherwise. Remember that # your test database is "scratch space" for the test suite and is wiped # and recreated between test runs. Don't rely on the data there! - config.cache_classes = true + config.cache_classes = false # Do not eager load code on boot. This avoids loading your whole application # just for the purpose of running a single test. If you are using a tool that diff --git a/spec/lib/importa_arquivos_spec.rb b/spec/lib/importa_arquivos_spec.rb index 1805d2a..6cafd27 100644 --- a/spec/lib/importa_arquivos_spec.rb +++ b/spec/lib/importa_arquivos_spec.rb @@ -32,14 +32,14 @@ expect do ImportaArquivos.importa_arquivo(@file) - end.to change(Resultado, :count).by(1) + end.to change(Resultado, :count).by(2) end it "inserindo linhas na base somente se arquivo valido" do @file = File.open(arquivo_invalido[:file]) expect do ImportaArquivos.importa_arquivo(@file) - end.to change(Resultado, :count).by(1) + end.to change(Resultado, :count).by(2) end end end From f7853612121f8538b12e2fddd16ae2d6e310376b Mon Sep 17 00:00:00 2001 From: Leandro Machado Pereira Date: Thu, 18 Jan 2024 00:56:42 -0300 Subject: [PATCH 09/23] feat: add database null coluns and strict load --- app/controllers/resultados_controller.rb | 2 +- app/models/application_record.rb | 1 + app/models/cliente.rb | 2 ++ app/models/resultado.rb | 2 ++ ...8035401_add_null_false_to_clientes_nome.rb | 5 ++++ ...0118035458_add_null_false_to_resultados.rb | 7 +++++ db/schema.rb | 29 +++++++++---------- spec/lib/importa_arquivos_spec.rb | 4 +-- 8 files changed, 34 insertions(+), 18 deletions(-) create mode 100644 db/migrate/20240118035401_add_null_false_to_clientes_nome.rb create mode 100644 db/migrate/20240118035458_add_null_false_to_resultados.rb diff --git a/app/controllers/resultados_controller.rb b/app/controllers/resultados_controller.rb index d84a764..b1b9831 100644 --- a/app/controllers/resultados_controller.rb +++ b/app/controllers/resultados_controller.rb @@ -37,7 +37,7 @@ def destroy private # Use callbacks to share common setup or constraints between actions. def set_resultado - @resultado = Resultado.find(params[:id]) + @resultado = Resultado.includes(:cliente).find(params[:id]) end # Never trust parameters from the scary internet, only allow the white list through. diff --git a/app/models/application_record.rb b/app/models/application_record.rb index 10a4cba..c39bae6 100644 --- a/app/models/application_record.rb +++ b/app/models/application_record.rb @@ -1,3 +1,4 @@ class ApplicationRecord < ActiveRecord::Base self.abstract_class = true + self.strict_loading_by_default = true end diff --git a/app/models/cliente.rb b/app/models/cliente.rb index 647dd4f..e304560 100644 --- a/app/models/cliente.rb +++ b/app/models/cliente.rb @@ -1,3 +1,5 @@ class Cliente < ApplicationRecord has_many :resultado + + validates :nome, presence: true end diff --git a/app/models/resultado.rb b/app/models/resultado.rb index 82eff68..2cc3d36 100644 --- a/app/models/resultado.rb +++ b/app/models/resultado.rb @@ -1,3 +1,5 @@ class Resultado < ApplicationRecord belongs_to :cliente + + validates :periodo, :valor_meta, :valor_realizado, presence: true end diff --git a/db/migrate/20240118035401_add_null_false_to_clientes_nome.rb b/db/migrate/20240118035401_add_null_false_to_clientes_nome.rb new file mode 100644 index 0000000..24b9b29 --- /dev/null +++ b/db/migrate/20240118035401_add_null_false_to_clientes_nome.rb @@ -0,0 +1,5 @@ +class AddNullFalseToClientesNome < ActiveRecord::Migration[7.1] + def change + change_column_null :clientes, :nome, false + end +end diff --git a/db/migrate/20240118035458_add_null_false_to_resultados.rb b/db/migrate/20240118035458_add_null_false_to_resultados.rb new file mode 100644 index 0000000..072d050 --- /dev/null +++ b/db/migrate/20240118035458_add_null_false_to_resultados.rb @@ -0,0 +1,7 @@ +class AddNullFalseToResultados < ActiveRecord::Migration[7.1] + def change + change_column_null :resultados, :periodo, false + change_column_null :resultados, :valor_meta, false + change_column_null :resultados, :valor_realizado, false + end +end diff --git a/db/schema.rb b/db/schema.rb index f135288..7b71ff2 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -2,29 +2,28 @@ # of editing this file, please use the migrations feature of Active Record to # incrementally modify your database, and then regenerate this schema definition. # -# Note that this schema.rb definition is the authoritative source for your -# database schema. If you need to create the application database on another -# system, you should be using db:schema:load, not running all the migrations -# from scratch. The latter is a flawed and unsustainable approach (the more migrations -# you'll amass, the slower it'll run and the greater likelihood for issues). +# This file is the source Rails uses to define your schema when running `bin/rails +# db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to +# be faster and is potentially less error prone than running all of your +# migrations from scratch. Old migrations may fail to apply correctly if those +# migrations use external dependencies or application code. # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2019_09_05_171950) do - +ActiveRecord::Schema[7.1].define(version: 2024_01_18_035458) do create_table "clientes", force: :cascade do |t| - t.string "nome" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.string "nome", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false end create_table "resultados", force: :cascade do |t| - t.date "periodo" + t.date "periodo", null: false t.integer "cliente_id" - t.decimal "valor_meta", precision: 10, scale: 2 - t.decimal "valor_realizado", precision: 10, scale: 2 - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.decimal "valor_meta", precision: 10, scale: 2, null: false + t.decimal "valor_realizado", precision: 10, scale: 2, null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.index ["cliente_id"], name: "index_resultados_on_cliente_id" end diff --git a/spec/lib/importa_arquivos_spec.rb b/spec/lib/importa_arquivos_spec.rb index 6cafd27..1805d2a 100644 --- a/spec/lib/importa_arquivos_spec.rb +++ b/spec/lib/importa_arquivos_spec.rb @@ -32,14 +32,14 @@ expect do ImportaArquivos.importa_arquivo(@file) - end.to change(Resultado, :count).by(2) + end.to change(Resultado, :count).by(1) end it "inserindo linhas na base somente se arquivo valido" do @file = File.open(arquivo_invalido[:file]) expect do ImportaArquivos.importa_arquivo(@file) - end.to change(Resultado, :count).by(2) + end.to change(Resultado, :count).by(1) end end end From f2222624de80a90121865b9551f6903b0aefe7e0 Mon Sep 17 00:00:00 2001 From: Leandro Machado Pereira Date: Thu, 18 Jan 2024 12:39:31 -0300 Subject: [PATCH 10/23] feat: remove unused code --- app/channels/application_cable/channel.rb | 4 --- app/channels/application_cable/connection.rb | 4 --- app/jobs/application_job.rb | 2 -- app/mailers/application_mailer.rb | 4 --- app/views/layouts/mailer.html.erb | 13 -------- app/views/layouts/mailer.text.erb | 1 - config/application.rb | 4 --- config/cable.yml | 10 ------ config/environments/development.rb | 8 ----- config/environments/production.rb | 9 ------ config/environments/test.rb | 10 ------ config/storage.yml | 34 -------------------- 12 files changed, 103 deletions(-) delete mode 100644 app/channels/application_cable/channel.rb delete mode 100644 app/channels/application_cable/connection.rb delete mode 100644 app/jobs/application_job.rb delete mode 100644 app/mailers/application_mailer.rb delete mode 100644 app/views/layouts/mailer.html.erb delete mode 100644 app/views/layouts/mailer.text.erb delete mode 100644 config/cable.yml delete mode 100644 config/storage.yml diff --git a/app/channels/application_cable/channel.rb b/app/channels/application_cable/channel.rb deleted file mode 100644 index d672697..0000000 --- a/app/channels/application_cable/channel.rb +++ /dev/null @@ -1,4 +0,0 @@ -module ApplicationCable - class Channel < ActionCable::Channel::Base - end -end diff --git a/app/channels/application_cable/connection.rb b/app/channels/application_cable/connection.rb deleted file mode 100644 index 0ff5442..0000000 --- a/app/channels/application_cable/connection.rb +++ /dev/null @@ -1,4 +0,0 @@ -module ApplicationCable - class Connection < ActionCable::Connection::Base - end -end diff --git a/app/jobs/application_job.rb b/app/jobs/application_job.rb deleted file mode 100644 index a009ace..0000000 --- a/app/jobs/application_job.rb +++ /dev/null @@ -1,2 +0,0 @@ -class ApplicationJob < ActiveJob::Base -end diff --git a/app/mailers/application_mailer.rb b/app/mailers/application_mailer.rb deleted file mode 100644 index 286b223..0000000 --- a/app/mailers/application_mailer.rb +++ /dev/null @@ -1,4 +0,0 @@ -class ApplicationMailer < ActionMailer::Base - default from: 'from@example.com' - layout 'mailer' -end diff --git a/app/views/layouts/mailer.html.erb b/app/views/layouts/mailer.html.erb deleted file mode 100644 index cbd34d2..0000000 --- a/app/views/layouts/mailer.html.erb +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - <%= yield %> - - diff --git a/app/views/layouts/mailer.text.erb b/app/views/layouts/mailer.text.erb deleted file mode 100644 index 37f0bdd..0000000 --- a/app/views/layouts/mailer.text.erb +++ /dev/null @@ -1 +0,0 @@ -<%= yield %> diff --git a/config/application.rb b/config/application.rb index db53b0f..dfce938 100644 --- a/config/application.rb +++ b/config/application.rb @@ -3,13 +3,9 @@ require "rails" # Pick the frameworks you want: require "active_model/railtie" -require "active_job/railtie" require "active_record/railtie" -require "active_storage/engine" require "action_controller/railtie" -require "action_mailer/railtie" require "action_view/railtie" -require "action_cable/engine" # require "sprockets/railtie" require "rails/test_unit/railtie" diff --git a/config/cable.yml b/config/cable.yml deleted file mode 100644 index 269b356..0000000 --- a/config/cable.yml +++ /dev/null @@ -1,10 +0,0 @@ -development: - adapter: async - -test: - adapter: async - -production: - adapter: redis - url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %> - channel_prefix: api_app_name_production diff --git a/config/environments/development.rb b/config/environments/development.rb index d52ec9e..136aa49 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -27,14 +27,6 @@ config.cache_store = :null_store end - # Store uploaded files on the local file system (see config/storage.yml for options) - config.active_storage.service = :local - - # Don't care if the mailer can't send. - config.action_mailer.raise_delivery_errors = false - - config.action_mailer.perform_caching = false - # Print deprecation notices to the Rails logger. config.active_support.deprecation = :log diff --git a/config/environments/production.rb b/config/environments/production.rb index 5a3c748..d86d77b 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -29,9 +29,6 @@ # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX - # Store uploaded files on the local file system (see config/storage.yml for options) - config.active_storage.service = :local - # Mount Action Cable outside main process or domain # config.action_cable.mount_path = nil # config.action_cable.url = 'wss://example.com/cable' @@ -54,12 +51,6 @@ # config.active_job.queue_adapter = :resque # config.active_job.queue_name_prefix = "api_app_name_#{Rails.env}" - config.action_mailer.perform_caching = false - - # Ignore bad email addresses and do not raise email delivery errors. - # Set this to true and configure the email server for immediate delivery to raise delivery errors. - # config.action_mailer.raise_delivery_errors = false - # Enable locale fallbacks for I18n (makes lookups for any locale fall back to # the I18n.default_locale when a translation cannot be found). config.i18n.fallbacks = true diff --git a/config/environments/test.rb b/config/environments/test.rb index 1714a94..9cdf835 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -28,16 +28,6 @@ # Disable request forgery protection in test environment. config.action_controller.allow_forgery_protection = false - # Store uploaded files on the local file system in a temporary directory - config.active_storage.service = :test - - config.action_mailer.perform_caching = false - - # Tell Action Mailer not to deliver emails to the real world. - # The :test delivery method accumulates sent emails in the - # ActionMailer::Base.deliveries array. - config.action_mailer.delivery_method = :test - # Print deprecation notices to the stderr. config.active_support.deprecation = :stderr diff --git a/config/storage.yml b/config/storage.yml deleted file mode 100644 index d32f76e..0000000 --- a/config/storage.yml +++ /dev/null @@ -1,34 +0,0 @@ -test: - service: Disk - root: <%= Rails.root.join("tmp/storage") %> - -local: - service: Disk - root: <%= Rails.root.join("storage") %> - -# Use rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key) -# amazon: -# service: S3 -# access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %> -# secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %> -# region: us-east-1 -# bucket: your_own_bucket - -# Remember not to checkin your GCS keyfile to a repository -# google: -# service: GCS -# project: your_project -# credentials: <%= Rails.root.join("path/to/gcs.keyfile") %> -# bucket: your_own_bucket - -# Use rails credentials:edit to set the Azure Storage secret (as azure_storage:storage_access_key) -# microsoft: -# service: AzureStorage -# storage_account_name: your_account_name -# storage_access_key: <%= Rails.application.credentials.dig(:azure_storage, :storage_access_key) %> -# container: your_container_name - -# mirror: -# service: Mirror -# primary: local -# mirrors: [ amazon, google, microsoft ] From 053c2376288ddfcc3fa0997e5f57543c0582f542 Mon Sep 17 00:00:00 2001 From: Leandro Machado Pereira Date: Thu, 18 Jan 2024 12:39:52 -0300 Subject: [PATCH 11/23] feat: improve docker run --- Dockerfile | 4 ++++ docker/run | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 3b92cb6..27dbf35 100644 --- a/Dockerfile +++ b/Dockerfile @@ -21,6 +21,10 @@ RUN gem update --system RUN bundle install COPY . /app +# Fix sqlite3_native.so: posix_fallocate64: symbol not found - source: https://gist.github.com/hopsoft/9a0bf00be2816cbe036fae5aa3d85b73 +RUN gem uninstall sqlite3 --all +RUN CFLAGS=-DSQLITE_DEFAULT_PAGE_SIZE=16300 gem install sqlite3 --platform=ruby + EXPOSE 3000 # Start the main process. diff --git a/docker/run b/docker/run index b659962..90dcc1c 100755 --- a/docker/run +++ b/docker/run @@ -1 +1 @@ -docker run -p 3000:3000 --rm -w /app -it achievemore-ruby +docker run -p 3000:3000 --rm -w /app -it achievemore-ruby $1 From 3e2a431d3d12bf704d9463a5f8551a04d1a9abfe Mon Sep 17 00:00:00 2001 From: Leandro Machado Pereira Date: Thu, 18 Jan 2024 14:57:21 -0300 Subject: [PATCH 12/23] feat: improve serializer --- app/controllers/clientes_controller.rb | 4 +++- app/controllers/resultados_controller.rb | 4 +++- app/serializers/application_serializer.rb | 3 +++ app/serializers/cliente_serializer.rb | 3 ++- app/serializers/resultado_serializer.rb | 3 ++- 5 files changed, 13 insertions(+), 4 deletions(-) create mode 100644 app/serializers/application_serializer.rb diff --git a/app/controllers/clientes_controller.rb b/app/controllers/clientes_controller.rb index 77fb2a7..b8599f5 100644 --- a/app/controllers/clientes_controller.rb +++ b/app/controllers/clientes_controller.rb @@ -3,12 +3,14 @@ class ClientesController < ApplicationController def index @clientes = Cliente.all + + render json: @clientes, each_serializer: ClienteSerializer end def show set_cliente - render json: @cliente + render json: ClienteSerializer.new(@cliente) end def create diff --git a/app/controllers/resultados_controller.rb b/app/controllers/resultados_controller.rb index b1b9831..d607f4a 100644 --- a/app/controllers/resultados_controller.rb +++ b/app/controllers/resultados_controller.rb @@ -3,12 +3,14 @@ class ResultadosController < ApplicationController def index @resultados = Resultado.all + + render json: @resultados, each_serializer: ResultadoSerializer end def show set_resultado - render json: @resultado + render json: ResultadoSerializer.new(@resultado, includes: :cliente) end def create diff --git a/app/serializers/application_serializer.rb b/app/serializers/application_serializer.rb new file mode 100644 index 0000000..c965ecd --- /dev/null +++ b/app/serializers/application_serializer.rb @@ -0,0 +1,3 @@ + +class ApplicationSerializer < ActiveModel::Serializer +end \ No newline at end of file diff --git a/app/serializers/cliente_serializer.rb b/app/serializers/cliente_serializer.rb index 40fe884..8510150 100644 --- a/app/serializers/cliente_serializer.rb +++ b/app/serializers/cliente_serializer.rb @@ -1,3 +1,4 @@ -class ClienteSerializer < ActiveModel::Serializer +class ClienteSerializer < ApplicationSerializer + type :cliente attributes :id, :nome end diff --git a/app/serializers/resultado_serializer.rb b/app/serializers/resultado_serializer.rb index 4bdf539..544d09a 100644 --- a/app/serializers/resultado_serializer.rb +++ b/app/serializers/resultado_serializer.rb @@ -1,4 +1,5 @@ -class ResultadoSerializer < ActiveModel::Serializer +class ResultadoSerializer < ApplicationSerializer + type :resultado belongs_to :cliente attributes :id, :valor_meta, :valor_realizado end From 679e7089d529428a2d6fa1933654a21beb568b99 Mon Sep 17 00:00:00 2001 From: Leandro Machado Pereira Date: Thu, 18 Jan 2024 14:57:47 -0300 Subject: [PATCH 13/23] feat: add faker and improve factories --- Gemfile | 1 + Gemfile.lock | 3 +++ spec/controllers/clientes_controller_spec.rb | 22 +++++++++---------- .../controllers/resultados_controller_spec.rb | 2 +- spec/factories/clientes.rb | 2 +- 5 files changed, 17 insertions(+), 13 deletions(-) diff --git a/Gemfile b/Gemfile index 81bfe78..0a4589a 100644 --- a/Gemfile +++ b/Gemfile @@ -15,6 +15,7 @@ end group :test do gem 'rspec-rails' + gem 'faker' gem 'factory_bot' gem 'database_cleaner' end diff --git a/Gemfile.lock b/Gemfile.lock index 7c29214..b239791 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -106,6 +106,8 @@ GEM erubi (1.12.0) factory_bot (6.4.5) activesupport (>= 5.0.0) + faker (3.2.1) + i18n (>= 1.8.11, < 2) ffi (1.16.3) globalid (1.2.1) activesupport (>= 6.1) @@ -240,6 +242,7 @@ DEPENDENCIES database_cleaner debug (~> 1.0) factory_bot + faker listen (~> 3.5) puma rails (~> 7.0) diff --git a/spec/controllers/clientes_controller_spec.rb b/spec/controllers/clientes_controller_spec.rb index ac6aab6..4c21bb3 100644 --- a/spec/controllers/clientes_controller_spec.rb +++ b/spec/controllers/clientes_controller_spec.rb @@ -2,25 +2,23 @@ RSpec.describe ClientesController, type: :controller do - let(:valid_attributes) { - { nome: "AchieveMore" } - } - let(:valid_session) { {} } describe "GET #index" do it "returns a success response" do - cliente = Cliente.create! valid_attributes + create_list(:cliente, 2) + create(:cliente, nome: "AchieveMore") get :index, params: {}, session: valid_session expect(response).to be_successful + expect(response.body).to include("AchieveMore") end end describe "GET #show" do it "returns a success response" do - cliente = Cliente.create! valid_attributes + cliente = create(:cliente) get :show, params: {id: cliente.to_param}, session: valid_session @@ -31,8 +29,10 @@ describe "POST #create" do context "with valid params" do it "creates a new Cliente" do + cliente = build(:cliente) + expect { - post :create, params: {cliente: valid_attributes}, session: valid_session + post :create, params: { cliente: cliente.attributes }, session: valid_session }.to change(Cliente, :count).by(1) end end @@ -45,7 +45,7 @@ } it "updates the requested cliente" do - cliente = Cliente.create! valid_attributes + cliente = create(:cliente) put :update, params: {id: cliente.to_param, cliente: new_attributes}, session: valid_session cliente.reload @@ -54,9 +54,9 @@ end it "renders a JSON response with the cliente" do - cliente = Cliente.create! valid_attributes + cliente = create(:cliente) - put :update, params: {id: cliente.to_param, cliente: valid_attributes}, session: valid_session + put :update, params: {id: cliente.to_param, cliente: cliente.attributes}, session: valid_session expect(response).to have_http_status(:ok) expect(response.content_type).to include('application/json') @@ -66,7 +66,7 @@ describe "DELETE #destroy" do it "destroys the requested cliente" do - cliente = Cliente.create! valid_attributes + cliente = create(:cliente) expect { delete :destroy, params: {id: cliente.to_param} diff --git a/spec/controllers/resultados_controller_spec.rb b/spec/controllers/resultados_controller_spec.rb index 7870f28..3a25c7c 100644 --- a/spec/controllers/resultados_controller_spec.rb +++ b/spec/controllers/resultados_controller_spec.rb @@ -23,7 +23,7 @@ describe "GET #show" do it "returns a success response" do - get :show, params: {id: resultado.to_param} + get :show, params: {id: resultado.id} expect(response).to be_successful end diff --git a/spec/factories/clientes.rb b/spec/factories/clientes.rb index 81b9dfa..f9ed0d4 100644 --- a/spec/factories/clientes.rb +++ b/spec/factories/clientes.rb @@ -1,5 +1,5 @@ FactoryBot.define do factory :cliente do - nome { "AchieveMore" } + nome { Faker::Name.name } end end From d1a55960c496340ccc48fc4869df8a1921c8b5a4 Mon Sep 17 00:00:00 2001 From: Leandro Machado Pereira Date: Thu, 18 Jan 2024 19:02:32 -0300 Subject: [PATCH 14/23] feat: add rake to import metas --- docs/wiki.MD | 7 +++++++ lib/importa_arquivos.rb | 2 ++ lib/tasks/import.rake | 17 +++++++++++++++++ 3 files changed, 26 insertions(+) create mode 100644 docs/wiki.MD create mode 100644 lib/tasks/import.rake diff --git a/docs/wiki.MD b/docs/wiki.MD new file mode 100644 index 0000000..70adf61 --- /dev/null +++ b/docs/wiki.MD @@ -0,0 +1,7 @@ +# App Cliente Resultado + +### Importar arquivo mensal de metas + +``` +rails import:arquivo_resultado["spec/fixtures/files/arquivo_valido.csv"] +``` \ No newline at end of file diff --git a/lib/importa_arquivos.rb b/lib/importa_arquivos.rb index 16c124c..cfc085d 100644 --- a/lib/importa_arquivos.rb +++ b/lib/importa_arquivos.rb @@ -1,3 +1,5 @@ +require 'csv' + class ImportaArquivos def self.importa_arquivo(arquivo) @arquivo = arquivo diff --git a/lib/tasks/import.rake b/lib/tasks/import.rake new file mode 100644 index 0000000..8d64d60 --- /dev/null +++ b/lib/tasks/import.rake @@ -0,0 +1,17 @@ + +require 'importa_arquivos' + +namespace :import do + desc "Importa arquivos" + task :arquivo_resultado, [:file] => :environment do |_, args| + puts "Arquivo: #{args[:file]}" + + abort("Arquivo não encontrado") unless File.exist?(args[:file]) + + puts "Iniciando task arquivo_resultado..." + + ImportaArquivos.importa_arquivo(args[:file]) + + puts "Finalizando task arquivo_resultado..." + end +end \ No newline at end of file From 862522c30ad79f5f3119864b6d207c0199ae99dd Mon Sep 17 00:00:00 2001 From: Leandro Machado Pereira Date: Thu, 18 Jan 2024 19:03:20 -0300 Subject: [PATCH 15/23] feat: improve docker and add docker-compose --- docker-compose.yml | 23 +++++++++++++++++++++++ docker/run | 1 + docker/server | 2 ++ spec/rails_helper.rb | 2 +- 4 files changed, 27 insertions(+), 1 deletion(-) create mode 100755 docker-compose.yml create mode 100755 docker/server diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100755 index 0000000..64349b8 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,23 @@ +version: '3.7' +services: + web: + build: + context: . + command: sh -c "rm -f tmp/pids/server.pid && bundle install --jobs 10 --retry 5 && bundle exec rails s -p 3000 -b '0.0.0.0'" + volumes: + - type: bind + source: . + target: /app + environment: + RAILS_ENV: development + ports: + - 3000:3000 + networks: + - app-network + +volumes: + bundle_vendor: + +networks: + app-network: + driver: bridge \ No newline at end of file diff --git a/docker/run b/docker/run index 90dcc1c..ece63af 100755 --- a/docker/run +++ b/docker/run @@ -1 +1,2 @@ +#!/bin/sh docker run -p 3000:3000 --rm -w /app -it achievemore-ruby $1 diff --git a/docker/server b/docker/server new file mode 100755 index 0000000..1b82af4 --- /dev/null +++ b/docker/server @@ -0,0 +1,2 @@ +#!/bin/sh +docker run -d -v pwd:/app -p 3000:3000 --rm -w /app -it achievemore-ruby rails s -b 0.0.0.0 diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 29b3efc..1063414 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -1,6 +1,6 @@ # This file is copied to spec/ when you run 'rails generate rspec:install' require 'spec_helper' -ENV['RAILS_ENV'] ||= 'test' +ENV['RAILS_ENV'] = 'test' require File.expand_path('../../config/environment', __FILE__) # Prevent database truncation if the environment is production abort("The Rails environment is running in production mode!") if Rails.env.production? From 868503e49d0ddb9ddfc764bf058160b63af74f30 Mon Sep 17 00:00:00 2001 From: Leandro Machado Pereira Date: Thu, 18 Jan 2024 19:08:55 -0300 Subject: [PATCH 16/23] feat: implement not found check and default response --- app/controllers/application_controller.rb | 11 +++++++++++ spec/controllers/clientes_controller_spec.rb | 6 ++++++ spec/controllers/resultados_controller_spec.rb | 6 ++++++ 3 files changed, 23 insertions(+) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 5799e38..d2eb0c7 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,3 +1,14 @@ class ApplicationController < ActionController::API include ActionController::Serialization + + rescue_from Exception, with: :exception_handler + + def exception_handler(exception) + case exception + when ActiveRecord::RecordNotFound, ActionController::UnknownController, ActionController::RoutingError + render json: { message: 'Not found' }, status: :not_found + else + render json: { message: 'Internal error' }, status: :internal_server_error + end + end end diff --git a/spec/controllers/clientes_controller_spec.rb b/spec/controllers/clientes_controller_spec.rb index 4c21bb3..08a0288 100644 --- a/spec/controllers/clientes_controller_spec.rb +++ b/spec/controllers/clientes_controller_spec.rb @@ -24,6 +24,12 @@ expect(response).to be_successful end + + it "returns a not found response" do + get :show, params: {id: 12481632}, session: valid_session + + expect(response).to have_http_status(:not_found) + end end describe "POST #create" do diff --git a/spec/controllers/resultados_controller_spec.rb b/spec/controllers/resultados_controller_spec.rb index 3a25c7c..8b0c998 100644 --- a/spec/controllers/resultados_controller_spec.rb +++ b/spec/controllers/resultados_controller_spec.rb @@ -27,6 +27,12 @@ expect(response).to be_successful end + + it "returns a not found response" do + get :show, params: {id: 12481632}, session: valid_session + + expect(response).to have_http_status(:not_found) + end end describe "POST #create" do From c05ef5d669b497dd654a75576f7ada516f49ba6f Mon Sep 17 00:00:00 2001 From: Leandro Machado Pereira Date: Thu, 18 Jan 2024 19:37:35 -0300 Subject: [PATCH 17/23] feat: add authentication --- app/controllers/application_controller.rb | 8 +++++ .../concerns/AuthorizeApiRequest.rb | 25 ++++++++++++++++ spec/controllers/calculos_controller_spec.rb | 14 +++++++-- spec/controllers/clientes_controller_spec.rb | 30 ++++++++++++++----- .../controllers/resultados_controller_spec.rb | 24 ++++++++++++--- spec/support/secured_behavior.rb | 10 +++++++ 6 files changed, 97 insertions(+), 14 deletions(-) create mode 100644 app/controllers/concerns/AuthorizeApiRequest.rb create mode 100644 spec/support/secured_behavior.rb diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index d2eb0c7..c1363fa 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,6 +1,14 @@ class ApplicationController < ActionController::API include ActionController::Serialization + before_action :authenticate_request + + def authenticate_request + @auth = AuthorizeApiRequest.new(request.headers).call + + render json: { error: 'Not Authorized' }, status: :unauthorized unless @auth.errors.empty? + end + rescue_from Exception, with: :exception_handler def exception_handler(exception) diff --git a/app/controllers/concerns/AuthorizeApiRequest.rb b/app/controllers/concerns/AuthorizeApiRequest.rb new file mode 100644 index 0000000..b7514c1 --- /dev/null +++ b/app/controllers/concerns/AuthorizeApiRequest.rb @@ -0,0 +1,25 @@ + + +class AuthorizeApiRequest + def initialize(headers = {}) + @headers = headers + @errors ||= ActiveModel::Errors.new(self) + end + + def call + validate_token + self + end + + attr_reader :errors + + private + + attr_reader :headers + + def validate_token + return if headers['Authorization'].present? + + @errors.add(:token, :invalid, message: 'Missing token') + end +end diff --git a/spec/controllers/calculos_controller_spec.rb b/spec/controllers/calculos_controller_spec.rb index e03e7da..3a948a8 100644 --- a/spec/controllers/calculos_controller_spec.rb +++ b/spec/controllers/calculos_controller_spec.rb @@ -13,13 +13,21 @@ { cliente_id: cliente.id, periodo: Date.today, valor_meta: 0.0, valor_realizado: 12.7 } } - let(:valid_session) { {} } + describe "not authorized" do + it "returns a not found response" do + get :performance + + expect(response).to have_http_status(:unauthorized) + end + end describe "GET #performance" do + include_context 'with authentication' + it "com atributos validos" do resultado = Resultado.create! valid_attributes - get :performance, params: {valor_meta: resultado.valor_meta, valor_realizado: resultado.valor_realizado}, session: valid_session + get :performance, params: {valor_meta: resultado.valor_meta, valor_realizado: resultado.valor_realizado} expect(response).to be_successful end @@ -27,7 +35,7 @@ it "com atributos inválidos" do resultado = Resultado.create! valid_attributes - get :performance, params: {valor_meta: resultado.valor_meta, valor_realizado: resultado.valor_realizado}, session: valid_session + get :performance, params: {valor_meta: resultado.valor_meta, valor_realizado: resultado.valor_realizado} expect(response).to be_successful end diff --git a/spec/controllers/clientes_controller_spec.rb b/spec/controllers/clientes_controller_spec.rb index 08a0288..6475058 100644 --- a/spec/controllers/clientes_controller_spec.rb +++ b/spec/controllers/clientes_controller_spec.rb @@ -2,14 +2,22 @@ RSpec.describe ClientesController, type: :controller do - let(:valid_session) { {} } + describe "not authorized" do + it "returns a not found response" do + get :index + + expect(response).to have_http_status(:unauthorized) + end + end describe "GET #index" do + include_context 'with authentication' + it "returns a success response" do create_list(:cliente, 2) create(:cliente, nome: "AchieveMore") - get :index, params: {}, session: valid_session + get :index, params: {} expect(response).to be_successful expect(response.body).to include("AchieveMore") @@ -17,34 +25,40 @@ end describe "GET #show" do + include_context 'with authentication' + it "returns a success response" do cliente = create(:cliente) - get :show, params: {id: cliente.to_param}, session: valid_session + get :show, params: {id: cliente.to_param} expect(response).to be_successful end it "returns a not found response" do - get :show, params: {id: 12481632}, session: valid_session + get :show, params: {id: 12481632} expect(response).to have_http_status(:not_found) end end describe "POST #create" do + include_context 'with authentication' + context "with valid params" do it "creates a new Cliente" do cliente = build(:cliente) expect { - post :create, params: { cliente: cliente.attributes }, session: valid_session + post :create, params: { cliente: cliente.attributes } }.to change(Cliente, :count).by(1) end end end describe "PUT #update" do + include_context 'with authentication' + context "with valid params" do let(:new_attributes) { { nome: "AchieveMore updated" } @@ -53,7 +67,7 @@ it "updates the requested cliente" do cliente = create(:cliente) - put :update, params: {id: cliente.to_param, cliente: new_attributes}, session: valid_session + put :update, params: {id: cliente.to_param, cliente: new_attributes} cliente.reload expect(cliente.nome).to eq("AchieveMore updated") @@ -62,7 +76,7 @@ it "renders a JSON response with the cliente" do cliente = create(:cliente) - put :update, params: {id: cliente.to_param, cliente: cliente.attributes}, session: valid_session + put :update, params: {id: cliente.to_param, cliente: cliente.attributes} expect(response).to have_http_status(:ok) expect(response.content_type).to include('application/json') @@ -71,6 +85,8 @@ end describe "DELETE #destroy" do + include_context 'with authentication' + it "destroys the requested cliente" do cliente = create(:cliente) diff --git a/spec/controllers/resultados_controller_spec.rb b/spec/controllers/resultados_controller_spec.rb index 8b0c998..4daff6b 100644 --- a/spec/controllers/resultados_controller_spec.rb +++ b/spec/controllers/resultados_controller_spec.rb @@ -11,9 +11,17 @@ let(:resultado) { Resultado.create! valid_attributes } - let(:valid_session) { {} } + describe "not authorized" do + it "returns a not found response" do + get :index + + expect(response).to have_http_status(:unauthorized) + end + end describe "GET #index" do + include_context 'with authentication' + it "returns a success response" do get :index, params: {} @@ -22,6 +30,8 @@ end describe "GET #show" do + include_context 'with authentication' + it "returns a success response" do get :show, params: {id: resultado.id} @@ -29,30 +39,34 @@ end it "returns a not found response" do - get :show, params: {id: 12481632}, session: valid_session + get :show, params: {id: 12481632} expect(response).to have_http_status(:not_found) end end describe "POST #create" do + include_context 'with authentication' + context "with valid params" do it "creates a new Resultado" do expect { - post :create, params: {resultado: valid_attributes}, session: valid_session + post :create, params: {resultado: valid_attributes} }.to change(Resultado, :count).by(1) end end end describe "PUT #update" do + include_context 'with authentication' + context "with valid params" do let(:new_attributes) { { valor_meta: 10.5, valor_realizado: 12.7 } } it "updates the requested resultado", :aggregate_failures do - put :update, params: {id: resultado.to_param, resultado: new_attributes}, session: valid_session + put :update, params: {id: resultado.to_param, resultado: new_attributes} resultado.reload @@ -70,6 +84,8 @@ end describe "DELETE #destroy" do + include_context 'with authentication' + it "destroys the requested resultado" do resultado = Resultado.create! valid_attributes diff --git a/spec/support/secured_behavior.rb b/spec/support/secured_behavior.rb new file mode 100644 index 0000000..c0280a9 --- /dev/null +++ b/spec/support/secured_behavior.rb @@ -0,0 +1,10 @@ + + +shared_context 'with authentication' do + let(:access_token) { 'secret' } + let(:headers) { { 'Authorization' => "Bearer #{access_token}" } } + + before do + request.headers['Authorization'] = "Bearer #{access_token}" + end +end \ No newline at end of file From 418a177c4983a81d620678ba6014503bc3fdaced Mon Sep 17 00:00:00 2001 From: Leandro Machado Pereira Date: Thu, 18 Jan 2024 21:14:08 -0300 Subject: [PATCH 18/23] feat: improve specs and add specs for serializers --- .rspec | 2 +- app/controllers/application_controller.rb | 4 +++- app/controllers/resultados_controller.rb | 2 +- spec/controllers/calculos_controller_spec.rb | 20 ++++++------------ spec/controllers/clientes_controller_spec.rb | 8 +++---- .../controllers/resultados_controller_spec.rb | 13 +++++++----- spec/lib/calculos_spec.rb | 1 - spec/lib/importa_arquivos_spec.rb | 1 - spec/lib/resultados_spec.rb | 1 - spec/lib/validadores_spec.rb | 1 - spec/rails_helper.rb | 2 +- spec/serializers/cliente_serializer_spec.rb | 16 ++++++++++++++ spec/serializers/resultado_serializer_spec.rb | 21 +++++++++++++++++++ 13 files changed, 61 insertions(+), 31 deletions(-) create mode 100644 spec/serializers/cliente_serializer_spec.rb create mode 100644 spec/serializers/resultado_serializer_spec.rb diff --git a/.rspec b/.rspec index cb1dd14..6a8f61f 100644 --- a/.rspec +++ b/.rspec @@ -1,3 +1,3 @@ ---require spec_helper +--require rails_helper --format documentation --colour \ No newline at end of file diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index c1363fa..4988eeb 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -12,8 +12,10 @@ def authenticate_request rescue_from Exception, with: :exception_handler def exception_handler(exception) + raise exception if Rails.env.development? + case exception - when ActiveRecord::RecordNotFound, ActionController::UnknownController, ActionController::RoutingError + when ActiveRecord::RecordNotFound, ActionController::RoutingError render json: { message: 'Not found' }, status: :not_found else render json: { message: 'Internal error' }, status: :internal_server_error diff --git a/app/controllers/resultados_controller.rb b/app/controllers/resultados_controller.rb index d607f4a..7a89de8 100644 --- a/app/controllers/resultados_controller.rb +++ b/app/controllers/resultados_controller.rb @@ -2,7 +2,7 @@ class ResultadosController < ApplicationController before_action :set_resultado, only: [:show, :update, :destroy] def index - @resultados = Resultado.all + @resultados = Resultado.includes(:cliente).all render json: @resultados, each_serializer: ResultadoSerializer end diff --git a/spec/controllers/calculos_controller_spec.rb b/spec/controllers/calculos_controller_spec.rb index 3a948a8..3320314 100644 --- a/spec/controllers/calculos_controller_spec.rb +++ b/spec/controllers/calculos_controller_spec.rb @@ -1,18 +1,8 @@ -require 'rails_helper' - RSpec.describe CalculosController, type: :controller do let(:cliente) { create(:cliente) } - let(:valid_attributes) { - { cliente_id: cliente.id, periodo: Date.today, valor_meta: 10.5, valor_realizado: 12.7 } - } - - let(:invalid_valid_attributes) { - { cliente_id: cliente.id, periodo: Date.today, valor_meta: 0.0, valor_realizado: 12.7 } - } - describe "not authorized" do it "returns a not found response" do get :performance @@ -24,20 +14,22 @@ describe "GET #performance" do include_context 'with authentication' - it "com atributos validos" do - resultado = Resultado.create! valid_attributes + it "com atributos validos", :aggregate_failures do + resultado = create(:resultado, cliente:, valor_meta: 10.5, valor_realizado: 12.7) get :performance, params: {valor_meta: resultado.valor_meta, valor_realizado: resultado.valor_realizado} expect(response).to be_successful + expect(json['valor_performance']).to eq(1.2095238095238094) end - it "com atributos inválidos" do - resultado = Resultado.create! valid_attributes + it "com atributos inválidos", :aggregate_failures do + resultado = create(:resultado, cliente:, valor_meta: 0, valor_realizado: 12.7) get :performance, params: {valor_meta: resultado.valor_meta, valor_realizado: resultado.valor_realizado} expect(response).to be_successful + expect(json['valor_performance']).to eq(0) end end end diff --git a/spec/controllers/clientes_controller_spec.rb b/spec/controllers/clientes_controller_spec.rb index 6475058..1c64bc1 100644 --- a/spec/controllers/clientes_controller_spec.rb +++ b/spec/controllers/clientes_controller_spec.rb @@ -1,5 +1,3 @@ -require 'rails_helper' - RSpec.describe ClientesController, type: :controller do describe "not authorized" do @@ -13,14 +11,15 @@ describe "GET #index" do include_context 'with authentication' - it "returns a success response" do + it "returns a success response", :aggregate_failures do create_list(:cliente, 2) create(:cliente, nome: "AchieveMore") get :index, params: {} expect(response).to be_successful - expect(response.body).to include("AchieveMore") + expect(json['clientes'].size).to eq(3) + expect(json['clientes'].pluck('nome')).to include("AchieveMore") end end @@ -33,6 +32,7 @@ get :show, params: {id: cliente.to_param} expect(response).to be_successful + expect(json['cliente']['nome']).to eq(cliente.nome) end it "returns a not found response" do diff --git a/spec/controllers/resultados_controller_spec.rb b/spec/controllers/resultados_controller_spec.rb index 4daff6b..454599a 100644 --- a/spec/controllers/resultados_controller_spec.rb +++ b/spec/controllers/resultados_controller_spec.rb @@ -1,5 +1,3 @@ -require 'rails_helper' - RSpec.describe ResultadosController, type: :controller do let(:cliente) { create(:cliente) @@ -22,20 +20,25 @@ describe "GET #index" do include_context 'with authentication' - it "returns a success response" do - get :index, params: {} + it "returns a success response", :aggregate_failures do + create_list(:resultado, 2, cliente:) + get :index, params: { cliente_id: cliente.id } expect(response).to be_successful + expect(json['resultados'].size).to eq(2) end end describe "GET #show" do include_context 'with authentication' - it "returns a success response" do + it "returns a success response", :aggregate_failures do get :show, params: {id: resultado.id} expect(response).to be_successful + expect(json['resultado']['id']).to eq(resultado.id) + expect(json['resultado']['valor_meta']).to eq("10.0") + expect(json['resultado']['valor_realizado']).to eq("12.0") end it "returns a not found response" do diff --git a/spec/lib/calculos_spec.rb b/spec/lib/calculos_spec.rb index 75c2920..545db3c 100644 --- a/spec/lib/calculos_spec.rb +++ b/spec/lib/calculos_spec.rb @@ -1,4 +1,3 @@ -require 'rails_helper' require 'calculos' RSpec.describe Calculos, type: :lib do diff --git a/spec/lib/importa_arquivos_spec.rb b/spec/lib/importa_arquivos_spec.rb index 1805d2a..dc17135 100644 --- a/spec/lib/importa_arquivos_spec.rb +++ b/spec/lib/importa_arquivos_spec.rb @@ -1,4 +1,3 @@ -require 'rails_helper' require 'csv' include ActionDispatch::TestProcess::FixtureFile diff --git a/spec/lib/resultados_spec.rb b/spec/lib/resultados_spec.rb index 0109f43..6357a62 100644 --- a/spec/lib/resultados_spec.rb +++ b/spec/lib/resultados_spec.rb @@ -1,4 +1,3 @@ -require 'rails_helper' require 'resultados' RSpec.describe Resultados, type: :lib do diff --git a/spec/lib/validadores_spec.rb b/spec/lib/validadores_spec.rb index d557ec7..68d8b11 100644 --- a/spec/lib/validadores_spec.rb +++ b/spec/lib/validadores_spec.rb @@ -1,4 +1,3 @@ -require 'rails_helper' require 'validadores' RSpec.describe Validadores, type: :lib do diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 1063414..70c18d3 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -36,7 +36,7 @@ Dir[Rails.root.join("spec/factories/**/*.rb")].each {|f| require f} RSpec.configure do |config| - config.include RequestSpecHelper, type: :request + config.include RequestSpecHelper, type: :controller # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures config.fixture_paths = ["#{::Rails.root}/spec/fixtures"] diff --git a/spec/serializers/cliente_serializer_spec.rb b/spec/serializers/cliente_serializer_spec.rb new file mode 100644 index 0000000..8f9180b --- /dev/null +++ b/spec/serializers/cliente_serializer_spec.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +RSpec.describe ClienteSerializer, type: :serializer do + let(:cliente) do + create(:cliente) + end + + it 'serializer correct' do + expect(ClienteSerializer.new(cliente).as_json).to eq( + { + id: cliente.id, + nome: cliente.nome + } + ) + end +end diff --git a/spec/serializers/resultado_serializer_spec.rb b/spec/serializers/resultado_serializer_spec.rb new file mode 100644 index 0000000..c48c8e9 --- /dev/null +++ b/spec/serializers/resultado_serializer_spec.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +RSpec.describe ResultadoSerializer, type: :serializer do + let(:resultado) do + create(:resultado) + end + + it 'serializer correct' do + expect(ResultadoSerializer.new(resultado).as_json).to eq( + { + id: resultado.id, + valor_meta: resultado.valor_meta, + valor_realizado: resultado.valor_realizado, + cliente: { + id: resultado.cliente.id, + nome: resultado.cliente.nome + } + } + ) + end +end From 3d95a64d0b9b92f7b7bd663d98f4d953c1e1b166 Mon Sep 17 00:00:00 2001 From: Leandro Machado Pereira Date: Thu, 18 Jan 2024 23:06:42 -0300 Subject: [PATCH 19/23] feat: add rubocop start config and todo file --- .github/workflows/deploy.yml | 4 + .rubocop.yml | 12 ++ .rubocop_todo.yml | 244 ++++++++++++++++++++++++++++++ Gemfile | 5 +- Gemfile.lock | 26 ++++ config/environments/production.rb | 2 +- docs/wiki.MD | 8 +- spec/rails_helper.rb | 2 +- 8 files changed, 298 insertions(+), 5 deletions(-) create mode 100644 .rubocop.yml create mode 100644 .rubocop_todo.yml diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index acdf40e..bbceef9 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -34,6 +34,10 @@ jobs: run: | bundle exec rake db:migrate + - name: Run rubocop + run: | + bundle exec rubocop + - name: Run tests env: RAILS_ENV: test diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 0000000..4839776 --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,12 @@ +inherit_from: .rubocop_todo.yml + +AllCops: + NewCops: enable + SuggestExtensions: false + +Style/NumericLiterals: + Exclude: + - db/schema.rb + +Methods/BlockLength: + Max: 100 \ No newline at end of file diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml new file mode 100644 index 0000000..ec154b9 --- /dev/null +++ b/.rubocop_todo.yml @@ -0,0 +1,244 @@ +# This configuration was generated by +# `rubocop --auto-gen-config` +# on 2024-01-19 00:20:16 UTC using RuboCop version 1.57.2. +# The point is for the user to remove these configuration records +# one by one as the offenses are removed from the code base. +# Note that changes in the inspected code, or installation of new +# versions of RuboCop, may require this file to be generated again. + +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +Layout/EmptyLineAfterGuardClause: + Exclude: + - 'lib/importa_arquivos.rb' + +# Offense count: 2 +# This cop supports safe autocorrection (--autocorrect). +Layout/EmptyLines: + Exclude: + - 'config/environments/development.rb' + - 'db/migrate/20190905171918_create_resultados.rb' + +# Offense count: 2 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyle. +# SupportedStyles: around, only_before +Layout/EmptyLinesAroundAccessModifier: + Exclude: + - 'app/controllers/clientes_controller.rb' + - 'app/controllers/resultados_controller.rb' + +# Offense count: 3 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyle. +# SupportedStyles: empty_lines, no_empty_lines +Layout/EmptyLinesAroundBlockBody: + Exclude: + - 'db/migrate/20190905171918_create_resultados.rb' + - 'db/schema.rb' + - 'spec/controllers/clientes_controller_spec.rb' + +# Offense count: 4 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyle. +# SupportedStyles: normal, indented_internal_methods +Layout/IndentationConsistency: + Exclude: + - 'app/controllers/clientes_controller.rb' + - 'app/controllers/resultados_controller.rb' + +# Offense count: 4 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: Width, AllowedPatterns. +Layout/IndentationWidth: + Exclude: + - 'app/controllers/clientes_controller.rb' + - 'app/controllers/resultados_controller.rb' + +# Offense count: 4 +# This cop supports safe autocorrection (--autocorrect). +Layout/LeadingEmptyLines: + Exclude: + - 'app/controllers/concerns/AuthorizeApiRequest.rb' + - 'app/serializers/application_serializer.rb' + - 'lib/tasks/import.rake' + - 'spec/support/secured_behavior.rb' + +# Offense count: 2 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBrackets. +# SupportedStyles: space, no_space, compact +# SupportedStylesForEmptyBrackets: space, no_space +Layout/SpaceInsideArrayLiteralBrackets: + Exclude: + - 'config/environments/production.rb' + +# Offense count: 2 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces, SpaceBeforeBlockParameters. +# SupportedStyles: space, no_space +# SupportedStylesForEmptyBraces: space, no_space +Layout/SpaceInsideBlockBraces: + Exclude: + - 'spec/rails_helper.rb' + +# Offense count: 26 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces. +# SupportedStyles: space, no_space, compact +# SupportedStylesForEmptyBraces: space, no_space +Layout/SpaceInsideHashLiteralBraces: + Exclude: + - 'spec/controllers/calculos_controller_spec.rb' + - 'spec/controllers/clientes_controller_spec.rb' + - 'spec/controllers/resultados_controller_spec.rb' + +# Offense count: 3 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyle. +# SupportedStyles: final_newline, final_blank_line +Layout/TrailingEmptyLines: + Exclude: + - 'app/serializers/application_serializer.rb' + - 'lib/tasks/import.rake' + - 'spec/support/secured_behavior.rb' + +# Offense count: 7 +# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns. +# AllowedMethods: refine +Metrics/BlockLength: + Max: 80 + +# Offense count: 1 +# Configuration parameters: ExpectMatchingDefinition, CheckDefinitionPathHierarchy, CheckDefinitionPathHierarchyRoots, Regex, IgnoreExecutableScripts, AllowedAcronyms. +# CheckDefinitionPathHierarchyRoots: lib, spec, test, src +# AllowedAcronyms: CLI, DSL, ACL, API, ASCII, CPU, CSS, DNS, EOF, GUID, HTML, HTTP, HTTPS, ID, IP, JSON, LHS, QPS, RAM, RHS, RPC, SLA, SMTP, SQL, SSH, TCP, TLS, TTL, UDP, UI, UID, UUID, URI, URL, UTF8, VM, XML, XMPP, XSRF, XSS +Naming/FileName: + Exclude: + - 'app/controllers/concerns/AuthorizeApiRequest.rb' + +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +Style/BlockComments: + Exclude: + - 'spec/spec_helper.rb' + +# Offense count: 9 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyle, ProceduralMethods, FunctionalMethods, AllowedMethods, AllowedPatterns, AllowBracesOnProceduralOneLiners, BracesRequiredMethods. +# SupportedStyles: line_count_based, semantic, braces_for_chaining, always_braces +# ProceduralMethods: benchmark, bm, bmbm, create, each_with_object, measure, new, realtime, tap, with_object +# FunctionalMethods: let, let!, subject, watch +# AllowedMethods: lambda, proc, it +Style/BlockDelimiters: + Exclude: + - 'spec/controllers/calculos_controller_spec.rb' + - 'spec/controllers/clientes_controller_spec.rb' + - 'spec/controllers/resultados_controller_spec.rb' + +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +Style/DefWithParentheses: + Exclude: + - 'lib/resultados.rb' + +# Offense count: 19 +# Configuration parameters: AllowedConstants. +Style/Documentation: + Enabled: false + +# Offense count: 3 +# This cop supports safe autocorrection (--autocorrect). +Style/ExpandPathArguments: + Exclude: + - 'bin/rails' + - 'bin/rake' + - 'spec/rails_helper.rb' + +# Offense count: 61 +# This cop supports unsafe autocorrection (--autocorrect-all). +# Configuration parameters: EnforcedStyle. +# SupportedStyles: always, always_true, never +Style/FrozenStringLiteralComment: + Enabled: false + +# Offense count: 1 +# This cop supports unsafe autocorrection (--autocorrect-all). +Style/GlobalStdStream: + Exclude: + - 'config/environments/production.rb' + +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyle, EnforcedShorthandSyntax, UseHashRocketsWithSymbolValues, PreferHashRocketsForNonAlnumEndingSymbols. +# SupportedStyles: ruby19, hash_rockets, no_mixed_keys, ruby19_no_mixed_keys +# SupportedShorthandSyntax: always, never, either, consistent +Style/HashSyntax: + Exclude: + - 'app/controllers/calculos_controller.rb' + +# Offense count: 3 +Style/MixinUsage: + Exclude: + - 'bin/setup' + - 'bin/update' + - 'spec/lib/importa_arquivos_spec.rb' + +# Offense count: 3 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: Strict, AllowedNumbers, AllowedPatterns. +Style/NumericLiterals: + MinDigits: 9 + +# Offense count: 2 +# This cop supports unsafe autocorrection (--autocorrect-all). +# Configuration parameters: SafeForConstants. +Style/RedundantFetchBlock: + Exclude: + - 'config/puma.rb' + +# Offense count: 11 +# This cop supports safe autocorrection (--autocorrect). +Style/RedundantRegexpCharacterClass: + Exclude: + - 'lib/validadores.rb' + +# Offense count: 15 +# This cop supports safe autocorrection (--autocorrect). +Style/RedundantRegexpEscape: + Exclude: + - 'lib/validadores.rb' + +# Offense count: 109 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyle, ConsistentQuotesInMultiline. +# SupportedStyles: single_quotes, double_quotes +Style/StringLiterals: + Exclude: + - 'config/application.rb' + - 'config/environments/production.rb' + - 'config/puma.rb' + - 'db/schema.rb' + - 'lib/tasks/import.rake' + - 'spec/controllers/calculos_controller_spec.rb' + - 'spec/controllers/clientes_controller_spec.rb' + - 'spec/controllers/resultados_controller_spec.rb' + - 'spec/lib/calculos_spec.rb' + - 'spec/lib/importa_arquivos_spec.rb' + - 'spec/lib/resultados_spec.rb' + - 'spec/lib/validadores_spec.rb' + - 'spec/rails_helper.rb' + +# Offense count: 3 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: MinSize. +# SupportedStyles: percent, brackets +Style/SymbolArray: + EnforcedStyle: brackets + +# Offense count: 2 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns. +# URISchemes: http, https +Layout/LineLength: + Max: 331 diff --git a/Gemfile b/Gemfile index 0a4589a..27afe41 100644 --- a/Gemfile +++ b/Gemfile @@ -11,13 +11,14 @@ gem 'sqlite3', platform: :ruby group :development, :test do gem 'debug', '~> 1.0' + gem 'rubocop', require: false end group :test do - gem 'rspec-rails' + gem 'database_cleaner' gem 'faker' gem 'factory_bot' - gem 'database_cleaner' + gem 'rspec-rails' end group :development do diff --git a/Gemfile.lock b/Gemfile.lock index b239791..e58814a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -80,6 +80,7 @@ GEM minitest (>= 5.1) mutex_m tzinfo (~> 2.0) + ast (2.4.2) base64 (0.2.0) bigdecimal (3.1.5) bootsnap (1.17.1) @@ -117,7 +118,9 @@ GEM irb (1.11.1) rdoc reline (>= 0.4.2) + json (2.6.3) jsonapi-renderer (0.2.2) + language_server-protocol (3.17.0.3) listen (3.8.0) rb-fsevent (~> 0.10, >= 0.10.3) rb-inotify (~> 0.9, >= 0.9.10) @@ -148,6 +151,10 @@ GEM nokogiri (1.16.0) mini_portile2 (~> 2.8.2) racc (~> 1.4) + parallel (1.23.0) + parser (3.2.2.4) + ast (~> 2.4.1) + racc psych (5.1.2) stringio puma (6.4.2) @@ -190,14 +197,17 @@ GEM rake (>= 12.2) thor (~> 1.0, >= 1.2.2) zeitwerk (~> 2.6) + rainbow (3.1.1) rake (13.1.0) rb-fsevent (0.11.2) rb-inotify (0.10.1) ffi (~> 1.0) rdoc (6.6.2) psych (>= 4.0.0) + regexp_parser (2.8.3) reline (0.4.2) io-console (~> 0.5) + rexml (3.2.6) rspec-core (3.12.2) rspec-support (~> 3.12.0) rspec-expectations (3.12.3) @@ -215,6 +225,20 @@ GEM rspec-mocks (~> 3.12) rspec-support (~> 3.12) rspec-support (3.12.1) + rubocop (1.57.2) + json (~> 2.3) + language_server-protocol (>= 3.17.0) + parallel (~> 1.10) + parser (>= 3.2.2.4) + rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 1.8, < 3.0) + rexml (>= 3.2.5, < 4.0) + rubocop-ast (>= 1.28.1, < 2.0) + ruby-progressbar (~> 1.7) + unicode-display_width (>= 2.4.0, < 3.0) + rubocop-ast (1.30.0) + parser (>= 3.2.1.0) + ruby-progressbar (1.13.0) ruby2_keywords (0.0.5) spring (4.1.3) spring-watcher-listen (2.1.0) @@ -227,6 +251,7 @@ GEM timeout (0.4.1) tzinfo (2.0.6) concurrent-ruby (~> 1.0) + unicode-display_width (2.5.0) webrick (1.8.1) websocket-driver (0.7.6) websocket-extensions (>= 0.1.0) @@ -247,6 +272,7 @@ DEPENDENCIES puma rails (~> 7.0) rspec-rails + rubocop spring spring-watcher-listen sqlite3 diff --git a/config/environments/production.rb b/config/environments/production.rb index d86d77b..8773e8f 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -59,7 +59,7 @@ config.active_support.deprecation = :notify # Use default logging formatter so that PID and timestamp are not suppressed. - config.log_formatter = ::Logger::Formatter.new + config.log_formatter = Logger::Formatter.new # Use a different logger for distributed setups. # require 'syslog/logger' diff --git a/docs/wiki.MD b/docs/wiki.MD index 70adf61..ca36e62 100644 --- a/docs/wiki.MD +++ b/docs/wiki.MD @@ -4,4 +4,10 @@ ``` rails import:arquivo_resultado["spec/fixtures/files/arquivo_valido.csv"] -``` \ No newline at end of file +``` + + +### TODO + + * verifique todos os cops do arquivo .rubocop_todo.yml e ajuste o código + * melhorar a cobertura de testes conforme relatório do coverage diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 70c18d3..0bcf363 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -39,7 +39,7 @@ config.include RequestSpecHelper, type: :controller # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures - config.fixture_paths = ["#{::Rails.root}/spec/fixtures"] + config.fixture_paths = ["#{Rails.root}/spec/fixtures"] # If you're not using ActiveRecord, or you'd prefer not to run each of your # examples within a transaction, remove the following line or assign false From d55ed56c320cd41000794148fceebea3e9d75bea Mon Sep 17 00:00:00 2001 From: Leandro Machado Pereira Date: Thu, 18 Jan 2024 23:09:09 -0300 Subject: [PATCH 20/23] fix: rubocop issue --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 27afe41..aa6bdeb 100644 --- a/Gemfile +++ b/Gemfile @@ -16,8 +16,8 @@ end group :test do gem 'database_cleaner' - gem 'faker' gem 'factory_bot' + gem 'faker' gem 'rspec-rails' end From b30076a295740e0e8e8ad07fbf06abe5cbbf1040 Mon Sep 17 00:00:00 2001 From: Leandro Machado Pereira Date: Thu, 18 Jan 2024 23:13:34 -0300 Subject: [PATCH 21/23] feat: add quality job --- .github/workflows/deploy.yml | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index bbceef9..2ab40f7 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -3,6 +3,22 @@ name: Main on: [push] jobs: + quality: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: 3.1.2 + bundler-cache: true + + - name: Run rubocop + run: | + bundle exec rubocop + test: runs-on: ubuntu-latest strategy: @@ -34,10 +50,6 @@ jobs: run: | bundle exec rake db:migrate - - name: Run rubocop - run: | - bundle exec rubocop - - name: Run tests env: RAILS_ENV: test From 5ac931aa00532d68fec1ca3cb4d02e389bba6f68 Mon Sep 17 00:00:00 2001 From: Leandro Machado Pereira Date: Thu, 18 Jan 2024 23:22:39 -0300 Subject: [PATCH 22/23] feat: add simplecov --- .gitignore | 2 ++ Gemfile | 2 ++ Gemfile.lock | 16 ++++++++++++++++ spec/rails_helper.rb | 5 +++++ 4 files changed, 25 insertions(+) diff --git a/.gitignore b/.gitignore index b6154ae..499059d 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ log/* tmp/* db/development.sqlite3* db/test.sqlite3* + +coverage/* diff --git a/Gemfile b/Gemfile index aa6bdeb..fe18a79 100644 --- a/Gemfile +++ b/Gemfile @@ -19,6 +19,8 @@ group :test do gem 'factory_bot' gem 'faker' gem 'rspec-rails' + gem 'simplecov' + gem 'simplecov-console' end group :development do diff --git a/Gemfile.lock b/Gemfile.lock index e58814a..65e3beb 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -80,6 +80,7 @@ GEM minitest (>= 5.1) mutex_m tzinfo (~> 2.0) + ansi (1.5.0) ast (2.4.2) base64 (0.2.0) bigdecimal (3.1.5) @@ -102,6 +103,7 @@ GEM irb (~> 1.10) reline (>= 0.3.8) diff-lcs (1.5.0) + docile (1.4.0) drb (2.2.0) ruby2_keywords erubi (1.12.0) @@ -240,6 +242,16 @@ GEM parser (>= 3.2.1.0) ruby-progressbar (1.13.0) ruby2_keywords (0.0.5) + simplecov (0.22.0) + docile (~> 1.1) + simplecov-html (~> 0.11) + simplecov_json_formatter (~> 0.1) + simplecov-console (0.9.1) + ansi + simplecov + terminal-table + simplecov-html (0.12.3) + simplecov_json_formatter (0.1.4) spring (4.1.3) spring-watcher-listen (2.1.0) listen (>= 2.7, < 4.0) @@ -247,6 +259,8 @@ GEM sqlite3 (1.7.0) mini_portile2 (~> 2.8.0) stringio (3.1.0) + terminal-table (3.0.2) + unicode-display_width (>= 1.1.1, < 3) thor (1.3.0) timeout (0.4.1) tzinfo (2.0.6) @@ -273,6 +287,8 @@ DEPENDENCIES rails (~> 7.0) rspec-rails rubocop + simplecov + simplecov-console spring spring-watcher-listen sqlite3 diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 0bcf363..538aa03 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -5,6 +5,11 @@ # Prevent database truncation if the environment is production abort("The Rails environment is running in production mode!") if Rails.env.production? require 'rspec/rails' +require 'simplecov' + +SimpleCov.minimum_coverage 100 +SimpleCov.formatter = SimpleCov::Formatter::Console +SimpleCov.start 'rails' # Add additional requires below this line. Rails is not loaded until this point! From 16093a3b19c3a006c4a5c1d89a3521cf8920bc6c Mon Sep 17 00:00:00 2001 From: Leandro Machado Pereira Date: Thu, 18 Jan 2024 23:23:17 -0300 Subject: [PATCH 23/23] feat: refactor class and improve specs --- app/controllers/clientes_controller.rb | 14 +++--- app/controllers/resultados_controller.rb | 12 ++--- lib/validadores.rb | 3 +- .../application_controller_spec.rb | 46 +++++++++++++++++++ spec/controllers/clientes_controller_spec.rb | 24 +++++++++- .../controllers/resultados_controller_spec.rb | 20 ++++++++ spec/lib/validadores_spec.rb | 26 +++++++++++ 7 files changed, 128 insertions(+), 17 deletions(-) create mode 100644 spec/controllers/application_controller_spec.rb diff --git a/app/controllers/clientes_controller.rb b/app/controllers/clientes_controller.rb index b8599f5..48ebc92 100644 --- a/app/controllers/clientes_controller.rb +++ b/app/controllers/clientes_controller.rb @@ -1,5 +1,5 @@ class ClientesController < ApplicationController - before_action :set_cliente, only: [:show, :edit, :update, :destroy] + before_action :set_cliente, only: [:show, :update, :destroy] def index @clientes = Cliente.all @@ -8,26 +8,24 @@ def index end def show - set_cliente - render json: ClienteSerializer.new(@cliente) end def create - @cliente = Cliente.new(cliente_params) + @cliente = Cliente.new(cliente_params.compact_blank) if @cliente.save - render json: { status: :created, location: @cliente } + render json: @cliente, location: @cliente, status: :created else - render json: { errors: @cliente.errors, status: :unprocessable_entity } + render json: { errors: @cliente.errors }, status: :unprocessable_entity end end def update if @cliente.update(cliente_params) - render json: { status: :ok, location: @cliente } + render json: @cliente, location: @cliente, status: :ok else - render json: { errors: @cliente.errors, status: :unprocessable_entity } + render json: { errors: @cliente.errors }, status: :unprocessable_entity end end diff --git a/app/controllers/resultados_controller.rb b/app/controllers/resultados_controller.rb index 7a89de8..2b524d2 100644 --- a/app/controllers/resultados_controller.rb +++ b/app/controllers/resultados_controller.rb @@ -8,26 +8,24 @@ def index end def show - set_resultado - render json: ResultadoSerializer.new(@resultado, includes: :cliente) end def create - @resultado = Resultado.new(resultado_params) + @resultado = Resultado.new(resultado_params.compact_blank) if @resultado.save - render json: { status: :created, location: @resultado } + render json: @resultado, status: :created, location: @resultado else - render json: { errors: @resultado.errors, status: :unprocessable_entity } + render json: { errors: @resultado.errors }, status: :unprocessable_entity end end def update if @resultado.update(resultado_params) - render json: { status: :ok, location: @resultado } + render json: @resultado, location: @resultado, status: :ok else - render json: { errors: @resultado.errors, status: :unprocessable_entity } + render json: { errors: @resultado.errors }, status: :unprocessable_entity end end diff --git a/lib/validadores.rb b/lib/validadores.rb index c310ac4..fbd4cdf 100644 --- a/lib/validadores.rb +++ b/lib/validadores.rb @@ -1,11 +1,12 @@ class Validadores - def match_periodo(periodo) + def self.match_periodo(periodo) case periodo when /(^(19|20)\d{2})((0[1-9])|(1[0-2])$)/ # YYYYMM format_str = '%Y%m' when /(^(19|20)\d{2})[\-]((0?[1-9]|1[012]){1}$)/ # YYYY-mm format_str = '%Y-%m' end + return nil unless format_str Date.strptime(periodo, format_str) end diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb new file mode 100644 index 0000000..d3f01cf --- /dev/null +++ b/spec/controllers/application_controller_spec.rb @@ -0,0 +1,46 @@ +RSpec.describe ApplicationController, type: :controller do + controller do + # Definido um dummy controller e action + def index + raise ActiveRecord::RecordNotFound if params[:foo] + + render json: { message: 'Hello!' }, status: :ok + end + end + + describe 'not authorized' do + it 'returns a not found response' do + get :index + + expect(response).to have_http_status(:unauthorized) + end + end + + describe '#authenticate_request' do + include_context 'with authentication' + + it 'returns a success response' do + get :index + + expect(response).to be_successful + end + end + + describe '#exception_handler' do + include_context 'with authentication' + + it 'returns a not found response' do + get :index, params: { foo: 'bar' } + + expect(response).to have_http_status(:not_found) + end + + it 'returns internal server error' do + allow(AuthorizeApiRequest).to receive(:new).and_raise(StandardError) + + get :index + + expect(response).to have_http_status(:internal_server_error) + end + end +end diff --git a/spec/controllers/clientes_controller_spec.rb b/spec/controllers/clientes_controller_spec.rb index 1c64bc1..759d664 100644 --- a/spec/controllers/clientes_controller_spec.rb +++ b/spec/controllers/clientes_controller_spec.rb @@ -54,6 +54,16 @@ }.to change(Cliente, :count).by(1) end end + + context "with invalid params" do + it "renders a JSON response with errors for the new cliente", :aggregate_failures do + post :create, params: { cliente: { nome: nil } } + + expect(response).to have_http_status(:unprocessable_entity) + expect(response.content_type).to include('application/json') + expect(json['errors']['nome']).to include("can't be blank") + end + end end describe "PUT #update" do @@ -76,12 +86,24 @@ it "renders a JSON response with the cliente" do cliente = create(:cliente) - put :update, params: {id: cliente.to_param, cliente: cliente.attributes} + put :update, params: {id: cliente.id, cliente: new_attributes} expect(response).to have_http_status(:ok) expect(response.content_type).to include('application/json') end end + + context "with invalid params" do + it "renders a JSON response with errors for the update cliente", :aggregate_failures do + cliente = create(:cliente) + + put :update, params: {id: cliente.id, cliente: { nome: nil }} + + expect(response).to have_http_status(:unprocessable_entity) + expect(response.content_type).to include('application/json') + # expect(json['errors']['nome']).to include("can't be blank") + end + end end describe "DELETE #destroy" do diff --git a/spec/controllers/resultados_controller_spec.rb b/spec/controllers/resultados_controller_spec.rb index 454599a..ee4dc81 100644 --- a/spec/controllers/resultados_controller_spec.rb +++ b/spec/controllers/resultados_controller_spec.rb @@ -58,6 +58,16 @@ }.to change(Resultado, :count).by(1) end end + + context "with invalid params" do + it "renders a JSON response with errors for the new resultado", :aggregate_failures do + post :create, params: { resultado: { valor_meta: nil } } + + expect(response).to have_http_status(:unprocessable_entity) + expect(response.content_type).to include('application/json') + expect(json['errors']['valor_meta']).to include("can't be blank") + end + end end describe "PUT #update" do @@ -84,6 +94,16 @@ expect(response.content_type).to include('application/json') end end + + context "with invalid params" do + it "renders a JSON response with errors for the resultado", :aggregate_failures do + put :update, params: {id: resultado.to_param, resultado: { valor_meta: nil } } + + expect(response).to have_http_status(:unprocessable_entity) + expect(response.content_type).to include('application/json') + expect(json['errors']['valor_meta']).to include("can't be blank") + end + end end describe "DELETE #destroy" do diff --git a/spec/lib/validadores_spec.rb b/spec/lib/validadores_spec.rb index 68d8b11..c2956f1 100644 --- a/spec/lib/validadores_spec.rb +++ b/spec/lib/validadores_spec.rb @@ -2,6 +2,32 @@ RSpec.describe Validadores, type: :lib do describe "Validadores" do + context "periodo" do + it "validador para o formato YYYYMM" do + periodo = Validadores.match_periodo('201912') + + expect(periodo).to eq(Date.new(2019, 12, 1)) + end + + it "validador para o formato YYYY-mm" do + periodo = Validadores.match_periodo('2019-12') + + expect(periodo).to eq(Date.new(2019, 12, 1)) + end + + it "validador para o formato DD/MM/YYYY" do + periodo = Validadores.match_periodo('12/12/2019') + + expect(periodo).to be_nil + end + + it "validador para o formato DD-MM-YYYY" do + periodo = Validadores.match_periodo('12-12-2019') + + expect(periodo).to be_nil + end + end + context "data" do it "validador data (YYYY-MM-DD)" do data = Validadores.data('2019-12-12')