background-step7-recovery.test.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  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 refreshes CPA oauth via step 7 replay before submitting verification code', 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. getPanelMode: () => 'cpa',
  44. getState: async () => ({ email: 'user@example.com', password: 'secret' }),
  45. getTabId: async (sourceName) => (sourceName === 'signup-page' ? 1 : 2),
  46. HOTMAIL_PROVIDER: 'hotmail-api',
  47. isTabAlive: async () => true,
  48. isVerificationMailPollingError: () => false,
  49. LUCKMAIL_PROVIDER: 'luckmail-api',
  50. resolveVerificationStep: async (_step, _state, _mail, options) => {
  51. calls.resolveOptions = options;
  52. await options.beforeSubmit({ code: '654321' });
  53. },
  54. reuseOrCreateTab: async () => {},
  55. setState: async () => {},
  56. setStepStatus: async () => {},
  57. shouldSkipLoginVerificationForCpaCallback: () => false,
  58. shouldUseCustomRegistrationEmail: () => false,
  59. sleepWithStop: async (ms) => {
  60. calls.sleep.push(ms);
  61. },
  62. STANDARD_MAIL_VERIFICATION_RESEND_INTERVAL_MS: 25000,
  63. STEP7_MAIL_POLLING_RECOVERY_MAX_ATTEMPTS: 8,
  64. throwIfStopped: () => {},
  65. });
  66. try {
  67. await executor.executeStep8({
  68. email: 'user@example.com',
  69. password: 'secret',
  70. oauthUrl: 'https://oauth.example/latest',
  71. });
  72. } finally {
  73. Date.now = realDateNow;
  74. }
  75. assert.equal(typeof calls.resolveOptions.beforeSubmit, 'function');
  76. assert.equal(calls.ensureReady, 2);
  77. assert.equal(calls.executeStep7, 1);
  78. assert.deepStrictEqual(calls.sleep, [1200]);
  79. assert.equal(calls.resolveOptions.filterAfterTimestamp, 123456);
  80. assert.equal(typeof calls.resolveOptions.getRemainingTimeMs, 'function');
  81. assert.equal(await calls.resolveOptions.getRemainingTimeMs({ actionLabel: '登录验证码流程' }), 5000);
  82. assert.equal(calls.resolveOptions.resendIntervalMs, 25000);
  83. assert.deepStrictEqual(calls.ensureReadyOptions, [
  84. { timeoutMs: 5000 },
  85. { timeoutMs: 5000 },
  86. ]);
  87. });
  88. test('step 8 disables resend interval for 2925 mailbox polling', async () => {
  89. let capturedOptions = null;
  90. const executor = api.createStep8Executor({
  91. addLog: async () => {},
  92. chrome: {
  93. tabs: {
  94. update: async () => {},
  95. },
  96. },
  97. CLOUDFLARE_TEMP_EMAIL_PROVIDER: 'cloudflare-temp-email',
  98. confirmCustomVerificationStepBypass: async () => {},
  99. ensureStep8VerificationPageReady: async () => ({ state: 'verification_page' }),
  100. executeStep7: async () => {},
  101. getOAuthFlowRemainingMs: async () => 8000,
  102. getOAuthFlowStepTimeoutMs: async (defaultTimeoutMs) => Math.min(defaultTimeoutMs, 8000),
  103. getMailConfig: () => ({
  104. provider: '2925',
  105. label: '2925 邮箱',
  106. source: 'mail-2925',
  107. url: 'https://2925.com',
  108. navigateOnReuse: false,
  109. }),
  110. getPanelMode: () => 'sub2api',
  111. getState: async () => ({ email: 'user@example.com', password: 'secret' }),
  112. getTabId: async (sourceName) => (sourceName === 'signup-page' ? 1 : 2),
  113. HOTMAIL_PROVIDER: 'hotmail-api',
  114. isTabAlive: async () => true,
  115. isVerificationMailPollingError: () => false,
  116. LUCKMAIL_PROVIDER: 'luckmail-api',
  117. resolveVerificationStep: async (_step, _state, _mail, options) => {
  118. capturedOptions = options;
  119. },
  120. reuseOrCreateTab: async () => {},
  121. setState: async () => {},
  122. setStepStatus: async () => {},
  123. shouldSkipLoginVerificationForCpaCallback: () => false,
  124. shouldUseCustomRegistrationEmail: () => false,
  125. sleepWithStop: async () => {},
  126. STANDARD_MAIL_VERIFICATION_RESEND_INTERVAL_MS: 25000,
  127. STEP7_MAIL_POLLING_RECOVERY_MAX_ATTEMPTS: 8,
  128. throwIfStopped: () => {},
  129. });
  130. await executor.executeStep8({
  131. email: 'user@example.com',
  132. password: 'secret',
  133. oauthUrl: 'https://oauth.example/latest',
  134. });
  135. assert.equal(capturedOptions.resendIntervalMs, 0);
  136. assert.equal(capturedOptions.beforeSubmit, undefined);
  137. assert.equal(typeof capturedOptions.getRemainingTimeMs, 'function');
  138. });