allow officers to update joined_at on members and phantoms

This commit is contained in:
Justin Edmund 2025-12-04 03:02:27 -08:00
parent 0337bc1e92
commit 7d27d3c8b1
3 changed files with 34 additions and 6 deletions

View file

@ -9,11 +9,18 @@ module Api
before_action :set_crew
before_action :set_membership, only: %i[update destroy promote demote]
before_action :authorize_crew_officer!, only: %i[destroy]
before_action :authorize_crew_captain!, only: %i[update promote demote]
before_action :authorize_crew_captain!, only: %i[promote demote]
before_action :authorize_membership_update!, only: %i[update]
# PUT /crews/:crew_id/memberships/:id
def update
if @membership.update(membership_params)
allowed_params = if current_user.crew_captain?
membership_params
else
membership_params.slice(:joined_at)
end
if @membership.update(allowed_params)
render json: CrewMembershipBlueprint.render(@membership, view: :with_user, root: :membership)
else
render_validation_error_response(@membership)
@ -59,7 +66,16 @@ module Api
end
def membership_params
params.require(:membership).permit(:role)
params.require(:membership).permit(:role, :joined_at)
end
def authorize_membership_update!
# Officers can update any membership's joined_at
# Captains can update anything
return if current_user.crew_captain?
return if current_user.crew_officer?
raise Api::V1::UnauthorizedError
end
end
end

View file

@ -72,7 +72,7 @@ module Api
end
def phantom_params
params.require(:phantom_player).permit(:name, :granblue_id, :notes)
params.require(:phantom_player).permit(:name, :granblue_id, :notes, :joined_at)
end
end
end

View file

@ -29,12 +29,24 @@ RSpec.describe 'Api::V1::CrewMemberships', type: :request do
context 'as vice captain' do
let!(:vc_membership) { create(:crew_membership, crew: crew, user: user, role: :vice_captain) }
it 'returns unauthorized' do
it 'cannot change role but request succeeds' do
put "/api/v1/crews/#{crew.id}/memberships/#{target_membership.id}",
params: { membership: { role: 'vice_captain' } },
headers: auth_headers
expect(response).to have_http_status(:unauthorized)
# Vice captains can access update endpoint (for joined_at) but role param is ignored
expect(response).to have_http_status(:ok)
expect(target_membership.reload.role).to eq('member') # Role not changed
end
it 'can update joined_at' do
put "/api/v1/crews/#{crew.id}/memberships/#{target_membership.id}",
params: { membership: { joined_at: '2024-01-15' } },
headers: auth_headers
expect(response).to have_http_status(:ok)
json = JSON.parse(response.body)
expect(json['membership']['joined_at']).to include('2024-01-15')
end
end
end