diff --git a/services/web/app/coffee/Features/PasswordReset/PasswordResetController.coffee b/services/web/app/coffee/Features/PasswordReset/PasswordResetController.coffee index ec5371f0f2..618e9e0a7d 100644 --- a/services/web/app/coffee/Features/PasswordReset/PasswordResetController.coffee +++ b/services/web/app/coffee/Features/PasswordReset/PasswordResetController.coffee @@ -53,7 +53,11 @@ module.exports = if req.body.login_after UserGetter.getUser user_id, {email: 1}, (err, user) -> return next(err) if err? - AuthenticationController.doLogin {email:user.email, password: password}, req, res, next + AuthenticationController.afterLoginSessionSetup req, user, (err) -> + if err? + logger.err {err, email: user.email}, "Error setting up session after setting password" + return next(err) + res.json {redir: AuthenticationController._getRedirectFromSession(req) || "/project"} else res.sendStatus 200 else diff --git a/services/web/app/coffee/Features/Project/ProjectEditorHandler.coffee b/services/web/app/coffee/Features/Project/ProjectEditorHandler.coffee index e25ff29b28..5da582aa4c 100644 --- a/services/web/app/coffee/Features/Project/ProjectEditorHandler.coffee +++ b/services/web/app/coffee/Features/Project/ProjectEditorHandler.coffee @@ -20,10 +20,10 @@ module.exports = ProjectEditorHandler = if !result.invites? result.invites = [] - hasTrackChanges = false + trackChangesVisible = false for member in members if member.privilegeLevel == "owner" and member.user?.featureSwitches?.track_changes - hasTrackChanges = true + trackChangesVisible = true {owner, ownerFeatures, members} = @buildOwnerAndMembersViews(members) result.owner = owner @@ -37,7 +37,8 @@ module.exports = ProjectEditorHandler = compileGroup:"standard" templates: false references: false - trackChanges: hasTrackChanges + trackChanges: false + trackChangesVisible: trackChangesVisible }) return result diff --git a/services/web/app/coffee/models/User.coffee b/services/web/app/coffee/models/User.coffee index 44cea29a70..e4097aaa67 100644 --- a/services/web/app/coffee/models/User.coffee +++ b/services/web/app/coffee/models/User.coffee @@ -37,6 +37,7 @@ UserSchema = new Schema compileGroup: { type:String, default: Settings.defaultFeatures.compileGroup } templates: { type:Boolean, default: Settings.defaultFeatures.templates } references: { type:Boolean, default: Settings.defaultFeatures.references } + trackChanges: { type:Boolean, default: Settings.defaultFeatures.trackChanges } } featureSwitches : { track_changes: { type: Boolean } diff --git a/services/web/app/views/project/editor/editor.pug b/services/web/app/views/project/editor/editor.pug index 98a2840069..9924fe1221 100644 --- a/services/web/app/views/project/editor/editor.pug +++ b/services/web/app/views/project/editor/editor.pug @@ -53,7 +53,7 @@ div.full-size( syntax-validation="settings.syntaxValidation", review-panel="reviewPanel", events-bridge="reviewPanelEventsBridge" - track-changes-enabled="project.features.trackChanges", + track-changes-enabled="project.features.trackChangesVisible", track-changes= "editor.trackChanges", doc-id="editor.open_doc_id" renderer-data="reviewPanel.rendererData" diff --git a/services/web/app/views/project/editor/header.pug b/services/web/app/views/project/editor/header.pug index 475ba1da52..85397fa83f 100644 --- a/services/web/app/views/project/editor/header.pug +++ b/services/web/app/views/project/editor/header.pug @@ -87,7 +87,7 @@ header.toolbar.toolbar-header.toolbar-with-labels( a.btn.btn-full-height( href, - ng-if="project.features.trackChanges", + ng-if="project.features.trackChangesVisible", ng-class="{ active: ui.reviewPanelOpen }" ng-click="toggleReviewPanel()" ) diff --git a/services/web/app/views/project/editor/review-panel.pug b/services/web/app/views/project/editor/review-panel.pug index 17d351be65..614da415e8 100644 --- a/services/web/app/views/project/editor/review-panel.pug +++ b/services/web/app/views/project/editor/review-panel.pug @@ -25,7 +25,13 @@ strong off span(ng-click="toggleTrackChanges(false)", ng-if="editor.wantTrackChanges === true") Track Changes is strong on - review-panel-toggle(ng-if="editor.wantTrackChanges == editor.trackChanges", ng-model="editor.wantTrackChanges", on-toggle="toggleTrackChanges") + review-panel-toggle( + ng-if="editor.wantTrackChanges == editor.trackChanges" + ng-model="editor.wantTrackChanges" + on-toggle="toggleTrackChanges" + disabled="!project.features.trackChanges" + on-disabled-click="openTrackChangesUpgradeModal" + ) span.review-panel-toolbar-label.review-panel-toolbar-label-disabled(ng-if="!permissions.write") span(ng-if="editor.wantTrackChanges === false") Track Changes is strong off @@ -201,7 +207,7 @@ script(type='text/ng-template', id='commentEntryTemplate') span.rp-entry-user( style="color: hsl({{ comment.user.hue }}, 70%, 40%);", ) {{ comment.user.name }}:  - | {{ comment.content }} + span(ng-bind-html="comment.content | linky:'_blank'") textarea.rp-comment-input( expandable-text-area ng-if="comment.editing" @@ -272,7 +278,7 @@ script(type='text/ng-template', id='resolvedCommentEntryTemplate') style="color: hsl({{ comment.user.hue }}, 70%, 40%);" ng-if="$first || comment.user.id !== thread.messages[$index - 1].user.id" ) {{ comment.user.name }}:  - | {{ comment.content }} + span(ng-bind-html="comment.content | linky:'_blank'") .rp-entry-metadata | {{ comment.timestamp | date : 'MMM d, y h:mm a' }} .rp-comment.rp-comment-resolver @@ -372,3 +378,49 @@ script(type='text/ng-template', id='resolvedCommentsDropdownTemplate') .rp-loading(ng-if="!resolvedComments.length") | No resolved threads. +script(type="text/ng-template", id="trackChangesUpgradeModalTemplate") + .modal-header + button.close( + type="button" + data-dismiss="modal" + ng-click="cancel()" + ) × + h3 Upgrade to Track Changes + .modal-body + .teaser-video-container + video.teaser-video(autoplay, loop) + source(src="/img/teasers/track-changes/teaser-track-changes.mp4", type="video/mp4") + img(src="/img/teasers/track-changes/teaser-track-changes.gif") + + h4.teaser-title See changes in your documents, live + + p.small(ng-show="startedFreeTrial") + | #{translate("refresh_page_after_starting_free_trial")} + + .row + .col-md-10.col-md-offset-1 + ul.list-unstyled + li + i.fa.fa-check   + | Track any change, in real-time + + li + i.fa.fa-check   + | Review your peers' work + + li + i.fa.fa-check   + | Accept or reject each change individually + + + .row.text-center(ng-controller="FreeTrialModalController") + a.btn.btn-success( + href + ng-click="startFreeTrial('track-changes')" + ) Try it for free + + .modal-footer() + button.btn.btn-default( + ng-click="cancel()" + ) + span #{translate("close")} diff --git a/services/web/app/views/translations/translation_message.pug b/services/web/app/views/translations/translation_message.pug index 225ad3ea2c..635a8c9265 100644 --- a/services/web/app/views/translations/translation_message.pug +++ b/services/web/app/views/translations/translation_message.pug @@ -2,7 +2,7 @@ span(ng-controller="TranslationsPopupController", ng-cloak) .translations-message(ng-hide="hidei18nNotification") a(href=recomendSubdomain.url+currentUrl) !{translate("click_here_to_view_sl_in_lng", {lngName:"" + translate(recomendSubdomain.lngCode) + ""})} - img(src=buildImgPath("flags/24/#{recomendSubdomain.lngCode}.png")) + img(src=buildImgPath("flags/24/" + recomendSubdomain.lngCode + ".png")) button(ng-click="dismiss()").close.pull-right span(aria-hidden="true") × span.sr-only #{translate("close")} \ No newline at end of file diff --git a/services/web/config/settings.defaults.coffee b/services/web/config/settings.defaults.coffee index 8e503801f9..b24c2568ab 100644 --- a/services/web/config/settings.defaults.coffee +++ b/services/web/config/settings.defaults.coffee @@ -179,6 +179,7 @@ module.exports = settings = compileGroup: "standard" references: true templates: true + trackChanges: true plans: plans = [{ planCode: "personal" diff --git a/services/web/public/coffee/directives/expandableTextArea.coffee b/services/web/public/coffee/directives/expandableTextArea.coffee index 8f646c10a7..d0bfa9cb99 100644 --- a/services/web/public/coffee/directives/expandableTextArea.coffee +++ b/services/web/public/coffee/directives/expandableTextArea.coffee @@ -5,12 +5,13 @@ define [ restrict: "A" link: (scope, el) -> resetHeight = () -> - el.css("height", "auto") - el.css("height", el.prop("scrollHeight")) + curHeight = el.outerHeight() + fitHeight = el.prop("scrollHeight") + + if fitHeight > curHeight and el.val() != "" + scope.$emit "expandable-text-area:resize" + el.css("height", fitHeight) scope.$watch (() -> el.val()), resetHeight - resetHeight() - - \ No newline at end of file diff --git a/services/web/public/coffee/ide/connection/ConnectionManager.coffee b/services/web/public/coffee/ide/connection/ConnectionManager.coffee index afbc656a02..a8696fc999 100644 --- a/services/web/public/coffee/ide/connection/ConnectionManager.coffee +++ b/services/web/public/coffee/ide/connection/ConnectionManager.coffee @@ -1,3 +1,4 @@ + define [], () -> ONEHOUR = 1000 * 60 * 60 class ConnectionManager diff --git a/services/web/public/coffee/ide/editor/EditorManager.coffee b/services/web/public/coffee/ide/editor/EditorManager.coffee index 3b6672fae8..e01a12cb8b 100644 --- a/services/web/public/coffee/ide/editor/EditorManager.coffee +++ b/services/web/public/coffee/ide/editor/EditorManager.coffee @@ -11,7 +11,7 @@ define [ open_doc_name: null opening: true trackChanges: false - wantTrackChanges: window.trackChangesEnabled + wantTrackChanges: false } @$scope.$on "entity:selected", (event, entity) => @@ -37,6 +37,10 @@ define [ @$scope.$watch "editor.wantTrackChanges", (value) => return if !value? @_syncTrackChangesState(@$scope.editor.sharejs_doc) + + @$scope.$watch "project.features.trackChanges", (trackChangesFeature) => + return if !trackChangesFeature? + @$scope.editor.wantTrackChanges = window.trackChangesEnabled and trackChangesFeature autoOpenDoc: () -> open_doc_id = diff --git a/services/web/public/coffee/ide/editor/directives/aceEditor.coffee b/services/web/public/coffee/ide/editor/directives/aceEditor.coffee index 93775fd78f..9205cb7b87 100644 --- a/services/web/public/coffee/ide/editor/directives/aceEditor.coffee +++ b/services/web/public/coffee/ide/editor/directives/aceEditor.coffee @@ -167,10 +167,22 @@ define [ if arg == "/" ace.require("ace/ext/searchbox").Search(editor, true) + getCursorScreenPosition = () -> + session = editor.getSession() + cursorPosition = session.selection.getCursor() + sessionPos = session.documentToScreenPosition(cursorPosition.row, cursorPosition.column) + screenPos = editor.renderer.textToScreenCoordinates(sessionPos.row, sessionPos.column) + return sessionPos.row * editor.renderer.lineHeight - session.getScrollTop() + if attrs.resizeOn? for event in attrs.resizeOn.split(",") scope.$on event, () -> + previousScreenPosition = getCursorScreenPosition() editor.resize() + # Put cursor back to same vertical position on screen + newScreenPosition = getCursorScreenPosition() + session = editor.getSession() + session.setScrollTop(session.getScrollTop() + newScreenPosition - previousScreenPosition) scope.$watch "theme", (value) -> editor.setTheme("ace/theme/#{value}") diff --git a/services/web/public/coffee/ide/editor/directives/aceEditor/spell-check/HighlightedWordManager.coffee b/services/web/public/coffee/ide/editor/directives/aceEditor/spell-check/HighlightedWordManager.coffee index 470909a9ed..5014559562 100644 --- a/services/web/public/coffee/ide/editor/directives/aceEditor/spell-check/HighlightedWordManager.coffee +++ b/services/web/public/coffee/ide/editor/directives/aceEditor/spell-check/HighlightedWordManager.coffee @@ -12,6 +12,9 @@ define [ class HighlightedWordManager constructor: (@editor) -> + @reset() + + reset: () -> @highlights = rows: [] addHighlight: (highlight) -> @@ -21,7 +24,7 @@ define [ highlight.row, highlight.column, highlight.row, highlight.column + highlight.word.length ) - highlight.markerId = @editor.getSession().addMarker range, "spelling-highlight", null, true + highlight.markerId = @editor.getSession().addMarker range, "spelling-highlight", 'text', false @highlights.rows[highlight.row] ||= [] @highlights.rows[highlight.row].push highlight diff --git a/services/web/public/coffee/ide/editor/directives/aceEditor/spell-check/SpellCheckManager.coffee b/services/web/public/coffee/ide/editor/directives/aceEditor/spell-check/SpellCheckManager.coffee index e84ce1d785..759b1d2b70 100644 --- a/services/web/public/coffee/ide/editor/directives/aceEditor/spell-check/SpellCheckManager.coffee +++ b/services/web/public/coffee/ide/editor/directives/aceEditor/spell-check/SpellCheckManager.coffee @@ -22,6 +22,10 @@ define [ @closeContextMenu() @editor.on "changeSession", (e) => + @highlightedWordManager.reset() + if @inProgressRequest? + @inProgressRequest.abort() + if @$scope.spellCheckEnabled and @$scope.spellCheckLanguage and @$scope.spellCheckLanguage != "" @runSpellCheckSoon(200) @@ -183,7 +187,8 @@ define [ if not words.length displayResult highlights else - @apiRequest "/check", {language: language, words: words}, (error, result) => + @inProgressRequest = @apiRequest "/check", {language: language, words: words}, (error, result) => + delete @inProgressRequest if error? or !result? or !result.misspellings? return null mispelled = [] @@ -240,4 +245,4 @@ define [ callback null, data error: (xhr, status, error) -> callback error - $.ajax options + return $.ajax options diff --git a/services/web/public/coffee/ide/review-panel/ReviewPanelManager.coffee b/services/web/public/coffee/ide/review-panel/ReviewPanelManager.coffee index 2ad425b737..1565d6db73 100644 --- a/services/web/public/coffee/ide/review-panel/ReviewPanelManager.coffee +++ b/services/web/public/coffee/ide/review-panel/ReviewPanelManager.coffee @@ -1,5 +1,6 @@ define [ "ide/review-panel/controllers/ReviewPanelController" + "ide/review-panel/controllers/TrackChangesUpgradeModalController" "ide/review-panel/directives/reviewPanelSorted" "ide/review-panel/directives/reviewPanelToggle" "ide/review-panel/directives/changeEntry" diff --git a/services/web/public/coffee/ide/review-panel/controllers/ReviewPanelController.coffee b/services/web/public/coffee/ide/review-panel/controllers/ReviewPanelController.coffee index 40be0ed372..d46ef404bc 100644 --- a/services/web/public/coffee/ide/review-panel/controllers/ReviewPanelController.coffee +++ b/services/web/public/coffee/ide/review-panel/controllers/ReviewPanelController.coffee @@ -4,7 +4,7 @@ define [ "ide/colors/ColorManager" "ide/review-panel/RangesTracker" ], (App, EventEmitter, ColorManager, RangesTracker) -> - App.controller "ReviewPanelController", ($scope, $element, ide, $timeout, $http, event_tracking) -> + App.controller "ReviewPanelController", ($scope, $element, ide, $timeout, $http, $modal, event_tracking) -> $reviewPanelEl = $element.find "#review-panel" $scope.SubViews = @@ -29,9 +29,15 @@ define [ $scope.$on "layout:pdf:linked", (event, state) -> $scope.reviewPanel.layoutToLeft = (state.east?.size < 220 || state.east?.initClosed) + $scope.$broadcast "review-panel:layout" $scope.$on "layout:pdf:resize", (event, state) -> $scope.reviewPanel.layoutToLeft = (state.east?.size < 220 || state.east?.initClosed) + $scope.$broadcast "review-panel:layout", false + + $scope.$on "expandable-text-area:resize", (event) -> + $timeout () -> + $scope.$broadcast "review-panel:layout" $scope.$watch "ui.pdfLayout", (layout) -> $scope.reviewPanel.layoutToLeft = (layout == "flat") @@ -142,13 +148,13 @@ define [ entries = $scope.reviewPanel.entries[$scope.editor.open_doc_id] or {} Object.keys(entries).length ), (nEntries) -> - $scope.reviewPanel.hasEntries = nEntries > 0 and $scope.project.features.trackChanges + $scope.reviewPanel.hasEntries = nEntries > 0 and $scope.project.features.trackChangesVisible $scope.$watch "ui.reviewPanelOpen", (reviewPanelOpen) -> return if !reviewPanelOpen? $timeout () -> $scope.$broadcast "review-panel:toggle" - $scope.$broadcast "review-panel:layout" + $scope.$broadcast "review-panel:layout", false regenerateTrackChangesId = (doc) -> old_id = getChangeTracker(doc.doc_id).getIdSeed() @@ -432,9 +438,12 @@ define [ ide.editorManager.openDocId(doc_id, { gotoOffset: entry.offset }) $scope.toggleTrackChanges = (value) -> - $scope.editor.wantTrackChanges = value - $http.post "/project/#{$scope.project_id}/track_changes", {_csrf: window.csrfToken, on: value} - event_tracking.sendMB "rp-trackchanges-toggle", { value } + if $scope.project.features.trackChanges + $scope.editor.wantTrackChanges = value + $http.post "/project/#{$scope.project_id}/track_changes", {_csrf: window.csrfToken, on: value} + event_tracking.sendMB "rp-trackchanges-toggle", { value } + else + $scope.openTrackChangesUpgradeModal() ide.socket.on "toggle-track-changes", (value) -> $scope.$apply () -> @@ -523,3 +532,10 @@ define [ hue: ColorManager.getHueForUserId(id) avatar_text: [user.first_name, user.last_name].filter((n) -> n?).map((n) -> n[0]).join "" } + + $scope.openTrackChangesUpgradeModal = () -> + $modal.open { + templateUrl: "trackChangesUpgradeModalTemplate" + controller: "TrackChangesUpgradeModalController" + scope: $scope.$new() + } diff --git a/services/web/public/coffee/ide/review-panel/controllers/TrackChangesUpgradeModalController.coffee b/services/web/public/coffee/ide/review-panel/controllers/TrackChangesUpgradeModalController.coffee new file mode 100644 index 0000000000..ae8c049f69 --- /dev/null +++ b/services/web/public/coffee/ide/review-panel/controllers/TrackChangesUpgradeModalController.coffee @@ -0,0 +1,11 @@ +define [ + "base" +], (App) -> + App.controller "TrackChangesUpgradeModalController", ($scope, $modalInstance) -> + $scope.cancel = () -> + $modalInstance.dismiss() + + $scope.startFreeTrial = (source) -> + ga?('send', 'event', 'subscription-funnel', 'upgraded-free-trial', source) + window.open("/user/subscription/new?planCode=student_free_trial_7_days") + $scope.startedFreeTrial = true \ No newline at end of file diff --git a/services/web/public/coffee/ide/review-panel/directives/reviewPanelSorted.coffee b/services/web/public/coffee/ide/review-panel/directives/reviewPanelSorted.coffee index 2bd66c723e..4028406713 100644 --- a/services/web/public/coffee/ide/review-panel/directives/reviewPanelSorted.coffee +++ b/services/web/public/coffee/ide/review-panel/directives/reviewPanelSorted.coffee @@ -6,7 +6,11 @@ define [ link: (scope, element, attrs) -> previous_focused_entry_index = 0 - layout = () -> + layout = (animate = true) -> + if animate + element.removeClass("no-animate") + else + element.addClass("no-animate") sl_console.log "LAYOUT" if scope.ui.reviewPanelOpen PADDING = 8 @@ -101,9 +105,9 @@ define [ scope.$applyAsync () -> layout() - scope.$on "review-panel:layout", () -> + scope.$on "review-panel:layout", (e, animate = true) -> scope.$applyAsync () -> - layout() + layout(animate) scope.$watch "reviewPanel.rendererData.lineHeight", () -> layout() diff --git a/services/web/public/coffee/ide/review-panel/directives/reviewPanelToggle.coffee b/services/web/public/coffee/ide/review-panel/directives/reviewPanelToggle.coffee index 24b7070d07..2b5180dce6 100644 --- a/services/web/public/coffee/ide/review-panel/directives/reviewPanelToggle.coffee +++ b/services/web/public/coffee/ide/review-panel/directives/reviewPanelToggle.coffee @@ -6,16 +6,23 @@ define [ scope: onToggle: '=' ngModel: '=' + disabled: '=?' + onDisabledClick: '=?' link: (scope) -> + if !scope.disabled? + scope.disabled = false scope.onChange = (args...) -> scope.onToggle(scope.localModel) + scope.handleClick = () -> + if scope.disabled + scope.onDisabledClick() scope.localModel = scope.ngModel scope.$watch "ngModel", (value) -> scope.localModel = value template: """ -
- +
+
""" diff --git a/services/web/public/img/about/joe_green.jpg b/services/web/public/img/about/joe_green.jpg new file mode 100644 index 0000000000..0b730673d0 Binary files /dev/null and b/services/web/public/img/about/joe_green.jpg differ diff --git a/services/web/public/img/teasers/track-changes/teaser-track-changes.gif b/services/web/public/img/teasers/track-changes/teaser-track-changes.gif new file mode 100644 index 0000000000..00e02a29b0 Binary files /dev/null and b/services/web/public/img/teasers/track-changes/teaser-track-changes.gif differ diff --git a/services/web/public/img/teasers/track-changes/teaser-track-changes.mp4 b/services/web/public/img/teasers/track-changes/teaser-track-changes.mp4 new file mode 100644 index 0000000000..1f75a461ad Binary files /dev/null and b/services/web/public/img/teasers/track-changes/teaser-track-changes.mp4 differ diff --git a/services/web/public/stylesheets/app/editor/review-panel.less b/services/web/public/stylesheets/app/editor/review-panel.less index 56a79e9e98..1d1900c90c 100644 --- a/services/web/public/stylesheets/app/editor/review-panel.less +++ b/services/web/public/stylesheets/app/editor/review-panel.less @@ -184,6 +184,9 @@ color: #FFF; cursor: pointer; transition: top 0.3s, left 0.1s, right 0.1s; + .no-animate & { + transition: none; + } &-focused { left: 0px; @@ -277,6 +280,9 @@ border-radius: 3px; background-color: #FFF; transition: top 0.3s, left 0.1s, right 0.1s; + .no-animate & { + transition: none; + } &-insert { border-color: @rp-green; @@ -339,6 +345,7 @@ // We need to set any low-enough flex base size (0px), making it growable (1) and non-shrinkable (0). // This is needed to ensure that IE makes the element fill the available space. flex: 1 0 1px; + overflow-x: auto; .rp-state-overview & { margin-left: 0; @@ -417,6 +424,7 @@ .rp-comment-content { margin: 0; color: @rp-type-darkgrey; + overflow-x: auto; // Long words, like links can overflow without this. } .rp-comment-resolver { @@ -451,6 +459,8 @@ resize: vertical; color: @rp-type-darkgrey; margin-top: 3px; + overflow-x: hidden; + min-height: 3em; } .rp-icon-delete { @@ -643,7 +653,7 @@ .rp-toggle { display: inline-block; vertical-align: middle; - margin-left: 5px; + padding-left: 5px; } .rp-toggle-hidden-input { display: none; diff --git a/services/web/test/UnitTests/coffee/PasswordReset/PasswordResetControllerTests.coffee b/services/web/test/UnitTests/coffee/PasswordReset/PasswordResetControllerTests.coffee index 89c6479734..d11507361c 100644 --- a/services/web/test/UnitTests/coffee/PasswordReset/PasswordResetControllerTests.coffee +++ b/services/web/test/UnitTests/coffee/PasswordReset/PasswordResetControllerTests.coffee @@ -145,18 +145,27 @@ describe "PasswordResetController", -> done() @PasswordResetController.setNewUserPassword @req, @res - it "should login user if login_after is set", (done) -> - @UserGetter.getUser = sinon.stub().callsArgWith(2, null, { email: "joe@example.com" }) - @PasswordResetHandler.setNewUserPassword.callsArgWith(2, null, true, @user_id = "user-id-123") - @req.body.login_after = "true" - @AuthenticationController.doLogin = (options, req, res, next)=> - @UserGetter.getUser.calledWith(@user_id).should.equal true - expect(options).to.deep.equal { - email: "joe@example.com", - password: @password - } + describe 'when login_after is set', -> + + beforeEach -> + @UserGetter.getUser = sinon.stub().callsArgWith(2, null, { email: "joe@example.com" }) + @PasswordResetHandler.setNewUserPassword.callsArgWith(2, null, true, @user_id = "user-id-123") + @req.body.login_after = "true" + @res.json = sinon.stub() + @AuthenticationController.afterLoginSessionSetup = sinon.stub().callsArgWith(2, null) + @AuthenticationController._getRedirectFromSession = sinon.stub().returns('/some/path') + + it "should login user if login_after is set", (done) -> + @PasswordResetController.setNewUserPassword @req, @res + @AuthenticationController.afterLoginSessionSetup.callCount.should.equal 1 + @AuthenticationController.afterLoginSessionSetup.calledWith( + @req, + {email: 'joe@example.com'} + ).should.equal true + @AuthenticationController._getRedirectFromSession.callCount.should.equal 1 + @res.json.callCount.should.equal 1 + @res.json.calledWith({redir: '/some/path'}).should.equal true done() - @PasswordResetController.setNewUserPassword @req, @res describe "renderSetPasswordForm", ->