Skip to content

Commit

Permalink
Merge branch 'EN-7996-outing-conversation' into staging
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolas-entourage committed Mar 10, 2025
2 parents 5c7c613 + ce83718 commit bc78a16
Show file tree
Hide file tree
Showing 6 changed files with 239 additions and 6 deletions.
35 changes: 33 additions & 2 deletions app/controllers/api/v1/conversations_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def index
conversations = Entourage.joins(:members)
.includes(:chat_messages)
.where.not(chat_messages: { id: nil })
.where(group_type: [:conversation, :action])
.where(group_type: [:conversation, :outing])
.where('join_requests.user_id = ?', current_user.id)
.merge(JoinRequest.accepted)
.order(updated_at: :desc)
Expand All @@ -22,11 +22,27 @@ def index
}
end

def privates
privates = Entourage.joins(:join_requests)
.includes(:join_requests, { user: :partner })
.where(group_type: :conversation)
.where('join_requests.user_id = ?', current_user.id)
.where('join_requests.status = ?', :accepted)
.order(updated_at: :desc)
.page(params[:page] || 1).per(per)

render json: privates, root: :conversations, each_serializer: ::V1::ConversationSerializer, scope: {
user: current_user, include_last_message: true
}
end

# to be deprecated
def private
entourages = Entourage.joins(:join_requests)
.includes(:join_requests, { user: :partner })
.where(group_type: :conversation)
.where('join_requests.user_id = ?', current_user.id)
.where('join_requests.status = ?', :accepted)
.order(updated_at: :desc)
.page(params[:page] || 1).per(per)

Expand All @@ -35,10 +51,25 @@ def private
}
end

def outings
outings = Entourage.joins(:join_requests)
.includes(:join_requests, { user: :partner })
.where(group_type: [:outing])
.where('join_requests.user_id = ?', current_user.id)
.where('join_requests.status = ?', :accepted)
.order(updated_at: :desc)
.page(params[:page] || 1).per(per)

render json: outings, root: :conversations, each_serializer: ::V1::ConversationSerializer, scope: {
user: current_user, include_last_message: true
}
end

# to be deprecated
def group
entourages = Entourage.joins(:join_requests)
.includes(:join_requests, { user: :partner })
.where(group_type: [:action, :outing])
.where(group_type: [:outing])
.where('join_requests.user_id = ?', current_user.id)
.where('join_requests.status = ?', :accepted)
.order(updated_at: :desc)
Expand Down
2 changes: 2 additions & 0 deletions app/serializers/v1/conversation_home_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ def user
end

def section
return unless object.action?

object.becomes(object.action_class).section
end

Expand Down
5 changes: 5 additions & 0 deletions app/serializers/v1/conversation_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ def user
end

def section
return unless object.action?

object.becomes(object.action_class).section
end

Expand All @@ -47,19 +49,22 @@ def section

def type
return :private if private_conversation?
return :outing if object.outing?
return :contribution if object.contribution?

:solicitation
end

def name
return object.title unless private_conversation?
return unless other_participant

UserPresenter.new(user: other_participant).display_name
end

def image_url
return object.image_url unless private_conversation?
return unless other_participant

UserServices::Avatar.new(user: other_participant).thumbnail_url
end
Expand Down
2 changes: 2 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -594,7 +594,9 @@
end

collection do
get :privates
get :private
get :outings
get :group
get :metadata
end
Expand Down
2 changes: 1 addition & 1 deletion spec/acceptance/api/v1/conversations_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
let(:other_user) { FactoryBot.create(:public_user, first_name: 'Michel', last_name: 'Ange') }

# conversations
let(:entourage) { FactoryBot.create(:entourage, title: "foo", status: :open, created_at: 2.hours.ago) }
let(:entourage) { FactoryBot.create(:outing, title: "foo", status: :open, created_at: 2.hours.ago) }
let(:conversation) { FactoryBot.create(:conversation, user: user, participants: [other_user], created_at: 1.hour.ago) }

# memberships
Expand Down
199 changes: 196 additions & 3 deletions spec/controllers/api/v1/conversations_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
let(:request) { get :index, params: { token: user.token }}
let(:participant) { create :public_user, first_name: :Jane }

