FIX: handle correctly the case when several subscribers call trackStatus() on the user model (#17497)
This commit is contained in:
parent
17e733b6a8
commit
517e2f7dc4
|
@ -1180,23 +1180,37 @@ User.reopenClass(Singleton, {
|
|||
|
||||
// user status tracking
|
||||
User.reopen(Evented, {
|
||||
_subscribersCount: 0,
|
||||
_clearStatusTimerId: null,
|
||||
|
||||
// always call stopTrackingStatus() when done with a user
|
||||
trackStatus() {
|
||||
this.addObserver("status", this, "_statusChanged");
|
||||
if (this._subscribersCount === 0) {
|
||||
this.addObserver("status", this, "_statusChanged");
|
||||
|
||||
this.appEvents.on("user-status:changed", this, this._updateStatus);
|
||||
this.appEvents.on("user-status:changed", this, this._updateStatus);
|
||||
|
||||
if (this.status && this.status.ends_at) {
|
||||
this._scheduleStatusClearing(this.status.ends_at);
|
||||
if (this.status && this.status.ends_at) {
|
||||
this._scheduleStatusClearing(this.status.ends_at);
|
||||
}
|
||||
}
|
||||
|
||||
this._subscribersCount++;
|
||||
},
|
||||
|
||||
stopTrackingStatus() {
|
||||
this.removeObserver("status", this, "_statusChanged");
|
||||
this.appEvents.off("user-status:changed", this, this._updateStatus);
|
||||
this._unscheduleStatusClearing();
|
||||
if (this._subscribersCount === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._subscribersCount === 1) {
|
||||
// the last subscriber is unsubscribing
|
||||
this.removeObserver("status", this, "_statusChanged");
|
||||
this.appEvents.off("user-status:changed", this, this._updateStatus);
|
||||
this._unscheduleStatusClearing();
|
||||
}
|
||||
|
||||
this._subscribersCount--;
|
||||
},
|
||||
|
||||
_statusChanged(sender, key) {
|
||||
|
|
|
@ -5,13 +5,7 @@ import PreloadStore from "discourse/lib/preload-store";
|
|||
import sinon from "sinon";
|
||||
import { settled } from "@ember/test-helpers";
|
||||
|
||||
module("Unit | Model | user", function (hooks) {
|
||||
hooks.afterEach(function () {
|
||||
if (this.clock) {
|
||||
this.clock.restore();
|
||||
}
|
||||
});
|
||||
|
||||
module("Unit | Model | user", function () {
|
||||
test("staff", function (assert) {
|
||||
let user = User.create({ id: 1, username: "eviltrout" });
|
||||
|
||||
|
@ -112,6 +106,29 @@ module("Unit | Model | user", function (hooks) {
|
|||
assert.ok(spyMomentGuess.notCalled);
|
||||
});
|
||||
|
||||
test("subsequent calls to trackStatus and stopTrackingStatus increase and decrease subscribers counter", function (assert) {
|
||||
const user = User.create();
|
||||
assert.equal(user._subscribersCount, 0);
|
||||
|
||||
user.trackStatus();
|
||||
assert.equal(user._subscribersCount, 1);
|
||||
|
||||
user.trackStatus();
|
||||
assert.equal(user._subscribersCount, 2);
|
||||
|
||||
user.stopTrackingStatus();
|
||||
assert.equal(user._subscribersCount, 1);
|
||||
|
||||
user.stopTrackingStatus();
|
||||
assert.equal(user._subscribersCount, 0);
|
||||
});
|
||||
|
||||
test("attempt to stop tracking status if status wasn't tracked doesn't throw", function (assert) {
|
||||
const user = User.create();
|
||||
user.stopTrackingStatus();
|
||||
assert.ok(true);
|
||||
});
|
||||
|
||||
test("clears statuses of several users correctly when receiving status updates via appEvents", function (assert) {
|
||||
const status1 = {
|
||||
description: "user1 status",
|
||||
|
|
Loading…
Reference in New Issue