discourse/plugins/chat/test/javascripts/unit/services/chat-test.js
Roman Rizzi 0a5f548635
DEV: Move discourse-chat to the core repo. (#18776)
As part of this move, we are also renaming `discourse-chat` to `chat`.
2022-11-02 10:41:30 -03:00

264 lines
8.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import MockPresenceChannel from "../../helpers/mock-presence-channel";
import {
acceptance,
publishToMessageBus,
} from "discourse/tests/helpers/qunit-helpers";
import { test } from "qunit";
import fabricators from "../../helpers/fabricators";
import { directMessageChannels } from "discourse/plugins/chat/chat-fixtures";
import { cloneJSON } from "discourse-common/lib/object";
import ChatChannel from "discourse/plugins/chat/discourse/models/chat-channel";
import sinon from "sinon";
import pretender from "discourse/tests/helpers/create-pretender";
import { settled } from "@ember/test-helpers";
acceptance("Discourse Chat | Unit | Service | chat", function (needs) {
needs.hooks.beforeEach(function () {
Object.defineProperty(this, "chatService", {
get: () => this.container.lookup("service:chat"),
});
Object.defineProperty(this, "currentUser", {
get: () => this.container.lookup("service:current-user"),
});
});
needs.user({ ignored_users: [] });
needs.pretender((server, helper) => {
server.get("/chat/chat_channels.json", () => {
return helper.response({
public_channels: [
{
id: 1,
title: "something",
chatable_type: "Category",
last_message_sent_at: "2021-11-08T21:26:05.710Z",
current_user_membership: {
unread_count: 2,
last_read_message_id: 123,
unread_mentions: 0,
muted: false,
},
},
],
direct_message_channels: [],
});
});
server.put("/chat/:chatChannelId/read/:messageId.json", () => {
return helper.response({ success: "OK" });
});
});
function setupMockPresenceChannel(chatService) {
chatService.set(
"presenceChannel",
MockPresenceChannel.create({
name: `/chat-reply/1`,
})
);
}
test("#markNetworkAsReliable", async function (assert) {
setupMockPresenceChannel(this.chatService);
this.chatService.markNetworkAsReliable();
assert.strictEqual(this.chatService.isNetworkUnreliable, false);
});
test("#markNetworkAsUnreliable", async function (assert) {
setupMockPresenceChannel(this.chatService);
this.chatService.markNetworkAsUnreliable();
assert.strictEqual(this.chatService.isNetworkUnreliable, true);
await settled();
assert.strictEqual(
this.chatService.isNetworkUnreliable,
false,
"it resets state after a delay"
);
});
test("#startTrackingChannel - sorts dm channels", async function (assert) {
setupMockPresenceChannel(this.chatService);
const fixtures = cloneJSON(directMessageChannels).mapBy("chat_channel");
const channel1 = ChatChannel.create(fixtures[0]);
const channel2 = ChatChannel.create(fixtures[1]);
await this.chatService.startTrackingChannel(channel1);
this.currentUser.set(
`chat_channel_tracking_state.${channel1.id}.unread_count`,
0
);
await this.chatService.startTrackingChannel(channel2);
assert.strictEqual(
this.chatService.directMessageChannels.firstObject.title,
channel2.title
);
});
test("#refreshTrackingState", async function (assert) {
this.currentUser.set("chat_channel_tracking_state", {});
await this.chatService.refreshTrackingState();
assert.equal(
this.currentUser.chat_channel_tracking_state[1].unread_count,
2
);
});
test("attempts to track a non followed channel", async function (assert) {
this.currentUser.set("chat_channel_tracking_state", {});
const channel = fabricators.chatChannel();
await this.chatService.startTrackingChannel(channel);
assert.false(channel.current_user_membership.following);
assert.notOk(
this.currentUser.chat_channel_tracking_state[channel.id],
"it doesnt track it"
);
});
test("/chat/:channelId/new-messages - message from current user", async function (assert) {
setupMockPresenceChannel(this.chatService);
await this.chatService.forceRefreshChannels();
await publishToMessageBus("/chat/1/new-messages", {
user_id: this.currentUser.id,
username: this.currentUser.username,
message_id: 124,
});
assert.equal(
this.currentUser.chat_channel_tracking_state[1].chat_message_id,
124,
"updates tracking state last message id to the message id sent by current user"
);
assert.equal(
this.currentUser.chat_channel_tracking_state[1].unread_count,
2,
"does not increment unread count"
);
});
test("/chat/:channelId/new-messages - message from user that current user is ignoring", async function (assert) {
this.currentUser.set("ignored_users", ["johnny"]);
setupMockPresenceChannel(this.chatService);
await this.chatService.forceRefreshChannels();
await publishToMessageBus("/chat/1/new-messages", {
user_id: 2327,
username: "johnny",
message_id: 124,
});
assert.equal(
this.currentUser.chat_channel_tracking_state[1].chat_message_id,
124,
"updates tracking state last message id to the message id sent by johnny"
);
assert.equal(
this.currentUser.chat_channel_tracking_state[1].unread_count,
2,
"does not increment unread count"
);
});
test("/chat/:channelId/new-messages - message from another user", async function (assert) {
setupMockPresenceChannel(this.chatService);
await this.chatService.forceRefreshChannels();
await publishToMessageBus("/chat/1/new-messages", {
user_id: 2327,
username: "jane",
message_id: 124,
});
assert.equal(
this.currentUser.chat_channel_tracking_state[1].chat_message_id,
123,
"does not update tracking state last message id to the message id sent by jane"
);
assert.equal(
this.currentUser.chat_channel_tracking_state[1].unread_count,
3,
"does increment unread count"
);
});
test("#updateLastReadMessage - updates and tracks the last read message", async function (assert) {
this.currentUser.set("chat_channel_tracking_state", {});
sinon.stub(document, "querySelectorAll").callsFake(function () {
return [{ dataset: { id: 2 } }];
});
const activeChannel = fabricators.chatChannel({
current_user_membership: { last_read_message_id: 1, following: true },
});
this.chatService.setActiveChannel(activeChannel);
this.chatService.updateLastReadMessage();
await settled();
assert.equal(activeChannel.lastSendReadMessageId, 2);
});
test("#updateLastReadMessage - does nothing if the user doesn't follow the channel", async function (assert) {
this.currentUser.set("chat_channel_tracking_state", {});
this.chatService.setActiveChannel(
fabricators.chatChannel({ current_user_membership: { following: false } })
);
sinon.stub(document, "querySelectorAll").callsFake(function () {
return [{ dataset: { id: 1 } }];
});
this.chatService.updateLastReadMessage();
await settled();
assert.equal(this.chatService.activeChannel.lastSendReadMessageId, null);
});
test("#updateLastReadMessage - does nothing if the user already read the message", async function (assert) {
this.currentUser.set("chat_channel_tracking_state", {});
sinon.stub(document, "querySelectorAll").callsFake(function () {
return [{ dataset: { id: 1 } }];
});
const activeChannel = fabricators.chatChannel({
current_user_membership: { last_read_message_id: 2, following: true },
});
this.chatService.setActiveChannel(activeChannel);
this.chatService.updateLastReadMessage();
await settled();
assert.equal(activeChannel.lastSendReadMessageId, 2);
});
});
acceptance(
"Discourse Chat | Unit | Service | chat - no current user",
function (needs) {
needs.hooks.beforeEach(function () {
Object.defineProperty(this, "chatService", {
get: () => this.container.lookup("service:chat"),
});
});
test("#refreshTrackingState", async function (assert) {
pretender.get(`/chat/chat_channels.json`, () => {
assert.step("unexpected");
return [200, { "Content-Type": "application/json" }, {}];
});
assert.step("start");
await this.chatService.refreshTrackingState();
assert.step("end");
assert.verifySteps(["start", "end"], "it does no requests");
});
}
);