context 'conversations and actions' do
context 'conversations and outings' do
let(:conversation) { create :conversation, participants: [user, participant] }
let(:action) { create :entourage, status: :open, group_type: :action, participants: [user] }
let(:outing) { create :outing, status: :open, participants: [user] }
Expand All @@ -24,7 +24,7 @@

it { expect(response.status).to eq(200) }
it { expect(subject.count).to eq(2) }
it { expect(subject.map{|c| c["id"] }).to match_array([conversation.id, action.id]) }
it { expect(subject.map{|c| c["id"] }).to match_array([conversation.id, outing.id]) }
end

context 'conversations of any status' do
Expand Down Expand Up @@ -273,8 +273,141 @@
end
end

describe 'GET privates' do
let(:other_user) { FactoryBot.create(:public_user) }
subject { JSON.parse(response.body) }

context "no private conversations" do
let!(:conversation) { create :conversation, participants: [other_user] }

before { get :privates, params: { token: user.token } }

it { expect(subject["conversations"].count).to eq(0) }
end

context "actions are not private" do
let(:entourage) { create :entourage, status: :open, group_type: :action }
let!(:join_request) { FactoryBot.create(:join_request, joinable: entourage, user: user, status: "accepted") }

before { get :privates, params: { token: user.token } }

it { expect(subject["conversations"].count).to eq(0) }
end

describe "some private conversations" do
let!(:conversation) { create :conversation, user: creator }
let!(:join_request) { FactoryBot.create(:join_request, joinable: conversation, user: user, status: "accepted", last_message_read: Time.now) }
let!(:other_conversation) { create :conversation, participants: [other_user] }

let(:creator) { user }

context "name" do
let!(:other_user) { FactoryBot.create :public_user, first_name: "foo", last_name: "bar" }
let!(:other_user_join_request) { FactoryBot.create(:join_request, joinable: conversation, user: other_user, status: "accepted", last_message_read: Time.now) }

before { get :privates, params: { token: user.token } }

context "name is other participant name when the user is the creator" do
# let(:creator) { user }
it { expect(subject["conversations"].count).to eq(1) }
it { expect(subject["conversations"][0]["name"]).to eq("Foo B.") }
end

context "name is other participant name when the user is not the creator" do
let(:creator) { other_user }
it { expect(subject["conversations"].count).to eq(1) }
it { expect(subject["conversations"][0]["name"]).to eq("Foo B.") }
end
end

context "default properties" do
before { get :privates, params: { token: user.token } }
it { expect(subject["conversations"].count).to eq(1) }
it { expect(subject["conversations"][0]).to have_key("last_message") }
it { expect(subject["conversations"][0]).to have_key("number_of_unread_messages") }
end

context "with unread" do
let!(:chat_message) { FactoryBot.create(:chat_message, created_at: 1.minute.from_now, messageable: conversation)}

before { get :privates, params: { token: user.token } }
it { expect(subject["conversations"].first["number_of_unread_messages"]).to eq(1) }
end

context "without unread" do
let!(:chat_message) { FactoryBot.create(:chat_message, created_at: 1.minute.ago, messageable: conversation)}

before { get :privates, params: { token: user.token } }
it { expect(subject["conversations"].first["number_of_unread_messages"]).to eq(0) }
end

context "with last_message" do
let!(:chat_message) { FactoryBot.create(:chat_message, messageable: conversation)}

before { get :privates, params: { token: user.token } }
it { expect(subject["conversations"].first["last_message"]).to be_a(Hash) }
end

context "with some messages, get last_message" do
let!(:chat_message_1) { FactoryBot.create(:chat_message, messageable: conversation, content: "foo", created_at: 1.hour.ago) }
let!(:chat_message_2) { FactoryBot.create(:chat_message, messageable: conversation, content: "bar", created_at: 2.hours.ago) }

before { get :privates, params: { token: user.token } }
it { expect(subject["conversations"].first["last_message"]).to be_a(Hash) }
it { expect(subject["conversations"].first["last_message"]["text"]).to eq("foo") }
end

context "without last_message" do
let!(:chat_message) { FactoryBot.create(:chat_message, messageable: other_conversation)}

before { get :privates, params: { token: user.token } }
it { expect(subject["conversations"].first["last_message"]).to eq(nil) }
end
end

