Skip to content

Commit

Permalink
Merge pull request #62 from Code-the-Dream-School/HER-71-Update-Order…
Browse files Browse the repository at this point in the history
…s-for-Address-Editing

HER-63-Update-User-Profile-To-Include-Speaker-Specific-Data
  • Loading branch information
bbcc33 authored Jan 18, 2025
2 parents 98fd161 + 048fd98 commit 45104b2
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 47 deletions.
5 changes: 2 additions & 3 deletions app/controllers/api/v1/users_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,9 @@ def destroy
render json: { message: "User deleted successfully!" }
end

# Add profile action and pass current_user as params
def profile
@user = User.find(params[:id])
render json: UserProfileSerializer.new(@user).serializable_hash
role = current_user.role
render json: UserProfileSerializer.new(@user, { params: { role: role } }).serializable_hash
end

private
Expand Down
17 changes: 7 additions & 10 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,19 +40,16 @@ def set_default_role
self.role ||= "user"
end

def admin?
role == "admin"
# Define methods to access bookings through orders and events
def pending_bookings
Booking.joins(:order).where(orders: { user_id: id }, status: "pending")
end

def teacher?
role == "teacher"
def confirmed_bookings
Booking.joins(:order).where(orders: { user_id: id }, status: "confirmed")
end

def speaker?
role == "speaker"
end

def user?
role == "user"
def bookings
Booking.joins(:order).where(orders: { user_id: id })
end
end
4 changes: 4 additions & 0 deletions app/serializers/availability_serializer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
class AvailabilitySerializer
include JSONAPI::Serializer
attributes :start_time, :end_time, :speaker, presence: true
end
6 changes: 6 additions & 0 deletions app/serializers/booking_serializer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class BookingSerializer
include JSONAPI::Serializer
attributes :id, :status, :start_time, :end_time, :created_at, :updated_at

belongs_to :event
end
7 changes: 7 additions & 0 deletions app/serializers/event_serializer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class EventSerializer
include JSONAPI::Serializer
attributes :id, :title, :description, :duration

belongs_to :speaker, serializer: UserSerializer
has_many :bookings
end
48 changes: 18 additions & 30 deletions app/serializers/user_profile_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,49 +2,37 @@ class UserProfileSerializer
include JSONAPI::Serializer
attributes :name, :email, :id, :bio, :profile_image_url, :organization_id

attribute :donations do |user|
user.donations ? user.donations.map { |donation| DonationSerializer.new(donation).serializable_hash } : []
attribute :events, if: Proc.new { |user, params| params[:role] == "speaker" || params[:role] == "teacher" } do |user|
user.events ? user.events.map { |event| EventSerializer.new(event).serializable_hash } : []
end

# attribute :orders do |user|
# user.orders ? user.orders.map { |order| OrderSerializer.new(order).serializable_hash } : []
# end
attribute :availabilities, if: Proc.new { |user, params| params[:role] == "speaker" || params[:role] == "teacher" } do |user|
user.availabilities ? user.availabilities.map { |availability| AvailabilitySerializer.new(availability).serializable_hash } : []
end

attribute :orders do |user|
if user.orders
kit_orders = user.orders.select { |order| order.product.is_a?(Kit) }
kit_orders.map { |order| OrderSerializer.new(order).serializable_hash }
else
[]
end
attribute :pending_bookings, if: Proc.new { |user, params| params[:role] == "speaker" } do |user|
user.pending_bookings ? user.pending_bookings.map { |booking| BookingSerializer.new(booking).serializable_hash } : []
end

attribute :bookings do |user|
if user.orders.present?
booking_orders = user.orders.select { |order| order.product.is_a?(Booking) }
booking_orders.map { |order| OrderSerializer.new(order).serializable_hash }
else
[]
end
attribute :confirmed_bookings, if: Proc.new { |user, params| params[:role] == "speaker" } do |user|
user.confirmed_bookings ? user.confirmed_bookings.map { |booking| BookingSerializer.new(booking).serializable_hash } : []
end

