From 536839a03c0aad18bae9f448a4b1bdc8067fe6a5 Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Sun, 4 Jan 2026 22:54:17 -0800 Subject: [PATCH] add crew shared_parties endpoint --- app/controllers/api/v1/crews_controller.rb | 20 ++++++-- config/routes.rb | 1 + spec/requests/api/v1/crews_spec.rb | 55 ++++++++++++++++++++++ 3 files changed, 73 insertions(+), 3 deletions(-) diff --git a/app/controllers/api/v1/crews_controller.rb b/app/controllers/api/v1/crews_controller.rb index 7879063..89ac110 100644 --- a/app/controllers/api/v1/crews_controller.rb +++ b/app/controllers/api/v1/crews_controller.rb @@ -6,9 +6,9 @@ module Api include CrewAuthorizationConcern before_action :restrict_access - before_action :set_crew, only: %i[show update members roster leave transfer_captain] - before_action :require_crew!, only: %i[show update members roster] - before_action :authorize_crew_member!, only: %i[show members] + before_action :set_crew, only: %i[show update members roster leave transfer_captain shared_parties] + before_action :require_crew!, only: %i[show update members roster shared_parties] + before_action :authorize_crew_member!, only: %i[show members shared_parties] before_action :authorize_crew_officer!, only: %i[update roster] before_action :authorize_crew_captain!, only: %i[transfer_captain] @@ -106,6 +106,20 @@ module Api render json: CrewBlueprint.render(@crew.reload, view: :full, root: :crew, current_user: current_user) end + # GET /crew/shared_parties + # Returns parties that have been shared with this crew + def shared_parties + parties = @crew.shared_parties + .includes(:user, :job, :raid) + .order(created_at: :desc) + .paginate(page: params[:page], per_page: page_size) + + render json: { + parties: PartyBlueprint.render_as_hash(parties, view: :preview, current_user: current_user), + meta: pagination_meta(parties) + } + end + private def set_crew diff --git a/config/routes.rb b/config/routes.rb index df02453..189b5cb 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -185,6 +185,7 @@ Rails.application.routes.draw do member do get :members get :roster + get :shared_parties post :leave end end diff --git a/spec/requests/api/v1/crews_spec.rb b/spec/requests/api/v1/crews_spec.rb index a21038c..7cbcdc5 100644 --- a/spec/requests/api/v1/crews_spec.rb +++ b/spec/requests/api/v1/crews_spec.rb @@ -261,4 +261,59 @@ RSpec.describe 'Api::V1::Crews', type: :request do end end end + + describe 'GET /api/v1/crew/shared_parties' do + let(:crew) { create(:crew) } + let!(:membership) { create(:crew_membership, crew: crew, user: user, role: :member) } + + context 'as crew member' do + it 'returns parties shared with the crew' do + other_user = create(:user) + create(:crew_membership, crew: crew, user: other_user) + party = create(:party, user: other_user, visibility: 3) # private + create(:party_share, party: party, shareable: crew, shared_by: other_user) + + get '/api/v1/crew/shared_parties', headers: auth_headers + + expect(response).to have_http_status(:ok) + json = JSON.parse(response.body) + expect(json['parties'].length).to eq(1) + expect(json['parties'][0]['id']).to eq(party.id) + end + + it 'returns empty array when no shared parties' do + get '/api/v1/crew/shared_parties', headers: auth_headers + + expect(response).to have_http_status(:ok) + json = JSON.parse(response.body) + expect(json['parties']).to eq([]) + end + + it 'includes pagination meta' do + get '/api/v1/crew/shared_parties', headers: auth_headers + + expect(response).to have_http_status(:ok) + json = JSON.parse(response.body) + expect(json['meta']).to include('count', 'total_pages', 'per_page') + end + end + + context 'when not in a crew' do + before { membership.retire! } + + it 'returns not found' do + get '/api/v1/crew/shared_parties', headers: auth_headers + + expect(response).to have_http_status(:not_found) + end + end + + context 'without authentication' do + it 'returns unauthorized' do + get '/api/v1/crew/shared_parties' + + expect(response).to have_http_status(:unauthorized) + end + end + end end