Skip to content

Commit

Permalink
implement project preference read settings endpoint (#4280)
Browse files Browse the repository at this point in the history
* implement project preference read settings endpoint

* pr cleanups and add failure test case

* more pr cleanups

* more pr cleanups

* refactor project_preferences_controller

* houndbot refactorings

* houndbot refactorings

* add new test case for UPP read settings

* text change on UPP spec
  • Loading branch information
Tooyosi authored Feb 20, 2024
1 parent 40677b0 commit 9a56310
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 20 deletions.
56 changes: 36 additions & 20 deletions app/controllers/api/v1/project_preferences_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,38 +6,54 @@ class Api::V1::ProjectPreferencesController < Api::ApiController
resource_actions :create, :update, :show, :index, :update_settings
extra_schema_actions :update_settings
schema_type :json_schema
before_action :find_upp_for_update_settings, only: [:update_settings]
before_action :find_upp, only: %i[update_settings read_settings]

def update_settings
def read_settings
skip_policy_scope
@upp.settings.merge! params_for[:settings]
@upp.save!
update_settings_response
end

private

def find_upp_for_update_settings
@upp = UserProjectPreference.find_by!(
user_id: params_for[:user_id],
project_id: params_for[:project_id]
render(
status: :ok,
json_api: serializer.page(
params,
@upp_list,
context
)
)
raise Api::Unauthorized, 'You must be the project owner or a collaborator' unless user_allowed?
end

def user_allowed?
@upp.project.owners_and_collaborators.include?(api_user.user) || api_user.is_admin?
end

def update_settings_response
def update_settings
skip_policy_scope
@upp.settings.merge! params_for[:settings]
@upp.save!
response.headers['Last-Modified'] = @upp.updated_at.httpdate

render(
status: :ok,
json_api: serializer.resource(
{},
UserProjectPreference.where(id: @upp.id),
@upp_list,
context
)
)
end

def fetch_upp_list
if action_name == 'read_settings'
@upp_list = UserProjectPreference.where(project_id: params[:project_id]).where.not(email_communication: nil)
@upp_list = @upp_list.where(user_id: params[:user_id]) if params[:user_id].present?
else
@upp_list = UserProjectPreference.where(user_id: params_for[:user_id], project_id: params_for[:project_id])
end
end

def find_upp
fetch_upp_list
@upp = @upp_list.first
raise ActiveRecord::RecordNotFound unless @upp.present?

raise Api::Unauthorized, 'You must be the project owner or a collaborator' unless user_allowed?
end

def user_allowed?
@upp.project.owners_and_collaborators.include?(api_user.user) || api_user.is_admin?
end
end
1 change: 1 addition & 0 deletions app/models/project.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class Project < ApplicationRecord
has_many :tutorials
has_many :field_guides, dependent: :destroy
belongs_to :organization
has_many :user_project_preference, dependent: :destroy
# uses the activated_state enum on the workflow
has_many :workflows,
-> { where(serialize_with_project: true).active},
Expand Down
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
json_api_resources :project_preferences do
collection do
post :update_settings
get :read_settings
end
end

Expand Down
52 changes: 52 additions & 0 deletions spec/controllers/api/v1/project_preferences_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -197,4 +197,56 @@
end
end
end

describe '#read_settings' do
let!(:second_authorized_user) { create(:user) }
let!(:project) { create(:project, owner: authorized_user) }
let!(:first_upp) { create(:user_project_preference, project: project, user_id: authorized_user.id) }
let!(:second_upp) { create(:user_project_preference, project: project, user_id: second_authorized_user.id) }
let(:run_generic_read) { get :read_settings, params: { project_id: project.id, format: :json } }
let(:run_invalid_project) { get :read_settings, params: { project_id: 500, format: :json } }
let(:unauthorised_user) { create(:user) }

describe 'generic preferences' do
before do
default_request user_id: authorized_user.id, scopes: scopes
run_generic_read
end

it 'responds with a 200' do
expect(response.status).to eq(200)
end

it 'returns the correct response data' do
json_response = JSON.parse(response.body)
expect(json_response['project_preferences'].count).to eq(2)
end
end

describe 'invalid project' do
before do
default_request user_id: authorized_user.id, scopes: scopes
run_invalid_project
end

it 'responds with a 404' do
expect(response.status).to eq(404)
end
end

describe 'user specific preferences' do
it 'only fetches settings of owned project' do
default_request user_id: unauthorised_user.id, scopes: scopes
get :read_settings, params: { project_id: project.id, user_id: unauthorised_user.id, format: :json }
expect(response.status).to eq(404)
end

it 'only fetches settings of the specified user' do
default_request user_id: authorized_user.id, scopes: scopes
get :read_settings, params: { project_id: project.id, user_id: authorized_user.id, format: :json }
json_response = JSON.parse(response.body)
expect(json_response['project_preferences'].count).to eq(1)
end
end
end
end

0 comments on commit 9a56310

Please sign in to comment.