mirror of
https://github.com/overleaf/overleaf.git
synced 2025-04-09 15:19:02 +00:00
Merge pull request #2521 from overleaf/ta-announcement-remove
Remove Announcements GitOrigin-RevId: 3fed602e89992ad5f4260134b87ade1e6e088cf7
This commit is contained in:
parent
294418b4ee
commit
db27215760
13 changed files with 3 additions and 783 deletions
|
@ -1,6 +1,4 @@
|
|||
const settings = require('settings-sharelatex')
|
||||
const logger = require('logger-sharelatex')
|
||||
const request = require('request')
|
||||
const FaultTolerantRequest = require('../../infrastructure/FaultTolerantRequest')
|
||||
const Errors = require('../Errors/Errors')
|
||||
|
||||
|
@ -61,18 +59,6 @@ const makeAnalyticsBackgroundRequest = function(userId, options, callback) {
|
|||
FaultTolerantRequest.backgroundRequest(options, callback)
|
||||
}
|
||||
|
||||
// make synchronous request to analytics without retries after checking and
|
||||
// preparing it.
|
||||
const makeAnalyticsRequest = function(userId, options, callback) {
|
||||
let { error, skip } = checkAnalyticsRequest(userId)
|
||||
if (error || skip) {
|
||||
return callback(error)
|
||||
}
|
||||
prepareAnalyticsRequest(options)
|
||||
|
||||
request(options, callback)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
identifyUser(userId, oldUserId, callback) {
|
||||
if (!callback) {
|
||||
|
@ -138,25 +124,5 @@ module.exports = {
|
|||
}
|
||||
|
||||
makeAnalyticsBackgroundRequest(userId, opts, callback)
|
||||
},
|
||||
|
||||
getLastOccurrence(userId, event, callback) {
|
||||
const opts = {
|
||||
body: {
|
||||
event
|
||||
},
|
||||
json: true,
|
||||
method: 'POST',
|
||||
timeout: 1000,
|
||||
url: `/user/${userId}/event/last_occurrence`
|
||||
}
|
||||
makeAnalyticsRequest(userId, opts, function(err, response, body) {
|
||||
if (err != null) {
|
||||
logger.warn({ userId, err }, 'error getting last occurance of event')
|
||||
callback(err)
|
||||
} else {
|
||||
callback(null, body)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,59 +0,0 @@
|
|||
/* eslint-disable
|
||||
max-len,
|
||||
*/
|
||||
// TODO: This file was created by bulk-decaffeinate.
|
||||
// Fix any style issues and re-enable lint.
|
||||
/*
|
||||
* decaffeinate suggestions:
|
||||
* DS102: Remove unnecessary code created because of implicit returns
|
||||
* DS103: Rewrite code to no longer use __guard__
|
||||
* DS207: Consider shorter variations of null checks
|
||||
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
||||
*/
|
||||
const AnnouncementsHandler = require('./AnnouncementsHandler')
|
||||
const AuthenticationController = require('../Authentication/AuthenticationController')
|
||||
const logger = require('logger-sharelatex')
|
||||
const settings = require('settings-sharelatex')
|
||||
|
||||
module.exports = {
|
||||
getUndreadAnnouncements(req, res, next) {
|
||||
if (
|
||||
__guard__(
|
||||
__guard__(
|
||||
settings != null ? settings.apis : undefined,
|
||||
x1 => x1.analytics
|
||||
),
|
||||
x => x.url
|
||||
) == null ||
|
||||
settings.apis.blog.url == null
|
||||
) {
|
||||
return res.json([])
|
||||
}
|
||||
|
||||
const user = AuthenticationController.getSessionUser(req)
|
||||
logger.log(
|
||||
{ user_id: user != null ? user._id : undefined },
|
||||
'getting unread announcements'
|
||||
)
|
||||
return AnnouncementsHandler.getUnreadAnnouncements(user, function(
|
||||
err,
|
||||
announcements
|
||||
) {
|
||||
if (err != null) {
|
||||
logger.warn(
|
||||
{ err, user_id: user._id },
|
||||
'unable to get unread announcements'
|
||||
)
|
||||
return next(err)
|
||||
} else {
|
||||
return res.json(announcements)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function __guard__(value, transform) {
|
||||
return typeof value !== 'undefined' && value !== null
|
||||
? transform(value)
|
||||
: undefined
|
||||
}
|
|
@ -1,126 +0,0 @@
|
|||
/* eslint-disable
|
||||
handle-callback-err,
|
||||
max-len,
|
||||
standard/no-callback-literal,
|
||||
*/
|
||||
// TODO: This file was created by bulk-decaffeinate.
|
||||
// Fix any style issues and re-enable lint.
|
||||
/*
|
||||
* decaffeinate suggestions:
|
||||
* DS102: Remove unnecessary code created because of implicit returns
|
||||
* DS103: Rewrite code to no longer use __guard__
|
||||
* DS207: Consider shorter variations of null checks
|
||||
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
||||
*/
|
||||
let AnnouncementsHandler
|
||||
const AnalyticsManager = require('../Analytics/AnalyticsManager')
|
||||
const BlogHandler = require('../Blog/BlogHandler')
|
||||
const logger = require('logger-sharelatex')
|
||||
const settings = require('settings-sharelatex')
|
||||
const async = require('async')
|
||||
const _ = require('lodash')
|
||||
|
||||
module.exports = AnnouncementsHandler = {
|
||||
_domainSpecificAnnouncements(email) {
|
||||
const domainSpecific = _.filter(
|
||||
settings != null ? settings.domainAnnouncements : undefined,
|
||||
function(domainAnnouncment) {
|
||||
const matches = _.filter(
|
||||
domainAnnouncment.domains,
|
||||
domain => email.indexOf(domain) !== -1
|
||||
)
|
||||
return matches.length > 0 && domainAnnouncment.id != null
|
||||
}
|
||||
)
|
||||
return domainSpecific || []
|
||||
},
|
||||
|
||||
getUnreadAnnouncements(user, callback) {
|
||||
if (callback == null) {
|
||||
callback = function(err, announcements) {}
|
||||
}
|
||||
if (user == null && user._id == null) {
|
||||
return callback(new Error('user not supplied'))
|
||||
}
|
||||
|
||||
const timestamp = user._id.toString().substring(0, 8)
|
||||
const userSignupDate = new Date(parseInt(timestamp, 16) * 1000)
|
||||
|
||||
return async.parallel(
|
||||
{
|
||||
lastEvent(cb) {
|
||||
return AnalyticsManager.getLastOccurrence(
|
||||
user._id,
|
||||
'announcement-alert-dismissed',
|
||||
cb
|
||||
)
|
||||
},
|
||||
announcements(cb) {
|
||||
return BlogHandler.getLatestAnnouncements(cb)
|
||||
}
|
||||
},
|
||||
function(err, results) {
|
||||
if (err != null) {
|
||||
logger.warn(
|
||||
{ err, user_id: user._id },
|
||||
'error getting unread announcements'
|
||||
)
|
||||
return callback(err)
|
||||
}
|
||||
|
||||
let domainSpecific = AnnouncementsHandler._domainSpecificAnnouncements(
|
||||
user != null ? user.email : undefined
|
||||
)
|
||||
|
||||
domainSpecific = _.map(domainSpecific, function(domainAnnouncment) {
|
||||
try {
|
||||
domainAnnouncment.date = new Date(domainAnnouncment.date)
|
||||
return domainAnnouncment
|
||||
} catch (e) {
|
||||
return callback(e)
|
||||
}
|
||||
})
|
||||
|
||||
let { announcements } = results
|
||||
announcements = _.union(announcements, domainSpecific)
|
||||
announcements = _.sortBy(announcements, 'date').reverse()
|
||||
|
||||
const lastSeenBlogId = __guard__(
|
||||
__guard__(
|
||||
results != null ? results.lastEvent : undefined,
|
||||
x1 => x1.segmentation
|
||||
),
|
||||
x => x.blogPostId
|
||||
)
|
||||
|
||||
const announcementIndex = _.findIndex(
|
||||
announcements,
|
||||
announcement => announcement.id === lastSeenBlogId
|
||||
)
|
||||
|
||||
announcements = _.map(announcements, function(announcement, index) {
|
||||
let read
|
||||
if (announcement.date < userSignupDate) {
|
||||
read = true
|
||||
} else if (announcementIndex === -1) {
|
||||
read = false
|
||||
} else if (index >= announcementIndex) {
|
||||
read = true
|
||||
} else {
|
||||
read = false
|
||||
}
|
||||
announcement.read = read
|
||||
return announcement
|
||||
})
|
||||
|
||||
return callback(null, announcements)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
function __guard__(value, transform) {
|
||||
return typeof value !== 'undefined' && value !== null
|
||||
? transform(value)
|
||||
: undefined
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
/* eslint-disable
|
||||
max-len,
|
||||
no-unused-vars,
|
||||
standard/no-callback-literal,
|
||||
*/
|
||||
// TODO: This file was created by bulk-decaffeinate.
|
||||
// Fix any style issues and re-enable lint.
|
||||
/*
|
||||
* decaffeinate suggestions:
|
||||
* DS102: Remove unnecessary code created because of implicit returns
|
||||
* DS207: Consider shorter variations of null checks
|
||||
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
||||
*/
|
||||
let BlogHandler
|
||||
const request = require('request')
|
||||
const settings = require('settings-sharelatex')
|
||||
const _ = require('underscore')
|
||||
const logger = require('logger-sharelatex')
|
||||
|
||||
module.exports = BlogHandler = {
|
||||
getLatestAnnouncements(callback) {
|
||||
const blogUrl = `${settings.apis.blog.url}/blog/latestannouncements.json`
|
||||
const opts = {
|
||||
url: blogUrl,
|
||||
json: true,
|
||||
timeout: 1000
|
||||
}
|
||||
return request.get(opts, function(err, res, announcements) {
|
||||
if (err != null) {
|
||||
return callback(err)
|
||||
}
|
||||
if (res.statusCode !== 200) {
|
||||
return callback(new Error('blog announcement returned non 200'))
|
||||
}
|
||||
announcements = _.map(announcements, function(announcement) {
|
||||
announcement.date = new Date(announcement.date)
|
||||
return announcement
|
||||
})
|
||||
return callback(err, announcements)
|
||||
})
|
||||
}
|
||||
}
|
|
@ -323,8 +323,7 @@ module.exports = function(webRouter, privateApiRouter, publicApiRouter) {
|
|||
chatMessageBgSaturation: '85%',
|
||||
chatMessageBgLightness: '40%',
|
||||
defaultFontFamily: 'lucida',
|
||||
defaultLineHeight: 'normal',
|
||||
renderAnnouncements: false
|
||||
defaultLineHeight: 'normal'
|
||||
}
|
||||
next()
|
||||
})
|
||||
|
|
|
@ -42,7 +42,6 @@ const BetaProgramController = require('./Features/BetaProgram/BetaProgramControl
|
|||
const SudoModeController = require('./Features/SudoMode/SudoModeController')
|
||||
const SudoModeMiddleware = require('./Features/SudoMode/SudoModeMiddleware')
|
||||
const AnalyticsRouter = require('./Features/Analytics/AnalyticsRouter')
|
||||
const AnnouncementsController = require('./Features/Announcements/AnnouncementsController')
|
||||
const MetaController = require('./Features/Metadata/MetaController')
|
||||
const TokenAccessController = require('./Features/TokenAccess/TokenAccessController')
|
||||
const Features = require('./infrastructure/Features')
|
||||
|
@ -688,12 +687,6 @@ function initialize(webRouter, privateApiRouter, publicApiRouter) {
|
|||
NotificationsController.markNotificationAsRead
|
||||
)
|
||||
|
||||
webRouter.get(
|
||||
'/announcements',
|
||||
AuthenticationController.requireLogin(),
|
||||
AnnouncementsController.getUndreadAnnouncements
|
||||
)
|
||||
|
||||
// Deprecated in favour of /internal/project/:project_id but still used by versioning
|
||||
privateApiRouter.get(
|
||||
'/project/:project_id/details',
|
||||
|
|
|
@ -16,46 +16,6 @@ block content
|
|||
}
|
||||
};
|
||||
|
||||
if uiConfig.renderAnnouncements
|
||||
.announcements(
|
||||
ng-controller="AnnouncementsController"
|
||||
ng-class="{ 'announcements-open': ui.isOpen }"
|
||||
ng-cloak
|
||||
)
|
||||
.announcements-backdrop(
|
||||
ng-if="ui.isOpen"
|
||||
ng-click="toggleAnnouncementsUI();"
|
||||
)
|
||||
a.announcements-btn(
|
||||
href
|
||||
ng-if="announcements.length"
|
||||
ng-click="toggleAnnouncementsUI();"
|
||||
ng-class="{ 'announcements-btn-open': ui.isOpen, 'announcements-btn-has-new': ui.newItems }"
|
||||
)
|
||||
span.announcements-badge(ng-if="ui.newItems") {{ ui.newItems }}
|
||||
.announcements-body(
|
||||
ng-if="ui.isOpen"
|
||||
)
|
||||
.announcements-scroller
|
||||
.announcement(
|
||||
ng-repeat="announcement in announcements | filter:(ui.newItems ? { read: false } : '') track by announcement.id"
|
||||
)
|
||||
h2.announcement-header {{ announcement.title }}
|
||||
p.announcement-description(ng-bind-html="announcement.excerpt")
|
||||
.announcement-meta
|
||||
p.announcement-date {{ announcement.date | date:"longDate" }}
|
||||
a.announcement-link(
|
||||
ng-href="{{ announcement.url }}"
|
||||
ng-click="logAnnouncementClick()",
|
||||
target="_blank"
|
||||
) Read more
|
||||
div.text-center(
|
||||
ng-if="ui.newItems > 0 && ui.newItems < announcements.length"
|
||||
)
|
||||
a.btn.btn-default.btn-sm(
|
||||
href
|
||||
ng-click="showAll();"
|
||||
) Show all
|
||||
main.content.content-alt.project-list-page(
|
||||
ng-controller="ProjectPageController"
|
||||
role="main"
|
||||
|
@ -77,7 +37,7 @@ block content
|
|||
span(aria-hidden="true") ×
|
||||
span.sr-only #{translate("close")}
|
||||
.system-message-content(ng-bind-html="htmlContent")
|
||||
|
||||
|
||||
include ../translations/translation_message
|
||||
|
||||
.project-list-content(event-tracking=settings.overleaf ? "loads_v2_dash" : "", onboard=settings.overleaf ? "true" : "", event-tracking-trigger=settings.overleaf ? "load" : "", event-tracking-mb="true", event-segmentation="{location: 'dash', v2_onboard: true}")
|
||||
|
@ -90,7 +50,7 @@ block content
|
|||
.project-list-main.col-md-10.col-xs-9
|
||||
include ./list/notifications
|
||||
include ./list/project-list
|
||||
|
||||
|
||||
.project-list-empty.row(ng-if="projects.length === 0")
|
||||
.project-list-empty-col.col-md-offset-2.col-md-8.col-md-offset-2.col-xs-8.col-xs-offset-2
|
||||
include ./list/empty-project-list
|
||||
|
|
|
@ -24,7 +24,6 @@ define([
|
|||
'main/subscription-dashboard',
|
||||
'main/new-subscription',
|
||||
'main/annual-upgrade',
|
||||
'main/announcements',
|
||||
'main/register-users',
|
||||
'main/subscription/team-invite-controller',
|
||||
'main/contact-us',
|
||||
|
|
|
@ -1,59 +0,0 @@
|
|||
/* eslint-disable
|
||||
camelcase,
|
||||
max-len,
|
||||
no-return-assign,
|
||||
no-undef,
|
||||
*/
|
||||
// TODO: This file was created by bulk-decaffeinate.
|
||||
// Fix any style issues and re-enable lint.
|
||||
/*
|
||||
* decaffeinate suggestions:
|
||||
* DS102: Remove unnecessary code created because of implicit returns
|
||||
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
||||
*/
|
||||
define(['base'], App =>
|
||||
App.controller('AnnouncementsController', function(
|
||||
$scope,
|
||||
$http,
|
||||
eventTracking,
|
||||
$window,
|
||||
_
|
||||
) {
|
||||
$scope.announcements = []
|
||||
$scope.ui = {
|
||||
isOpen: false,
|
||||
newItems: 0
|
||||
}
|
||||
|
||||
const refreshAnnouncements = () =>
|
||||
$http.get('/announcements').then(function(response) {
|
||||
$scope.announcements = response.data
|
||||
return ($scope.ui.newItems = _.filter(
|
||||
$scope.announcements,
|
||||
announcement => !announcement.read
|
||||
).length)
|
||||
})
|
||||
|
||||
const markAnnouncementsAsRead = () =>
|
||||
eventTracking.sendMB('announcement-alert-dismissed', {
|
||||
blogPostId: $scope.announcements[0].id
|
||||
})
|
||||
|
||||
$scope.logAnnouncementClick = () =>
|
||||
eventTracking.sendMB('announcement-read-more-clicked', {
|
||||
blogPostId: $scope.announcements[0].id
|
||||
})
|
||||
|
||||
refreshAnnouncements()
|
||||
|
||||
$scope.toggleAnnouncementsUI = function() {
|
||||
$scope.ui.isOpen = !$scope.ui.isOpen
|
||||
|
||||
if (!$scope.ui.isOpen && $scope.ui.newItems) {
|
||||
$scope.ui.newItems = 0
|
||||
return markAnnouncementsAsRead()
|
||||
}
|
||||
}
|
||||
|
||||
return ($scope.showAll = () => ($scope.ui.newItems = 0))
|
||||
}))
|
|
@ -1,7 +1,5 @@
|
|||
@import './list/v1-import-modal.less';
|
||||
|
||||
@announcements-shadow: 0 2px 20px rgba(0, 0, 0, 0.5);
|
||||
|
||||
@keyframes pulse {
|
||||
0% {
|
||||
opacity: 0.7;
|
||||
|
@ -648,147 +646,3 @@ ul.project-list {
|
|||
margin-left: -100px;
|
||||
}
|
||||
}
|
||||
|
||||
.announcements {
|
||||
position: absolute;
|
||||
bottom: @footer-height;
|
||||
right: 0;
|
||||
height: 150px;
|
||||
width: 100%;
|
||||
pointer-events: none;
|
||||
overflow: hidden;
|
||||
|
||||
&-open {
|
||||
top: -100%;
|
||||
height: auto;
|
||||
pointer-events: all;
|
||||
}
|
||||
}
|
||||
|
||||
.announcements-backdrop {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
background-color: rgba(0, 0, 0, 0.35);
|
||||
opacity: 0;
|
||||
animation: fade-in 0.35s forwards;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.announcements-btn {
|
||||
position: absolute;
|
||||
bottom: -35px;
|
||||
right: 3%;
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
background: url(/img/brand/lion.svg) no-repeat center/80% transparent;
|
||||
border-radius: 50%;
|
||||
box-shadow: none;
|
||||
z-index: 1;
|
||||
pointer-events: all;
|
||||
transition: bottom 0.25s cubic-bezier(0.68, -0.55, 0.265, 1.55),
|
||||
background 0.25s ease, box-shadow 0.25s ease;
|
||||
|
||||
&:hover {
|
||||
bottom: -25px;
|
||||
}
|
||||
|
||||
&-open,
|
||||
&-open:hover,
|
||||
&-has-new,
|
||||
&-has-new:hover {
|
||||
background-color: #fff;
|
||||
box-shadow: @announcements-shadow;
|
||||
bottom: 30px;
|
||||
}
|
||||
}
|
||||
.announcements-badge {
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
font-size: 11px;
|
||||
height: 1.8em;
|
||||
min-width: 1.8em;
|
||||
border-radius: 0.9em;
|
||||
line-height: 1.8;
|
||||
padding: 0 2px;
|
||||
top: 1px;
|
||||
right: 1px;
|
||||
font-weight: bold;
|
||||
color: #fff;
|
||||
background-color: @red;
|
||||
vertical-align: baseline;
|
||||
white-space: nowrap;
|
||||
text-align: center;
|
||||
z-index: 1;
|
||||
animation: pulse 1s alternate infinite;
|
||||
}
|
||||
|
||||
.announcements-body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
position: absolute;
|
||||
right: 3%;
|
||||
margin-right: 95px;
|
||||
bottom: 30px;
|
||||
width: 700px;
|
||||
max-height: 40%;
|
||||
min-height: 100px;
|
||||
background: #fff;
|
||||
z-index: 1;
|
||||
box-shadow: @announcements-shadow;
|
||||
border-radius: @border-radius-base;
|
||||
animation: fade-in 0.35s forwards;
|
||||
|
||||
&::after {
|
||||
content: '\25b8';
|
||||
position: absolute;
|
||||
left: 100%;
|
||||
bottom: 17px;
|
||||
width: 30px;
|
||||
color: #fff;
|
||||
text-shadow: @announcements-shadow;
|
||||
font-size: 2em;
|
||||
overflow: hidden;
|
||||
text-indent: -7px;
|
||||
}
|
||||
}
|
||||
|
||||
.announcements-scroller {
|
||||
padding: @line-height-computed;
|
||||
flex-grow: 0;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.announcement {
|
||||
margin-bottom: @line-height-computed * 1.5;
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
.announcement-header {
|
||||
.page-header;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.announcement-description {
|
||||
margin: (@line-height-computed / 4) 0 (@line-height-computed / 2);
|
||||
}
|
||||
|
||||
.announcement-meta {
|
||||
.clearfix;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.announcement-date {
|
||||
float: left;
|
||||
color: @gray;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.announcement-link {
|
||||
float: right;
|
||||
margin: 0;
|
||||
}
|
||||
|
|
|
@ -102,17 +102,5 @@ describe('AnalyticsManager', function() {
|
|||
}
|
||||
)
|
||||
})
|
||||
|
||||
it('getLastOccurrence', function(done) {
|
||||
const event = 'fake-event'
|
||||
this.AnalyticsManager.getLastOccurrence(this.fakeUserId, event, error => {
|
||||
expect(error).to.not.exist
|
||||
sinon.assert.calledWithMatch(this.request, {
|
||||
body: { event },
|
||||
url: 'analytics.test/user/123abc/event/last_occurrence'
|
||||
})
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,250 +0,0 @@
|
|||
/* eslint-disable
|
||||
handle-callback-err,
|
||||
max-len,
|
||||
no-return-assign,
|
||||
no-unused-vars,
|
||||
*/
|
||||
// TODO: This file was created by bulk-decaffeinate.
|
||||
// Fix any style issues and re-enable lint.
|
||||
/*
|
||||
* decaffeinate suggestions:
|
||||
* DS102: Remove unnecessary code created because of implicit returns
|
||||
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
||||
*/
|
||||
const should = require('chai').should()
|
||||
const SandboxedModule = require('sandboxed-module')
|
||||
const assert = require('assert')
|
||||
const path = require('path')
|
||||
const modulePath = path.join(
|
||||
__dirname,
|
||||
'../../../../app/src/Features/Announcements/AnnouncementsHandler'
|
||||
)
|
||||
const sinon = require('sinon')
|
||||
const { expect } = require('chai')
|
||||
|
||||
describe('AnnouncementsHandler', function() {
|
||||
beforeEach(function() {
|
||||
this.user = {
|
||||
_id: '3c6afe000000000000000000', // 2002-02-14T00:00:00.000Z
|
||||
email: 'someone@gmail.com'
|
||||
}
|
||||
this.AnalyticsManager = { getLastOccurrence: sinon.stub() }
|
||||
this.BlogHandler = { getLatestAnnouncements: sinon.stub() }
|
||||
this.settings = {}
|
||||
return (this.handler = SandboxedModule.require(modulePath, {
|
||||
globals: {
|
||||
console: console
|
||||
},
|
||||
requires: {
|
||||
'../Analytics/AnalyticsManager': this.AnalyticsManager,
|
||||
'../Blog/BlogHandler': this.BlogHandler,
|
||||
'settings-sharelatex': this.settings,
|
||||
'logger-sharelatex': {
|
||||
log() {}
|
||||
}
|
||||
}
|
||||
}))
|
||||
})
|
||||
|
||||
describe('getUnreadAnnouncements', function() {
|
||||
beforeEach(function() {
|
||||
this.stubbedAnnouncements = [
|
||||
{
|
||||
date: new Date(1478836800000),
|
||||
id: '/2016/11/01/introducting-latex-code-checker'
|
||||
},
|
||||
{
|
||||
date: new Date(1308369600000),
|
||||
id: '/2013/08/02/thesis-series-pt1'
|
||||
},
|
||||
{
|
||||
date: new Date(1108369600000),
|
||||
id: '/2005/08/04/somethingelse'
|
||||
},
|
||||
{
|
||||
date: new Date(1208369600000),
|
||||
id: '/2008/04/12/title-date-irrelivant'
|
||||
}
|
||||
]
|
||||
return this.BlogHandler.getLatestAnnouncements.callsArgWith(
|
||||
0,
|
||||
null,
|
||||
this.stubbedAnnouncements
|
||||
)
|
||||
})
|
||||
|
||||
it('should mark all announcements as read is false', function(done) {
|
||||
this.AnalyticsManager.getLastOccurrence.callsArgWith(2, null, [])
|
||||
return this.handler.getUnreadAnnouncements(
|
||||
this.user,
|
||||
(err, announcements) => {
|
||||
announcements[0].read.should.equal(false)
|
||||
announcements[1].read.should.equal(false)
|
||||
announcements[2].read.should.equal(false)
|
||||
announcements[3].read.should.equal(false)
|
||||
return done()
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
it('should should be sorted again to ensure correct order', function(done) {
|
||||
this.AnalyticsManager.getLastOccurrence.callsArgWith(2, null, [])
|
||||
return this.handler.getUnreadAnnouncements(
|
||||
this.user,
|
||||
(err, announcements) => {
|
||||
announcements[3].should.equal(this.stubbedAnnouncements[2])
|
||||
announcements[2].should.equal(this.stubbedAnnouncements[3])
|
||||
announcements[1].should.equal(this.stubbedAnnouncements[1])
|
||||
announcements[0].should.equal(this.stubbedAnnouncements[0])
|
||||
return done()
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
it('should return older ones marked as read as well', function(done) {
|
||||
this.AnalyticsManager.getLastOccurrence.callsArgWith(2, null, {
|
||||
segmentation: { blogPostId: '/2008/04/12/title-date-irrelivant' }
|
||||
})
|
||||
return this.handler.getUnreadAnnouncements(
|
||||
this.user,
|
||||
(err, announcements) => {
|
||||
announcements[0].id.should.equal(this.stubbedAnnouncements[0].id)
|
||||
announcements[0].read.should.equal(false)
|
||||
|
||||
announcements[1].id.should.equal(this.stubbedAnnouncements[1].id)
|
||||
announcements[1].read.should.equal(false)
|
||||
|
||||
announcements[2].id.should.equal(this.stubbedAnnouncements[3].id)
|
||||
announcements[2].read.should.equal(true)
|
||||
|
||||
announcements[3].id.should.equal(this.stubbedAnnouncements[2].id)
|
||||
announcements[3].read.should.equal(true)
|
||||
|
||||
return done()
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
it('should return all of them marked as read', function(done) {
|
||||
this.AnalyticsManager.getLastOccurrence.callsArgWith(2, null, {
|
||||
segmentation: {
|
||||
blogPostId: '/2016/11/01/introducting-latex-code-checker'
|
||||
}
|
||||
})
|
||||
return this.handler.getUnreadAnnouncements(
|
||||
this.user,
|
||||
(err, announcements) => {
|
||||
announcements[0].read.should.equal(true)
|
||||
announcements[1].read.should.equal(true)
|
||||
announcements[2].read.should.equal(true)
|
||||
announcements[3].read.should.equal(true)
|
||||
return done()
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
it('should return posts older than signup date as read', function(done) {
|
||||
this.stubbedAnnouncements.push({
|
||||
date: new Date(978836800000),
|
||||
id: '/2001/04/12/title-date-irrelivant'
|
||||
})
|
||||
this.AnalyticsManager.getLastOccurrence.callsArgWith(2, null, [])
|
||||
return this.handler.getUnreadAnnouncements(
|
||||
this.user,
|
||||
(err, announcements) => {
|
||||
announcements[0].read.should.equal(false)
|
||||
announcements[1].read.should.equal(false)
|
||||
announcements[2].read.should.equal(false)
|
||||
announcements[3].read.should.equal(false)
|
||||
announcements[4].read.should.equal(true)
|
||||
announcements[4].id.should.equal('/2001/04/12/title-date-irrelivant')
|
||||
return done()
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
describe('with custom domain announcements', function() {
|
||||
beforeEach(function() {
|
||||
this.stubbedDomainSpecificAnn = [
|
||||
{
|
||||
domains: ['gmail.com', 'yahoo.edu'],
|
||||
title: 'some message',
|
||||
excerpt: 'read this',
|
||||
url: 'http://www.sharelatex.com/i/somewhere',
|
||||
id: 'iaaa',
|
||||
date: new Date(1308369600000).toString()
|
||||
}
|
||||
]
|
||||
|
||||
return (this.handler._domainSpecificAnnouncements = sinon
|
||||
.stub()
|
||||
.returns(this.stubbedDomainSpecificAnn))
|
||||
})
|
||||
|
||||
it('should insert the domain specific in the correct place', function(done) {
|
||||
this.AnalyticsManager.getLastOccurrence.callsArgWith(2, null, [])
|
||||
return this.handler.getUnreadAnnouncements(
|
||||
this.user,
|
||||
(err, announcements) => {
|
||||
announcements[4].should.equal(this.stubbedAnnouncements[2])
|
||||
announcements[3].should.equal(this.stubbedAnnouncements[3])
|
||||
announcements[2].should.equal(this.stubbedAnnouncements[1])
|
||||
announcements[1].should.equal(this.stubbedDomainSpecificAnn[0])
|
||||
announcements[0].should.equal(this.stubbedAnnouncements[0])
|
||||
return done()
|
||||
}
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('_domainSpecificAnnouncements', function() {
|
||||
beforeEach(function() {
|
||||
return (this.settings.domainAnnouncements = [
|
||||
{
|
||||
domains: ['gmail.com', 'yahoo.edu'],
|
||||
title: 'some message',
|
||||
excerpt: 'read this',
|
||||
url: 'http://www.sharelatex.com/i/somewhere',
|
||||
id: 'id1',
|
||||
date: new Date(1308369600000).toString()
|
||||
},
|
||||
{
|
||||
domains: ['gmail.com', 'yahoo.edu'],
|
||||
title: 'some message',
|
||||
excerpt: 'read this',
|
||||
url: 'http://www.sharelatex.com/i/somewhere',
|
||||
date: new Date(1308369600000).toString()
|
||||
},
|
||||
{
|
||||
domains: ['gmail.com', 'yahoo.edu'],
|
||||
title: 'some message',
|
||||
excerpt: 'read this',
|
||||
url: 'http://www.sharelatex.com/i/somewhere',
|
||||
id: 'id3',
|
||||
date: new Date(1308369600000).toString()
|
||||
}
|
||||
])
|
||||
})
|
||||
|
||||
it("should filter announcments which don't have an id", function(done) {
|
||||
const result = this.handler._domainSpecificAnnouncements(
|
||||
'someone@gmail.com'
|
||||
)
|
||||
result.length.should.equal(2)
|
||||
result[0].id.should.equal('id1')
|
||||
result[1].id.should.equal('id3')
|
||||
return done()
|
||||
})
|
||||
|
||||
it('should match on domain', function(done) {
|
||||
this.settings.domainAnnouncements[2].domains = ['yahoo.com']
|
||||
const result = this.handler._domainSpecificAnnouncements(
|
||||
'someone@gmail.com'
|
||||
)
|
||||
result.length.should.equal(1)
|
||||
result[0].id.should.equal('id1')
|
||||
return done()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
|
@ -87,7 +87,6 @@ describe('ProjectController', function() {
|
|||
this.UserController = {
|
||||
logout: sinon.stub()
|
||||
}
|
||||
this.AnalyticsManager = { getLastOccurrence: sinon.stub() }
|
||||
this.TokenAccessHandler = {
|
||||
getRequestToken: sinon.stub().returns(this.token),
|
||||
protectTokens: sinon.stub()
|
||||
|
@ -174,7 +173,6 @@ describe('ProjectController', function() {
|
|||
'./ProjectDetailsHandler': this.ProjectDetailsHandler,
|
||||
'../Authentication/AuthenticationController': this
|
||||
.AuthenticationController,
|
||||
'../Analytics/AnalyticsManager': this.AnalyticsManager,
|
||||
'../TokenAccess/TokenAccessHandler': this.TokenAccessHandler,
|
||||
'../Collaborators/CollaboratorsGetter': this.CollaboratorsGetter,
|
||||
'../../infrastructure/Modules': this.Modules,
|
||||
|
@ -1055,7 +1053,6 @@ describe('ProjectController', function() {
|
|||
)
|
||||
this.ProjectDeleter.unmarkAsDeletedByExternalSource = sinon.stub()
|
||||
this.InactiveProjectManager.reactivateProjectIfRequired.callsArgWith(1)
|
||||
this.AnalyticsManager.getLastOccurrence.yields(null, { mock: 'event' })
|
||||
this.ProjectUpdateHandler.markAsOpened.callsArgWith(1)
|
||||
})
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue