mirror of
https://github.com/discourse/discourse.git
synced 2025-02-26 07:38:40 +08:00

This moves chat tracking state calculation for channels and threads into a central Chat::TrackingStateManager service, that serves a similar purpose to the TopicTrackingState model in core. This service calls down to these query classes: * ThreadUnreadsQuery * ChannelUnreadsQuery To get the unread_count and mention_count for the appropriate channels and threads. As well as this, this commit refactors the client-side chat tracking state. Now, there is a central ChatTrackingStateManager Ember Service so all tracking is accessible and can be counted from one place, which can also initialize tracking from an initial payload. The actual tracking counts are now maintained in a ChatTrackingState class that is initialized on the `.tracking` property of both channel and thread objects. This removes the attributes on UserChatChannelMembership and decoration of said membership from ChannelFetcher, preferring instead to have an additional object for tracking in the JSON.
185 lines
6.5 KiB
Ruby
185 lines
6.5 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
RSpec.describe ::Chat::TrackingState do
|
|
describe ".call" do
|
|
subject(:result) { described_class.call(params) }
|
|
|
|
fab!(:current_user) { Fabricate(:user) }
|
|
fab!(:channel_1) { Fabricate(:chat_channel, threading_enabled: true) }
|
|
fab!(:channel_2) { Fabricate(:chat_channel, threading_enabled: true) }
|
|
fab!(:thread_1) { Fabricate(:chat_thread, channel: channel_1) }
|
|
fab!(:thread_2) { Fabricate(:chat_thread, channel: channel_1) }
|
|
fab!(:thread_3) { Fabricate(:chat_thread, channel: channel_2) }
|
|
fab!(:thread_4) { Fabricate(:chat_thread, channel: channel_2) }
|
|
|
|
let(:guardian) { Guardian.new(current_user) }
|
|
let(:id_params) { { channel_ids: [channel_1.id], thread_ids: [thread_1.id] } }
|
|
let(:include_threads) { nil }
|
|
let(:include_missing_memberships) { nil }
|
|
|
|
let(:params) do
|
|
id_params.merge(guardian: guardian).merge(
|
|
include_threads: include_threads,
|
|
include_missing_memberships: include_missing_memberships,
|
|
)
|
|
end
|
|
|
|
context "when enable_experimental_chat_threaded_discussions is disabled" do
|
|
before { SiteSetting.enable_experimental_chat_threaded_discussions = false }
|
|
|
|
context "when include_threads is true" do
|
|
let(:include_threads) { true }
|
|
it { is_expected.to fail_a_policy(:threaded_discussions_settings_ok) }
|
|
end
|
|
|
|
context "when include_threads is false" do
|
|
let(:include_threads) { false }
|
|
it { is_expected.not_to fail_a_policy(:threaded_discussions_settings_ok) }
|
|
end
|
|
end
|
|
|
|
context "when enable_experimental_chat_threaded_discussions is enabled" do
|
|
before { SiteSetting.enable_experimental_chat_threaded_discussions = true }
|
|
|
|
let(:include_threads) { true }
|
|
fab!(:channel_1_membership) do
|
|
Fabricate(:user_chat_channel_membership, chat_channel: channel_1, user: current_user)
|
|
end
|
|
fab!(:thread_1_membership) do
|
|
Fabricate(:user_chat_thread_membership, thread: thread_1, user: current_user)
|
|
end
|
|
fab!(:thread_2_membership) do
|
|
Fabricate(:user_chat_thread_membership, thread: thread_2, user: current_user)
|
|
end
|
|
|
|
context "when not including channels and threads where the user is not a member" do
|
|
context "when only channel_ids are provided" do
|
|
let(:id_params) { { channel_ids: [channel_1.id, channel_2.id] } }
|
|
|
|
it "gets the tracking state of the channels" do
|
|
generate_tracking_state
|
|
expect(result.report.channel_tracking).to eq(
|
|
channel_1.id => {
|
|
unread_count: 4, # 2 messages + 2 thread original messages
|
|
mention_count: 0,
|
|
},
|
|
)
|
|
end
|
|
|
|
it "gets the tracking state of the threads in the channels" do
|
|
generate_tracking_state
|
|
expect(result.report.thread_tracking).to eq(
|
|
thread_1.id => {
|
|
channel_id: channel_1.id,
|
|
unread_count: 1,
|
|
mention_count: 0,
|
|
},
|
|
thread_2.id => {
|
|
channel_id: channel_1.id,
|
|
unread_count: 2,
|
|
mention_count: 0,
|
|
},
|
|
)
|
|
end
|
|
|
|
context "when include_threads is false" do
|
|
let(:include_threads) { false }
|
|
|
|
it "only gets channel tracking state and no thread tracking state" do
|
|
generate_tracking_state
|
|
expect(result.report.thread_tracking).to eq({})
|
|
expect(result.report.channel_tracking).to eq(
|
|
channel_1.id => {
|
|
unread_count: 4, # 2 messages + 2 thread original messages
|
|
mention_count: 0,
|
|
},
|
|
)
|
|
end
|
|
end
|
|
end
|
|
|
|
context "when thread_ids and channel_ids are provided" do
|
|
let(:id_params) do
|
|
{ channel_ids: [channel_1.id, channel_2.id], thread_ids: [thread_2.id] }
|
|
end
|
|
|
|
it "gets the tracking state of the channels" do
|
|
generate_tracking_state
|
|
expect(result.report.channel_tracking).to eq(
|
|
channel_1.id => {
|
|
unread_count: 4, # 2 messages + 2 thread original messages
|
|
mention_count: 0,
|
|
},
|
|
)
|
|
end
|
|
|
|
it "only gets the tracking state of the specified threads in the channels" do
|
|
generate_tracking_state
|
|
expect(result.report.thread_tracking).to eq(
|
|
thread_2.id => {
|
|
channel_id: channel_1.id,
|
|
unread_count: 2,
|
|
mention_count: 0,
|
|
},
|
|
)
|
|
end
|
|
end
|
|
end
|
|
|
|
context "when including channels and threads where the user is not a member" do
|
|
let(:id_params) { { channel_ids: [channel_1.id, channel_2.id] } }
|
|
let(:include_missing_memberships) { true }
|
|
let(:include_threads) { true }
|
|
|
|
it "gets the tracking state of all channels including the ones where the user is not a member" do
|
|
generate_tracking_state
|
|
expect(result.report.channel_tracking).to eq(
|
|
channel_1.id => {
|
|
unread_count: 4, # 2 messages + 2 thread original messages
|
|
mention_count: 0,
|
|
},
|
|
channel_2.id => {
|
|
unread_count: 0,
|
|
mention_count: 0,
|
|
},
|
|
)
|
|
end
|
|
|
|
it "gets the tracking state of all the threads in the channels including the ones where the user is not a member" do
|
|
generate_tracking_state
|
|
expect(result.report.thread_tracking).to eq(
|
|
thread_1.id => {
|
|
channel_id: channel_1.id,
|
|
unread_count: 1,
|
|
mention_count: 0,
|
|
},
|
|
thread_2.id => {
|
|
channel_id: channel_1.id,
|
|
unread_count: 2,
|
|
mention_count: 0,
|
|
},
|
|
thread_3.id => {
|
|
channel_id: channel_2.id,
|
|
unread_count: 0,
|
|
mention_count: 0,
|
|
},
|
|
thread_4.id => {
|
|
channel_id: channel_2.id,
|
|
unread_count: 0,
|
|
mention_count: 0,
|
|
},
|
|
)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
def generate_tracking_state
|
|
Fabricate(:chat_message, chat_channel: channel_1)
|
|
Fabricate(:chat_message, chat_channel: channel_1)
|
|
Fabricate(:chat_message, chat_channel: channel_1, thread: thread_1)
|
|
Fabricate(:chat_message, chat_channel: channel_1, thread: thread_2)
|
|
Fabricate(:chat_message, chat_channel: channel_1, thread: thread_2)
|
|
end
|
|
end
|