background-signup-step2-branching.test.js 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. const test = require('node:test');
  2. const assert = require('node:assert/strict');
  3. const fs = require('node:fs');
  4. const step2Source = fs.readFileSync('background/steps/submit-signup-email.js', 'utf8');
  5. const step2GlobalScope = {};
  6. const step2Api = new Function('self', `${step2Source}; return self.MultiPageBackgroundStep2;`)(step2GlobalScope);
  7. const signupFlowSource = fs.readFileSync('background/signup-flow-helpers.js', 'utf8');
  8. const signupFlowGlobalScope = {};
  9. const signupFlowApi = new Function('self', `${signupFlowSource}; return self.MultiPageSignupFlowHelpers;`)(signupFlowGlobalScope);
  10. test('step 2 completes with password step skipped when landing on email verification page', async () => {
  11. const completedPayloads = [];
  12. const executor = step2Api.createStep2Executor({
  13. addLog: async () => {},
  14. chrome: { tabs: { update: async () => {} } },
  15. completeStepFromBackground: async (step, payload) => {
  16. completedPayloads.push({ step, payload });
  17. },
  18. ensureContentScriptReadyOnTab: async () => {},
  19. ensureSignupEntryPageReady: async () => ({ tabId: 11 }),
  20. ensureSignupPostEmailPageReadyInTab: async () => ({
  21. state: 'verification_page',
  22. url: 'https://auth.openai.com/email-verification',
  23. }),
  24. getTabId: async () => 11,
  25. isTabAlive: async () => true,
  26. resolveSignupEmailForFlow: async () => 'user@example.com',
  27. sendToContentScriptResilient: async () => ({ submitted: true }),
  28. SIGNUP_PAGE_INJECT_FILES: [],
  29. });
  30. await executor.executeStep2({ email: 'user@example.com' });
  31. assert.deepStrictEqual(completedPayloads, [
  32. {
  33. step: 2,
  34. payload: {
  35. email: 'user@example.com',
  36. nextSignupState: 'verification_page',
  37. nextSignupUrl: 'https://auth.openai.com/email-verification',
  38. skippedPasswordStep: true,
  39. },
  40. },
  41. ]);
  42. });
  43. test('step 2 keeps password flow when landing on password page', async () => {
  44. const completedPayloads = [];
  45. const executor = step2Api.createStep2Executor({
  46. addLog: async () => {},
  47. chrome: { tabs: { update: async () => {} } },
  48. completeStepFromBackground: async (step, payload) => {
  49. completedPayloads.push({ step, payload });
  50. },
  51. ensureContentScriptReadyOnTab: async () => {},
  52. ensureSignupEntryPageReady: async () => ({ tabId: 12 }),
  53. ensureSignupPostEmailPageReadyInTab: async () => ({
  54. state: 'password_page',
  55. url: 'https://auth.openai.com/create-account/password',
  56. }),
  57. getTabId: async () => 12,
  58. isTabAlive: async () => true,
  59. resolveSignupEmailForFlow: async () => 'user@example.com',
  60. sendToContentScriptResilient: async () => ({ submitted: true }),
  61. SIGNUP_PAGE_INJECT_FILES: [],
  62. });
  63. await executor.executeStep2({ email: 'user@example.com' });
  64. assert.deepStrictEqual(completedPayloads, [
  65. {
  66. step: 2,
  67. payload: {
  68. email: 'user@example.com',
  69. nextSignupState: 'password_page',
  70. nextSignupUrl: 'https://auth.openai.com/create-account/password',
  71. skippedPasswordStep: false,
  72. },
  73. },
  74. ]);
  75. });
  76. test('signup flow helper recognizes email verification page as post-email landing page', async () => {
  77. let ensureCalls = 0;
  78. let passwordReadyChecks = 0;
  79. const helpers = signupFlowApi.createSignupFlowHelpers({
  80. buildGeneratedAliasEmail: () => '',
  81. chrome: {
  82. tabs: {
  83. get: async () => ({
  84. id: 21,
  85. url: 'https://auth.openai.com/email-verification',
  86. }),
  87. },
  88. },
  89. ensureContentScriptReadyOnTab: async () => {
  90. ensureCalls += 1;
  91. },
  92. ensureHotmailAccountForFlow: async () => ({}),
  93. ensureLuckmailPurchaseForFlow: async () => ({}),
  94. isGeneratedAliasProvider: () => false,
  95. isHotmailProvider: () => false,
  96. isLuckmailProvider: () => false,
  97. isSignupEmailVerificationPageUrl: (url) => /\/email-verification(?:[/?#]|$)/i.test(url || ''),
  98. isSignupPasswordPageUrl: (url) => /\/create-account\/password(?:[/?#]|$)/i.test(url || ''),
  99. reuseOrCreateTab: async () => 21,
  100. sendToContentScriptResilient: async () => {
  101. passwordReadyChecks += 1;
  102. return {};
  103. },
  104. setEmailState: async () => {},
  105. SIGNUP_ENTRY_URL: 'https://chatgpt.com/',
  106. SIGNUP_PAGE_INJECT_FILES: [],
  107. waitForTabUrlMatch: async () => ({
  108. id: 21,
  109. url: 'https://auth.openai.com/email-verification',
  110. }),
  111. });
  112. const result = await helpers.ensureSignupPostEmailPageReadyInTab(21, 2);
  113. assert.deepStrictEqual(result, {
  114. ready: true,
  115. state: 'verification_page',
  116. url: 'https://auth.openai.com/email-verification',
  117. });
  118. assert.equal(ensureCalls, 1);
  119. assert.equal(passwordReadyChecks, 0);
  120. });
  121. test('signup flow helper reuses existing managed alias email when it is still compatible', async () => {
  122. let buildCalls = 0;
  123. let setEmailCalls = 0;
  124. const helpers = signupFlowApi.createSignupFlowHelpers({
  125. buildGeneratedAliasEmail: () => {
  126. buildCalls += 1;
  127. return 'demo+fresh@gmail.com';
  128. },
  129. chrome: { tabs: { get: async () => ({ id: 21, url: 'https://auth.openai.com/create-account/password' }) } },
  130. ensureContentScriptReadyOnTab: async () => {},
  131. ensureHotmailAccountForFlow: async () => ({}),
  132. ensureLuckmailPurchaseForFlow: async () => ({}),
  133. isGeneratedAliasProvider: () => true,
  134. isReusableGeneratedAliasEmail: (_state, email) => email === 'demo+saved@gmail.com',
  135. isHotmailProvider: () => false,
  136. isLuckmailProvider: () => false,
  137. isSignupEmailVerificationPageUrl: () => false,
  138. isSignupPasswordPageUrl: () => true,
  139. reuseOrCreateTab: async () => 21,
  140. sendToContentScriptResilient: async () => ({}),
  141. setEmailState: async () => {
  142. setEmailCalls += 1;
  143. },
  144. SIGNUP_ENTRY_URL: 'https://chatgpt.com/',
  145. SIGNUP_PAGE_INJECT_FILES: [],
  146. waitForTabUrlMatch: async () => null,
  147. });
  148. const email = await helpers.resolveSignupEmailForFlow({
  149. mailProvider: 'gmail',
  150. email: 'demo+saved@gmail.com',
  151. });
  152. assert.equal(email, 'demo+saved@gmail.com');
  153. assert.equal(buildCalls, 0);
  154. assert.equal(setEmailCalls, 0);
  155. });