background-step7-recovery.test.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. const test = require('node:test');
  2. const assert = require('node:assert/strict');
  3. const fs = require('node:fs');
  4. const source = fs.readFileSync('background/steps/fetch-login-code.js', 'utf8');
  5. const globalScope = {};
  6. const api = new Function('self', `${source}; return self.MultiPageBackgroundStep8;`)(globalScope);
  7. test('step 8 submits login verification directly without replaying step 7', async () => {
  8. const calls = {
  9. ensureReady: 0,
  10. ensureReadyOptions: [],
  11. executeStep7: 0,
  12. sleep: [],
  13. resolveOptions: null,
  14. };
  15. const realDateNow = Date.now;
  16. Date.now = () => 123456;
  17. const executor = api.createStep8Executor({
  18. addLog: async () => {},
  19. chrome: {
  20. tabs: {
  21. update: async () => {},
  22. },
  23. },
  24. CLOUDFLARE_TEMP_EMAIL_PROVIDER: 'cloudflare-temp-email',
  25. confirmCustomVerificationStepBypass: async () => {},
  26. ensureStep8VerificationPageReady: async (options) => {
  27. calls.ensureReady += 1;
  28. calls.ensureReadyOptions.push(options || null);
  29. return { state: 'verification_page' };
  30. },
  31. executeStep7: async () => {
  32. calls.executeStep7 += 1;
  33. },
  34. getOAuthFlowRemainingMs: async () => 5000,
  35. getOAuthFlowStepTimeoutMs: async (defaultTimeoutMs) => Math.min(defaultTimeoutMs, 5000),
  36. getMailConfig: () => ({
  37. provider: 'qq',
  38. label: 'QQ 邮箱',
  39. source: 'mail-qq',
  40. url: 'https://mail.qq.com',
  41. navigateOnReuse: false,
  42. }),
  43. getState: async () => ({ email: 'user@example.com', password: 'secret' }),
  44. getTabId: async (sourceName) => (sourceName === 'signup-page' ? 1 : 2),
  45. HOTMAIL_PROVIDER: 'hotmail-api',
  46. isTabAlive: async () => true,
  47. isVerificationMailPollingError: () => false,
  48. LUCKMAIL_PROVIDER: 'luckmail-api',
  49. resolveVerificationStep: async (_step, _state, _mail, options) => {
  50. calls.resolveOptions = options;
  51. },
  52. reuseOrCreateTab: async () => {},
  53. setState: async () => {},
  54. setStepStatus: async () => {},
  55. shouldSkipLoginVerificationForCpaCallback: () => false,
  56. shouldUseCustomRegistrationEmail: () => false,
  57. sleepWithStop: async (ms) => {
  58. calls.sleep.push(ms);
  59. },
  60. STANDARD_MAIL_VERIFICATION_RESEND_INTERVAL_MS: 25000,
  61. STEP7_MAIL_POLLING_RECOVERY_MAX_ATTEMPTS: 8,
  62. throwIfStopped: () => {},
  63. });
  64. try {
  65. await executor.executeStep8({
  66. email: 'user@example.com',
  67. password: 'secret',
  68. oauthUrl: 'https://oauth.example/latest',
  69. });
  70. } finally {
  71. Date.now = realDateNow;
  72. }
  73. assert.equal(calls.resolveOptions.beforeSubmit, undefined);
  74. assert.equal(calls.ensureReady, 1);
  75. assert.equal(calls.executeStep7, 0);
  76. assert.deepStrictEqual(calls.sleep, []);
  77. assert.equal(calls.resolveOptions.filterAfterTimestamp, 123456);
  78. assert.equal(typeof calls.resolveOptions.getRemainingTimeMs, 'function');
  79. assert.equal(await calls.resolveOptions.getRemainingTimeMs({ actionLabel: '登录验证码流程' }), 5000);
  80. assert.equal(calls.resolveOptions.resendIntervalMs, 25000);
  81. assert.deepStrictEqual(calls.ensureReadyOptions, [
  82. { timeoutMs: 5000 },
  83. ]);
  84. });
  85. test('step 8 disables resend interval for 2925 mailbox polling', async () => {
  86. let capturedOptions = null;
  87. const executor = api.createStep8Executor({
  88. addLog: async () => {},
  89. chrome: {
  90. tabs: {
  91. update: async () => {},
  92. },
  93. },
  94. CLOUDFLARE_TEMP_EMAIL_PROVIDER: 'cloudflare-temp-email',
  95. confirmCustomVerificationStepBypass: async () => {},
  96. ensureStep8VerificationPageReady: async () => ({ state: 'verification_page' }),
  97. executeStep7: async () => {},
  98. getOAuthFlowRemainingMs: async () => 8000,
  99. getOAuthFlowStepTimeoutMs: async (defaultTimeoutMs) => Math.min(defaultTimeoutMs, 8000),
  100. getMailConfig: () => ({
  101. provider: '2925',
  102. label: '2925 邮箱',
  103. source: 'mail-2925',
  104. url: 'https://2925.com',
  105. navigateOnReuse: false,
  106. }),
  107. getState: async () => ({ email: 'user@example.com', password: 'secret' }),
  108. getTabId: async (sourceName) => (sourceName === 'signup-page' ? 1 : 2),
  109. HOTMAIL_PROVIDER: 'hotmail-api',
  110. isTabAlive: async () => true,
  111. isVerificationMailPollingError: () => false,
  112. LUCKMAIL_PROVIDER: 'luckmail-api',
  113. resolveVerificationStep: async (_step, _state, _mail, options) => {
  114. capturedOptions = options;
  115. },
  116. reuseOrCreateTab: async () => {},
  117. setState: async () => {},
  118. setStepStatus: async () => {},
  119. shouldSkipLoginVerificationForCpaCallback: () => false,
  120. shouldUseCustomRegistrationEmail: () => false,
  121. sleepWithStop: async () => {},
  122. STANDARD_MAIL_VERIFICATION_RESEND_INTERVAL_MS: 25000,
  123. STEP7_MAIL_POLLING_RECOVERY_MAX_ATTEMPTS: 8,
  124. throwIfStopped: () => {},
  125. });
  126. await executor.executeStep8({
  127. email: 'user@example.com',
  128. password: 'secret',
  129. oauthUrl: 'https://oauth.example/latest',
  130. });
  131. assert.equal(capturedOptions.resendIntervalMs, 0);
  132. assert.equal(capturedOptions.beforeSubmit, undefined);
  133. assert.equal(typeof capturedOptions.getRemainingTimeMs, 'function');
  134. });