diff --git a/client/src/redux/selectors.js b/client/src/redux/selectors.js index ca564626265..0f1ee707ca4 100644 --- a/client/src/redux/selectors.js +++ b/client/src/redux/selectors.js @@ -42,6 +42,10 @@ export const shouldRequestDonationSelector = state => { // don't request donation if already donating if (isDonating) return false; + // donations only appear after the user has completed ten challenges (i.e. + // not before the 11th challenge has mounted) + if (completedChallengeCount < 10) return false; + // a block has been completed if (recentlyClaimedBlock) return true; @@ -56,10 +60,6 @@ export const shouldRequestDonationSelector = state => { return sessionChallengeData.countSinceSave >= 20; } - // donations only appear after the user has completed ten challenges (i.e. - // not before the 11th challenge has mounted) - if (completedChallengeCount < 10) return false; - /* Show modal if user has completed 10 challanged in total and 3 or more in this session. diff --git a/e2e/donation-modal.spec.ts b/e2e/donation-modal.spec.ts index e3a347aeb94..a0041e5de61 100644 --- a/e2e/donation-modal.spec.ts +++ b/e2e/donation-modal.spec.ts @@ -6,7 +6,7 @@ import { clearEditor, focusEditor } from './utils/editor'; const slowExpect = expect.configure({ timeout: 25000 }); -const completeFrontEndCert = async (page: Page) => { +const completeFrontEndCert = async (page: Page, number?: number) => { await page.goto( `/learn/front-end-development-libraries/front-end-development-libraries-projects/build-a-random-quote-machine` ); @@ -19,9 +19,10 @@ const completeFrontEndCert = async (page: Page) => { '25--5-clock' ]; - for (const project of projects) { + const loopNumber = number || projects.length; + for (let i = 0; i < loopNumber; i++) { await page.waitForURL( - `/learn/front-end-development-libraries/front-end-development-libraries-projects/build-a-${project}` + `/learn/front-end-development-libraries/front-end-development-libraries-projects/build-a-${projects[i]}` ); await page .getByRole('textbox', { name: 'solution' }) @@ -257,13 +258,33 @@ test.describe('Donation modal appearance logic - New user', () => { await expect(donationModal).toBeHidden(); }); - test('should appear if the user has just completed a new block, and should not appear if the user re-submits the projects of the block', async ({ + test('should not appear if the user has just completed a new block but has less than 10 completed challenges', async ({ page }) => { test.setTimeout(40000); await completeFrontEndCert(page); + const donationModal = page + .getByRole('dialog') + .filter({ hasText: 'Become a Supporter' }); + await expect(donationModal).toBeHidden(); + }); +}); + +test.describe('Donation modal appearance logic - Certified user claiming a new block', () => { + test.use({ storageState: 'playwright/.auth/certified-user.json' }); + execSync('node ./tools/scripts/seed/seed-demo-user --almost-certified-user'); + + test('should appear if the user has just completed a new block, and should not appear if the user re-submits the projects of the block', async ({ + page, + context + }) => { + await context.grantPermissions(['clipboard-read', 'clipboard-write']); + test.setTimeout(40000); + + await completeFrontEndCert(page, 1); + const donationModal = page .getByRole('dialog') .filter({ hasText: 'Become a Supporter' }); @@ -284,7 +305,7 @@ test.describe('Donation modal appearance logic - New user', () => { await donationModal.getByRole('button', { name: 'Ask me later' }).click(); await expect(donationModal).toBeHidden(); - await completeFrontEndCert(page); + await completeFrontEndCert(page, 1); await expect(donationModal).toBeHidden(); }); }); diff --git a/tools/scripts/seed/seed-demo-user.js b/tools/scripts/seed/seed-demo-user.js index 60fb5d6095b..f4c3c934353 100644 --- a/tools/scripts/seed/seed-demo-user.js +++ b/tools/scripts/seed/seed-demo-user.js @@ -10,7 +10,8 @@ const { blankUser, publicUser, fullyCertifiedUser, - userIds + userIds, + almostFullyCertifiedUser } = require('./user-data'); const options = { @@ -18,7 +19,8 @@ const options = { 'top-contributor': { type: 'boolean' }, 'set-false': { type: 'string', multiple: true }, 'seed-trophy-challenges': { type: 'boolean' }, - 'certified-user': { type: 'boolean' } + 'certified-user': { type: 'boolean' }, + 'almost-certified-user': { type: 'boolean' } }; const { values: argValues } = parseArgs({ options }); @@ -124,13 +126,15 @@ const run = async () => { await dropUsers(); if (argValues['certified-user']) { await user.insertOne(fullyCertifiedUser); - await user.insertOne(blankUser); - await user.insertOne(publicUser); + } else if (argValues['almost-certified-user']) { + await user.insertOne(almostFullyCertifiedUser); } else { await user.insertOne(demoUser); - await user.insertOne(blankUser); - await user.insertOne(publicUser); } + + await user.insertOne(blankUser); + await user.insertOne(publicUser); + log('local auth user seed complete'); }; diff --git a/tools/scripts/seed/user-data.js b/tools/scripts/seed/user-data.js index ab470da9901..28c92c3fa7a 100644 --- a/tools/scripts/seed/user-data.js +++ b/tools/scripts/seed/user-data.js @@ -5,8 +5,15 @@ const blankUserId = new ObjectId('5bd30e0f1caf6ac3ddddddb9'); const publicUserId = new ObjectId('663b839b24a8b29f57728b13'); const demoUserId = new ObjectId('5bd30e0f1caf6ac3ddddddb5'); const fullyCertifiedUserId = new ObjectId('5fa2db00a25c1c1fa49ce067'); +const almostFullyCertifiedUserId = new ObjectId('5bd30e0f1caf6ac3ddddddb9'); -const userIds = [blankUserId, publicUserId, demoUserId, fullyCertifiedUserId]; +const userIds = [ + blankUserId, + publicUserId, + demoUserId, + fullyCertifiedUserId, + almostFullyCertifiedUserId +]; module.exports.blankUser = { _id: blankUserId, @@ -12287,4 +12294,13 @@ module.exports.fullyCertifiedUser = { unsubscribeId: 'tBX8stC5jiustPBteF2mV' }; +module.exports.almostFullyCertifiedUser = { + ...module.exports.fullyCertifiedUser, + id: almostFullyCertifiedUserId, + completedChallenges: + module.exports.fullyCertifiedUser.completedChallenges.filter( + challenge => challenge.id !== 'bd7158d8c442eddfaeb5bd13' + ) +}; + module.exports.userIds = userIds;