mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-07 20:31:06 -05:00
Merge pull request #2998 from overleaf/as-beta-page-updates
Update beta program page to include feedback survey link GitOrigin-RevId: 549cd2be01b8f64d952d0347c8c102d0d2efae24
This commit is contained in:
parent
d4d6e2c45d
commit
2556fded1e
4 changed files with 66 additions and 97 deletions
|
@ -1,60 +1,47 @@
|
||||||
/* eslint-disable
|
|
||||||
camelcase,
|
|
||||||
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
|
|
||||||
* DS207: Consider shorter variations of null checks
|
|
||||||
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
|
||||||
*/
|
|
||||||
let BetaProgramController
|
|
||||||
const BetaProgramHandler = require('./BetaProgramHandler')
|
const BetaProgramHandler = require('./BetaProgramHandler')
|
||||||
const UserGetter = require('../User/UserGetter')
|
const UserGetter = require('../User/UserGetter')
|
||||||
const Settings = require('settings-sharelatex')
|
const Settings = require('settings-sharelatex')
|
||||||
const logger = require('logger-sharelatex')
|
const logger = require('logger-sharelatex')
|
||||||
const AuthenticationController = require('../Authentication/AuthenticationController')
|
const AuthenticationController = require('../Authentication/AuthenticationController')
|
||||||
|
|
||||||
module.exports = BetaProgramController = {
|
const BetaProgramController = {
|
||||||
optIn(req, res, next) {
|
optIn(req, res, next) {
|
||||||
const user_id = AuthenticationController.getLoggedInUserId(req)
|
const userId = AuthenticationController.getLoggedInUserId(req)
|
||||||
logger.log({ user_id }, 'user opting in to beta program')
|
logger.log({ userId }, 'user opting in to beta program')
|
||||||
if (user_id == null) {
|
if (userId == null) {
|
||||||
return next(new Error('no user id in session'))
|
return next(new Error('no user id in session'))
|
||||||
}
|
}
|
||||||
return BetaProgramHandler.optIn(user_id, function(err) {
|
BetaProgramHandler.optIn(userId, function(err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return next(err)
|
return next(err)
|
||||||
}
|
}
|
||||||
return res.redirect('/beta/participate')
|
res.redirect('/beta/participate')
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
optOut(req, res, next) {
|
optOut(req, res, next) {
|
||||||
const user_id = AuthenticationController.getLoggedInUserId(req)
|
const userId = AuthenticationController.getLoggedInUserId(req)
|
||||||
logger.log({ user_id }, 'user opting out of beta program')
|
logger.log({ userId }, 'user opting out of beta program')
|
||||||
if (user_id == null) {
|
if (userId == null) {
|
||||||
return next(new Error('no user id in session'))
|
return next(new Error('no user id in session'))
|
||||||
}
|
}
|
||||||
return BetaProgramHandler.optOut(user_id, function(err) {
|
BetaProgramHandler.optOut(userId, function(err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return next(err)
|
return next(err)
|
||||||
}
|
}
|
||||||
return res.redirect('/beta/participate')
|
res.redirect('/beta/participate')
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
optInPage(req, res, next) {
|
optInPage(req, res, next) {
|
||||||
const user_id = AuthenticationController.getLoggedInUserId(req)
|
const userId = AuthenticationController.getLoggedInUserId(req)
|
||||||
logger.log({ user_id }, 'showing beta participation page for user')
|
logger.log({ user_id: userId }, 'showing beta participation page for user')
|
||||||
return UserGetter.getUser(user_id, function(err, user) {
|
UserGetter.getUser(userId, function(err, user) {
|
||||||
if (err) {
|
if (err) {
|
||||||
logger.warn({ err, user_id }, 'error fetching user')
|
logger.warn({ err, userId }, 'error fetching user')
|
||||||
return next(err)
|
return next(err)
|
||||||
}
|
}
|
||||||
return res.render('beta_program/opt_in', {
|
res.render('beta_program/opt_in', {
|
||||||
title: 'sharelatex_beta_program',
|
title: 'sharelatex_beta_program',
|
||||||
user,
|
user,
|
||||||
languages: Settings.languages
|
languages: Settings.languages
|
||||||
|
@ -62,3 +49,5 @@ module.exports = BetaProgramController = {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module.exports = BetaProgramController
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
extends ../layout
|
extends ../layout
|
||||||
|
|
||||||
block content
|
block content
|
||||||
.content.content-alt
|
main.content.content-alt
|
||||||
.container.beta-opt-in-wrapper
|
.container.beta-opt-in-wrapper
|
||||||
.row
|
.row
|
||||||
.col-md-10.col-md-offset-1.col-lg-8.col-lg-offset-2
|
.col-md-10.col-md-offset-1.col-lg-8.col-lg-offset-2
|
||||||
|
@ -13,29 +13,44 @@ block content
|
||||||
.container-fluid
|
.container-fluid
|
||||||
.row
|
.row
|
||||||
.col-md-12
|
.col-md-12
|
||||||
p.text-centered #{translate("beta_program_benefits")}
|
if user.betaProgram
|
||||||
p.text-centered
|
p #{translate("beta_program_already_participating")}.
|
||||||
| #{translate("beta_program_badge_description")}
|
p #{translate("thank_you_for_being_part_of_our_beta_program")}.
|
||||||
span.beta-feature-badge
|
else
|
||||||
|
p #{translate("beta_program_benefits")}
|
||||||
|
|
||||||
|
p #[strong How it works:]
|
||||||
|
ul
|
||||||
|
li #{translate("beta_program_badge_description")}#[span(aria-label=translate("beta_feature_badge") role="img").beta-feature-badge]
|
||||||
|
li #{translate("you_will_be_able_to_contact_us_any_time_to_share_your_feedback")}.
|
||||||
|
li #{translate("we_may_also_contact_you_from_time_to_time_by_email_with_a_survey")}.
|
||||||
|
li #{translate("you_can_opt_in_and_out_of_the_program_at_any_time_on_this_page")}.
|
||||||
|
|
||||||
.row.text-centered
|
.row.text-centered
|
||||||
.col-md-12
|
.col-md-12
|
||||||
if user.betaProgram
|
if user.betaProgram
|
||||||
p #{translate("beta_program_already_participating")}
|
|
||||||
form(id="beta-program-opt-out", method="post", action="/beta/opt-out", novalidate)
|
form(id="beta-program-opt-out", method="post", action="/beta/opt-out", novalidate)
|
||||||
|
input(type="hidden", name="_csrf", value=csrfToken)
|
||||||
.form-group
|
.form-group
|
||||||
input(type="hidden", name="_csrf", value=csrfToken)
|
a(
|
||||||
button.btn.btn-primary(
|
href="https://forms.gle/CFEsmvZQTAwHCd3X9"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
).btn.btn-primary.btn-lg #{translate("give_feedback")}
|
||||||
|
.form-group
|
||||||
|
button.btn.btn-info.btn-sm(
|
||||||
type="submit"
|
type="submit"
|
||||||
)
|
)
|
||||||
span #{translate("beta_program_opt_out_action")}
|
span #{translate("beta_program_opt_out_action")}
|
||||||
.form-group
|
.form-group
|
||||||
a(href="/project").btn.btn-info #{translate("back_to_your_projects")}
|
a(href="/project").btn.btn-link.btn-sm #{translate("back_to_your_projects")}
|
||||||
else
|
else
|
||||||
form(id="beta-program-opt-in", method="post", action="/beta/opt-in", novalidate)
|
form(id="beta-program-opt-in", method="post", action="/beta/opt-in", novalidate)
|
||||||
|
input(type="hidden", name="_csrf", value=csrfToken)
|
||||||
.form-group
|
.form-group
|
||||||
input(type="hidden", name="_csrf", value=csrfToken)
|
|
||||||
button.btn.btn-primary(
|
button.btn.btn-primary(
|
||||||
type="submit"
|
type="submit"
|
||||||
)
|
)
|
||||||
span #{translate("beta_program_opt_in_action")}
|
span #{translate("beta_program_opt_in_action")}
|
||||||
|
.form-group
|
||||||
|
a(href="/project").btn.btn-link.btn-sm #{translate("back_to_your_projects")}
|
||||||
|
|
|
@ -1,7 +1,3 @@
|
||||||
.beta-opt-in-wrapper {
|
|
||||||
min-height: 400px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.beta-opt-in {
|
.beta-opt-in {
|
||||||
.form-group {
|
.form-group {
|
||||||
margin-top: 15px;
|
margin-top: 15px;
|
||||||
|
|
|
@ -1,26 +1,12 @@
|
||||||
/* eslint-disable
|
require('chai').should()
|
||||||
max-len,
|
|
||||||
mocha/no-identical-title,
|
|
||||||
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 SandboxedModule = require('sandboxed-module')
|
||||||
const assert = require('assert')
|
|
||||||
const path = require('path')
|
const path = require('path')
|
||||||
const sinon = require('sinon')
|
const sinon = require('sinon')
|
||||||
|
|
||||||
const modulePath = path.join(
|
const modulePath = path.join(
|
||||||
__dirname,
|
__dirname,
|
||||||
'../../../../app/src/Features/BetaProgram/BetaProgramController'
|
'../../../../app/src/Features/BetaProgram/BetaProgramController'
|
||||||
)
|
)
|
||||||
const { expect } = require('chai')
|
|
||||||
|
|
||||||
describe('BetaProgramController', function() {
|
describe('BetaProgramController', function() {
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
|
@ -67,130 +53,113 @@ describe('BetaProgramController', function() {
|
||||||
redirect: sinon.stub(),
|
redirect: sinon.stub(),
|
||||||
render: sinon.stub()
|
render: sinon.stub()
|
||||||
}
|
}
|
||||||
return (this.next = sinon.stub())
|
this.next = sinon.stub()
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('optIn', function() {
|
describe('optIn', function() {
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
return this.BetaProgramHandler.optIn.callsArgWith(1, null)
|
this.BetaProgramHandler.optIn.callsArgWith(1, null)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should redirect to '/beta/participate'", function() {
|
it("should redirect to '/beta/participate'", function() {
|
||||||
this.BetaProgramController.optIn(this.req, this.res, this.next)
|
this.BetaProgramController.optIn(this.req, this.res, this.next)
|
||||||
this.res.redirect.callCount.should.equal(1)
|
this.res.redirect.callCount.should.equal(1)
|
||||||
return this.res.redirect.firstCall.args[0].should.equal(
|
this.res.redirect.firstCall.args[0].should.equal('/beta/participate')
|
||||||
'/beta/participate'
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should not call next with an error', function() {
|
it('should not call next with an error', function() {
|
||||||
this.BetaProgramController.optIn(this.req, this.res, this.next)
|
this.BetaProgramController.optIn(this.req, this.res, this.next)
|
||||||
return this.next.callCount.should.equal(0)
|
this.next.callCount.should.equal(0)
|
||||||
})
|
|
||||||
|
|
||||||
it('should not call next with an error', function() {
|
|
||||||
this.BetaProgramController.optIn(this.req, this.res, this.next)
|
|
||||||
return this.next.callCount.should.equal(0)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should call BetaProgramHandler.optIn', function() {
|
it('should call BetaProgramHandler.optIn', function() {
|
||||||
this.BetaProgramController.optIn(this.req, this.res, this.next)
|
this.BetaProgramController.optIn(this.req, this.res, this.next)
|
||||||
return this.BetaProgramHandler.optIn.callCount.should.equal(1)
|
this.BetaProgramHandler.optIn.callCount.should.equal(1)
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('when BetaProgramHandler.opIn produces an error', function() {
|
describe('when BetaProgramHandler.opIn produces an error', function() {
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
return this.BetaProgramHandler.optIn.callsArgWith(1, new Error('woops'))
|
this.BetaProgramHandler.optIn.callsArgWith(1, new Error('woops'))
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should not redirect to '/beta/participate'", function() {
|
it("should not redirect to '/beta/participate'", function() {
|
||||||
this.BetaProgramController.optIn(this.req, this.res, this.next)
|
this.BetaProgramController.optIn(this.req, this.res, this.next)
|
||||||
return this.res.redirect.callCount.should.equal(0)
|
this.res.redirect.callCount.should.equal(0)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should produce an error', function() {
|
it('should produce an error', function() {
|
||||||
this.BetaProgramController.optIn(this.req, this.res, this.next)
|
this.BetaProgramController.optIn(this.req, this.res, this.next)
|
||||||
this.next.callCount.should.equal(1)
|
this.next.callCount.should.equal(1)
|
||||||
return this.next.firstCall.args[0].should.be.instanceof(Error)
|
this.next.firstCall.args[0].should.be.instanceof(Error)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('optOut', function() {
|
describe('optOut', function() {
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
return this.BetaProgramHandler.optOut.callsArgWith(1, null)
|
this.BetaProgramHandler.optOut.callsArgWith(1, null)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should redirect to '/beta/participate'", function() {
|
it("should redirect to '/beta/participate'", function() {
|
||||||
this.BetaProgramController.optOut(this.req, this.res, this.next)
|
this.BetaProgramController.optOut(this.req, this.res, this.next)
|
||||||
this.res.redirect.callCount.should.equal(1)
|
this.res.redirect.callCount.should.equal(1)
|
||||||
return this.res.redirect.firstCall.args[0].should.equal(
|
this.res.redirect.firstCall.args[0].should.equal('/beta/participate')
|
||||||
'/beta/participate'
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should not call next with an error', function() {
|
it('should not call next with an error', function() {
|
||||||
this.BetaProgramController.optOut(this.req, this.res, this.next)
|
this.BetaProgramController.optOut(this.req, this.res, this.next)
|
||||||
return this.next.callCount.should.equal(0)
|
this.next.callCount.should.equal(0)
|
||||||
})
|
|
||||||
|
|
||||||
it('should not call next with an error', function() {
|
|
||||||
this.BetaProgramController.optOut(this.req, this.res, this.next)
|
|
||||||
return this.next.callCount.should.equal(0)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should call BetaProgramHandler.optOut', function() {
|
it('should call BetaProgramHandler.optOut', function() {
|
||||||
this.BetaProgramController.optOut(this.req, this.res, this.next)
|
this.BetaProgramController.optOut(this.req, this.res, this.next)
|
||||||
return this.BetaProgramHandler.optOut.callCount.should.equal(1)
|
this.BetaProgramHandler.optOut.callCount.should.equal(1)
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('when BetaProgramHandler.optOut produces an error', function() {
|
describe('when BetaProgramHandler.optOut produces an error', function() {
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
return this.BetaProgramHandler.optOut.callsArgWith(
|
this.BetaProgramHandler.optOut.callsArgWith(1, new Error('woops'))
|
||||||
1,
|
|
||||||
new Error('woops')
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should not redirect to '/beta/participate'", function() {
|
it("should not redirect to '/beta/participate'", function() {
|
||||||
this.BetaProgramController.optOut(this.req, this.res, this.next)
|
this.BetaProgramController.optOut(this.req, this.res, this.next)
|
||||||
return this.res.redirect.callCount.should.equal(0)
|
this.res.redirect.callCount.should.equal(0)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should produce an error', function() {
|
it('should produce an error', function() {
|
||||||
this.BetaProgramController.optOut(this.req, this.res, this.next)
|
this.BetaProgramController.optOut(this.req, this.res, this.next)
|
||||||
this.next.callCount.should.equal(1)
|
this.next.callCount.should.equal(1)
|
||||||
return this.next.firstCall.args[0].should.be.instanceof(Error)
|
this.next.firstCall.args[0].should.be.instanceof(Error)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('optInPage', function() {
|
describe('optInPage', function() {
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
return this.UserGetter.getUser.callsArgWith(1, null, this.user)
|
this.UserGetter.getUser.callsArgWith(1, null, this.user)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should render the opt-in page', function() {
|
it('should render the opt-in page', function() {
|
||||||
this.BetaProgramController.optInPage(this.req, this.res, this.next)
|
this.BetaProgramController.optInPage(this.req, this.res, this.next)
|
||||||
this.res.render.callCount.should.equal(1)
|
this.res.render.callCount.should.equal(1)
|
||||||
const { args } = this.res.render.firstCall
|
const { args } = this.res.render.firstCall
|
||||||
return args[0].should.equal('beta_program/opt_in')
|
args[0].should.equal('beta_program/opt_in')
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('when UserGetter.getUser produces an error', function() {
|
describe('when UserGetter.getUser produces an error', function() {
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
return this.UserGetter.getUser.callsArgWith(1, new Error('woops'))
|
this.UserGetter.getUser.callsArgWith(1, new Error('woops'))
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should not render the opt-in page', function() {
|
it('should not render the opt-in page', function() {
|
||||||
this.BetaProgramController.optInPage(this.req, this.res, this.next)
|
this.BetaProgramController.optInPage(this.req, this.res, this.next)
|
||||||
return this.res.render.callCount.should.equal(0)
|
this.res.render.callCount.should.equal(0)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should produce an error', function() {
|
it('should produce an error', function() {
|
||||||
this.BetaProgramController.optInPage(this.req, this.res, this.next)
|
this.BetaProgramController.optInPage(this.req, this.res, this.next)
|
||||||
this.next.callCount.should.equal(1)
|
this.next.callCount.should.equal(1)
|
||||||
return this.next.firstCall.args[0].should.be.instanceof(Error)
|
this.next.firstCall.args[0].should.be.instanceof(Error)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in a new issue