attribute :organization do |user|
if user.organization
OrganizationSerializer.new(user.organization).serializable_hash[:data][:attributes]
else
{}
end
attribute :bookings, if: Proc.new { |user, params| params[:role] == "teacher" } do |user|
user.bookings ? user.bookings.map { |booking| BookingSerializer.new(booking).serializable_hash } : []
end

attribute :addresses do |user|
user.addresses.map { |address| AddressSerializer.new(address).serializable_hash[:data][:attributes] }
attribute :donations do |user|
user.donations ? user.donations.map { |donation| DonationSerializer.new(donation).serializable_hash } : []
end

# Added the profile_image_url method here
attribute :orders, if: Proc.new { |user, params| params[:role] == "teacher" } do |user|
user.orders ? user.orders.map { |order| OrderSerializer.new(order).serializable_hash } : []
end

def profile_image_url
if object.profile_image.attached?
Rails.application.routes.url_helpers.rails_blob_url(object.profile_image, only_path: false)
if @resource.profile_image.attached?
Rails.application.routes.url_helpers.rails_blob_url(@resource.profile_image, only_path: false)
end
end
end
66 changes: 62 additions & 4 deletions spec/requests/users_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,22 @@
RSpec.describe "Users", type: :request do
let(:admin_user) { create(:user, :admin_user) }
let(:regular_user) { create(:user, :regular_user) }

# let(:speaker_user) { create(:user, role: 'speaker', events: [ create(:event) ], availabilities: [ create(:availability) ]) }
# let(:teacher) { create(:user, role: 'teacher') }
let(:speaker_user) do
create(
:user,
role: 'speaker',
events: [ create(:event) ],
availabilities: [ create(:availability) ],
)
end
let(:teacher_user) do
create(
:user,
role: 'teacher',
)
end

describe "GET /index" do
context "when user role is admin" do
Expand All @@ -24,11 +39,11 @@
end
end

describe "GET/ show" do
describe "GET /show" do
context "when user role is admin" do
it "returns http success" do
sign_in admin_user
get api_v1_users_path(admin_user), headers: { 'Authorization': "Bearer #{@auth_token}" }
get api_v1_user_path(admin_user), headers: { 'Authorization': "Bearer #{@auth_token}" }
expect(response).to have_http_status(:success)
end
end
Expand All @@ -37,7 +52,7 @@
it "returns http response success" do
# Changed permissions to view speakers
sign_in regular_user
get api_v1_users_path(regular_user), headers: { 'Authorization': "Bearer #{@auth_token}" }
get api_v1_user_path(regular_user), headers: { 'Authorization': "Bearer #{@auth_token}" }
expect(response).to have_http_status(:success)
end
end
Expand Down Expand Up @@ -96,4 +111,47 @@
end
end
end

# describe "GET /profile" do
context "when user is a speaker" do
it "returns the full speaker profile with all bookings and events" do
sign_in speaker_user
get profile_api_v1_user_path(speaker_user), headers: { 'Authorization': "Bearer #{@auth_token}" }
expect(response).to have_http_status(:success)

json_response = JSON.parse(response.body)
expect(json_response['data']['attributes']).to include(
'bio', 'profile_image_url', 'events', 'availabilities', 'pending_bookings', 'confirmed_bookings'
)
end
end

context "when user is a teacher" do
it "returns a teacher profile with limited information" do
sign_in teacher_user
get profile_api_v1_user_path(teacher_user), headers: { 'Authorization': "Bearer #{@auth_token}" }
expect(response).to have_http_status(:success)

json_response = JSON.parse(response.body)
expect(json_response['data']['attributes']).to include(
'bio', 'profile_image_url', 'events', 'availabilities', 'bookings'
)
end
end

context "when teacher views a speaker profile" do
it "returns the speaker profile with limited information" do
sign_in teacher_user
get profile_api_v1_user_path(speaker_user), headers: { 'Authorization': "Bearer #{@auth_token}" }
expect(response).to have_http_status(:success)

json_response = JSON.parse(response.body)
expect(json_response['data']['attributes']).to include(
'bio', 'profile_image_url', 'events', 'availabilities'
)
expect(json_response['data']['attributes']).not_to include(
'pending_bookings', 'confirmed_bookings'
)
end
end
end

0 comments on commit 45104b2

Please sign in to comment.