Upgrade Notifications to fix deprecations and use store
This commit is contained in:
parent
aab9706b7a
commit
0b65c88003
|
@ -1,22 +1,55 @@
|
|||
const INVITED_TYPE = 8;
|
||||
|
||||
export default Ember.Component.extend({
|
||||
tagName: 'li',
|
||||
classNameBindings: ['notification.read', 'notification.is_warning'],
|
||||
|
||||
scope: function() {
|
||||
return "notifications." + this.site.get("notificationLookup")[this.get("notification.notification_type")];
|
||||
}.property("notification.notification_type"),
|
||||
|
||||
url: function() {
|
||||
const it = this.get('notification');
|
||||
const badgeId = it.get("data.badge_id");
|
||||
if (badgeId) {
|
||||
const badgeName = it.get("data.badge_name");
|
||||
return Discourse.getURL('/badges/' + badgeId + '/' + badgeName.replace(/[^A-Za-z0-9_]+/g, '-').toLowerCase());
|
||||
}
|
||||
|
||||
const topicId = it.get('topic_id');
|
||||
if (topicId) {
|
||||
return Discourse.Utilities.postUrl(it.get("slug"), topicId, it.get("post_number"));
|
||||
}
|
||||
|
||||
if (it.get('notification_type') === INVITED_TYPE) {
|
||||
return Discourse.getURL('/my/invited');
|
||||
}
|
||||
}.property("notification.data.{badge_id,badge_name}", "model.slug", "model.topic_id", "model.post_number"),
|
||||
|
||||
description: function() {
|
||||
const badgeName = this.get("notification.data.badge_name");
|
||||
if (badgeName) { return Handlebars.Utils.escapeExpression(badgeName); }
|
||||
|
||||
const title = this.get('notification.data.topic_title');
|
||||
return Ember.isEmpty(title) ? "" : Handlebars.Utils.escapeExpression(title);
|
||||
}.property("notification.data.{badge_name,topic_title}"),
|
||||
|
||||
_markRead: function(){
|
||||
var self = this;
|
||||
this.$('a').click(function(){
|
||||
self.set('notification.read', true);
|
||||
this.$('a').click(() => {
|
||||
this.set('notification.read', true);
|
||||
return true;
|
||||
});
|
||||
}.on('didInsertElement'),
|
||||
|
||||
render: function(buffer) {
|
||||
var notification = this.get('notification'),
|
||||
text = I18n.t(this.get('scope'), Em.getProperties(notification, 'description', 'username'));
|
||||
render(buffer) {
|
||||
const notification = this.get('notification');
|
||||
const description = this.get('description');
|
||||
const username = notification.get('data.display_username');
|
||||
const text = I18n.t(this.get('scope'), {description, username});
|
||||
|
||||
var url = notification.get('url');
|
||||
const url = this.get('url');
|
||||
if (url) {
|
||||
buffer.push('<a href="' + notification.get('url') + '">' + text + '</a>');
|
||||
buffer.push('<a href="' + url + '">' + text + '</a>');
|
||||
} else {
|
||||
buffer.push(text);
|
||||
}
|
||||
|
|
|
@ -41,10 +41,11 @@ const HeaderController = DiscourseController.extend({
|
|||
if (self.get("loadingNotifications")) { return; }
|
||||
|
||||
self.set("loadingNotifications", true);
|
||||
Discourse.NotificationContainer.loadRecent().then(function(result) {
|
||||
|
||||
this.store.find('notification', {recent: true}).then(function(notifications) {
|
||||
self.setProperties({
|
||||
'currentUser.unread_notifications': 0,
|
||||
notifications: result
|
||||
notifications
|
||||
});
|
||||
}).catch(function() {
|
||||
self.setProperties({
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
import ObjectController from 'discourse/controllers/object';
|
||||
|
||||
const INVITED_TYPE = 8;
|
||||
|
||||
export default ObjectController.extend({
|
||||
|
||||
notificationUrl: function(it) {
|
||||
var badgeId = it.get("data.badge_id");
|
||||
if (badgeId) {
|
||||
var badgeName = it.get("data.badge_name");
|
||||
return Discourse.getURL('/badges/' + badgeId + '/' + badgeName.replace(/[^A-Za-z0-9_]+/g, '-').toLowerCase());
|
||||
}
|
||||
|
||||
var topicId = it.get('topic_id');
|
||||
if (topicId) {
|
||||
return Discourse.Utilities.postUrl(it.get("slug"), topicId, it.get("post_number"));
|
||||
}
|
||||
|
||||
if (it.get('notification_type') === INVITED_TYPE) {
|
||||
return Discourse.getURL('/my/invited');
|
||||
}
|
||||
},
|
||||
|
||||
scope: function() {
|
||||
return "notifications." + this.site.get("notificationLookup")[this.get("notification_type")];
|
||||
}.property("notification_type"),
|
||||
|
||||
username: Em.computed.alias("data.display_username"),
|
||||
|
||||
url: function() {
|
||||
return this.notificationUrl(this);
|
||||
}.property("data.{badge_id,badge_name}", "slug", "topic_id", "post_number"),
|
||||
|
||||
description: function() {
|
||||
const badgeName = this.get("data.badge_name");
|
||||
if (badgeName) { return Handlebars.Utils.escapeExpression(badgeName); }
|
||||
return this.blank("data.topic_title") ? "" : Handlebars.Utils.escapeExpression(this.get("data.topic_title"));
|
||||
}.property("data.{badge_name,topic_title}")
|
||||
|
||||
});
|
|
@ -1,43 +1,21 @@
|
|||
|
||||
export default Ember.ArrayController.extend({
|
||||
needs: ['user-notifications', 'application'],
|
||||
loading: false,
|
||||
needs: ['application'],
|
||||
|
||||
_showFooter: function() {
|
||||
this.set("controllers.application.showFooter", !this.get("canLoadMore"));
|
||||
}.observes("canLoadMore"),
|
||||
this.set("controllers.application.showFooter", !this.get("model.canLoadMore"));
|
||||
}.observes("model.canLoadMore"),
|
||||
|
||||
showDismissButton: function() {
|
||||
return this.get('user').total_unread_notifications > 0;
|
||||
}.property('user'),
|
||||
showDismissButton: Ember.computed.gt('user.total_unread_notifications', 0),
|
||||
|
||||
actions: {
|
||||
resetNew: function() {
|
||||
var self = this;
|
||||
Discourse.NotificationContainer.resetNew().then(function() {
|
||||
self.get('controllers.user-notifications').setEach('read', true);
|
||||
Discourse.ajax('/notifications/mark-read', { method: 'PUT' }).then(() => {
|
||||
this.setEach('read', true);
|
||||
});
|
||||
},
|
||||
|
||||
loadMore: function() {
|
||||
if (this.get('canLoadMore') && !this.get('loading')) {
|
||||
this.set('loading', true);
|
||||
var self = this;
|
||||
Discourse.NotificationContainer.loadHistory(
|
||||
self.get('model.lastObject.created_at'),
|
||||
self.get('user.username')).then(function(result) {
|
||||
self.set('loading', false);
|
||||
var notifications = result.get('content');
|
||||
self.pushObjects(notifications);
|
||||
// Stop trying if it's the end
|
||||
if (notifications && (notifications.length === 0 || notifications.length < 60)) {
|
||||
self.set('canLoadMore', false);
|
||||
}
|
||||
}).catch(function(error) {
|
||||
self.set('loading', false);
|
||||
Em.Logger.error(error);
|
||||
});
|
||||
}
|
||||
this.get('model').loadMore();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -38,13 +38,13 @@ export default {
|
|||
app.register('session:main', Session.current(), { instantiate: false });
|
||||
injectAll(app, 'session');
|
||||
|
||||
app.register('store:main', Store);
|
||||
inject(app, 'store', 'route', 'controller');
|
||||
|
||||
app.register('current-user:main', Discourse.User.current(), { instantiate: false });
|
||||
inject(app, 'currentUser', 'component', 'route', 'controller');
|
||||
|
||||
app.register('message-bus:main', window.MessageBus, { instantiate: false });
|
||||
inject(app, 'messageBus', 'route', 'controller', 'view');
|
||||
|
||||
app.register('store:main', Store);
|
||||
inject(app, 'store', 'route', 'controller');
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,22 +1,15 @@
|
|||
/**
|
||||
Provides the ability to load more items for a view which is scrolled to the bottom.
|
||||
**/
|
||||
|
||||
// Provides the ability to load more items for a view which is scrolled to the bottom.
|
||||
export default Em.Mixin.create(Ember.ViewTargetActionSupport, Discourse.Scrolling, {
|
||||
|
||||
scrolled: function() {
|
||||
var eyeline = this.get('eyeline');
|
||||
const eyeline = this.get('eyeline');
|
||||
if (eyeline) { eyeline.update(); }
|
||||
},
|
||||
|
||||
_bindEyeline: function() {
|
||||
var eyeline = new Discourse.Eyeline(this.get('eyelineSelector') + ":last");
|
||||
const eyeline = new Discourse.Eyeline(this.get('eyelineSelector') + ":last");
|
||||
this.set('eyeline', eyeline);
|
||||
|
||||
var self = this;
|
||||
eyeline.on('sawBottom', function() {
|
||||
self.send('loadMore');
|
||||
});
|
||||
eyeline.on('sawBottom', () => this.send('loadMore'));
|
||||
this.bindScrolling();
|
||||
}.on('didInsertElement'),
|
||||
|
||||
|
|
|
@ -1,54 +0,0 @@
|
|||
Discourse.NotificationContainer = Ember.ArrayProxy.extend({
|
||||
|
||||
});
|
||||
|
||||
Discourse.NotificationContainer.reopenClass({
|
||||
|
||||
createFromJson: function(json_array) {
|
||||
return Discourse.NotificationContainer.create({content: json_array});
|
||||
},
|
||||
|
||||
createFromError: function(error) {
|
||||
return Discourse.NotificationContainer.create({
|
||||
content: [],
|
||||
error: true,
|
||||
forbidden: error.status === 403
|
||||
});
|
||||
},
|
||||
|
||||
loadRecent: function() {
|
||||
// TODO - add .json (breaks tests atm)
|
||||
return Discourse.ajax('/notifications').then(function(result) {
|
||||
return Discourse.NotificationContainer.createFromJson(result);
|
||||
}).catch(function(error) {
|
||||
// TODO HeaderController can't handle a createFromError
|
||||
// just throw for now
|
||||
throw error;
|
||||
});
|
||||
},
|
||||
|
||||
loadHistory: function(beforeDate, username) {
|
||||
var url = '/notifications/history.json',
|
||||
params = [
|
||||
beforeDate ? ('before=' + beforeDate) : null,
|
||||
username ? ('user=' + username) : null
|
||||
];
|
||||
|
||||
// Remove nulls
|
||||
params = params.filter(function(param) { return !!param; });
|
||||
// Build URL
|
||||
params.forEach(function(param, idx) {
|
||||
url = url + (idx === 0 ? '?' : '&') + param;
|
||||
});
|
||||
|
||||
return Discourse.ajax(url).then(function(result) {
|
||||
return Discourse.NotificationContainer.createFromJson(result);
|
||||
}).catch(function(error) {
|
||||
return Discourse.NotificationContainer.createFromError(error);
|
||||
});
|
||||
},
|
||||
|
||||
resetNew: function() {
|
||||
return Discourse.ajax("/notifications/reset-new", {type: 'PUT'});
|
||||
}
|
||||
});
|
|
@ -4,6 +4,10 @@ export default Ember.ArrayProxy.extend({
|
|||
totalRows: 0,
|
||||
refreshing: false,
|
||||
|
||||
canLoadMore: function() {
|
||||
return this.get('length') < this.get('totalRows');
|
||||
}.property('totalRows', 'length'),
|
||||
|
||||
loadMore() {
|
||||
const loadMoreUrl = this.get('loadMoreUrl');
|
||||
if (!loadMoreUrl) { return; }
|
||||
|
|
|
@ -434,16 +434,13 @@ User.reopenClass(Discourse.Singleton, {
|
|||
return user.findDetails(options);
|
||||
},
|
||||
|
||||
/**
|
||||
The current singleton will retrieve its attributes from the `PreloadStore`
|
||||
if it exists. Otherwise, no instance is created.
|
||||
|
||||
@method createCurrent
|
||||
@returns {Discourse.User} the user, if logged in.
|
||||
**/
|
||||
// TODO: Use app.register and junk Discourse.Singleton
|
||||
createCurrent: function() {
|
||||
var userJson = PreloadStore.get('currentUser');
|
||||
if (userJson) { return Discourse.User.create(userJson); }
|
||||
if (userJson) {
|
||||
const store = Discourse.__container__.lookup('store:main');
|
||||
return store.createRecord('user', userJson);
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
|
|
|
@ -1,31 +1,22 @@
|
|||
import ShowFooter from "discourse/mixins/show-footer";
|
||||
import ViewingActionType from "discourse/mixins/viewing-action-type";
|
||||
|
||||
export default Discourse.Route.extend(ShowFooter, {
|
||||
export default Discourse.Route.extend(ShowFooter, ViewingActionType, {
|
||||
actions: {
|
||||
didTransition: function() {
|
||||
this.controllerFor("user_notifications")._showFooter();
|
||||
didTransition() {
|
||||
this.controllerFor("user-notifications")._showFooter();
|
||||
return true;
|
||||
}
|
||||
},
|
||||
|
||||
model: function() {
|
||||
model() {
|
||||
var user = this.modelFor('user');
|
||||
return Discourse.NotificationContainer.loadHistory(undefined, user.get('username'));
|
||||
return this.store.find('notification', {username: user.get('username')});
|
||||
},
|
||||
|
||||
setupController: function(controller, model) {
|
||||
setupController(controller, model) {
|
||||
controller.set('model', model);
|
||||
controller.set('user', this.modelFor('user'));
|
||||
|
||||
if (this.controllerFor('user_activity').get('content')) {
|
||||
this.controllerFor('user_activity').set('userActionType', -1);
|
||||
}
|
||||
|
||||
// properly initialize "canLoadMore"
|
||||
controller.set("canLoadMore", model.get("length") === 60);
|
||||
},
|
||||
|
||||
renderTemplate: function() {
|
||||
this.render('user-notification-history', {into: 'user'});
|
||||
this.viewingActionType(-1);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
{{#conditional-loading-spinner condition=loadingNotifications}}
|
||||
{{#if content}}
|
||||
<ul>
|
||||
{{#each n in model itemController="notification"}}
|
||||
{{notification-item notification=n scope=n.scope}}
|
||||
{{#each n in model}}
|
||||
{{notification-item notification=n}}
|
||||
{{/each}}
|
||||
<li class="read last">
|
||||
<a href="{{unbound myNotificationsUrl}}">{{i18n 'notifications.more'}}…</a>
|
||||
|
|
|
@ -14,9 +14,9 @@
|
|||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#each n in model itemController="notification"}}
|
||||
{{#each n in model}}
|
||||
<div {{bind-attr class=":item :notification n.read::unread"}}>
|
||||
{{notification-item notification=n scope=n.scope}}
|
||||
{{notification-item notification=n}}
|
||||
<span class="time">
|
||||
{{format-date n.created_at leaveAgo="true"}}
|
||||
</span>
|
||||
|
@ -24,7 +24,7 @@
|
|||
{{/each}}
|
||||
|
||||
{{#conditional-loading-spinner condition=loading}}
|
||||
{{#unless canLoadMore}}
|
||||
{{#unless model.canLoadMore}}
|
||||
{{#if showDismissButton}}
|
||||
<div class='notification-buttons'>
|
||||
<button title="{{i18n 'user.dismiss_notifications_tooltip'}}" id='dismiss-notifications' class='btn notifications-read' {{action "resetNew"}}>{{i18n 'user.dismiss_notifications'}}</button>
|
||||
|
|
|
@ -2,6 +2,5 @@ import LoadMore from "discourse/mixins/load-more";
|
|||
|
||||
export default Ember.View.extend(LoadMore, {
|
||||
eyelineSelector: '.user-stream .notification',
|
||||
classNames: ['user-stream', 'notification-history'],
|
||||
templateName: 'user/notifications'
|
||||
classNames: ['user-stream', 'notification-history']
|
||||
});
|
|
@ -1,56 +1,51 @@
|
|||
require_dependency 'notification_serializer'
|
||||
|
||||
class NotificationsController < ApplicationController
|
||||
|
||||
before_filter :ensure_logged_in
|
||||
|
||||
def recent
|
||||
notifications = Notification.recent_report(current_user, 10)
|
||||
def index
|
||||
user = current_user
|
||||
if params[:recent].present?
|
||||
notifications = Notification.recent_report(current_user, 10)
|
||||
|
||||
if notifications.present?
|
||||
# ordering can be off due to PMs
|
||||
max_id = notifications.map(&:id).max
|
||||
current_user.saw_notification_id(max_id) unless params.has_key?(:silent)
|
||||
if notifications.present?
|
||||
# ordering can be off due to PMs
|
||||
max_id = notifications.map(&:id).max
|
||||
current_user.saw_notification_id(max_id) unless params.has_key?(:silent)
|
||||
end
|
||||
current_user.reload
|
||||
current_user.publish_notifications_state
|
||||
|
||||
render_serialized(notifications, NotificationSerializer, root: :notifications)
|
||||
else
|
||||
offset = params[:offset].to_i
|
||||
user = User.find_by_username(params[:username].to_s) if params[:username]
|
||||
|
||||
guardian.ensure_can_see_notifications!(user)
|
||||
|
||||
notifications = Notification.where(user_id: user.id)
|
||||
.visible
|
||||
.includes(:topic)
|
||||
.order(created_at: :desc)
|
||||
|
||||
total_rows = notifications.dup.count
|
||||
notifications = notifications.offset(offset).limit(60)
|
||||
render_json_dump(notifications: serialize_data(notifications, NotificationSerializer),
|
||||
total_rows_notifications: total_rows,
|
||||
load_more_notifications: notifications_path(username: user.username, offset: offset + 60))
|
||||
end
|
||||
current_user.reload
|
||||
current_user.publish_notifications_state
|
||||
|
||||
render_serialized(notifications, NotificationSerializer)
|
||||
end
|
||||
|
||||
def history
|
||||
params.permit(:before, :user)
|
||||
params[:before] ||= 1.day.from_now
|
||||
|
||||
user = current_user
|
||||
user = User.find_by_username(params[:user].to_s) if params[:user]
|
||||
|
||||
unless guardian.can_see_notifications?(user)
|
||||
return render json: {errors: [I18n.t('js.errors.reasons.forbidden')]}, status: 403
|
||||
end
|
||||
|
||||
notifications = Notification.where(user_id: user.id)
|
||||
.visible
|
||||
.includes(:topic)
|
||||
.limit(60)
|
||||
.where('created_at < ?', params[:before])
|
||||
.order(created_at: :desc)
|
||||
|
||||
render_serialized(notifications, NotificationSerializer)
|
||||
end
|
||||
|
||||
def reset_new
|
||||
params.permit(:user)
|
||||
|
||||
user = current_user
|
||||
if params[:user]
|
||||
user = User.find_by_username(params[:user].to_s)
|
||||
end
|
||||
|
||||
Notification.where(user_id: user.id).includes(:topic).where(read: false).update_all(read: true)
|
||||
def mark_read
|
||||
Notification.where(user_id: current_user.id).includes(:topic).where(read: false).update_all(read: true)
|
||||
|
||||
current_user.saw_notification_id(Notification.recent_report(current_user, 1).max)
|
||||
current_user.reload
|
||||
current_user.publish_notifications_state
|
||||
|
||||
render nothing: true
|
||||
render json: success_json
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
class NotificationSerializer < ApplicationSerializer
|
||||
|
||||
attributes :notification_type,
|
||||
attributes :id,
|
||||
:notification_type,
|
||||
:read,
|
||||
:created_at,
|
||||
:post_number,
|
||||
|
|
|
@ -329,9 +329,8 @@ Discourse::Application.routes.draw do
|
|||
end
|
||||
end
|
||||
|
||||
get "notifications" => "notifications#recent"
|
||||
get "notifications/history" => "notifications#history"
|
||||
put "notifications/reset-new" => 'notifications#reset_new'
|
||||
get 'notifications' => 'notifications#index'
|
||||
put 'notifications/mark-read' => 'notifications#mark_read'
|
||||
|
||||
match "/auth/:provider/callback", to: "users/omniauth_callbacks#complete", via: [:get, :post]
|
||||
match "/auth/failure", to: "users/omniauth_callbacks#failure", via: [:get, :post]
|
||||
|
|
|
@ -6,17 +6,17 @@ describe NotificationsController do
|
|||
let!(:user) { log_in }
|
||||
|
||||
it 'should succeed for recent' do
|
||||
xhr :get, :recent
|
||||
xhr :get, :index, recent: true
|
||||
expect(response).to be_success
|
||||
end
|
||||
|
||||
it 'should succeed for history' do
|
||||
xhr :get, :history
|
||||
xhr :get, :index
|
||||
expect(response).to be_success
|
||||
end
|
||||
|
||||
it 'should succeed for history' do
|
||||
xhr :get, :reset_new
|
||||
it 'should succeed' do
|
||||
xhr :put, :mark_read
|
||||
expect(response).to be_success
|
||||
end
|
||||
|
||||
|
@ -24,7 +24,7 @@ describe NotificationsController do
|
|||
notification = Fabricate(:notification, user: user)
|
||||
expect(user.reload.unread_notifications).to eq(1)
|
||||
expect(user.reload.total_unread_notifications).to eq(1)
|
||||
xhr :get, :recent
|
||||
xhr :get, :index, recent: true
|
||||
expect(user.reload.unread_notifications).to eq(0)
|
||||
expect(user.reload.total_unread_notifications).to eq(1)
|
||||
end
|
||||
|
@ -33,7 +33,7 @@ describe NotificationsController do
|
|||
notification = Fabricate(:notification, user: user)
|
||||
expect(user.reload.unread_notifications).to eq(1)
|
||||
expect(user.reload.total_unread_notifications).to eq(1)
|
||||
xhr :get, :recent, silent: true
|
||||
xhr :get, :index, recent: true, silent: true
|
||||
expect(user.reload.unread_notifications).to eq(1)
|
||||
expect(user.reload.total_unread_notifications).to eq(1)
|
||||
end
|
||||
|
@ -42,7 +42,7 @@ describe NotificationsController do
|
|||
notification = Fabricate(:notification, user: user)
|
||||
expect(user.reload.unread_notifications).to eq(1)
|
||||
expect(user.reload.total_unread_notifications).to eq(1)
|
||||
xhr :put, :reset_new
|
||||
xhr :put, :mark_read
|
||||
user.reload
|
||||
expect(user.reload.unread_notifications).to eq(0)
|
||||
expect(user.reload.total_unread_notifications).to eq(0)
|
||||
|
@ -51,7 +51,7 @@ describe NotificationsController do
|
|||
|
||||
context 'when not logged in' do
|
||||
it 'should raise an error' do
|
||||
expect { xhr :get, :recent }.to raise_error(Discourse::NotLoggedIn)
|
||||
expect { xhr :get, :index, recent: true }.to raise_error(Discourse::NotLoggedIn)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
moduleFor("controller:header", "controller:header", {
|
||||
needs: ['controller:application']
|
||||
});
|
||||
|
||||
test("showNotifications action", function() {
|
||||
let resolveRequestWith;
|
||||
const request = new Ember.RSVP.Promise(function(resolve) {
|
||||
resolveRequestWith = resolve;
|
||||
});
|
||||
|
||||
const currentUser = Discourse.User.create({ unread_notifications: 1});
|
||||
const controller = this.subject({ currentUser: currentUser });
|
||||
const viewSpy = { showDropdownBySelector: sinon.spy() };
|
||||
|
||||
sandbox.stub(Discourse, "ajax").withArgs("/notifications").returns(request);
|
||||
|
||||
Ember.run(function() {
|
||||
controller.send("showNotifications", viewSpy);
|
||||
});
|
||||
|
||||
equal(controller.get("notifications"), null, "notifications are null before data has finished loading");
|
||||
equal(currentUser.get("unread_notifications"), 1, "current user's unread notifications count is not zeroed before data has finished loading");
|
||||
ok(viewSpy.showDropdownBySelector.calledWith("#user-notifications"), "dropdown with loading glyph is shown before data has finished loading");
|
||||
|
||||
Ember.run(function() {
|
||||
resolveRequestWith(["notification"]);
|
||||
});
|
||||
|
||||
// Can't use deepEquals because controller.get("notifications") is an ArrayProxy, not an Array
|
||||
ok(controller.get("notifications").indexOf("notification") !== -1, "notification is in the controller");
|
||||
equal(currentUser.get("unread_notifications"), 0, "current user's unread notifications count is zeroed after data has finished loading");
|
||||
ok(viewSpy.showDropdownBySelector.calledWith("#user-notifications"), "dropdown with notifications is shown after data has finished loading");
|
||||
});
|
|
@ -1,56 +0,0 @@
|
|||
import Site from 'discourse/models/site';
|
||||
|
||||
function buildFixture() {
|
||||
return {
|
||||
notification_type: 1, //mentioned
|
||||
post_number: 1,
|
||||
topic_id: 1234,
|
||||
slug: "a-slug",
|
||||
data: {
|
||||
topic_title: "some title",
|
||||
display_username: "velesin"
|
||||
},
|
||||
site: Site.current()
|
||||
};
|
||||
}
|
||||
|
||||
moduleFor("controller:notification");
|
||||
|
||||
test("scope property is correct", function() {
|
||||
const controller = this.subject(buildFixture());
|
||||
equal(controller.get("scope"), "notifications.mentioned");
|
||||
});
|
||||
|
||||
test("username property is correct", function() {
|
||||
const controller = this.subject(buildFixture());
|
||||
equal(controller.get("username"), "velesin");
|
||||
});
|
||||
|
||||
test("description property returns badge name when there is one", function() {
|
||||
const fixtureWithBadgeName = _.extend({}, buildFixture(), { data: { badge_name: "badge" } });
|
||||
const controller = this.subject(fixtureWithBadgeName);
|
||||
equal(controller.get("description"), "badge");
|
||||
});
|
||||
|
||||
test("description property returns empty string when there is no topic title", function() {
|
||||
const fixtureWithEmptyTopicTitle = _.extend({}, buildFixture(), { data: { topic_title: "" } });
|
||||
const controller = this.subject(fixtureWithEmptyTopicTitle);
|
||||
equal(controller.get("description"), "");
|
||||
});
|
||||
|
||||
test("description property returns topic title", function() {
|
||||
const fixtureWithTopicTitle = _.extend({}, buildFixture(), { data: { topic_title: "topic" } });
|
||||
const controller = this.subject(fixtureWithTopicTitle);
|
||||
equal(controller.get("description"), "topic");
|
||||
});
|
||||
|
||||
test("url property returns badge's url when there is a badge", function() {
|
||||
const fixtureWithBadge = _.extend({}, buildFixture(), { data: { badge_id: 1, badge_name: "Badge Name"} });
|
||||
const controller = this.subject(fixtureWithBadge);
|
||||
equal(controller.get("url"), "/badges/1/badge-name");
|
||||
});
|
||||
|
||||
test("url property returns topic's url when there is a topic", function() {
|
||||
const controller = this.subject(buildFixture());
|
||||
equal(controller.get("url"), "/t/a-slug/1234");
|
||||
});
|
|
@ -1,2 +1,2 @@
|
|||
/*jshint maxlen:10000000 */
|
||||
export default {"/notifications": [ { notification_type: 2, read: true, post_number: 2, topic_id: 1234, slug: "a-slug", data: { topic_title: "some title", display_username: "velesin" } } ] };
|
||||
export default {"/notifications": {notifications: [ { id: 123, notification_type: 2, read: true, post_number: 2, topic_id: 1234, slug: "a-slug", data: { topic_title: "some title", display_username: "velesin" } } ] }};
|
||||
|
|
|
@ -36,7 +36,7 @@ test('updating simultaneously', function() {
|
|||
expect(2);
|
||||
|
||||
const store = createStore();
|
||||
store.find('widget', 123).then(function(widget) {
|
||||
return store.find('widget', 123).then(function(widget) {
|
||||
|
||||
const firstPromise = widget.update({ name: 'new name' });
|
||||
const secondPromise = widget.update({ name: 'new name' });
|
||||
|
@ -90,7 +90,7 @@ test('creating simultaneously', function() {
|
|||
|
||||
test('destroyRecord', function() {
|
||||
const store = createStore();
|
||||
store.find('widget', 123).then(function(widget) {
|
||||
return store.find('widget', 123).then(function(widget) {
|
||||
widget.destroyRecord().then(function(result) {
|
||||
ok(result);
|
||||
});
|
||||
|
|
|
@ -20,6 +20,7 @@ test('pagination support', function() {
|
|||
equal(rs.get('totalRows'), 4);
|
||||
ok(rs.get('loadMoreUrl'), 'has a url to load more');
|
||||
ok(!rs.get('loadingMore'), 'it is not loading more');
|
||||
ok(rs.get('canLoadMore'));
|
||||
|
||||
const promise = rs.loadMore();
|
||||
|
||||
|
@ -28,6 +29,7 @@ test('pagination support', function() {
|
|||
ok(!rs.get('loadingMore'), 'it finished loading more');
|
||||
equal(rs.get('length'), 4);
|
||||
ok(!rs.get('loadMoreUrl'));
|
||||
ok(!rs.get('canLoadMore'));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue