mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-16 06:07:21 +01:00
drop cap ab test: misc fixes (#12694)
This commit is contained in:
@@ -592,6 +592,20 @@ describe('User Model', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
context('pre-save hook', () => {
|
context('pre-save hook', () => {
|
||||||
|
it('enrolls users that signup through web in the Drop Cap AB test', async () => {
|
||||||
|
let user = new User();
|
||||||
|
user.registeredThrough = 'habitica-web';
|
||||||
|
user = await user.save();
|
||||||
|
expect(user._ABtests.dropCapNotif).to.exist;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not enroll users that signup through modal in the Drop Cap AB test', async () => {
|
||||||
|
let user = new User();
|
||||||
|
user.registeredThrough = 'habitica-ios';
|
||||||
|
user = await user.save();
|
||||||
|
expect(user._ABtests.dropCapNotif).to.not.exist;
|
||||||
|
});
|
||||||
|
|
||||||
it('marks the last news post as read for new users', async () => {
|
it('marks the last news post as read for new users', async () => {
|
||||||
const lastNewsPost = { _id: '1' };
|
const lastNewsPost = { _id: '1' };
|
||||||
sandbox.stub(NewsPost, 'lastNewsPost').returns(lastNewsPost);
|
sandbox.stub(NewsPost, 'lastNewsPost').returns(lastNewsPost);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
id="drop-cap-reached"
|
id="drop-cap-reached"
|
||||||
size="md"
|
size="md"
|
||||||
:hide-header="true"
|
:hide-header="true"
|
||||||
:hide-footer="!hasSubscription"
|
:hide-footer="hasSubscription"
|
||||||
>
|
>
|
||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
<div
|
<div
|
||||||
@@ -235,15 +235,15 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
toLearnMore () {
|
toLearnMore () {
|
||||||
this.close();
|
|
||||||
this.$router.push('/user/settings/subscription');
|
|
||||||
|
|
||||||
Analytics.track({
|
Analytics.track({
|
||||||
hitType: 'event',
|
hitType: 'event',
|
||||||
eventCategory: 'drop-cap-reached',
|
eventCategory: 'drop-cap-reached',
|
||||||
eventAction: 'click',
|
eventAction: 'click',
|
||||||
eventLabel: 'Drop Cap Reached > Modal > Subscriptions',
|
eventLabel: 'Drop Cap Reached > Modal > Subscriptions',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.close();
|
||||||
|
this.$router.push('/user/settings/subscription');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -94,7 +94,7 @@
|
|||||||
<button
|
<button
|
||||||
v-once
|
v-once
|
||||||
class="btn btn-primary mb-4"
|
class="btn btn-primary mb-4"
|
||||||
@click="$router.push({name: 'subscription'})"
|
@click="toLearnMore()"
|
||||||
>
|
>
|
||||||
{{ $t('learnMore') }}
|
{{ $t('learnMore') }}
|
||||||
</button>
|
</button>
|
||||||
@@ -173,15 +173,15 @@ export default {
|
|||||||
showProfile (startingPage) {
|
showProfile (startingPage) {
|
||||||
this.$router.push({ name: startingPage });
|
this.$router.push({ name: startingPage });
|
||||||
},
|
},
|
||||||
showBuyGemsModal () {
|
toLearnMore () {
|
||||||
Analytics.track({
|
Analytics.track({
|
||||||
hitType: 'event',
|
hitType: 'event',
|
||||||
eventCategory: 'button',
|
eventCategory: 'button',
|
||||||
eventAction: 'click',
|
eventAction: 'click',
|
||||||
eventLabel: 'Gems > User Dropdown',
|
eventLabel: 'User Dropdown > Subscriptions',
|
||||||
});
|
});
|
||||||
|
|
||||||
this.$root.$emit('bv::show::modal', 'buy-gems', { alreadyTracked: true });
|
this.$router.push({ name: 'subscription' });
|
||||||
},
|
},
|
||||||
logout () {
|
logout () {
|
||||||
this.$store.dispatch('auth:logout');
|
this.$store.dispatch('auth:logout');
|
||||||
|
|||||||
@@ -52,26 +52,6 @@ async function unlockUser (user) {
|
|||||||
}).exec();
|
}).exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enroll users in the Drop Cap A/B Test
|
|
||||||
function dropCapABTest (user, req) {
|
|
||||||
// Only target users that use web for cron and aren't subscribed.
|
|
||||||
// Those using mobile aren't excluded as they may use it later
|
|
||||||
const isWeb = req.headers['x-client'] === 'habitica-web';
|
|
||||||
|
|
||||||
if (isWeb && !user._ABtests.dropCapNotif && !user.isSubscribed()) {
|
|
||||||
const testGroup = Math.random();
|
|
||||||
// Enroll 20% of users, splitting them 50/50
|
|
||||||
if (testGroup <= 0.25) {
|
|
||||||
user._ABtests.dropCapNotif = 'drop-cap-notif-enabled';
|
|
||||||
} else if (testGroup <= 0.5) {
|
|
||||||
user._ABtests.dropCapNotif = 'drop-cap-notif-disabled';
|
|
||||||
} else {
|
|
||||||
user._ABtests.dropCapNotif = 'drop-cap-notif-not-enrolled';
|
|
||||||
}
|
|
||||||
user.markModified('_ABtests');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function cronAsync (req, res) {
|
async function cronAsync (req, res) {
|
||||||
let { user } = res.locals;
|
let { user } = res.locals;
|
||||||
if (!user) return null; // User might not be available when authentication is not mandatory
|
if (!user) return null; // User might not be available when authentication is not mandatory
|
||||||
@@ -86,7 +66,7 @@ async function cronAsync (req, res) {
|
|||||||
res.locals.user = user;
|
res.locals.user = user;
|
||||||
const { daysMissed, timezoneUtcOffsetFromUserPrefs } = user.daysUserHasMissed(now, req);
|
const { daysMissed, timezoneUtcOffsetFromUserPrefs } = user.daysUserHasMissed(now, req);
|
||||||
|
|
||||||
dropCapABTest(user, req);
|
user.enrollInDropCapABTest(req.headers['x-client']);
|
||||||
await updateLastCron(user, now);
|
await updateLastCron(user, now);
|
||||||
|
|
||||||
if (daysMissed <= 0) {
|
if (daysMissed <= 0) {
|
||||||
|
|||||||
@@ -164,6 +164,8 @@ function _setUpNewUser (user) {
|
|||||||
|
|
||||||
user.markModified('items achievements');
|
user.markModified('items achievements');
|
||||||
|
|
||||||
|
user.enrollInDropCapABTest(user.registeredThrough);
|
||||||
|
|
||||||
if (user.registeredThrough === 'habitica-web') {
|
if (user.registeredThrough === 'habitica-web') {
|
||||||
taskTypes = ['habit', 'daily', 'todo', 'reward', 'tag'];
|
taskTypes = ['habit', 'daily', 'todo', 'reward', 'tag'];
|
||||||
|
|
||||||
|
|||||||
@@ -525,3 +525,23 @@ schema.methods.getSecretData = function getSecretData () {
|
|||||||
|
|
||||||
return user.secret;
|
return user.secret;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Enroll users in the Drop Cap A/B Test
|
||||||
|
schema.methods.enrollInDropCapABTest = function enrollInDropCapABTest (xClientHeader) {
|
||||||
|
// Only target users that use web for cron and aren't subscribed.
|
||||||
|
// Those using mobile aren't excluded as they may use it later
|
||||||
|
const isWeb = xClientHeader === 'habitica-web';
|
||||||
|
|
||||||
|
if (isWeb && !this._ABtests.dropCapNotif && !this.isSubscribed()) {
|
||||||
|
const testGroup = Math.random();
|
||||||
|
// Enroll 20% of users, splitting them 50/50
|
||||||
|
if (testGroup <= 0.25) {
|
||||||
|
this._ABtests.dropCapNotif = 'drop-cap-notif-enabled';
|
||||||
|
} else if (testGroup <= 0.5) {
|
||||||
|
this._ABtests.dropCapNotif = 'drop-cap-notif-disabled';
|
||||||
|
} else {
|
||||||
|
this._ABtests.dropCapNotif = 'drop-cap-notif-not-enrolled';
|
||||||
|
}
|
||||||
|
this.markModified('_ABtests');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user