describe "some private conversations with blockers" do
context 'blocked conversations' do
let(:participant) { create :public_user, first_name: :Jane }
let!(:conversation) { create :conversation, participants: [user, participant] }

let(:request) { get :privates, params: { token: user.token } }

context 'user blocked' do
let!(:user_blocked_user) { create(:user_blocked_user, user: user, blocked_user: participant) }

before { request }

it { expect(response.status).to eq(200) }
it { expect(subject["conversations"].count).to eq(1) }
it { expect(subject["conversations"][0]['blockers']).to match_array([ "me" ]) }
end

context 'participant blocked' do
let!(:user_blocked_user) { create(:user_blocked_user, user: participant, blocked_user: user) }

before { request }

it { expect(response.status).to eq(200) }
it { expect(subject["conversations"].count).to eq(1) }
it { expect(subject["conversations"][0]['blockers']).to match_array([ "participant" ]) }
end

context 'both blocked' do
let!(:user_blocked_user_1) { create(:user_blocked_user, user: user, blocked_user: participant) }
let!(:user_blocked_user_2) { create(:user_blocked_user, user: participant, blocked_user: user) }

before { request }

it { expect(response.status).to eq(200) }
it { expect(subject["conversations"].count).to eq(1) }
it { expect(subject["conversations"][0]['blockers']).to match_array([ "me", "participant" ]) }
end
end
end
end

describe 'GET group' do
let!(:entourage) { FactoryBot.create(:entourage, status: :open) }
let!(:entourage) { FactoryBot.create(:outing, status: :open) }
let!(:other_entourage) { FactoryBot.create(:entourage, status: :open) }
let(:other_user) { FactoryBot.create(:public_user) }
subject { JSON.parse(response.body) }
Expand Down Expand Up @@ -333,6 +466,66 @@
end
end

describe 'GET outings' do
let!(:entourage) { FactoryBot.create(:outing, status: :open) }
let!(:other_entourage) { FactoryBot.create(:entourage, status: :open) }
let(:other_user) { FactoryBot.create(:public_user) }
subject { JSON.parse(response.body) }

describe "some outings conversations" do
let!(:join_request) { FactoryBot.create(:join_request, joinable: entourage, user: user, status: "accepted", last_message_read: Time.now) }

context "default properties" do
before { get :outings, params: { token: user.token } }
it { expect(subject["conversations"].count).to eq(1) }
it { expect(subject["conversations"][0]).to have_key("last_message") }
it { expect(subject["conversations"][0]).to have_key("number_of_unread_messages") }
end

context "with unread" do
let!(:chat_message) { FactoryBot.create(:chat_message, created_at: 1.minute.from_now, messageable: entourage)}

before { get :outings, params: { token: user.token } }
it { expect(subject["conversations"].first["number_of_unread_messages"]).to eq(1) }
end

context "without unread" do
let!(:chat_message) { FactoryBot.create(:chat_message, created_at: 1.minute.ago, messageable: entourage)}

before { get :outings, params: { token: user.token } }
it { expect(subject["conversations"].first["number_of_unread_messages"]).to eq(0) }
end

context "with last_message" do
let!(:chat_message) { FactoryBot.create(:chat_message, messageable: entourage)}

before { get :outings, params: { token: user.token } }
it { expect(subject["conversations"].first["last_message"]).to be_a(Hash) }
end

context "without last_message" do
let!(:chat_message) { FactoryBot.create(:chat_message, messageable: other_entourage)}

before { get :outings, params: { token: user.token } }
it { expect(subject["conversations"].first["last_message"]).to eq(nil) }
end
end

context "no outings conversations" do
let!(:join_request) { FactoryBot.create(:join_request, joinable: entourage, user: other_user, status: "accepted") }

before { get :outings, params: { token: user.token } }
it { expect(subject["conversations"].count).to eq(0) }
end

context "outings conversations are not accepted" do
let!(:join_request) { FactoryBot.create(:join_request, joinable: entourage, user: user, status: "pending") }

before { get :outings, params: { token: user.token } }
it { expect(subject["conversations"].count).to eq(0) }
end
end

describe 'GET metadata' do
let!(:group) { FactoryBot.create(:entourage, user: create(:public_user), status: :open) }
let(:other_user) { FactoryBot.create(:public_user) }
Expand Down

0 comments on commit bc78a16

Please sign in to comment.