From 770525774dd68f46a7e09d1ae5b3ce0a7f61b661 Mon Sep 17 00:00:00 2001 From: Pratham Goel Date: Wed, 28 Sep 2022 14:54:17 +0530 Subject: [PATCH 1/7] Added success and error messages for the user --- config/locales/en.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/config/locales/en.yml b/config/locales/en.yml index 06801a3..4e37dca 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -37,6 +37,18 @@ en: success: "Logged in successfully" failure: "Invalid Credentials" hello: "Hello world" + + users: + success: + create: "User created successfully" + update: "Users data successfully updated" + destroy: "User deleted successfully" + error: + create: "Unable to create User" + show: "User not exists" + update: "You are not the user itself/User does not exists" + destroy: "Cannot destroy user" + department: success: create: "Department created successfully" From 1962620072bc769fbde351bf6c7ede88113dc2eb Mon Sep 17 00:00:00 2001 From: Pratham Goel Date: Wed, 28 Sep 2022 14:54:57 +0530 Subject: [PATCH 2/7] Added routes for the users model. create, show, destroy, update --- config/routes.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/config/routes.rb b/config/routes.rb index dcdd613..7cb18d8 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -6,6 +6,7 @@ resources :sessions, only: :create resources :categories, only: :create resources :departments, only: :create + resources :users, only: [:create, :update, :destroy, :show] get '/organizations/:id/departments', to: 'organizations#show_departments' end end From 4c4e781ea3210d8a4fab484f6f71d2339ebcc4d1 Mon Sep 17 00:00:00 2001 From: Pratham Goel Date: Wed, 28 Sep 2022 14:56:04 +0530 Subject: [PATCH 3/7] Added the controller for the user. It also make a spec file. The controller also have the code for the CRUD application --- app/controllers/api/v1/users_controller.rb | 49 ++++++++++++++++++++++ spec/requests/api/v1/users_spec.rb | 7 ++++ 2 files changed, 56 insertions(+) create mode 100644 app/controllers/api/v1/users_controller.rb create mode 100644 spec/requests/api/v1/users_spec.rb diff --git a/app/controllers/api/v1/users_controller.rb b/app/controllers/api/v1/users_controller.rb new file mode 100644 index 0000000..7cc3f90 --- /dev/null +++ b/app/controllers/api/v1/users_controller.rb @@ -0,0 +1,49 @@ +module Api::V1 + class UsersController < ApplicationController + def create + user = Users::V1::Create.new(user_params).call + if user[:status] + render json: { message: I18n.t('users.success.create') } + else + render json: { message: I18n.t('users.error.create') }, status: :unprocessable_entity + end + end + + def show + user = Users::V1::Show.new(params[:id]).call + if user[:status] + render json: user, status: :ok + else + render json: {message: I18n.t('users.error.show')}, status: :unprocessable_entity + end + end + + def update + user_new_data = Users::V1::Update.new(user_params, current_user, params[:id]).call + if user_new_data[:status] + render json: {message: I18n.t('users.success.update')}, status: 200 + else + render json: {message: I18n.t('users.error.update')}, status: :unprocessable_entity + end + end + + def destroy + user = Users::V1::Destroy.new(params[:id]).call + if user[:status] + render json: { message: I18n.t('users.success.destroy'), status: true }, status: :ok + else + render json: { message: I18n.t('users.error.destroy'), status: false }, status: :unprocessable_entity + end + end + + private + + def user_params + params.require(:user_data).permit(:name, + :email, + :role_id, + :organization_id, + :department_id) + end + end +end diff --git a/spec/requests/api/v1/users_spec.rb b/spec/requests/api/v1/users_spec.rb new file mode 100644 index 0000000..2202557 --- /dev/null +++ b/spec/requests/api/v1/users_spec.rb @@ -0,0 +1,7 @@ +require 'rails_helper' + +RSpec.describe "Users", type: :request do + describe "GET /index" do + pending "add some examples (or delete) #{__FILE__}" + end +end From dc4b229cb6a887b3096f087458ee9cfff4f4d18d Mon Sep 17 00:00:00 2001 From: Pratham Goel Date: Wed, 28 Sep 2022 14:59:08 +0530 Subject: [PATCH 4/7] Added files for all the CRUD operations for the user --- app/services/users/v1/create.rb | 24 ++++++++++++++++++++++++ app/services/users/v1/destroy.rb | 23 +++++++++++++++++++++++ app/services/users/v1/show.rb | 16 ++++++++++++++++ app/services/users/v1/update.rb | 25 +++++++++++++++++++++++++ 4 files changed, 88 insertions(+) create mode 100644 app/services/users/v1/create.rb create mode 100644 app/services/users/v1/destroy.rb create mode 100644 app/services/users/v1/show.rb create mode 100644 app/services/users/v1/update.rb diff --git a/app/services/users/v1/create.rb b/app/services/users/v1/create.rb new file mode 100644 index 0000000..85c8716 --- /dev/null +++ b/app/services/users/v1/create.rb @@ -0,0 +1,24 @@ +module Users::V1 + class Create + def initialize(user) + @name = user[:name] + @email = user[:email] + @role_id = user[:role_id] + @organization_id = user[:organization_id] + @department_id = user[:department_id] + end + + def call + @user = User.new(name: @name, + email: @email, + role_id: @role_id, + organization_id: @organization_id, + department_id: @department_id) + if @user.save + { status: true } + else + { status: false, error_message: @user.errors.full_messages.join(', ') } + end + end + end +end \ No newline at end of file diff --git a/app/services/users/v1/destroy.rb b/app/services/users/v1/destroy.rb new file mode 100644 index 0000000..6484395 --- /dev/null +++ b/app/services/users/v1/destroy.rb @@ -0,0 +1,23 @@ +module::Users::V1 + class Destroy + def initialize(user_id) + @user_id = user_id + end + + def call + (check_user_existence && delete_user) ? { status: true } : { status: false } + end + + def check_user_existence + User.exists?(@user_id) + end + + def delete_user + if User.find(@user_id).destroy + { status: true } + else + { status: false } + end + end + end +end \ No newline at end of file diff --git a/app/services/users/v1/show.rb b/app/services/users/v1/show.rb new file mode 100644 index 0000000..65b9a80 --- /dev/null +++ b/app/services/users/v1/show.rb @@ -0,0 +1,16 @@ +module Users::V1 + class Show + def initialize(user_id) + @user_id = user_id + end + + def call + if User.exists?(@user_id.to_i) + { status: true, user_data: User.find(@user_id.to_i).as_json } + else + { status: false } + end + end + + end +end \ No newline at end of file diff --git a/app/services/users/v1/update.rb b/app/services/users/v1/update.rb new file mode 100644 index 0000000..b7466eb --- /dev/null +++ b/app/services/users/v1/update.rb @@ -0,0 +1,25 @@ +module::Users::V1 + class Update + def initialize(user_data, current_user, id) + @id = id + @name = user_data[:name] + @email = user_data[:email] + @role_id = user_data[:role_id] + @organization_id = user_data[:organization_id] + @department_id = user_data[:department_id] + @current_user = current_user + end + + def call + return { status: false } unless User.exists?(@id) && @id.to_i == @current_user[:id] + user = User.find @id.to_i + user.name = @name if @name + user.email = @email if @email + user.role_id = @role_id if @role_id + user.organization_id = @organization_id if @organization_id + user.department_id = @department_id if @department_id + + user.save ? { status: true } : { status: false } + end + end +end \ No newline at end of file From 10ba2213f448555c28e17e823e24a704bfc5b2cd Mon Sep 17 00:00:00 2001 From: Pratham Goel Date: Wed, 28 Sep 2022 14:59:48 +0530 Subject: [PATCH 5/7] Added the rspec API doc code for the user --- spec/acceptance/v1/users_spec.rb | 125 +++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 spec/acceptance/v1/users_spec.rb diff --git a/spec/acceptance/v1/users_spec.rb b/spec/acceptance/v1/users_spec.rb new file mode 100644 index 0000000..61a0a32 --- /dev/null +++ b/spec/acceptance/v1/users_spec.rb @@ -0,0 +1,125 @@ + +require 'rails_helper' +require 'rspec_api_documentation/dsl' + +resource 'Users' do + Organization.destroy_all + let!(:organization) { Organization.create!(name: "Josh", domain: ["joshsoftware.com"]) } + let!(:department) { FactoryBot.create(:department, name: Faker::Name.name, organization_id: organization.id)} + let!(:category) { FactoryBot.create(:category, name: "Hardware", priority: "High", department_id: department.id)} + let!(:role) { FactoryBot.create(:role, name: 'employee')} + let!(:user) { FactoryBot.create(:user, role_id: role.id) } + before do + header 'Accept', 'application/vnd.providesk; version=1' + header 'Authorization', JsonWebToken.encode({user_id: user.id, email: user.email, name: user.name}) + end + + put '/users/:id' do + context '200' do + let!(:user) { User.create(name: "prathamgoel", email: "pratham.goel@joshsoftware.com") } + let(:id) { User.where(name: "prathamgoel")[0].id } + example 'a successful updation of a user' do + header 'Authorization', JsonWebToken.encode({user_id: user.id, email: user.email, name: user.name}) + do_request({ + "user_data": { + "email": "pratham.goelupdated@joshsoftware.com", + "name": "prathamgoel" + } + }) + response_data = JSON.parse(response_body) + expect(response_status).to eq(200) + expect(response_data["message"]).to eq(I18n.t('users.success.update')) + end + end + context '422' do + let!(:user) { User.create(name: "prathamgoel", email: "pratham.goel@joshsoftware.com") } + let(:id) { 0 } + example 'a successful updation of a user' do + header 'Authorization', JsonWebToken.encode({user_id: user.id, email: user.email, name: user.name}) + do_request({ + "user_data": { + "email": "pratham.goelupdated@joshsoftware.com", + "name": "prathamgoel" + } + }) + response_data = JSON.parse(response_body) + expect(response_status).to eq(422) + expect(response_data["message"]).to eq(I18n.t('users.error.update')) + end + end + end + + post '/users' do + context '200' do + example 'a successful creation of a user' do + do_request({ + "user_data": { + "name": "Sandeep Goel", + "email": "sandeep@joshsoftware.com", + "role_id": Role.first.id, + "organization_id": Organization.first.id + } + }) + response_data = JSON.parse(response_body) + expect(response_status).to eq(200) + expect(response_data["message"]).to eq(I18n.t('users.success.create')) + end + end + context '200' do + example 'a unsuccessful creation of a user' do + do_request({ + "user_data": { + "name": "Sandeep Goel", + "email": "sandeep@joshsoftware.com", + "role_id": 0, + "organization_id": Organization.first.id + } + }) + response_data = JSON.parse(response_body) + expect(status).to eq(422) + expect(response_data["message"]).to eq(I18n.t('users.error.create')) + end + end + end + + get '/users/:id' do + context '200' do + let(:id) {User.first.id} + example 'Show a existing user' do + do_request() + response_data = JSON.parse(response_body) + expect(response_status).to eq(200) + expect(response_data["status"]).to eq(true) + end + end + context '422' do + let(:id) {0} + example 'Show a non existing user' do + do_request() + response_data = JSON.parse(response_body) + expect(response_status).to eq(422) + end + end + end + + delete 'users/:id' do + context '200' do + let(:id) {User.first.id} + example 'Deleting a existing user' do + do_request() + response_data = JSON.parse(response_body) + expect(response_status).to eq(200) + expect(response_data["status"]).to eq(true) + end + end + context '422' do + let(:id) {0} + example 'Deleting a non xisting user' do + do_request() + response_data = JSON.parse(response_body) + expect(response_status).to eq(422) + expect(response_data["status"]).to eq(false) + end + end + end +end \ No newline at end of file From adffe73115dbf72223ffe3e2ceb90ca8f2d16c22 Mon Sep 17 00:00:00 2001 From: Pratham Goel Date: Wed, 28 Sep 2022 15:00:59 +0530 Subject: [PATCH 6/7] Added the service test cases for the user CRUD operation --- spec/services/v1/users_spec.rb | 90 ++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 spec/services/v1/users_spec.rb diff --git a/spec/services/v1/users_spec.rb b/spec/services/v1/users_spec.rb new file mode 100644 index 0000000..e9e8546 --- /dev/null +++ b/spec/services/v1/users_spec.rb @@ -0,0 +1,90 @@ +require 'rails_helper' + +RSpec.describe Api::V1::OrganizationsController, type: :model do + Organization.destroy_all + Role.destroy_all + User.destroy_all + let!(:organization) { Organization.create(name: "google", domain: ["gmail.com"] ) } + let!(:role) { Role.create(name: 'super_admin')} + + describe '#create' do + it 'User created successfully' do + response_body = Users::V1::Create.new(params).call + expect(response_body[:status]).to eq(true) + end + + it 'Unable to create user' do + selected_params = params + selected_params[:email] = nil + + response_body = Users::V1::Create.new(selected_params).call + expect(response_body[:status]).to eq(false) + end + end + + describe '#update' do + before do + User.create(params) + end + + it 'User updated successfully' do + user = User.where(name: "Manu Goel")[0] + updated_user = user + updated_user.update(email: "manugoel96@joshsoftware.com") + + response_body = Users::V1::Update.new(updated_user, user, updated_user["id"].to_s).call + expect(response_body[:status]).to eq(true) + end + + it 'Unable to create user' do + user = User.where(name: "Manu Goel")[0] + updated_user = user + updated_user.update(role_id: 0) + + response_body = Users::V1::Update.new(updated_user, user, updated_user["id"].to_s).call + expect(response_body[:status]).to eq(false) + end + end + + describe '#show' do + before do + User.create(params) + end + + it 'User shown successfully' do + response_body = Users::V1::Destroy.new(User.first.id).call + expect(response_body[:status]).to eq(true) + end + + it 'Unable to show user' do + response_body = Users::V1::Destroy.new(0).call + expect(response_body[:status]).to eq(false) + end + end + + describe '#delete' do + before do + User.create(params) + end + + it 'User deleted successfully' do + response_body = Users::V1::Destroy.new(User.first.id).call + expect(response_body[:status]).to eq(true) + end + + it 'Unable to delete user' do + response_body = Users::V1::Destroy.new(0).call + expect(response_body[:status]).to eq(false) + end + end + + private + + def params + { + name: "Manu Goel", + email: "manugoel@gmail.com", + role_id: Role.find_by(name: 'super_admin').id + } + end +end \ No newline at end of file From 3dd84b817b9237cc47901f1870897ff2880b7127 Mon Sep 17 00:00:00 2001 From: Pratham Goel Date: Fri, 30 Sep 2022 12:39:13 +0530 Subject: [PATCH 7/7] Resolved issues for execption when there are no parameters given in the request --- app/controllers/api/v1/users_controller.rb | 14 +++++++++----- config/locales/en.yml | 1 + 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/app/controllers/api/v1/users_controller.rb b/app/controllers/api/v1/users_controller.rb index 7cc3f90..a66da68 100644 --- a/app/controllers/api/v1/users_controller.rb +++ b/app/controllers/api/v1/users_controller.rb @@ -1,11 +1,15 @@ module Api::V1 class UsersController < ApplicationController def create - user = Users::V1::Create.new(user_params).call - if user[:status] - render json: { message: I18n.t('users.success.create') } - else - render json: { message: I18n.t('users.error.create') }, status: :unprocessable_entity + begin + user = Users::V1::Create.new(user_params).call + if user[:status] + render json: { message: I18n.t('users.success.create') } + else + render json: { message: I18n.t('users.error.create') }, status: :unprocessable_entity + end + rescue ActionController::ParameterMissing + render json: { message: I18n.t('users.error.invalid_parameter') }, status: :unprocessable_entity end end diff --git a/config/locales/en.yml b/config/locales/en.yml index 3948a73..9752d37 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -48,6 +48,7 @@ en: show: "User not exists" update: "You are not the user itself/User does not exists" destroy: "Cannot destroy user" + invalid_parameters: "Invalid params" department: success: