Merge branch 'master' into node-6.9

This commit is contained in:
Shane Kilkelly 2017-02-14 14:42:35 +00:00
commit 2d0a7b2bdb
27 changed files with 328 additions and 161 deletions

View file

@ -19,6 +19,9 @@ module.exports = AnnouncementsHandler =
if !user? and !user._id?
return callback("user not supplied")
timestamp = user._id.toString().substring(0,8)
userSignupDate = new Date( parseInt( timestamp, 16 ) * 1000 )
async.parallel {
lastEvent: (cb)->
AnalyticsManager.getLastOccurance user._id, "announcement-alert-dismissed", cb
@ -48,7 +51,9 @@ module.exports = AnnouncementsHandler =
announcement.id == lastSeenBlogId
announcements = _.map announcements, (announcement, index)->
if announcementIndex == -1
if announcement.date < userSignupDate
read = true
else if announcementIndex == -1
read = false
else if index >= announcementIndex
read = true

View file

@ -10,7 +10,7 @@ TagsHandler = require("../Tags/TagsHandler")
SubscriptionLocator = require("../Subscription/SubscriptionLocator")
NotificationsHandler = require("../Notifications/NotificationsHandler")
LimitationsManager = require("../Subscription/LimitationsManager")
_ = require("underscore")
underscore = require("underscore")
Settings = require("settings-sharelatex")
AuthorizationManager = require("../Authorization/AuthorizationManager")
fs = require "fs"
@ -20,6 +20,7 @@ ProjectGetter = require("./ProjectGetter")
PrivilegeLevels = require("../Authorization/PrivilegeLevels")
AuthenticationController = require("../Authentication/AuthenticationController")
PackageVersions = require("../../infrastructure/PackageVersions")
AnalyticsManager = require "../Analytics/AnalyticsManager"
module.exports = ProjectController =
@ -219,6 +220,19 @@ module.exports = ProjectController =
#don't need to wait for this to complete
ProjectUpdateHandler.markAsOpened project_id, ->
cb()
showTrackChangesOnboarding: (cb) ->
cb = underscore.once(cb)
if !user_id?
return cb()
timeout = setTimeout cb, 500
AnalyticsManager.getLastOccurance user_id, "shown-track-changes-onboarding", (error, event) ->
clearTimeout timeout
if error?
return cb(null, false)
else if event?
return cb(null, false)
else
return cb(null, true)
}, (err, results)->
if err?
logger.err err:err, "error getting details for project page"
@ -226,7 +240,7 @@ module.exports = ProjectController =
project = results.project
user = results.user
subscription = results.subscription
showTrackChangesOnboarding = results.showTrackChangesOnboarding
daysSinceLastUpdated = (new Date() - project.lastUpdated) /86400000
logger.log project_id:project_id, daysSinceLastUpdated:daysSinceLastUpdated, "got db results for loading editor"
@ -268,6 +282,7 @@ module.exports = ProjectController =
syntaxValidation: user.ace.syntaxValidation
}
trackChangesEnabled: !!project.track_changes
showTrackChangesOnboarding: !!showTrackChangesOnboarding
privilegeLevel: privilegeLevel
chatUrl: Settings.apis.chat.url
anonymous: anonymous

View file

@ -22,7 +22,7 @@ module.exports = ProjectEditorHandler =
trackChangesVisible = false
for member in members
if member.privilegeLevel == "owner" and member.user?.featureSwitches?.track_changes
if member.privilegeLevel == "owner" and (member.user?.featureSwitches?.track_changes or member.user?.betaProgram)
trackChangesVisible = true
{owner, ownerFeatures, members} = @buildOwnerAndMembersViews(members)

View file

@ -18,11 +18,9 @@ block content
| #{translate("beta_program_badge_description")}
span.beta-feature-badge
p.text-centered
| #{translate("beta_program_current_beta_features_description")}
ul.list-unstyled.text-center
li
i.fa.fa-fw.fa-book
| &nbsp;#{translate("syntax_checking")}
strong We're currently testing track changes and commenting:
p.text-centered
img(src="/img/teasers/track-changes/track-changes-beta.png", style="max-width: 100%; border-bottom: 1px solid #ddd")
.row.text-centered
.col-md-12
if user.betaProgram

View file

@ -108,6 +108,7 @@ block requirejs
window.anonymous = #{anonymous};
window.maxDocLength = #{maxDocLength};
window.trackChangesEnabled = #{trackChangesEnabled};
window.showTrackChangesOnboarding = #{!!showTrackChangesOnboarding};
window.wikiEnabled = #{!!(settings.apis.wiki && settings.apis.wiki.url)};
window.requirejs = {
"paths" : {

View file

@ -1,54 +1,112 @@
.feat-onboard(
ng-controller="FeatureOnboardingController"
ng-class="('feat-onboard-step' + innerStep)"
ng-if="!state.loading && ui.showCodeCheckerOnboarding"
ng-cloak
)
.feat-onboard-wrapper
h1.feat-onboard-title
| Introducing&nbsp;
span.feat-onboard-title-name Code check
div(ng-if="innerStep === 1;")
div(ng-controller="FeatureOnboardingController")
.feat-onboard(
ng-class="('feat-onboard-step' + onboarding.innerStep)"
ng-if="!state.loading && showCollabFeaturesOnboarding"
ng-cloak
stop-propagation="click"
)
a.feat-onboard-dismiss(
href
ng-click="dismiss();"
) &times;
.feat-onboard-wrapper
h1.feat-onboard-title
| Introducing&nbsp;
span.feat-onboard-highlight Commenting
| &amp;
span.feat-onboard-highlight Track Changes
p.feat-onboard-description
span.feat-onboard-description-name Code check&nbsp;
| will highlight potential problems in your LaTeX code, allowing you to handle errors earlier and become more productive.
.row
video.feat-onboard-video(autoplay, loop)
source(src="/img/teasers/code-checker/code-checker.mp4", type="video/mp4")
img(src="/img/teasers/code-checker/code-checker.gif")
.row.feat-onboard-adv-wrapper
.col-xs-4
h2.feat-onboard-adv-title
| Missing&nbsp;
span.feat-onboard-adv-title-highlight brackets
p Forgot to place a closing bracket? We'll warn you.
.col-xs-4
h2.feat-onboard-adv-title
| Unclosed&nbsp;
span.feat-onboard-adv-title-highlight environments
p
| Know when you are missing an&nbsp;
code \end{...}
| &nbsp;command.
.col-xs-4
h2.feat-onboard-adv-title
| Incorrect&nbsp;
span.feat-onboard-adv-title-highlight nesting
p
| Order matters. Get notified when you use an&nbsp;
code \end{...}
| &nbsp; too soon.
.feat-onboard-btn-wrapper
button.btn.btn-primary(ng-click="turnCodeCheckOn();") Yes, turn Code check on
.feat-onboard-btn-wrapper
button.btn.btn-default(ng-click="turnCodeCheckOff();") No, disable it for now
div(ng-if="innerStep === 2;")
p.feat-onboard-description
| Remember: you can always turn&nbsp;
span.feat-onboard-description-name Code check&nbsp;
em on&nbsp;
| or&nbsp;
em off&nbsp;
|, in the settings menu.
.feat-onboard-btn-wrapper
button.btn.btn-primary(ng-click="dismiss();") OK, got it
span.feat-onboard-highlight Commenting
| and
span.feat-onboard-highlight Track Changes
| will make it easier for you to work with peers in your documents.
.feat-onboard-tutorial-wrapper
button.btn.btn-primary.feat-onboard-nav-btn(
ng-click="gotoPrevStep();"
ng-disabled="onboarding.innerStep === 1;")
i.fa.fa-arrow-left
div(ng-show="onboarding.innerStep === 1;")
video.feat-onboard-video(
video-play-state="onboarding.innerStep === 1;"
autoplay
loop
)
source(src="/img/onboarding/review-panel/open-review.mp4", type="video/mp4")
img(src="/img/onboarding/review-panel/open-review.gif")
div(ng-show="onboarding.innerStep === 2;")
video.feat-onboard-video(
video-play-state="onboarding.innerStep === 2;"
autoplay
loop
)
source(src="/img/onboarding/review-panel/commenting.mp4", type="video/mp4")
img(src="/img/onboarding/review-panel/commenting.gif")
div(ng-show="onboarding.innerStep === 3;")
video.feat-onboard-video(
video-play-state="onboarding.innerStep === 3;"
autoplay
loop
)
source(src="/img/onboarding/review-panel/add-changes.mp4", type="video/mp4")
img(src="/img/onboarding/review-panel/add-changes.gif")
div(ng-show="onboarding.innerStep === 4;")
video.feat-onboard-video(
video-play-state="onboarding.innerStep === 4;"
autoplay
loop
)
source(src="/img/onboarding/review-panel/accept-changes.mp4", type="video/mp4")
img(src="/img/onboarding/review-panel/accept-changes.gif")
button.btn.btn-primary.feat-onboard-nav-btn(
ng-click="gotoNextStep();"
ng-disabled="onboarding.innerStep === onboarding.nSteps;")
i.fa.fa-arrow-right
div(ng-switch="onboarding.innerStep")
.row(ng-switch-when="1")
.col-xs-6
h2.feat-onboard-adv-title Commenting
p.feat-onboard-description Want to discuss specific parts of the text?
p.feat-onboard-description Use our brand-new commenting system.
.col-xs-6
h2.feat-onboard-adv-title Track Changes
p.feat-onboard-description See changes in your documents, live.
p.feat-onboard-description Track, accept and reject changes individually.
.row(ng-switch-when="2")
.col-xs-12
h2.feat-onboard-adv-title Commenting
p.feat-onboard-description Just select a span of text and click on
span.feat-onboard-highlight &ldquo;Add comment&rdquo;
| .
p.feat-onboard-description
span.feat-onboard-highlight Comments
| can be
span.feat-onboard-highlight replied
| to,
span.feat-onboard-highlight resolved
| and permanently
span.feat-onboard-highlight deleted
| .
.row(ng-switch-when="3")
.col-xs-12
h2.feat-onboard-adv-title Track Changes
p.feat-onboard-description
| Let your peers know what you've been up to.
p.feat-onboard-description
| Click on the
span.feat-onboard-highlight &ldquo;Track Changes&rdquo;
| toggle to start marking your insertions, as well as your deletions.
.row(ng-switch-when="4")
.col-xs-12
h2.feat-onboard-adv-title Track Changes
p.feat-onboard-description Upon reviewing,
span.feat-onboard-highlight changes
| can be accepted or undone.
p.feat-onboard-description
| Click&nbsp;
span.feat-onboard-highlight &ldquo;Accept&rdquo;
| or&nbsp;
span.feat-onboard-highlight &ldquo;Reject&rdquo;
| to incorporate or discard an individual change.

View file

@ -92,7 +92,9 @@ header.toolbar.toolbar-header.toolbar-with-labels(
ng-click="toggleReviewPanel()"
)
i.review-icon
p.toolbar-label Review
p.toolbar-label
| Review
span(style="vertical-align: 20%; margin-left: 4px; padding: 2px 4px;").beta-feature-badge
a.btn.btn-full-height(
href,
ng-if="permissions.admin",

View file

@ -6,7 +6,7 @@
ng-class="{ 'rp-track-changes-indicator-on-dark' : darkTheme }"
) Track changes is
strong on
.review-panel-toolbar
resolved-comments-dropdown(
class="rp-flex-block"
@ -332,6 +332,7 @@ script(type='text/ng-template', id='addCommentEntryTemplate')
ng-keypress="handleCommentKeyPress($event);"
placeholder="Add your comment here"
focus-on="comment:new:open"
ng-blur="submitNewComment()"
)
.rp-entry-actions
button.rp-entry-button(
@ -417,10 +418,12 @@ script(type="text/ng-template", id="trackChangesUpgradeModalTemplate")
a.btn.btn-success(
href
ng-click="startFreeTrial('track-changes')"
ng-show="project.owner._id == user.id"
) Try it for free
p(ng-show="project.owner._id != user.id"): strong Please ask the project owner to upgrade to use track changes
.modal-footer()
button.btn.btn-default(
ng-click="cancel()"
)
span #{translate("close")}
span #{translate("close")}

View file

@ -0,0 +1,15 @@
define [
"base"
], (App) ->
App.directive "videoPlayState", ($parse) ->
return {
restrict: "A",
link: (scope, element, attrs) ->
videoDOMEl = element[0]
scope.$watch (() -> $parse(attrs.videoPlayState)(scope)), (shouldPlay) ->
if shouldPlay
videoDOMEl.currentTime = 0
videoDOMEl.play()
else
videoDOMEl.pause()
}

View file

@ -29,6 +29,7 @@ define [
"directives/stopPropagation"
"directives/rightClick"
"directives/expandableTextArea"
"directives/videoPlayState"
"services/queued-http"
"filters/formatDate"
"main/event"
@ -69,7 +70,6 @@ define [
chatOpen: false
pdfLayout: 'sideBySide'
reviewPanelOpen: localStorage("ui.reviewPanelOpen.#{window.project_id}")
showCodeCheckerOnboarding: !window.userSettings.syntaxValidation?
}
$scope.user = window.user

View file

@ -1,35 +1,36 @@
define [
"base"
], (App) ->
App.controller "FeatureOnboardingController", ($scope, settings) ->
$scope.innerStep = 1
$scope.turnCodeCheckOn = () ->
settings.saveSettings({ syntaxValidation: true })
$scope.settings.syntaxValidation = true
navToInnerStep2()
$scope.turnCodeCheckOff = () ->
settings.saveSettings({ syntaxValidation: false })
$scope.settings.syntaxValidation = false
navToInnerStep2()
App.controller "FeatureOnboardingController", ($scope, settings, event_tracking) ->
$scope.onboarding =
innerStep: 1
nSteps: 4
$scope.$watch "project.features.trackChangesVisible", (visible) ->
return if !visible?
$scope.showCollabFeaturesOnboarding = window.showTrackChangesOnboarding and visible
$scope.dismiss = () ->
$scope.ui.leftMenuShown = false
$scope.ui.showCodeCheckerOnboarding = false
event_tracking.sendMB "shown-track-changes-onboarding"
$scope.$applyAsync(() -> $scope.showCollabFeaturesOnboarding = false)
navToInnerStep2 = () ->
$scope.innerStep = 2
$scope.ui.leftMenuShown = true
$scope.gotoPrevStep = () ->
if $scope.onboarding.innerStep > 1
$scope.$applyAsync(() -> $scope.onboarding.innerStep--)
handleKeypress = (e) ->
if e.keyCode == 13
if $scope.innerStep == 1
$scope.turnCodeCheckOn()
else
$scope.dismiss()
$scope.gotoNextStep = () ->
if $scope.onboarding.innerStep < 4
$scope.$applyAsync(() -> $scope.onboarding.innerStep++)
$(document).on "keypress", handleKeypress
handleKeydown = (e) ->
switch e.keyCode
when 37 then $scope.gotoPrevStep() # left directional key
when 39, 13 then $scope.gotoNextStep() # right directional key, enter
when 27 then $scope.dismiss() # escape
$(document).on "keydown", handleKeydown
$(document).on "click", $scope.dismiss
$scope.$on "$destroy", () ->
$(document).off "keypress", handleKeypress
$(document).off "keydown", handleKeydown
$(document).off "click", $scope.dismiss

View file

@ -20,8 +20,8 @@ define [
@rangesTracker = doc.ranges
@connectToRangesTracker()
@$scope.$on "comment:add", (e, thread_id) =>
@addCommentToSelection(thread_id)
@$scope.$on "comment:add", (e, thread_id, offset, length) =>
@addCommentToSelection(thread_id, offset, length)
@$scope.$on "comment:select_line", (e) =>
@selectLineIfNoSelection()
@ -45,7 +45,7 @@ define [
@recalculateReviewEntriesScreenPositions()
changingSelection = false
onChangeSelection = (args...) =>
onChangeSelection = () =>
# Deletes can send about 5 changeSelection events, so
# just act on the last one.
if !changingSelection
@ -53,7 +53,6 @@ define [
@$scope.$evalAsync () =>
changingSelection = false
@updateFocus()
@recalculateReviewEntriesScreenPositions()
onResize = () =>
@recalculateReviewEntriesScreenPositions()
@ -64,11 +63,13 @@ define [
bindToAce = () =>
@editor.on "changeSelection", onChangeSelection
@editor.on "change", onChangeSelection # Selection also moves with updates elsewhere in the document
@editor.on "changeSession", onChangeSession
@editor.renderer.on "resize", onResize
unbindFromAce = () =>
@editor.off "changeSelection", onChangeSelection
@editor.off "change", onChangeSelection
@editor.off "changeSession", onChangeSession
@editor.renderer.off "resize", onResize
@ -174,10 +175,11 @@ define [
# @rangesTracker.applyOp op # Will apply via sharejs
@$scope.sharejsDoc.submitOp op
addCommentToSelection: (thread_id) ->
range = @editor.getSelectionRange()
content = @editor.getSelectedText()
offset = @_aceRangeToShareJs(range.start)
addCommentToSelection: (thread_id, offset, length) ->
start = @_shareJsOffsetToAcePosition(offset)
end = @_shareJsOffsetToAcePosition(offset + length)
range = new Range(start.row, start.column, end.row, end.column)
content = @editor.session.getTextRange(range)
@addComment(offset, content, thread_id)
selectLineIfNoSelection: () ->

View file

@ -280,6 +280,7 @@ define [
entries["add-comment"] = {
type: "add-comment"
offset: selection_offset_start
length: selection_offset_end - selection_offset_start
}
for id, entry of entries
@ -310,10 +311,15 @@ define [
$scope.$broadcast "review-panel:layout"
$scope.submitNewComment = (content) ->
return if !content? or content == ""
doc_id = $scope.editor.open_doc_id
entries = getDocEntries(doc_id)
return if !entries["add-comment"]?
{offset, length} = entries["add-comment"]
thread_id = RangesTracker.generateId()
thread = getThread(thread_id)
thread.submitting = true
$scope.$broadcast "comment:add", thread_id
$scope.$broadcast "comment:add", thread_id, offset, length
$http.post("/project/#{$scope.project_id}/thread/#{thread_id}/messages", {content, _csrf: window.csrfToken})
.error (error) ->
ide.showGenericMessageModal("Error submitting comment", "Sorry, there was a problem submitting your comment")

View file

@ -28,10 +28,9 @@ define [
if ev.keyCode == 13 and !ev.shiftKey and !ev.ctrlKey and !ev.metaKey
ev.preventDefault()
if scope.state.content.length > 0
ev.target.blur()
scope.submitNewComment()
scope.submitNewComment = () ->
scope.onSubmit { content: scope.state.content }
scope.state.isAdding = false
scope.state.content = ""
scope.state.content = ""

Binary file not shown.

After

Width:  |  Height:  |  Size: 557 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 491 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

View file

@ -1,78 +1,101 @@
@feat-onboard-wrapper-width: 820px;
@feat-onboard-max-text-width: 750px;
@feat-onboard-width: 900px;
.feat-onboard {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
top: 50px;
bottom: 50px;
left: 50%;
width: @feat-onboard-width;
margin-left: -(@feat-onboard-width / 2);
display: flex;
justify-content: center;
align-items: center;
background-image: linear-gradient(rgba(0, 0, 0, .85), rgba(0, 0, 0, .85));
align-items: baseline;
background-color: rgba(0, 0, 0, .85);
background-repeat: no-repeat;
background-position-x: 0;
color: #FFF;
text-align: center;
border-radius: 1em;
z-index: 102;
transition: background-position ease-in-out @left-menu-animation-duration;
overflow: auto;
}
.feat-onboard-step2 {
background-position-x: @left-menu-width;
~ #left-menu {
pointer-events: none;
.code-check-setting {
box-shadow: 0 0 300px 0 #000;
}
}
}
.feat-onboard-wrapper {
width: @feat-onboard-wrapper-width;
padding: 30px 0;
}
.feat-onboard-title {
color: @brand-primary;
margin-bottom: 40px;
.feat-onboard-title {
color: #FFF;
margin-bottom: 30px;
}
.feat-onboard-title-name {
color: #FFF;
font-weight: bold;
}
.feat-onboard-description {
max-width: @feat-onboard-max-text-width;
margin: 0 auto 30px;
padding: 0 80px;
max-width: 35em;
margin: 0 auto 5px;
}
.feat-onboard-description-name {
.feat-onboard-highlight {
font-weight: bold;
white-space: nowrap;
}
.feat-onboard-adv-title {
font-weight: bold;
white-space: nowrap;
color: #FFF;
font-size: 23px;
margin-top: 0;
}
.feat-onboard-video {
box-shadow: 0 0 70px 0 rgba(255, 255, 255, 0.3);
.feat-onboard-tutorial-wrapper {
display: flex;
align-items: center;
padding: 30px 0 15px;
}
.feat-onboard-adv-wrapper {
text-align: left;
margin-bottom: 30px;
}
.feat-onboard-adv-title {
color: #FFF;
font-size: 23px;
}
.feat-onboard-adv-title-highlight {
font-weight: bold;
}
.feat-onboard-btn-wrapper {
margin-bottom: 10px;
> .btn {
.feat-onboard-video {
width: 616px;
margin: 0 30px;
box-shadow: 0 0 70px 0 rgba(255, 255, 255, 0.3);
}
}
.feat-onboard-nav-btn {
border-radius: 1em;
width: 2em;
height: 2em;
text-align: center;
padding: 0;
font-size: 1.3em;
line-height: 1em;
box-shadow: 0 0 70px 0 rgba(255, 255, 255, 0.3);
&[disabled] {
opacity: 0.2;
}
&:focus,
&:active:focus {
outline: 0;
box-shadow: 0 0 70px 0 rgba(255, 255, 255, 0.3);
}
}
a.feat-onboard-dismiss {
position: absolute;
top: 10px;
right: 10px;
width: 1em;
height: 1em;
line-height: 1em;
font-size: 2.5em;
color: #FFF;
background-color: rgba(0,0,0, .25);
opacity: 0.7;
border-radius: 0.5em;
transition: opacity .15s ease-in-out;
&:hover,
&:focus {
text-decoration: none;
color: #FFF;
opacity: 1;
}
}

View file

@ -391,7 +391,7 @@
border-right-width: 0;
}
.rp-layout-left & {
.rp-state-current-file-mini.rp-layout-left & {
&:first-child {
border-bottom-left-radius: 3px;
}

View file

@ -11,7 +11,7 @@ describe 'AnnouncementsHandler', ->
beforeEach ->
@user =
_id:"some_id"
_id:"3c6afe000000000000000000" #2002-02-14T00:00:00.000Z
email: "someone@gmail.com"
@AnalyticsManager =
getLastOccurance: sinon.stub()
@ -36,10 +36,10 @@ describe 'AnnouncementsHandler', ->
id: '/2013/08/02/thesis-series-pt1'
}, {
date: new Date(1108369600000),
id: '/2011/08/04/somethingelse'
id: '/2005/08/04/somethingelse'
}, {
date: new Date(1208369600000),
id: '/2014/04/12/title-date-irrelivant'
id: '/2008/04/12/title-date-irrelivant'
}
]
@BlogHandler.getLatestAnnouncements.callsArgWith(0, null, @stubbedAnnouncements)
@ -64,7 +64,7 @@ describe 'AnnouncementsHandler', ->
done()
it "should return older ones marked as read as well", (done)->
@AnalyticsManager.getLastOccurance.callsArgWith(2, null, {segmentation:{blogPostId:"/2014/04/12/title-date-irrelivant"}})
@AnalyticsManager.getLastOccurance.callsArgWith(2, null, {segmentation:{blogPostId:"/2008/04/12/title-date-irrelivant"}})
@handler.getUnreadAnnouncements @user, (err, announcements)=>
announcements[0].id.should.equal @stubbedAnnouncements[0].id
announcements[0].read.should.equal false
@ -89,6 +89,21 @@ describe 'AnnouncementsHandler', ->
announcements[3].read.should.equal true
done()
it "should return posts older than signup date as read", (done)->
@stubbedAnnouncements.push({
date: new Date(978836800000),
id: '/2001/04/12/title-date-irrelivant'
})
@AnalyticsManager.getLastOccurance.callsArgWith(2, null, [])
@handler.getUnreadAnnouncements @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'
done()
describe "with custom domain announcements", ->
beforeEach ->

View file

@ -58,6 +58,8 @@ describe "ProjectController", ->
getLoggedInUserId: sinon.stub().returns(@user._id)
getSessionUser: sinon.stub().returns(@user)
isUserLoggedIn: sinon.stub().returns(true)
@AnalyticsManager =
getLastOccurance: sinon.stub()
@ProjectController = SandboxedModule.require modulePath, requires:
"settings-sharelatex":@settings
"logger-sharelatex":
@ -82,6 +84,7 @@ describe "ProjectController", ->
"../ReferencesSearch/ReferencesSearchHandler": @ReferencesSearchHandler
"./ProjectGetter": @ProjectGetter
'../Authentication/AuthenticationController': @AuthenticationController
"../Analytics/AnalyticsManager": @AnalyticsManager
@projectName = "£12321jkj9ujkljds"
@req =
@ -310,9 +313,9 @@ describe "ProjectController", ->
@AuthorizationManager.getPrivilegeLevelForProject.callsArgWith 2, null, "owner"
@ProjectDeleter.unmarkAsDeletedByExternalSource = sinon.stub()
@InactiveProjectManager.reactivateProjectIfRequired.callsArgWith(1)
@AnalyticsManager.getLastOccurance.yields(null, {"mock": "event"})
@ProjectUpdateHandler.markAsOpened.callsArgWith(1)
it "should render the project/editor page", (done)->
@res.render = (pageName, opts)=>
pageName.should.equal "project/editor"
@ -357,3 +360,24 @@ describe "ProjectController", ->
@ProjectUpdateHandler.markAsOpened.calledWith(@project_id).should.equal true
done()
@ProjectController.loadEditor @req, @res
it "should set showTrackChangesOnboarding = false if there is an event", (done) ->
@AnalyticsManager.getLastOccurance.yields(null, {"mock": "event"})
@res.render = (pageName, opts)=>
opts.showTrackChangesOnboarding.should.equal false
done()
@ProjectController.loadEditor @req, @res
it "should set showTrackChangesOnboarding = true if there is no event", (done) ->
@AnalyticsManager.getLastOccurance.yields(null, null)
@res.render = (pageName, opts)=>
opts.showTrackChangesOnboarding.should.equal true
done()
@ProjectController.loadEditor @req, @res
it "should set showTrackChangesOnboarding = false if there is an error", (done) ->
@AnalyticsManager.getLastOccurance.yields(new Error("oops"), null)
@res.render = (pageName, opts)=>
opts.showTrackChangesOnboarding.should.equal false
done()
@ProjectController.loadEditor @req, @res