From a698ed0549ac5be85522f44c4f8ac15a5f3d33e9 Mon Sep 17 00:00:00 2001 From: Joao Gilberto Saraiva Date: Sat, 23 Dec 2023 15:07:06 -0300 Subject: [PATCH 01/11] remove: tests dir --- test/application_system_test_case.rb | 7 ------- .../application_cable/connection_test.rb | 15 --------------- test/controllers/.keep | 0 test/fixtures/files/.keep | 0 test/helpers/.keep | 0 test/integration/.keep | 0 test/mailers/.keep | 0 test/models/.keep | 0 test/system/.keep | 0 test/test_helper.rb | 17 ----------------- 10 files changed, 39 deletions(-) delete mode 100644 test/application_system_test_case.rb delete mode 100644 test/channels/application_cable/connection_test.rb delete mode 100644 test/controllers/.keep delete mode 100644 test/fixtures/files/.keep delete mode 100644 test/helpers/.keep delete mode 100644 test/integration/.keep delete mode 100644 test/mailers/.keep delete mode 100644 test/models/.keep delete mode 100644 test/system/.keep delete mode 100644 test/test_helper.rb diff --git a/test/application_system_test_case.rb b/test/application_system_test_case.rb deleted file mode 100644 index 652febb..0000000 --- a/test/application_system_test_case.rb +++ /dev/null @@ -1,7 +0,0 @@ -# frozen_string_literal: true - -require 'test_helper' - -class ApplicationSystemTestCase < ActionDispatch::SystemTestCase - driven_by :selenium, using: :chrome, screen_size: [1400, 1400] -end diff --git a/test/channels/application_cable/connection_test.rb b/test/channels/application_cable/connection_test.rb deleted file mode 100644 index 4aee9b3..0000000 --- a/test/channels/application_cable/connection_test.rb +++ /dev/null @@ -1,15 +0,0 @@ -# frozen_string_literal: true - -require 'test_helper' - -module ApplicationCable - class ConnectionTest < ActionCable::Connection::TestCase - # test "connects with cookies" do - # cookies.signed[:user_id] = 42 - # - # connect - # - # assert_equal connection.user_id, "42" - # end - end -end diff --git a/test/controllers/.keep b/test/controllers/.keep deleted file mode 100644 index e69de29..0000000 diff --git a/test/fixtures/files/.keep b/test/fixtures/files/.keep deleted file mode 100644 index e69de29..0000000 diff --git a/test/helpers/.keep b/test/helpers/.keep deleted file mode 100644 index e69de29..0000000 diff --git a/test/integration/.keep b/test/integration/.keep deleted file mode 100644 index e69de29..0000000 diff --git a/test/mailers/.keep b/test/mailers/.keep deleted file mode 100644 index e69de29..0000000 diff --git a/test/models/.keep b/test/models/.keep deleted file mode 100644 index e69de29..0000000 diff --git a/test/system/.keep b/test/system/.keep deleted file mode 100644 index e69de29..0000000 diff --git a/test/test_helper.rb b/test/test_helper.rb deleted file mode 100644 index 0c92e8e..0000000 --- a/test/test_helper.rb +++ /dev/null @@ -1,17 +0,0 @@ -# frozen_string_literal: true - -ENV['RAILS_ENV'] ||= 'test' -require_relative '../config/environment' -require 'rails/test_help' - -module ActiveSupport - class TestCase - # Run tests in parallel with specified workers - parallelize(workers: :number_of_processors) - - # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order. - fixtures :all - - # Add more helper methods to be used by all tests here... - end -end From 6f3247da5b04a9a3c7dd5aa0815d0a75962fd08a Mon Sep 17 00:00:00 2001 From: Joao Gilberto Saraiva Date: Sat, 23 Dec 2023 17:50:59 -0300 Subject: [PATCH 02/11] create: scopes tests --- app/assets/builds/application.css | 1 + app/models/job.rb | 2 +- app/models/proposal_comment.rb | 1 - app/models/user.rb | 1 - spec/models/application_to_job_spec.rb | 6 -- spec/models/apply_spec.rb | 23 +++++ spec/models/comment_spec.rb | 17 ++++ spec/models/job_spec.rb | 122 ++++++++++++++++++++++--- spec/models/profile_spec.rb | 27 ++++-- spec/models/proposal_comment_spec.rb | 30 +++++- spec/models/proposal_spec.rb | 16 ++++ spec/models/star_spec.rb | 28 ++++++ 12 files changed, 243 insertions(+), 31 deletions(-) create mode 100644 app/assets/builds/application.css delete mode 100644 spec/models/application_to_job_spec.rb diff --git a/app/assets/builds/application.css b/app/assets/builds/application.css new file mode 100644 index 0000000..d44e99a --- /dev/null +++ b/app/assets/builds/application.css @@ -0,0 +1 @@ +/*! tailwindcss v3.4.0 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder, textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]{display:none}*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgb(59 130 246/0.5);--tw-ring-offset-shadow:0 0 transparent;--tw-ring-shadow:0 0 transparent;--tw-shadow:0 0 transparent;--tw-shadow-colored:0 0 transparent;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgb(59 130 246/0.5);--tw-ring-offset-shadow:0 0 transparent;--tw-ring-shadow:0 0 transparent;--tw-shadow:0 0 transparent;--tw-shadow-colored:0 0 transparent;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.inline{display:inline} \ No newline at end of file diff --git a/app/models/job.rb b/app/models/job.rb index 819caed..aec4436 100644 --- a/app/models/job.rb +++ b/app/models/job.rb @@ -7,7 +7,7 @@ class Job < ApplicationRecord has_many :users, through: :applies validates :title, :description, :skills, :salary, :company, :level, :country, :city, :date, presence: true validates :salary, numericality: { only_decimal: true } - validates :code, uniqueness: true + validates :code, uniqueness: true, length: { is: 8 } validate :job_date_is_future before_validation :generate_code, on: :create diff --git a/app/models/proposal_comment.rb b/app/models/proposal_comment.rb index 3c5c8d0..268365f 100644 --- a/app/models/proposal_comment.rb +++ b/app/models/proposal_comment.rb @@ -6,6 +6,5 @@ class ProposalComment < ApplicationRecord validates :body, :proposal_id, presence: true scope :by_proposal_id, ->(proposal_id) { where(proposal_id: proposal_id) } - scope :by_author, ->(author_type, author_id) { where(author_type: author_type, author_id: author_id) } end diff --git a/app/models/user.rb b/app/models/user.rb index e9230db..c40b7a7 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -10,5 +10,4 @@ class User < ApplicationRecord has_many :applies has_many :jobs, through: :applies has_many :proposal_comments, as: :author - # has_many :feedbacks, through: :applies end diff --git a/spec/models/application_to_job_spec.rb b/spec/models/application_to_job_spec.rb deleted file mode 100644 index 8060c28..0000000 --- a/spec/models/application_to_job_spec.rb +++ /dev/null @@ -1,6 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -RSpec.describe ApplicationJob, type: :model do -end diff --git a/spec/models/apply_spec.rb b/spec/models/apply_spec.rb index 9f085c3..0db920b 100644 --- a/spec/models/apply_spec.rb +++ b/spec/models/apply_spec.rb @@ -3,4 +3,27 @@ require 'rails_helper' RSpec.describe Apply, type: :model do + describe 'scopes' do + describe '.sorted_id' do + it 'orders the applies by id' do + apply1 = create(:apply) + apply2 = create(:apply) + apply3 = create(:apply) + + expect(Apply.sorted_id).to eq([apply1, apply2, apply3]) + end + end + + describe '.applied_by_user' do + let(:job) { create(:job) } + let(:user) { create(:user) } + + it 'returns the applies applied by the specified user for the specified job' do + apply1 = create(:apply, job: job, user: user) + create(:apply) + + expect(Apply.applied_by_user(job.id, user.id)).to eq([apply1]) + end + end + end end diff --git a/spec/models/comment_spec.rb b/spec/models/comment_spec.rb index da09307..2862355 100644 --- a/spec/models/comment_spec.rb +++ b/spec/models/comment_spec.rb @@ -4,4 +4,21 @@ RSpec.describe Comment, type: :model do it { should validate_presence_of(:body) } + + describe 'scope comments_by_headhunter' do + let(:headhunter) { create(:headhunter) } + let(:profile) { create(:profile) } + + before do + create(:comment, headhunter: headhunter, profile: profile) + create(:comment, headhunter: headhunter, profile: profile) + create(:comment, headhunter: headhunter) + end + + it 'returns comments by the specified headhunter and profile' do + comments = Comment.comments_by_headhunter(headhunter, profile) + expect(comments.count).to eq(2) + expect(comments).to all(have_attributes(headhunter: headhunter, profile: profile)) + end + end end diff --git a/spec/models/job_spec.rb b/spec/models/job_spec.rb index ee2c8a5..715ae5b 100644 --- a/spec/models/job_spec.rb +++ b/spec/models/job_spec.rb @@ -18,45 +18,141 @@ let(:country) { build(:country) } let(:company) { build(:company) } - let(:job) { build(:job) } let(:apply) { build(:apply) } + describe 'scopes' do + describe '.search' do + it 'returns jobs with matching title' do + job = create(:job, title: 'Ruby Developer') + create(:job, title: 'Python Developer') + create(:job, title: 'Java Developer') + + expect(Job.search('Ruby')).to contain_exactly(job) + end + + it 'returns empty array if no matching jobs' do + create(:job, title: 'Ruby Developer') + create(:job, title: 'Python Developer') + create(:job, title: 'Java Developer') + + expect(Job.search('PHP')).to be_empty + end + + it 'returns all jobs if search term is blank' do + job1 = create(:job, title: 'Ruby Developer') + job2 = create(:job, title: 'Python Developer') + job3 = create(:job, title: 'Java Developer') + + expect(Job.search('')).to contain_exactly(job1, job2, job3) + end + end + + describe '.sorted_id' do + it 'returns jobs sorted by id in ascending order' do + job1 = create(:job) + job2 = create(:job) + job3 = create(:job) + + expect(Job.sorted_id).to eq([job1, job2, job3]) + end + end + + describe '.indexed' do + it 'returns jobs with the specified job_status' do + job1 = create(:job, job_status: :draft) + job2 = create(:job, job_status: :published) + job3 = create(:job, job_status: :archived) + + expect(Job.indexed(:draft)).to contain_exactly(job1) + expect(Job.indexed(:published)).to contain_exactly(job2) + expect(Job.indexed(:archived)).to contain_exactly(job3) + end + end + + describe '.search_web' do + it 'returns jobs with matching code' do + allow(SecureRandom).to receive(:alphanumeric).and_return('ABC12345') + job1 = create(:job) + allow(SecureRandom).to receive(:alphanumeric).and_return('DEF67890') + create(:job) + + expect(Job.search_web('ABC')).to contain_exactly(job1) + end + + it 'returns jobs with matching title' do + job1 = create(:job, title: 'Ruby Developer') + create(:job, title: 'Python Developer') + create(:job, title: 'Java Developer') + + expect(Job.search_web('Ruby')).to contain_exactly(job1) + end + + it 'returns jobs with matching description' do + job1 = create(:job, description: 'Ruby on Rails Developer') + create(:job, description: 'Python Developer') + create(:job, description: 'Java Developer') + + expect(Job.search_web('Rails')).to contain_exactly(job1) + end + + it 'returns jobs with matching title or description' do + job1 = create(:job, title: 'Ruby Developer', description: 'Ruby on Rails Developer') + job2 = create(:job, title: 'Python Developer', description: 'Django Developer') + job3 = create(:job, title: 'Java Developer', description: 'Spring Developer') + + expect(Job.search_web('Developer')).to contain_exactly(job1, job2, job3) + end + + it 'returns empty array if no matching jobs' do + create(:job, code: 'ABC123', title: 'Ruby Developer') + create(:job, code: 'DEF456', title: 'Python Developer') + create(:job, code: 'GHI789', title: 'Java Developer') + + expect(Job.search_web('PHP')).to be_empty + end + + it 'returns all jobs if search term is blank' do + job1 = create(:job, code: 'ABC123', title: 'Ruby Developer') + job2 = create(:job, code: 'DEF456', title: 'Python Developer') + job3 = create(:job, code: 'GHI789', title: 'Java Developer') + + expect(Job.search_web('')).to contain_exactly(job1, job2, job3) + end + end + end + describe 'generate a code' do + let(:job) { build(:job) } + it 'when create a job with sucess' do expect(job.code.length).to eq 8 end it 'and it should be is uniqueness' do allow(SecureRandom).to receive(:alphanumeric).and_return('12345678') - Job.create!(title: job.title, description: 'Lorem ipsum dolor sit amet', - skills: 'Nam mattis, felis ut adipiscing.', salary: '99', - company: company, level: 0, country: country, city: 'Test', - date: 1.month.from_now) - job2 = Job.new(title: 'Test 2', description: 'Dolor sit amet', - skills: 'Nam mattis.', salary: '299', - company: company, level: 1, country: country, city: 'Test', - date: 1.month.from_now) - expect(job2.valid?).to eq false + create(:job) + job = build(:job) + expect(job.valid?).to eq false end end describe 'date' do it "can't be in past" do - job = Job.new(date: 10.day.ago) + job = build(:job, date: 10.day.ago) job.valid? expect(job.errors.include?(:date)).to be true expect(job.errors[:date]).to include(" date can't be in past or today.") end it "can't be today" do - job = Job.new(date: Date.today) + job = build(:job, date: Date.today) job.valid? expect(job.errors.include?(:date)).to be true expect(job.errors[:date]).to include(" date can't be in past or today.") end it 'must be in future' do - job = Job.new(date: 1.day.from_now) + job = build(:job, date: 1.day.from_now) job.valid? expect(job.errors.include?(:date)).to be false end diff --git a/spec/models/profile_spec.rb b/spec/models/profile_spec.rb index ceed173..89a8ede 100644 --- a/spec/models/profile_spec.rb +++ b/spec/models/profile_spec.rb @@ -10,21 +10,32 @@ it { should validate_presence_of(:country_id) } it { should validate_presence_of(:user_id) } + describe 'scopes' do + describe '.find_by_user_id' do + let!(:profile1) { create(:profile) } + let!(:profile2) { create(:profile) } + + it 'returns profile with matching user_id' do + expect(Profile.find_by_user_id(profile1.user_id)).to contain_exactly(profile1) + end + + it 'does not return profile with non-matching user_id' do + expect(Profile.find_by_user_id(9_999_999_999)).to be_empty + end + end + end + context 'Custom validation of' do let(:profile) { create(:profile) } - it 'user_id is uniquess' do - profile2 = Profile.new(name: 'Teste', social_name: 'Just a test 2', birthdate: '21/03/1977', - educacional_background: 'Test 3', experience: 'Test 4', - user_id: profile.user_id, country: profile.country) + it 'user_id is uniqueness' do + profile2 = build(:profile, user_id: profile.user_id) profile2.valid? expect(profile2.errors.include?(:user_id)).to be true end - it 'birthdate meet legal age' do - profile2 = Profile.new(name: 'Teste', social_name: 'Just a test 2', birthdate: 17.years.ago, - educacional_background: 'Test 3', experience: 'Test 4', - user_id: profile.user_id, country: profile.country) + it 'birthdate meets legal age' do + profile2 = build(:profile, birthdate: 17.years.ago) profile2.valid? expect(profile2.errors.include?(:birthdate)).to be true end diff --git a/spec/models/proposal_comment_spec.rb b/spec/models/proposal_comment_spec.rb index 1b1ee23..376b207 100644 --- a/spec/models/proposal_comment_spec.rb +++ b/spec/models/proposal_comment_spec.rb @@ -3,5 +3,33 @@ require 'rails_helper' RSpec.describe ProposalComment, type: :model do - it { should validate_presence_of(:body) } + describe 'scopes' do + describe '.by_proposal_id' do + subject { ProposalComment.by_proposal_id(proposal1.id) } + + let!(:proposal1) { create(:proposal) } + let!(:proposal2) { create(:proposal) } + let!(:proposal_comment1) { create(:proposal_comment, proposal_id: proposal1.id) } + let!(:proposal_comment2) { create(:proposal_comment, proposal_id: proposal2.id) } + + it 'returns proposal comments with the given proposal_id' do + expect(subject).to include(proposal_comment1) + expect(subject).not_to include(proposal_comment2) + end + end + + describe '.by_author' do + subject { ProposalComment.by_author('Headhunter', author1.id) } + + let!(:author1) { create(:headhunter) } + let!(:author2) { create(:headhunter) } + let!(:proposal_comment1) { create(:proposal_comment, author_type: 'Headhunter', author_id: author1.id) } + let!(:proposal_comment2) { create(:proposal_comment, author_type: 'Headhunter', author_id: author2.id) } + + it 'returns proposal comments with the given author_type and author_id' do + expect(subject).to include(proposal_comment1) + expect(subject).not_to include(proposal_comment2) + end + end + end end diff --git a/spec/models/proposal_spec.rb b/spec/models/proposal_spec.rb index cd7f6c5..5ff2c49 100644 --- a/spec/models/proposal_spec.rb +++ b/spec/models/proposal_spec.rb @@ -49,4 +49,20 @@ expect(proposal.errors.include?(:expected_start)).to be false end end + + describe 'scopes' do + describe '.by_apply_id' do + let!(:apply) { create(:apply) } + + subject { Proposal.by_apply_id(apply.id) } + + it 'returns proposals with matching apply_id' do + proposal1 = create(:proposal, apply_id: apply.id) + proposal2 = create(:proposal) + + expect(subject).to include(proposal1) + expect(subject).not_to include(proposal2) + end + end + end end diff --git a/spec/models/star_spec.rb b/spec/models/star_spec.rb index a320c06..cf5d9f8 100644 --- a/spec/models/star_spec.rb +++ b/spec/models/star_spec.rb @@ -3,4 +3,32 @@ require 'rails_helper' RSpec.describe Star, type: :model do + describe 'scopes' do + let(:headhunter) { create(:headhunter) } + let(:apply) { create(:apply) } + + describe '.filtered_by_ids' do + subject { Star.filtered_by_ids(headhunter.id, apply.id) } + + it 'returns stars filtered by headhunter_id and apply_id' do + star1 = create(:star, headhunter: headhunter, apply: apply) + star2 = create(:star, headhunter: headhunter) + expect(subject).to eq([star1]) + expect(subject).not_to eq([star2]) + end + end + + describe '.filtered_by_headhunter' do + subject { Star.filtered_by_headhunter(headhunter.id) } + + it 'returns only stars filtered by headhunter_id' do + star1 = create(:star, headhunter: headhunter) + star2 = create(:star, headhunter: headhunter) + star3 = create(:star) + expect(subject).to include(star1) + expect(subject).to include(star2) + expect(subject).not_to include(star3) + end + end + end end From 6e458342a83a0e72caae1b549e5463fce1b0d42f Mon Sep 17 00:00:00 2001 From: Joao Gilberto Saraiva Date: Sat, 23 Dec 2023 20:27:31 -0300 Subject: [PATCH 03/11] create: routing tests --- app/controllers/api/v1/applies_controller.rb | 8 --- config/routes.rb | 4 +- spec/requests/apis/apply_api_spec.rb | 57 +++++--------------- spec/requests/apis/jobs_api_spec.rb | 32 +++++------ spec/requests/apis/profiles_api_spec.rb | 18 ------- spec/routing/apply_routing_spec.rb | 18 +++++++ spec/routing/job_routing_spec.rb | 12 +++++ spec/routing/profile_routing_spec.rb | 12 +++++ 8 files changed, 74 insertions(+), 87 deletions(-) create mode 100644 spec/routing/apply_routing_spec.rb create mode 100644 spec/routing/job_routing_spec.rb create mode 100644 spec/routing/profile_routing_spec.rb diff --git a/app/controllers/api/v1/applies_controller.rb b/app/controllers/api/v1/applies_controller.rb index c04fad0..0491815 100644 --- a/app/controllers/api/v1/applies_controller.rb +++ b/app/controllers/api/v1/applies_controller.rb @@ -28,14 +28,6 @@ def create end end - def update - if @apply.update(apply_update_params) - render status: 200, json: @apply - else - render status: 412, json: { errors: @apply.errors.full_messages } - end - end - def destroy if @apply.destroy render status: 200, json: {} diff --git a/config/routes.rb b/config/routes.rb index 488f301..812d909 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -30,9 +30,9 @@ namespace :api, defaults: { format: :json } do namespace :v1 do resources :jobs, only: %i[show index create update destroy] do - resources :applies, only: %i[show index create update destroy] + resources :applies, only: %i[show index create destroy] end - resources :profiles, only: %i[show index create update destroy] + resources :profiles, only: %i[show index create update] end end diff --git a/spec/requests/apis/apply_api_spec.rb b/spec/requests/apis/apply_api_spec.rb index d1aa585..b4d1c24 100644 --- a/spec/requests/apis/apply_api_spec.rb +++ b/spec/requests/apis/apply_api_spec.rb @@ -3,6 +3,8 @@ require 'rails_helper' describe 'Apply API' do + subject { JSON.parse(response.body) } + let(:job) { create(:job) } context 'GET /api/v1/jobs/1/applies/1' do @@ -14,13 +16,11 @@ expect(response.status).to eq 200 expect(response.content_type).to eq('application/json; charset=utf-8') - json_response = JSON.parse(response.body) - - expect(json_response['user_id']).to eq(apply.user_id) - expect(json_response['job_id']).to eq(job.id) - expect(json_response['feedback_headhunter']).to include(apply.feedback_headhunter) - expect(json_response.keys).not_to include('created_at') - expect(json_response.keys).not_to include('updated_at') + expect(subject['user_id']).to eq(apply.user_id) + expect(subject['job_id']).to eq(job.id) + expect(subject['feedback_headhunter']).to include(apply.feedback_headhunter) + expect(subject.keys).not_to include('created_at') + expect(subject.keys).not_to include('updated_at') end it "and fail because can't find the job" do @@ -39,11 +39,9 @@ expect(response.status).to eq 200 expect(response.content_type).to eq('application/json; charset=utf-8') - json_response = JSON.parse(response.body) - - expect(json_response.length).to eq 2 - expect(json_response.first['user_id']).to eq(apply1.user_id) - expect(json_response.last['user_id']).to eq(apply2.user_id) + expect(subject.length).to eq 2 + expect(subject.first['user_id']).to eq(apply1.user_id) + expect(subject.last['user_id']).to eq(apply2.user_id) end it "return empty - there aren't applies" do @@ -52,8 +50,7 @@ expect(response.status).to eq 200 expect(response.content_type).to eq('application/json; charset=utf-8') - json_response = JSON.parse(response.body) - expect(json_response).to eq [] + expect(subject).to eq [] end it 'without sucess - internal error' do @@ -77,11 +74,9 @@ expect(response).to have_http_status(201) expect(response.content_type).to eq('application/json; charset=utf-8') - json_response = JSON.parse(response.body) - - expect(json_response['user_id']).to eq(user.id) - expect(json_response['job_id']).to eq(job.id) - expect(json_response['feedback_headhunter']).to include('test') + expect(subject['user_id']).to eq(user.id) + expect(subject['job_id']).to eq(job.id) + expect(subject['feedback_headhunter']).to include('test') end it 'without sucess - imcomplete parameters' do @@ -107,30 +102,6 @@ end end - context 'PUT /api/v1/jobs/1' do - let(:apply) { create(:apply) } - - it 'with sucess' do - apply_params = { apply: { feedback_headhunter: 'test' } } - put "/api/v1/jobs/#{job.id}/applies/#{apply.id}", params: apply_params - - expect(response).to have_http_status(200) - expect(response.body).to include('test') - expect(response.content_type).to eq('application/json; charset=utf-8') - end - - it 'without sucess when try change user_id or job_id' do - apply_params = { apply: { user_id: 999_999, job_id: 999_999 } } - put "/api/v1/jobs/#{job.id}/applies/#{apply.id}", params: apply_params - - expect(response.content_type).to eq('application/json; charset=utf-8') - - json_response = JSON.parse(response.body) - expect(json_response['user_id']).to eq(apply.user_id) - expect(json_response['job_id']).to eq(apply.job_id) - end - end - context 'DELETE /api/v1/jobs/1' do let(:apply) { create(:apply) } diff --git a/spec/requests/apis/jobs_api_spec.rb b/spec/requests/apis/jobs_api_spec.rb index 81d4984..dcc961d 100644 --- a/spec/requests/apis/jobs_api_spec.rb +++ b/spec/requests/apis/jobs_api_spec.rb @@ -12,6 +12,8 @@ end context 'GET /api/v1/jobs/1' do + subject { JSON.parse(response.body) } + it 'with sucess' do job = create(:job) @@ -20,12 +22,10 @@ expect(response.status).to eq 200 expect(response.content_type).to eq('application/json; charset=utf-8') - json_response = JSON.parse(response.body) - - expect(json_response['title']).to include(job.title) - expect(json_response['description']).to include(job.description) - expect(json_response.keys).not_to include('created_at') - expect(json_response.keys).not_to include('updated_at') + expect(subject['title']).to include(job.title) + expect(subject['description']).to include(job.description) + expect(subject.keys).not_to include('created_at') + expect(subject.keys).not_to include('updated_at') end it "and fail because can't find the job" do @@ -86,6 +86,8 @@ end context 'POST /api/v1/jobs/1' do + subject { JSON.parse(response.body) } + let(:country) { create(:country) } let(:company) { create(:company) } @@ -99,16 +101,14 @@ expect(response).to have_http_status(201) expect(response.content_type).to eq('application/json; charset=utf-8') - json_response = JSON.parse(response.body) - - expect(json_response['title']).to include('Job Opening Test 123') - expect(json_response['description']).to include('Lorem ipsum dolor sit amet') - expect(json_response['skills']).to include('Nam mattis, felis ut adipiscing.') - expect(json_response['salary']).to eq('99.0') - expect(json_response['company_id']).to eq(company.id) - expect(json_response['level']).to include('junior') - expect(json_response['country_id']).to eq(country.id) - expect(json_response['city']).to include('Remote Job') + expect(subject['title']).to include('Job Opening Test 123') + expect(subject['description']).to include('Lorem ipsum dolor sit amet') + expect(subject['skills']).to include('Nam mattis, felis ut adipiscing.') + expect(subject['salary']).to eq('99.0') + expect(subject['company_id']).to eq(company.id) + expect(subject['level']).to include('junior') + expect(subject['country_id']).to eq(country.id) + expect(subject['city']).to include('Remote Job') end it 'without sucess - imcomplete parameters' do diff --git a/spec/requests/apis/profiles_api_spec.rb b/spec/requests/apis/profiles_api_spec.rb index c6c70d4..14f681a 100644 --- a/spec/requests/apis/profiles_api_spec.rb +++ b/spec/requests/apis/profiles_api_spec.rb @@ -163,22 +163,4 @@ expect(response.body).to include('Usuário não pode ficar em branco') end end - - context 'DELETE /api/v1/profiles/1' do - let(:profile) { create(:profile) } - - it 'with sucess' do - delete "/api/v1/profiles/#{profile.id}" - - expect(response.status).to eq 200 - expect(response.content_type).to eq('application/json; charset=utf-8') - end - - it 'without sucess - no profile' do - delete '/api/v1/profiles/999999' - - expect(response.status).to eq 404 - expect(response.content_type).to eq('application/json; charset=utf-8') - end - end end diff --git a/spec/routing/apply_routing_spec.rb b/spec/routing/apply_routing_spec.rb new file mode 100644 index 0000000..c98f9c5 --- /dev/null +++ b/spec/routing/apply_routing_spec.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe Api::V1::AppliesController, type: :routing do + it { should route(:get, '/api/v1/jobs/1/applies').to('api/v1/applies#index', job_id: 1, format: :json) } + it { should route(:get, '/api/v1/jobs/1/applies/1').to('api/v1/applies#show', id: '1', job_id: 1, format: :json) } + it { should route(:post, '/api/v1/jobs/1/applies').to('api/v1/applies#create', job_id: 1, format: :json) } + it { + should_not route(:put, '/api/v1/jobs/1/applies/1').to('api/v1/applies#update', id: '1', job_id: 1, format: :json) + } + it { + should_not route(:patch, '/api/jobs/1/v1/applies/1').to('api/v1/applies#update', id: '1', job_id: 1, format: :json) + } + it { + should route(:delete, '/api/v1/jobs/1/applies/1').to('api/v1/applies#destroy', id: '1', job_id: 1, format: :json) + } +end diff --git a/spec/routing/job_routing_spec.rb b/spec/routing/job_routing_spec.rb new file mode 100644 index 0000000..74524af --- /dev/null +++ b/spec/routing/job_routing_spec.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe Api::V1::JobsController, type: :routing do + it { should route(:get, '/api/v1/jobs').to('api/v1/jobs#index', format: :json) } + it { should route(:get, '/api/v1/jobs/1').to('api/v1/jobs#show', id: '1', format: :json) } + it { should route(:post, '/api/v1/jobs').to('api/v1/jobs#create', format: :json) } + it { should route(:put, '/api/v1/jobs/1').to('api/v1/jobs#update', id: '1', format: :json) } + it { should route(:patch, '/api/v1/jobs/1').to('api/v1/jobs#update', id: '1', format: :json) } + it { should route(:delete, '/api/v1/jobs/1').to('api/v1/jobs#destroy', id: '1', format: :json) } +end diff --git a/spec/routing/profile_routing_spec.rb b/spec/routing/profile_routing_spec.rb new file mode 100644 index 0000000..7e510a8 --- /dev/null +++ b/spec/routing/profile_routing_spec.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe Api::V1::ProfilesController, type: :routing do + it { should route(:get, '/api/v1/profiles').to('api/v1/profiles#index', format: :json) } + it { should route(:get, '/api/v1/profiles/1').to('api/v1/profiles#show', id: '1', format: :json) } + it { should route(:post, '/api/v1/profiles').to('api/v1/profiles#create', format: :json) } + it { should route(:put, '/api/v1/profiles/1').to('api/v1/profiles#update', id: '1', format: :json) } + it { should route(:patch, '/api/v1/profiles/1').to('api/v1/profiles#update', id: '1', format: :json) } + it { should_not route(:delete, '/api/v1/profiles/1').to('api/v1/profiles#destroy', id: '1', format: :json) } +end From 75b574c2301b2faeb4dd0322cead922bb318ddde Mon Sep 17 00:00:00 2001 From: Joao Gilberto Saraiva Date: Sun, 24 Dec 2023 14:27:36 -0300 Subject: [PATCH 04/11] refactor: search using title --- app/controllers/api/v1/jobs_controller.rb | 2 +- app/models/job.rb | 2 +- spec/rails_helper.rb | 3 ++- spec/requests/apis/jobs_api_spec.rb | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/app/controllers/api/v1/jobs_controller.rb b/app/controllers/api/v1/jobs_controller.rb index ecbafd8..14a9beb 100644 --- a/app/controllers/api/v1/jobs_controller.rb +++ b/app/controllers/api/v1/jobs_controller.rb @@ -14,7 +14,7 @@ def show end def index - @jobs = Job.search(params[:term]).sorted_id + @jobs = Job.search(params[:title]).sorted_id render status: 200, json: @jobs end diff --git a/app/models/job.rb b/app/models/job.rb index aec4436..36b678e 100644 --- a/app/models/job.rb +++ b/app/models/job.rb @@ -16,7 +16,7 @@ class Job < ApplicationRecord enum job_status: { draft: 0, published: 1, archived: 9 } enum level: { junior: 0, mid_level: 1, senior: 7, specialist: 9 } - scope :search, ->(term) { where('LOWER(title) LIKE ?', "%#{term.downcase}%") if term.present? } + scope :search, ->(title) { where('LOWER(title) LIKE ?', "%#{title.downcase}%") if title.present? } scope :sorted_id, -> { order(:id) } scope :indexed, ->(status) { where(job_status: status).sorted_id } scope :search_web, lambda { |term| diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index fbdad52..59a68e8 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -11,11 +11,12 @@ SimpleCov.start do add_group 'Config', 'config' + add_group 'Models', 'app/models' add_group 'Controllers', 'app/controllers' add_group 'API', 'app/controllers/api' add_group 'Helpers', 'app/helpers' add_group 'Jobs', 'app/jobs' - add_group 'Models', 'app/models' + add_group 'Specs', 'spec' end ENV['RAILS_ENV'] ||= 'test' diff --git a/spec/requests/apis/jobs_api_spec.rb b/spec/requests/apis/jobs_api_spec.rb index dcc961d..f4e47ef 100644 --- a/spec/requests/apis/jobs_api_spec.rb +++ b/spec/requests/apis/jobs_api_spec.rb @@ -52,7 +52,7 @@ end it 'with sucess - using search' do - get '/api/v1/jobs?term=123', headers: valid_headers, as: :json + get '/api/v1/jobs?title=123', headers: valid_headers, as: :json expect(response.status).to eq 200 expect(response.content_type).to eq('application/json; charset=utf-8') From e920477c9736621f1185fe036a261d05d523b062 Mon Sep 17 00:00:00 2001 From: Joao Gilberto Saraiva Date: Mon, 25 Dec 2023 17:29:30 -0300 Subject: [PATCH 05/11] refactor: move test params to let --- .../apis/access_without_autorization.rb | 12 +- spec/requests/apis/jobs_api_spec.rb | 115 ++++++++++-------- 2 files changed, 67 insertions(+), 60 deletions(-) diff --git a/spec/requests/apis/access_without_autorization.rb b/spec/requests/apis/access_without_autorization.rb index 64a79e0..b652cb9 100644 --- a/spec/requests/apis/access_without_autorization.rb +++ b/spec/requests/apis/access_without_autorization.rb @@ -4,15 +4,14 @@ describe 'API' do context 'Try a route' do + subject { JSON.parse(response.body) } + it 'without an authorization' do get '/api/v1/jobs' expect(response.status).to eq 401 expect(response.content_type).to eq('application/json; charset=utf-8') - - json_response = JSON.parse(response.body) - - expect(json_response).to include('errors' => 'Provide an valid Authorization header.') + expect(subject).to include('errors' => 'Provide an valid Authorization header.') end it 'without a valid authorization' do @@ -20,10 +19,7 @@ expect(response.status).to eq 401 expect(response.content_type).to eq('application/json; charset=utf-8') - - json_response = JSON.parse(response.body) - - expect(json_response).to include('errors' => 'Provide an valid Authorization header.') + expect(subject).to include('errors' => 'Provide an valid Authorization header.') end end end diff --git a/spec/requests/apis/jobs_api_spec.rb b/spec/requests/apis/jobs_api_spec.rb index f4e47ef..b47c093 100644 --- a/spec/requests/apis/jobs_api_spec.rb +++ b/spec/requests/apis/jobs_api_spec.rb @@ -2,7 +2,9 @@ require 'rails_helper' -describe 'Job API' do +RSpec.describe 'Job API', type: :request do + subject { JSON.parse(response.body) } + let(:valid_headers) do { Authorization: '0123456789' } end @@ -10,14 +12,26 @@ let(:invalid_headers) do { Authorization: '' } end + let(:country) { create(:country) } + let(:company) { create(:company) } + let(:job_attributes_valid) do + { job: { title: 'Job Opening Test 123', description: 'Lorem ipsum dolor sit amet', + skills: 'Nam mattis, felis ut adipiscing.', salary: '99', company_id: company.id.to_s, + level: :junior, country_id: country.id.to_s, city: 'Remote Job', + date: 1.month.from_now } } + end + let(:job_attributes_invalid) do + { job: { title: 'Job Opening Test 123', description: 'Lorem ipsum dolor sit amet', + skills: '', salary: '', company_id: '', + level: '', country_id: '', city: '', + date: '' } } + end context 'GET /api/v1/jobs/1' do - subject { JSON.parse(response.body) } - it 'with sucess' do job = create(:job) - get "/api/v1/jobs/#{job.id}", headers: valid_headers, as: :json + get api_v1_job_path(job.id), headers: valid_headers, as: :json expect(response.status).to eq 200 expect(response.content_type).to eq('application/json; charset=utf-8') @@ -29,7 +43,7 @@ end it "and fail because can't find the job" do - get '/api/v1/jobs/99999999', headers: valid_headers, as: :json + get api_v1_job_path(99_999_999), headers: valid_headers, as: :json expect(response.status).to eq 404 end end @@ -39,16 +53,14 @@ let!(:job2) { create(:job, title: 'Job Opening Test 456') } it 'with sucess' do - get '/api/v1/jobs/', headers: valid_headers, as: :json + get api_v1_jobs_path, headers: valid_headers, as: :json expect(response.status).to eq 200 expect(response.content_type).to eq('application/json; charset=utf-8') - json_response = JSON.parse(response.body) - - expect(json_response.length).to eq 2 - expect(json_response.first['title']).to eq(job1.title) - expect(json_response.last['title']).to eq(job2.title) + expect(subject.length).to eq 2 + expect(subject.first['title']).to eq(job1.title) + expect(subject.last['title']).to eq(job2.title) end it 'with sucess - using search' do @@ -57,28 +69,24 @@ expect(response.status).to eq 200 expect(response.content_type).to eq('application/json; charset=utf-8') - json_response = JSON.parse(response.body) - - expect(json_response.length).to eq 1 - expect(json_response.first['title']).to eq(job1.title) + expect(subject.length).to eq 1 + expect(subject.first['title']).to eq(job1.title) end end context 'GET /api/v1/jobs' do it "return empty - there aren't jobs" do - get '/api/v1/jobs/', headers: valid_headers, as: :json + get api_v1_jobs_path, headers: valid_headers, as: :json expect(response.status).to eq 200 expect(response.content_type).to eq('application/json; charset=utf-8') - - json_response = JSON.parse(response.body) - expect(json_response).to eq [] + expect(subject).to eq [] end it 'without sucess - internal error' do allow(Job).to receive(:all).and_raise(ActiveRecord::QueryCanceled) - get '/api/v1/jobs/', headers: valid_headers, as: :json + get api_v1_jobs_path, headers: valid_headers, as: :json expect(response).to have_http_status(500) expect(response.content_type).to eq('application/json; charset=utf-8') @@ -86,17 +94,8 @@ end context 'POST /api/v1/jobs/1' do - subject { JSON.parse(response.body) } - - let(:country) { create(:country) } - let(:company) { create(:company) } - it 'with sucess' do - job_params = { job: { title: 'Job Opening Test 123', description: 'Lorem ipsum dolor sit amet', - skills: 'Nam mattis, felis ut adipiscing.', salary: '99', company_id: company.id.to_s, - level: :junior, country_id: country.id.to_s, city: 'Remote Job', - date: 1.month.from_now } } - post '/api/v1/jobs/', params: job_params, headers: valid_headers, as: :json + post api_v1_jobs_path, params: job_attributes_valid, headers: valid_headers, as: :json expect(response).to have_http_status(201) expect(response.content_type).to eq('application/json; charset=utf-8') @@ -112,10 +111,7 @@ end it 'without sucess - imcomplete parameters' do - job_params = { job: { title: 'Job Opening Test 123', description: 'Lorem ipsum dolor sit amet', - skills: '', salary: '', company: '', level: '', place: '', - date: '' } } - post '/api/v1/jobs/', params: job_params, headers: valid_headers, as: :json + post api_v1_jobs_path, params: job_attributes_invalid, headers: valid_headers, as: :json expect(response).to have_http_status(412) expect(response.content_type).to eq('application/json; charset=utf-8') @@ -132,12 +128,7 @@ it 'without sucess - internal error' do allow(Job).to receive(:new).and_raise(ActiveRecord::ActiveRecordError) - job_params = { job: { title: 'Job Opening Test 123', description: 'Lorem ipsum dolor sit amet', - skills: 'Nam mattis, felis ut adipiscing.', salary: '99', company_id: company.id.to_s, - level: 'Junior', country_id: country.id.to_s, city: 'Remote Job', - date: 1.month.from_now } } - - post '/api/v1/jobs/', params: job_params, headers: valid_headers, as: :json + post api_v1_jobs_path, params: job_attributes_valid, headers: valid_headers, as: :json expect(response).to have_http_status(500) expect(response.content_type).to eq('application/json; charset=utf-8') @@ -145,24 +136,44 @@ end context 'PUT /api/v1/jobs/1' do - let(:job) { create(:job) } + let(:job) { create(:job, title: 'Job Opening Test 456') } + + it 'with sucess' do + put api_v1_job_path(job.id), params: job_attributes_valid, headers: valid_headers, as: :json + + expect(response).to have_http_status(200) + expect(response.body).to include('Job Opening Test 123') + expect(response.content_type).to eq('application/json; charset=utf-8') + end + + it 'without sucess - imcomplete parameters' do + put api_v1_job_path(job.id), params: job_attributes_invalid, headers: valid_headers, as: :json + + expect(response).to have_http_status(412) + expect(response.content_type).to eq('application/json; charset=utf-8') + + expect(response.body).not_to include('Título não pode ficar em branco') + expect(response.body).to include('Habilidades não pode ficar em branco') + expect(response.body).to include('Salário não pode ficar em branco') + expect(response.body).to include('Nível não pode ficar em branco') + expect(response.body).to include('Data não pode ficar em branco') + expect(response.body).to include('Salário não pode ficar em branco') + end + end + + context 'PATCH /api/v1/jobs/1' do + let(:job) { create(:job, title: 'Job Opening Test 456') } it 'with sucess' do - job_params = { job: { title: 'Test title', description: 'Test description', - skills: 'Test skills', salary: '66', level: :junior, city: 'Test place', - date: 1.month.from_now } } - put "/api/v1/jobs/#{job.id}", params: job_params, headers: valid_headers, as: :json + patch api_v1_job_path(job.id), params: job_attributes_valid, headers: valid_headers, as: :json expect(response).to have_http_status(200) - expect(response.body).to include('Test title') + expect(response.body).to include('Job Opening Test 123') expect(response.content_type).to eq('application/json; charset=utf-8') end it 'without sucess - imcomplete parameters' do - job_params = { job: { title: 'Test title', description: 'Test description', - skills: '', salary: '', company: '', level: '', city: '', - date: '' } } - put "/api/v1/jobs/#{job.id}", params: job_params, headers: valid_headers, as: :json + patch api_v1_job_path(job.id), params: job_attributes_invalid, headers: valid_headers, as: :json expect(response).to have_http_status(412) expect(response.content_type).to eq('application/json; charset=utf-8') @@ -180,13 +191,13 @@ let(:job) { create(:job) } it 'with sucess' do - delete "/api/v1/jobs/#{job.id}", headers: valid_headers, as: :json + delete api_v1_job_path(job.id), headers: valid_headers, as: :json expect(response.status).to eq 204 end it 'without sucess - no job' do - delete '/api/v1/jobs/999999', headers: valid_headers, as: :json + delete api_v1_job_path(99_999_999), headers: valid_headers, as: :json expect(response.status).to eq 404 expect(response.content_type).to eq('application/json; charset=utf-8') From 086ddcb0a082666a123ff4594b97e2e10cf915e1 Mon Sep 17 00:00:00 2001 From: Joao Gilberto Saraiva Date: Mon, 25 Dec 2023 17:32:53 -0300 Subject: [PATCH 06/11] bundle update --- Gemfile.lock | 184 +++++++++++++++++++++++++-------------------------- 1 file changed, 92 insertions(+), 92 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 697fa8d..0d281a8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,50 +1,51 @@ GEM remote: https://rubygems.org/ specs: - actioncable (7.1.1) - actionpack (= 7.1.1) - activesupport (= 7.1.1) + actioncable (7.1.2) + actionpack (= 7.1.2) + activesupport (= 7.1.2) nio4r (~> 2.0) websocket-driver (>= 0.6.1) zeitwerk (~> 2.6) - actionmailbox (7.1.1) - actionpack (= 7.1.1) - activejob (= 7.1.1) - activerecord (= 7.1.1) - activestorage (= 7.1.1) - activesupport (= 7.1.1) + actionmailbox (7.1.2) + actionpack (= 7.1.2) + activejob (= 7.1.2) + activerecord (= 7.1.2) + activestorage (= 7.1.2) + activesupport (= 7.1.2) mail (>= 2.7.1) net-imap net-pop net-smtp - actionmailer (7.1.1) - actionpack (= 7.1.1) - actionview (= 7.1.1) - activejob (= 7.1.1) - activesupport (= 7.1.1) + actionmailer (7.1.2) + actionpack (= 7.1.2) + actionview (= 7.1.2) + activejob (= 7.1.2) + activesupport (= 7.1.2) mail (~> 2.5, >= 2.5.4) net-imap net-pop net-smtp rails-dom-testing (~> 2.2) - actionpack (7.1.1) - actionview (= 7.1.1) - activesupport (= 7.1.1) + actionpack (7.1.2) + actionview (= 7.1.2) + activesupport (= 7.1.2) nokogiri (>= 1.8.5) + racc rack (>= 2.2.4) rack-session (>= 1.0.1) rack-test (>= 0.6.3) rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) - actiontext (7.1.1) - actionpack (= 7.1.1) - activerecord (= 7.1.1) - activestorage (= 7.1.1) - activesupport (= 7.1.1) + actiontext (7.1.2) + actionpack (= 7.1.2) + activerecord (= 7.1.2) + activestorage (= 7.1.2) + activesupport (= 7.1.2) globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (7.1.1) - activesupport (= 7.1.1) + actionview (7.1.2) + activesupport (= 7.1.2) builder (~> 3.1) erubi (~> 1.11) rails-dom-testing (~> 2.2) @@ -54,22 +55,22 @@ GEM activemodel (>= 4.1) case_transform (>= 0.2) jsonapi-renderer (>= 0.1.1.beta1, < 0.3) - activejob (7.1.1) - activesupport (= 7.1.1) + activejob (7.1.2) + activesupport (= 7.1.2) globalid (>= 0.3.6) - activemodel (7.1.1) - activesupport (= 7.1.1) - activerecord (7.1.1) - activemodel (= 7.1.1) - activesupport (= 7.1.1) + activemodel (7.1.2) + activesupport (= 7.1.2) + activerecord (7.1.2) + activemodel (= 7.1.2) + activesupport (= 7.1.2) timeout (>= 0.4.0) - activestorage (7.1.1) - actionpack (= 7.1.1) - activejob (= 7.1.1) - activerecord (= 7.1.1) - activesupport (= 7.1.1) + activestorage (7.1.2) + actionpack (= 7.1.2) + activejob (= 7.1.2) + activerecord (= 7.1.2) + activesupport (= 7.1.2) marcel (~> 1.0) - activesupport (7.1.1) + activesupport (7.1.2) base64 bigdecimal concurrent-ruby (~> 1.0, >= 1.0.2) @@ -79,14 +80,14 @@ GEM minitest (>= 5.1) mutex_m tzinfo (~> 2.0) - addressable (2.8.5) + addressable (2.8.6) public_suffix (>= 2.0.2, < 6.0) ast (2.4.2) - base64 (0.1.1) - bcrypt (3.1.19) - bigdecimal (3.1.4) + base64 (0.2.0) + bcrypt (3.1.20) + bigdecimal (3.1.5) bindex (0.8.1) - bootsnap (1.16.0) + bootsnap (1.17.0) msgpack (~> 1.2) builder (3.2.4) byebug (11.1.3) @@ -104,7 +105,7 @@ GEM concurrent-ruby (1.2.2) connection_pool (2.4.1) crass (1.0.6) - date (3.3.3) + date (3.3.4) devise (4.9.3) bcrypt (~> 3.0) orm_adapter (~> 0.1) @@ -113,29 +114,29 @@ GEM warden (~> 1.2.3) diff-lcs (1.5.0) docile (1.4.0) - drb (2.1.1) + drb (2.2.0) ruby2_keywords erubi (1.12.0) - factory_bot (6.2.1) + factory_bot (6.4.2) activesupport (>= 5.0.0) - factory_bot_rails (6.2.0) - factory_bot (~> 6.2.0) + factory_bot_rails (6.4.2) + factory_bot (~> 6.4) railties (>= 5.0.0) - faker (3.2.1) + faker (3.2.2) i18n (>= 1.8.11, < 2) ffi (1.16.3) globalid (1.2.1) activesupport (>= 6.1) i18n (1.14.1) concurrent-ruby (~> 1.0) - io-console (0.6.0) - irb (1.8.2) + io-console (0.7.1) + irb (1.11.0) rdoc reline (>= 0.3.8) jbuilder (2.11.5) actionview (>= 5.0.0) activesupport (>= 5.0.0) - json (2.6.3) + json (2.7.1) jsonapi-renderer (0.2.2) kaminari (1.2.2) activesupport (>= 4.1.0) @@ -153,7 +154,7 @@ GEM listen (3.8.0) rb-fsevent (~> 0.10, >= 0.10.3) rb-inotify (~> 0.9, >= 0.9.10) - loofah (2.21.4) + loofah (2.22.0) crass (~> 1.0.2) nokogiri (>= 1.12.0) mail (2.8.1) @@ -166,31 +167,31 @@ GEM mini_mime (1.1.5) minitest (5.20.0) msgpack (1.7.2) - mutex_m (0.1.2) - net-imap (0.4.1) + mutex_m (0.2.0) + net-imap (0.4.9) date net-protocol net-pop (0.1.2) net-protocol - net-protocol (0.2.1) + net-protocol (0.2.2) timeout net-smtp (0.4.0) net-protocol - nio4r (2.5.9) - nokogiri (1.15.4-x86_64-linux) + nio4r (2.7.0) + nokogiri (1.15.5-x86_64-linux) racc (~> 1.4) orm_adapter (0.5.0) - parallel (1.23.0) + parallel (1.24.0) parser (3.2.2.4) ast (~> 2.4.1) racc pg (1.5.4) - psych (5.1.1) + psych (5.1.2) stringio - public_suffix (5.0.3) + public_suffix (5.0.4) puma (6.4.0) nio4r (~> 2.0) - racc (1.7.1) + racc (1.7.3) rack (3.0.8) rack-mini-profiler (2.3.4) rack (>= 1.2.0) @@ -203,20 +204,20 @@ GEM rackup (2.1.0) rack (>= 3) webrick (~> 1.8) - rails (7.1.1) - actioncable (= 7.1.1) - actionmailbox (= 7.1.1) - actionmailer (= 7.1.1) - actionpack (= 7.1.1) - actiontext (= 7.1.1) - actionview (= 7.1.1) - activejob (= 7.1.1) - activemodel (= 7.1.1) - activerecord (= 7.1.1) - activestorage (= 7.1.1) - activesupport (= 7.1.1) + rails (7.1.2) + actioncable (= 7.1.2) + actionmailbox (= 7.1.2) + actionmailer (= 7.1.2) + actionpack (= 7.1.2) + actiontext (= 7.1.2) + actionview (= 7.1.2) + activejob (= 7.1.2) + activemodel (= 7.1.2) + activerecord (= 7.1.2) + activestorage (= 7.1.2) + activesupport (= 7.1.2) bundler (>= 1.15.0) - railties (= 7.1.1) + railties (= 7.1.2) rails-dom-testing (2.2.0) activesupport (>= 5.0.0) minitest @@ -224,25 +225,25 @@ GEM rails-html-sanitizer (1.6.0) loofah (~> 2.21) nokogiri (~> 1.14) - railties (7.1.1) - actionpack (= 7.1.1) - activesupport (= 7.1.1) + railties (7.1.2) + actionpack (= 7.1.2) + activesupport (= 7.1.2) irb rackup (>= 1.0.0) rake (>= 12.2) thor (~> 1.0, >= 1.2.2) zeitwerk (~> 2.6) rainbow (3.1.1) - rake (13.0.6) + rake (13.1.0) rb-fsevent (0.11.2) rb-inotify (0.10.1) ffi (~> 1.0) - rdoc (6.5.0) + rdoc (6.6.2) psych (>= 4.0.0) - redis-client (0.17.0) + redis-client (0.19.1) connection_pool - regexp_parser (2.8.2) - reline (0.3.9) + regexp_parser (2.8.3) + reline (0.4.1) io-console (~> 0.5) responders (3.1.1) actionpack (>= 5.2) @@ -256,7 +257,7 @@ GEM rspec-mocks (3.12.6) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.12.0) - rspec-rails (6.0.3) + rspec-rails (6.1.0) actionpack (>= 6.1) activesupport (>= 6.1) railties (>= 6.1) @@ -265,8 +266,7 @@ GEM rspec-mocks (~> 3.12) rspec-support (~> 3.12) rspec-support (3.12.1) - rubocop (1.57.1) - base64 (~> 0.1.1) + rubocop (1.59.0) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) @@ -274,10 +274,10 @@ GEM 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) + rubocop-ast (>= 1.30.0, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 3.0) - rubocop-ast (1.29.0) + rubocop-ast (1.30.0) parser (>= 3.2.1.0) ruby-progressbar (1.13.0) ruby2_keywords (0.0.5) @@ -299,7 +299,7 @@ GEM semantic_range (3.0.0) shoulda-matchers (5.3.0) activesupport (>= 5.2.0) - sidekiq (7.1.6) + sidekiq (7.2.0) concurrent-ruby (< 2) connection_pool (>= 2.3.0) rack (>= 2.2.4) @@ -310,7 +310,7 @@ GEM simplecov_json_formatter (~> 0.1) simplecov-html (0.12.3) simplecov_json_formatter (0.1.4) - spring (4.1.1) + spring (4.1.3) sprockets (4.2.1) concurrent-ruby (~> 1.0) rack (>= 2.2.4, < 4) @@ -318,10 +318,10 @@ GEM actionpack (>= 5.2) activesupport (>= 5.2) sprockets (>= 3.0.0) - stringio (3.0.8) - thor (1.2.2) + stringio (3.1.0) + thor (1.3.0) tilt (2.3.0) - timeout (0.4.0) + timeout (0.4.1) turbolinks (5.2.1) turbolinks-source (~> 5.2) turbolinks-source (5.2.0) From be1b2c421f6aa5ad676a91ddcc21b2bf0057bee1 Mon Sep 17 00:00:00 2001 From: Joao Gilberto Saraiva Date: Mon, 25 Dec 2023 19:41:25 -0300 Subject: [PATCH 07/11] update: gemfile --- Gemfile | 2 +- Gemfile.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile b/Gemfile index 33afd1b..c88f3b1 100644 --- a/Gemfile +++ b/Gemfile @@ -21,7 +21,7 @@ gem 'webpacker', '~> 5.0' group :development, :test do gem 'byebug', platforms: %i[mri mingw x64_mingw] - gem 'factory_bot_rails' + gem 'factory_bot_rails', '~> 6.2' gem 'faker' gem 'rspec-rails', '~> 6.0' end diff --git a/Gemfile.lock b/Gemfile.lock index 0d281a8..7e389d9 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -362,7 +362,7 @@ DEPENDENCIES byebug capybara (>= 3.26) devise - factory_bot_rails + factory_bot_rails (~> 6.2) faker jbuilder (~> 2.7) kaminari (~> 1.2, >= 1.2.1) From bf696a959818cf52e59fc8c57435b39c89423afb Mon Sep 17 00:00:00 2001 From: Joao Gilberto Saraiva Date: Mon, 25 Dec 2023 19:41:49 -0300 Subject: [PATCH 08/11] refactor api tests --- app/controllers/api/v1/profiles_controller.rb | 1 - spec/requests/apis/jobs_api_spec.rb | 26 +++--- spec/requests/apis/profiles_api_spec.rb | 93 +++++++------------ 3 files changed, 44 insertions(+), 76 deletions(-) diff --git a/app/controllers/api/v1/profiles_controller.rb b/app/controllers/api/v1/profiles_controller.rb index cd1889e..2f257ad 100644 --- a/app/controllers/api/v1/profiles_controller.rb +++ b/app/controllers/api/v1/profiles_controller.rb @@ -2,7 +2,6 @@ module Api module V1 - # ProfileController of API class ProfilesController < Api::V1::ApiController before_action :find_id_profile, only: %i[update destroy] diff --git a/spec/requests/apis/jobs_api_spec.rb b/spec/requests/apis/jobs_api_spec.rb index b47c093..12e8b13 100644 --- a/spec/requests/apis/jobs_api_spec.rb +++ b/spec/requests/apis/jobs_api_spec.rb @@ -12,14 +12,10 @@ let(:invalid_headers) do { Authorization: '' } end + let(:country) { create(:country) } let(:company) { create(:company) } - let(:job_attributes_valid) do - { job: { title: 'Job Opening Test 123', description: 'Lorem ipsum dolor sit amet', - skills: 'Nam mattis, felis ut adipiscing.', salary: '99', company_id: company.id.to_s, - level: :junior, country_id: country.id.to_s, city: 'Remote Job', - date: 1.month.from_now } } - end + let(:job_attributes_valid) { attributes_for(:job, company_id: company.id, country_id: country.id) } let(:job_attributes_invalid) do { job: { title: 'Job Opening Test 123', description: 'Lorem ipsum dolor sit amet', skills: '', salary: '', company_id: '', @@ -100,14 +96,14 @@ expect(response).to have_http_status(201) expect(response.content_type).to eq('application/json; charset=utf-8') - expect(subject['title']).to include('Job Opening Test 123') - expect(subject['description']).to include('Lorem ipsum dolor sit amet') - expect(subject['skills']).to include('Nam mattis, felis ut adipiscing.') - expect(subject['salary']).to eq('99.0') + expect(subject['title']).to include(job_attributes_valid[:title]) + expect(subject['description']).to include(job_attributes_valid[:description]) + expect(subject['skills']).to include(job_attributes_valid[:skills]) + expect(subject['salary'].to_f).to eq(job_attributes_valid[:salary]) expect(subject['company_id']).to eq(company.id) expect(subject['level']).to include('junior') expect(subject['country_id']).to eq(country.id) - expect(subject['city']).to include('Remote Job') + expect(subject['city']).to include(job_attributes_valid[:city]) end it 'without sucess - imcomplete parameters' do @@ -136,13 +132,13 @@ end context 'PUT /api/v1/jobs/1' do - let(:job) { create(:job, title: 'Job Opening Test 456') } + let(:job) { create(:job) } it 'with sucess' do put api_v1_job_path(job.id), params: job_attributes_valid, headers: valid_headers, as: :json expect(response).to have_http_status(200) - expect(response.body).to include('Job Opening Test 123') + expect(subject['title']).to include(job_attributes_valid[:title]) expect(response.content_type).to eq('application/json; charset=utf-8') end @@ -162,13 +158,13 @@ end context 'PATCH /api/v1/jobs/1' do - let(:job) { create(:job, title: 'Job Opening Test 456') } + let(:job) { create(:job) } it 'with sucess' do patch api_v1_job_path(job.id), params: job_attributes_valid, headers: valid_headers, as: :json expect(response).to have_http_status(200) - expect(response.body).to include('Job Opening Test 123') + expect(subject['title']).to include(job_attributes_valid[:title]) expect(response.content_type).to eq('application/json; charset=utf-8') end diff --git a/spec/requests/apis/profiles_api_spec.rb b/spec/requests/apis/profiles_api_spec.rb index 14f681a..061ee53 100644 --- a/spec/requests/apis/profiles_api_spec.rb +++ b/spec/requests/apis/profiles_api_spec.rb @@ -3,28 +3,28 @@ require 'rails_helper' describe 'Profile API' do - let(:country) { create(:country) } - let(:user) { create(:user) } + subject { JSON.parse(response.body) } + + let!(:country) { create(:country) } + let!(:user) { create(:user) } + let(:profile_valid_attributes) { { profile: attributes_for(:profile, country_id: country.id, user_id: user.id) } } context 'GET /api/v1/profiles/1' do it 'with sucess' do profile = create(:profile) - get "/api/v1/profiles/#{profile.id}" + get api_v1_profile_path(profile.id) expect(response.status).to eq 200 expect(response.content_type).to eq('application/json; charset=utf-8') - - json_response = JSON.parse(response.body) - - expect(json_response['name']).to include(profile.name) - expect(json_response['description']).to include(profile.description) - expect(json_response.keys).not_to include('created_at') - expect(json_response.keys).not_to include('updated_at') + expect(subject['name']).to include(profile.name) + expect(subject['description']).to include(profile.description) + expect(subject.keys).not_to include('created_at') + expect(subject.keys).not_to include('updated_at') end it "and fail because can't find the profile" do - get '/api/v1/profiles/99999999' + get api_v1_profile_path(99_999_999) expect(response.status).to eq 404 end end @@ -34,32 +34,27 @@ profile1 = create(:profile) profile2 = create(:profile) - get '/api/v1/profiles/' + get api_v1_profiles_path expect(response.status).to eq 200 expect(response.content_type).to eq('application/json; charset=utf-8') - - json_response = JSON.parse(response.body) - - expect(json_response.length).to eq 2 - expect(json_response.first['name']).to eq(profile1.name) - expect(json_response.last['name']).to eq(profile2.name) + expect(subject.length).to eq 2 + expect(subject.first['name']).to eq(profile1.name) + expect(subject.last['name']).to eq(profile2.name) end it "return empty - there aren't profiles" do - get '/api/v1/profiles/' + get api_v1_profiles_path expect(response.status).to eq 200 expect(response.content_type).to eq('application/json; charset=utf-8') - - json_response = JSON.parse(response.body) - expect(json_response).to eq [] + expect(subject).to eq [] end it 'without sucess - internal error' do allow(Profile).to receive(:all).and_raise(ActiveRecord::QueryCanceled) - get '/api/v1/profiles/' + get api_v1_profiles_path expect(response).to have_http_status(500) expect(response.content_type).to eq('application/json; charset=utf-8') @@ -68,34 +63,26 @@ context 'POST /api/v1/profiles/1' do it 'with sucess' do - profile_params = { profile: { name: 'Profile Tester', social_name: 'Social Name Test', - birthdate: '1970-01-01', description: 'Lorem ipsum dolor sit amet', - educacional_background: 'Nam mattis, felis ut adipiscing.', - experience: 'Test Experience', city: 'Test City', country_id: country.id.to_s, - user_id: user.id.to_s } } - post '/api/v1/profiles/', params: profile_params + post api_v1_profiles_path, params: profile_valid_attributes expect(response).to have_http_status(201) expect(response.content_type).to eq('application/json; charset=utf-8') - - json_response = JSON.parse(response.body) - - expect(json_response['name']).to include('Profile Tester') - expect(json_response['social_name']).to include('Social Name Test') - expect(json_response['birthdate']).to include('1970-01-01') - expect(json_response['description']).to include('Lorem ipsum dolor sit amet') - expect(json_response['educacional_background']).to include('Nam mattis, felis ut adipiscing.') - expect(json_response['experience']).to include('Test Experience') - expect(json_response['city']).to include('Test City') - expect(json_response['country_id']).to eq(country.id) - expect(json_response['user_id']).to eq(user.id) + expect(subject['name']).to include(profile_valid_attributes.values[0][:name]) + expect(subject['social_name']).to include(profile_valid_attributes.values[0][:social_name]) + expect(subject['birthdate']).to include(profile_valid_attributes.values[0][:birthdate].to_s[0..9]) + expect(subject['description']).to include(profile_valid_attributes.values[0][:description]) + expect(subject['educacional_background']).to include(profile_valid_attributes.values[0][:educacional_background]) + expect(subject['experience']).to include(profile_valid_attributes.values[0][:experience]) + expect(subject['city']).to include(profile_valid_attributes.values[0][:city]) + expect(subject['country_id']).to eq(country.id) + expect(subject['user_id']).to eq(user.id) end it 'without sucess - imcomplete parameters' do profile_params = { profile: { name: 'Profile Tester', social_name: '', birthdate: '', description: '', educacional_background: '', experience: '', city: '', country_id: '', user_id: '' } } - post '/api/v1/profiles/', params: profile_params + post api_v1_profiles_path, params: profile_params expect(response).to have_http_status(412) expect(response.content_type).to eq('application/json; charset=utf-8') @@ -112,14 +99,7 @@ it 'without sucess - internal error' do allow(Profile).to receive(:new).and_raise(ActiveRecord::ActiveRecordError) - - profile_params = { profile: { name: 'Profile Tester', social_name: 'Social Name Test', - birthdate: '1970-01-01', description: 'Lorem ipsum dolor sit amet', - educacional_background: 'Nam mattis, felis ut adipiscing.', - experience: 'Test Experience', city: 'Test City', country_id: country.id.to_s, - user_id: user.id.to_s } } - - post '/api/v1/profiles/', params: profile_params + post api_v1_profiles_path, params: profile_valid_attributes expect(response).to have_http_status(500) expect(response.content_type).to eq('application/json; charset=utf-8') @@ -130,25 +110,18 @@ let(:profile) { create(:profile) } it 'with sucess' do - profile_params = { profile: { name: 'Profile Tester', social_name: 'Social Name Test', - birthdate: '1970-01-01', description: 'Lorem ipsum dolor sit amet', - educacional_background: 'Nam mattis, felis ut adipiscing.', - experience: 'Test Experience', city: 'Test City', country_id: country.id.to_s, - user_id: user.id.to_s } } - put "/api/v1/profiles/#{profile.id}", params: profile_params + put api_v1_profile_path(profile.id), params: profile_valid_attributes expect(response).to have_http_status(200) - expect(response.body).to include('Profile Tester') + expect(response.body).to include(profile_valid_attributes.values[0][:name]) expect(response.content_type).to eq('application/json; charset=utf-8') - - JSON.parse(response.body) end it 'without sucess - imcomplete parameters' do profile_params = { profile: { name: 'Profile Tester', social_name: '', birthdate: '', description: '', educacional_background: '', experience: '', city: '', country_id: '', user_id: '' } } - put "/api/v1/profiles/#{profile.id}", params: profile_params + put api_v1_profile_path(profile.id), params: profile_params expect(response).to have_http_status(412) expect(response.content_type).to eq('application/json; charset=utf-8') From c954f13b9e743f7e017c007b37424d9027540dce Mon Sep 17 00:00:00 2001 From: Joao Gilberto Saraiva Date: Mon, 25 Dec 2023 20:56:22 -0300 Subject: [PATCH 09/11] refactor: profiles api specs --- spec/requests/apis/profiles_api_spec.rb | 34 ++++++++++++------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/spec/requests/apis/profiles_api_spec.rb b/spec/requests/apis/profiles_api_spec.rb index 061ee53..fd7487b 100644 --- a/spec/requests/apis/profiles_api_spec.rb +++ b/spec/requests/apis/profiles_api_spec.rb @@ -7,13 +7,13 @@ let!(:country) { create(:country) } let!(:user) { create(:user) } - let(:profile_valid_attributes) { { profile: attributes_for(:profile, country_id: country.id, user_id: user.id) } } + let(:profile_valid_attributes) { attributes_for(:profile, country_id: country.id, user_id: user.id) } context 'GET /api/v1/profiles/1' do it 'with sucess' do profile = create(:profile) - get api_v1_profile_path(profile.id) + get api_v1_profile_path(profile.id), as: :json expect(response.status).to eq 200 expect(response.content_type).to eq('application/json; charset=utf-8') @@ -24,7 +24,7 @@ end it "and fail because can't find the profile" do - get api_v1_profile_path(99_999_999) + get api_v1_profile_path(99_999_999), as: :json expect(response.status).to eq 404 end end @@ -34,7 +34,7 @@ profile1 = create(:profile) profile2 = create(:profile) - get api_v1_profiles_path + get api_v1_profiles_path, as: :json expect(response.status).to eq 200 expect(response.content_type).to eq('application/json; charset=utf-8') @@ -44,7 +44,7 @@ end it "return empty - there aren't profiles" do - get api_v1_profiles_path + get api_v1_profiles_path, as: :json expect(response.status).to eq 200 expect(response.content_type).to eq('application/json; charset=utf-8') @@ -54,7 +54,7 @@ it 'without sucess - internal error' do allow(Profile).to receive(:all).and_raise(ActiveRecord::QueryCanceled) - get api_v1_profiles_path + get api_v1_profiles_path, as: :json expect(response).to have_http_status(500) expect(response.content_type).to eq('application/json; charset=utf-8') @@ -63,17 +63,17 @@ context 'POST /api/v1/profiles/1' do it 'with sucess' do - post api_v1_profiles_path, params: profile_valid_attributes + post api_v1_profiles_path, params: profile_valid_attributes, as: :json expect(response).to have_http_status(201) expect(response.content_type).to eq('application/json; charset=utf-8') - expect(subject['name']).to include(profile_valid_attributes.values[0][:name]) - expect(subject['social_name']).to include(profile_valid_attributes.values[0][:social_name]) - expect(subject['birthdate']).to include(profile_valid_attributes.values[0][:birthdate].to_s[0..9]) - expect(subject['description']).to include(profile_valid_attributes.values[0][:description]) - expect(subject['educacional_background']).to include(profile_valid_attributes.values[0][:educacional_background]) - expect(subject['experience']).to include(profile_valid_attributes.values[0][:experience]) - expect(subject['city']).to include(profile_valid_attributes.values[0][:city]) + expect(subject['name']).to include(profile_valid_attributes[:name]) + expect(subject['social_name']).to include(profile_valid_attributes[:social_name]) + expect(subject['birthdate']).to include(profile_valid_attributes[:birthdate].to_s[0..9]) + expect(subject['description']).to include(profile_valid_attributes[:description]) + expect(subject['educacional_background']).to include(profile_valid_attributes[:educacional_background]) + expect(subject['experience']).to include(profile_valid_attributes[:experience]) + expect(subject['city']).to include(profile_valid_attributes[:city]) expect(subject['country_id']).to eq(country.id) expect(subject['user_id']).to eq(user.id) end @@ -99,7 +99,7 @@ it 'without sucess - internal error' do allow(Profile).to receive(:new).and_raise(ActiveRecord::ActiveRecordError) - post api_v1_profiles_path, params: profile_valid_attributes + post api_v1_profiles_path, params: profile_valid_attributes, as: :json expect(response).to have_http_status(500) expect(response.content_type).to eq('application/json; charset=utf-8') @@ -110,10 +110,10 @@ let(:profile) { create(:profile) } it 'with sucess' do - put api_v1_profile_path(profile.id), params: profile_valid_attributes + put api_v1_profile_path(profile.id), params: profile_valid_attributes, as: :json expect(response).to have_http_status(200) - expect(response.body).to include(profile_valid_attributes.values[0][:name]) + expect(response.body).to include(profile_valid_attributes[:name]) expect(response.content_type).to eq('application/json; charset=utf-8') end From c175d3d32437a91fbd9fa88061e312fa53cf1862 Mon Sep 17 00:00:00 2001 From: Joao Gilberto Saraiva Date: Mon, 25 Dec 2023 22:06:38 -0300 Subject: [PATCH 10/11] create: request helper for tests --- .../apis/access_without_autorization.rb | 6 +-- spec/requests/apis/apply_api_spec.rb | 27 ++++++------ spec/requests/apis/jobs_api_spec.rb | 42 +++++++++---------- spec/requests/apis/profiles_api_spec.rb | 36 ++++++++-------- spec/support/request.rb | 11 +++++ 5 files changed, 62 insertions(+), 60 deletions(-) create mode 100644 spec/support/request.rb diff --git a/spec/requests/apis/access_without_autorization.rb b/spec/requests/apis/access_without_autorization.rb index b652cb9..b3b5835 100644 --- a/spec/requests/apis/access_without_autorization.rb +++ b/spec/requests/apis/access_without_autorization.rb @@ -4,14 +4,12 @@ describe 'API' do context 'Try a route' do - subject { JSON.parse(response.body) } - it 'without an authorization' do get '/api/v1/jobs' expect(response.status).to eq 401 expect(response.content_type).to eq('application/json; charset=utf-8') - expect(subject).to include('errors' => 'Provide an valid Authorization header.') + expect(json_response).to include('errors' => 'Provide an valid Authorization header.') end it 'without a valid authorization' do @@ -19,7 +17,7 @@ expect(response.status).to eq 401 expect(response.content_type).to eq('application/json; charset=utf-8') - expect(subject).to include('errors' => 'Provide an valid Authorization header.') + expect(json_response).to include('errors' => 'Provide an valid Authorization header.') end end end diff --git a/spec/requests/apis/apply_api_spec.rb b/spec/requests/apis/apply_api_spec.rb index b4d1c24..e9cea96 100644 --- a/spec/requests/apis/apply_api_spec.rb +++ b/spec/requests/apis/apply_api_spec.rb @@ -3,8 +3,6 @@ require 'rails_helper' describe 'Apply API' do - subject { JSON.parse(response.body) } - let(:job) { create(:job) } context 'GET /api/v1/jobs/1/applies/1' do @@ -16,11 +14,11 @@ expect(response.status).to eq 200 expect(response.content_type).to eq('application/json; charset=utf-8') - expect(subject['user_id']).to eq(apply.user_id) - expect(subject['job_id']).to eq(job.id) - expect(subject['feedback_headhunter']).to include(apply.feedback_headhunter) - expect(subject.keys).not_to include('created_at') - expect(subject.keys).not_to include('updated_at') + expect(json_response['user_id']).to eq(apply.user_id) + expect(json_response['job_id']).to eq(job.id) + expect(json_response['feedback_headhunter']).to include(apply.feedback_headhunter) + expect(json_response.keys).not_to include('created_at') + expect(json_response.keys).not_to include('updated_at') end it "and fail because can't find the job" do @@ -39,9 +37,9 @@ expect(response.status).to eq 200 expect(response.content_type).to eq('application/json; charset=utf-8') - expect(subject.length).to eq 2 - expect(subject.first['user_id']).to eq(apply1.user_id) - expect(subject.last['user_id']).to eq(apply2.user_id) + expect(json_response.length).to eq 2 + expect(json_response.first['user_id']).to eq(apply1.user_id) + expect(json_response.last['user_id']).to eq(apply2.user_id) end it "return empty - there aren't applies" do @@ -50,7 +48,7 @@ expect(response.status).to eq 200 expect(response.content_type).to eq('application/json; charset=utf-8') - expect(subject).to eq [] + expect(json_response).to eq [] end it 'without sucess - internal error' do @@ -74,9 +72,9 @@ expect(response).to have_http_status(201) expect(response.content_type).to eq('application/json; charset=utf-8') - expect(subject['user_id']).to eq(user.id) - expect(subject['job_id']).to eq(job.id) - expect(subject['feedback_headhunter']).to include('test') + expect(json_response['user_id']).to eq(user.id) + expect(json_response['job_id']).to eq(job.id) + expect(json_response['feedback_headhunter']).to include('test') end it 'without sucess - imcomplete parameters' do @@ -86,7 +84,6 @@ expect(response).to have_http_status(412) expect(response.content_type).to eq('application/json; charset=utf-8') - expect(response.body).not_to include('Job não pode ficar em branco') expect(response.body).to include('User é obrigatório') end diff --git a/spec/requests/apis/jobs_api_spec.rb b/spec/requests/apis/jobs_api_spec.rb index 12e8b13..5c3c08f 100644 --- a/spec/requests/apis/jobs_api_spec.rb +++ b/spec/requests/apis/jobs_api_spec.rb @@ -3,8 +3,6 @@ require 'rails_helper' RSpec.describe 'Job API', type: :request do - subject { JSON.parse(response.body) } - let(:valid_headers) do { Authorization: '0123456789' } end @@ -32,10 +30,10 @@ expect(response.status).to eq 200 expect(response.content_type).to eq('application/json; charset=utf-8') - expect(subject['title']).to include(job.title) - expect(subject['description']).to include(job.description) - expect(subject.keys).not_to include('created_at') - expect(subject.keys).not_to include('updated_at') + expect(json_response['title']).to include(job.title) + expect(json_response['description']).to include(job.description) + expect(json_response.keys).not_to include('created_at') + expect(json_response.keys).not_to include('updated_at') end it "and fail because can't find the job" do @@ -54,9 +52,9 @@ expect(response.status).to eq 200 expect(response.content_type).to eq('application/json; charset=utf-8') - expect(subject.length).to eq 2 - expect(subject.first['title']).to eq(job1.title) - expect(subject.last['title']).to eq(job2.title) + expect(json_response.length).to eq 2 + expect(json_response.first['title']).to eq(job1.title) + expect(json_response.last['title']).to eq(job2.title) end it 'with sucess - using search' do @@ -65,8 +63,8 @@ expect(response.status).to eq 200 expect(response.content_type).to eq('application/json; charset=utf-8') - expect(subject.length).to eq 1 - expect(subject.first['title']).to eq(job1.title) + expect(json_response.length).to eq 1 + expect(json_response.first['title']).to eq(job1.title) end end @@ -76,7 +74,7 @@ expect(response.status).to eq 200 expect(response.content_type).to eq('application/json; charset=utf-8') - expect(subject).to eq [] + expect(json_response).to eq [] end it 'without sucess - internal error' do @@ -96,14 +94,14 @@ expect(response).to have_http_status(201) expect(response.content_type).to eq('application/json; charset=utf-8') - expect(subject['title']).to include(job_attributes_valid[:title]) - expect(subject['description']).to include(job_attributes_valid[:description]) - expect(subject['skills']).to include(job_attributes_valid[:skills]) - expect(subject['salary'].to_f).to eq(job_attributes_valid[:salary]) - expect(subject['company_id']).to eq(company.id) - expect(subject['level']).to include('junior') - expect(subject['country_id']).to eq(country.id) - expect(subject['city']).to include(job_attributes_valid[:city]) + expect(json_response['title']).to include(job_attributes_valid[:title]) + expect(json_response['description']).to include(job_attributes_valid[:description]) + expect(json_response['skills']).to include(job_attributes_valid[:skills]) + expect(json_response['salary'].to_f).to eq(job_attributes_valid[:salary]) + expect(json_response['company_id']).to eq(company.id) + expect(json_response['level']).to include('junior') + expect(json_response['country_id']).to eq(country.id) + expect(json_response['city']).to include(job_attributes_valid[:city]) end it 'without sucess - imcomplete parameters' do @@ -138,7 +136,7 @@ put api_v1_job_path(job.id), params: job_attributes_valid, headers: valid_headers, as: :json expect(response).to have_http_status(200) - expect(subject['title']).to include(job_attributes_valid[:title]) + expect(json_response['title']).to include(job_attributes_valid[:title]) expect(response.content_type).to eq('application/json; charset=utf-8') end @@ -164,7 +162,7 @@ patch api_v1_job_path(job.id), params: job_attributes_valid, headers: valid_headers, as: :json expect(response).to have_http_status(200) - expect(subject['title']).to include(job_attributes_valid[:title]) + expect(json_response['title']).to include(job_attributes_valid[:title]) expect(response.content_type).to eq('application/json; charset=utf-8') end diff --git a/spec/requests/apis/profiles_api_spec.rb b/spec/requests/apis/profiles_api_spec.rb index fd7487b..ce4d747 100644 --- a/spec/requests/apis/profiles_api_spec.rb +++ b/spec/requests/apis/profiles_api_spec.rb @@ -3,8 +3,6 @@ require 'rails_helper' describe 'Profile API' do - subject { JSON.parse(response.body) } - let!(:country) { create(:country) } let!(:user) { create(:user) } let(:profile_valid_attributes) { attributes_for(:profile, country_id: country.id, user_id: user.id) } @@ -17,10 +15,10 @@ expect(response.status).to eq 200 expect(response.content_type).to eq('application/json; charset=utf-8') - expect(subject['name']).to include(profile.name) - expect(subject['description']).to include(profile.description) - expect(subject.keys).not_to include('created_at') - expect(subject.keys).not_to include('updated_at') + expect(json_response['name']).to include(profile.name) + expect(json_response['description']).to include(profile.description) + expect(json_response.keys).not_to include('created_at') + expect(json_response.keys).not_to include('updated_at') end it "and fail because can't find the profile" do @@ -38,9 +36,9 @@ expect(response.status).to eq 200 expect(response.content_type).to eq('application/json; charset=utf-8') - expect(subject.length).to eq 2 - expect(subject.first['name']).to eq(profile1.name) - expect(subject.last['name']).to eq(profile2.name) + expect(json_response.length).to eq 2 + expect(json_response.first['name']).to eq(profile1.name) + expect(json_response.last['name']).to eq(profile2.name) end it "return empty - there aren't profiles" do @@ -48,7 +46,7 @@ expect(response.status).to eq 200 expect(response.content_type).to eq('application/json; charset=utf-8') - expect(subject).to eq [] + expect(json_response).to eq [] end it 'without sucess - internal error' do @@ -67,15 +65,15 @@ expect(response).to have_http_status(201) expect(response.content_type).to eq('application/json; charset=utf-8') - expect(subject['name']).to include(profile_valid_attributes[:name]) - expect(subject['social_name']).to include(profile_valid_attributes[:social_name]) - expect(subject['birthdate']).to include(profile_valid_attributes[:birthdate].to_s[0..9]) - expect(subject['description']).to include(profile_valid_attributes[:description]) - expect(subject['educacional_background']).to include(profile_valid_attributes[:educacional_background]) - expect(subject['experience']).to include(profile_valid_attributes[:experience]) - expect(subject['city']).to include(profile_valid_attributes[:city]) - expect(subject['country_id']).to eq(country.id) - expect(subject['user_id']).to eq(user.id) + expect(json_response['name']).to include(profile_valid_attributes[:name]) + expect(json_response['social_name']).to include(profile_valid_attributes[:social_name]) + expect(json_response['birthdate']).to include(profile_valid_attributes[:birthdate].to_s[0..9]) + expect(json_response['description']).to include(profile_valid_attributes[:description]) + expect(json_response['educacional_background']).to include(profile_valid_attributes[:educacional_background]) + expect(json_response['experience']).to include(profile_valid_attributes[:experience]) + expect(json_response['city']).to include(profile_valid_attributes[:city]) + expect(json_response['country_id']).to eq(country.id) + expect(json_response['user_id']).to eq(user.id) end it 'without sucess - imcomplete parameters' do diff --git a/spec/support/request.rb b/spec/support/request.rb new file mode 100644 index 0000000..cc7cd27 --- /dev/null +++ b/spec/support/request.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +require 'json' + +module Request + module JsonHelper + def json_response + @json_response ||= JSON.parse(response.body) + end + end +end From 7db47cd52d445ede51c9e883e24daf010fb084fc Mon Sep 17 00:00:00 2001 From: Joao Gilberto Saraiva Date: Mon, 25 Dec 2023 22:07:00 -0300 Subject: [PATCH 11/11] remove: tests fixtures warnings --- Gemfile | 2 +- Gemfile.lock | 2 +- spec/rails_helper.rb | 18 +++--------------- 3 files changed, 5 insertions(+), 17 deletions(-) diff --git a/Gemfile b/Gemfile index c88f3b1..d5d4fb9 100644 --- a/Gemfile +++ b/Gemfile @@ -23,7 +23,7 @@ group :development, :test do gem 'byebug', platforms: %i[mri mingw x64_mingw] gem 'factory_bot_rails', '~> 6.2' gem 'faker' - gem 'rspec-rails', '~> 6.0' + gem 'rspec-rails', '~> 6.1' end group :development do diff --git a/Gemfile.lock b/Gemfile.lock index 7e389d9..a4f1059 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -371,7 +371,7 @@ DEPENDENCIES puma (~> 6.0) rack-mini-profiler (~> 2.0) rails (~> 7.0) - rspec-rails (~> 6.0) + rspec-rails (~> 6.1) rubocop sass-rails (>= 6) selenium-webdriver diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 59a68e8..e7cdd06 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -27,6 +27,7 @@ require 'rspec/rails' require 'support/factory_bot' +require 'support/request' Shoulda::Matchers.configure do |config| config.integrate do |with| @@ -48,27 +49,13 @@ driven_by :rack_test end # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures - config.fixture_path = "#{::Rails.root}/spec/fixtures" + # config.fixture_path = "#{::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 # instead of true. config.use_transactional_fixtures = true - # You can uncomment this line to turn off ActiveRecord support entirely. - # config.use_active_record = false - - # RSpec Rails can automatically mix in different behaviours to your tests - # based on their file location, for example enabling you to call `get` and - # `post` in specs under `spec/controllers`. - # - # You can disable this behaviour by removing the line below, and instead - # explicitly tag your specs with their type, e.g.: - # - # RSpec.describe UsersController, type: :controller do - # # ... - # end - # # The different available types are documented in the features, such as in # https://relishapp.com/rspec/rspec-rails/docs config.infer_spec_type_from_file_location! @@ -77,4 +64,5 @@ config.filter_rails_from_backtrace! # arbitrary gems may also be filtered via: # config.filter_gems_from_backtrace("gem name") + config.include Request::JsonHelper, type: :request end