diff --git a/.rubocop.yml b/.rubocop.yml index 656507a..bd33f56 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -5,10 +5,10 @@ require: AllCops: Exclude: - - "bin/**/*" - - "tmp/**/*" - - "db/**/*" - - "node_modules/**/*" + - 'bin/**/*' + - 'tmp/**/*' + - 'db/**/*' + - 'node_modules/**/*' TargetRubyVersion: 2.7 Layout/LineLength: @@ -17,6 +17,10 @@ Layout/LineLength: Metrics/MethodLength: Max: 15 +Metrics/BlockLength: + Exclude: + - 'spec/**/*.rb' + Layout/ArgumentAlignment: EnforcedStyle: with_fixed_indentation diff --git a/Gemfile b/Gemfile index 3649305..9f7f212 100644 --- a/Gemfile +++ b/Gemfile @@ -33,6 +33,7 @@ gem 'bootsnap', '>= 1.4.2', require: false group :development, :test do gem 'byebug', platforms: %i[mri mingw x64_mingw] + gem 'pry-rails' gem 'factory_bot_rails' gem 'rspec-rails', '~> 4.0' diff --git a/Gemfile.lock b/Gemfile.lock index c4ffec7..a8d3b8b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -73,6 +73,7 @@ GEM byebug (11.1.1) case_transform (0.2) activesupport + coderay (1.1.2) concurrent-ruby (1.1.6) crass (1.0.6) diff-lcs (1.3) @@ -116,6 +117,11 @@ GEM parser (2.7.0.4) ast (~> 2.4.0) pg (1.2.3) + pry (0.13.0) + coderay (~> 1.1) + method_source (~> 1.0) + pry-rails (0.3.9) + pry (>= 0.10.4) puma (4.3.3) nio4r (~> 2.0) rack (2.2.2) @@ -252,6 +258,7 @@ DEPENDENCIES jbuilder (~> 2.7) listen (>= 3.0.5, < 3.2) pg (>= 0.18, < 2.0) + pry-rails puma (~> 4.1) rails (~> 6.0.2, >= 6.0.2.2) rspec-rails (~> 4.0) diff --git a/app/controllers/api/base_controller.rb b/app/controllers/api/base_controller.rb new file mode 100644 index 0000000..d0bb8cb --- /dev/null +++ b/app/controllers/api/base_controller.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +module API + class BaseController < ApplicationController + end +end diff --git a/app/controllers/api/volunteers_controller.rb b/app/controllers/api/volunteers_controller.rb new file mode 100644 index 0000000..4692994 --- /dev/null +++ b/app/controllers/api/volunteers_controller.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +module API + class VolunteersController < ApplicationController + def create + volunteer = Volunteer.new(volunteer_params) + if volunteer.save + render json: volunteer, status: :created + else + render json: volunteer.errors, status: :unprocessable_entity + end + end + + private + + def volunteer_params + params.require(:volunteer).permit(:fullname, :email, :password, :cellphone, :province, :county, types_of_availability: []) + end + end +end diff --git a/app/serializers/volunteer_serializer.rb b/app/serializers/volunteer_serializer.rb new file mode 100644 index 0000000..bd4dd2a --- /dev/null +++ b/app/serializers/volunteer_serializer.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +class VolunteerSerializer < ApplicationSerializer + attributes :id, :fullname, :email, :cellphone, :province, :county, :types_of_availability +end diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb index aa7435f..2617c3c 100644 --- a/config/initializers/inflections.rb +++ b/config/initializers/inflections.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + # Be sure to restart your server when you modify this file. # Add new inflection rules using the following format. Inflections @@ -12,6 +13,6 @@ # end # These inflection rules are supported but not enabled by default: -# ActiveSupport::Inflector.inflections(:en) do |inflect| -# inflect.acronym 'RESTful' -# end +ActiveSupport::Inflector.inflections(:en) do |inflect| + inflect.acronym 'API' +end diff --git a/config/routes.rb b/config/routes.rb index 5e36ee8..3d4c2d5 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,6 +1,10 @@ # frozen_string_literal: true Rails.application.routes.draw do + namespace :api, defaults: { format: :json } do + resources :volunteers, only: %i[create] + end + get '*path', to: 'pages#index', constraints: ->(req) { req.path.exclude? 'storage' } root to: 'pages#index' end diff --git a/spec/requests/api/volunteers_request_spec.rb b/spec/requests/api/volunteers_request_spec.rb new file mode 100644 index 0000000..5218f7d --- /dev/null +++ b/spec/requests/api/volunteers_request_spec.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'API::Volunteers', type: :request do + let(:headers) { { 'ACCEPT' => 'application/json' } } + + describe 'POST /api/volunteers' do + before do + post '/api/volunteers', params: params, headers: headers + end + + context 'with invalid params' do + let(:params) { { volunteer: { fullname: '' } } } + + it { expect(response.content_type).to eq('application/json; charset=utf-8') } + it { expect(response).to have_http_status(:unprocessable_entity) } + + it { expect(response.parsed_body['fullname']).to eq(["can't be blank"]) } + it { expect(response.parsed_body['email']).to eq(["can't be blank"]) } + it { expect(response.parsed_body['password']).to eq(["can't be blank"]) } + it { expect(response.parsed_body['cellphone']).to eq(["can't be blank"]) } + it { expect(response.parsed_body['province']).to eq(["can't be blank"]) } + it { expect(response.parsed_body['county']).to eq(["can't be blank"]) } + end + + context 'with valid params' do + let(:params) do + { + volunteer: { + fullname: 'John Doe', + email: 'john.doe@example.com', + password: 'secret$123', + cellphone: '924123456', + province: 'Luanda', + county: 'Belas', + types_of_availability: %w[donation_food_clothes psychological_support] + } + } + end + + it { expect(response.content_type).to eq('application/json; charset=utf-8') } + it { expect(response).to have_http_status(:created) } + + it { expect(response.parsed_body['fullname']).to eq('John Doe') } + it { expect(response.parsed_body['email']).to eq('john.doe@example.com') } + it { expect(response.parsed_body['cellphone']).to eq('924123456') } + it { expect(response.parsed_body['province']).to eq('Luanda') } + it { expect(response.parsed_body['county']).to eq('Belas') } + it { expect(response.parsed_body['types_of_availability']).to eq(%w[donation_food_clothes psychological_support]) } + end + end +end