background-message-router-step2-skip.test.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  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/message-router.js', 'utf8');
  5. const globalScope = {};
  6. const api = new Function('self', `${source}; return self.MultiPageBackgroundMessageRouter;`)(globalScope);
  7. function createRouter(overrides = {}) {
  8. const events = {
  9. logs: [],
  10. stepStatuses: [],
  11. emailStates: [],
  12. };
  13. const router = api.createMessageRouter({
  14. addLog: async (message, level) => {
  15. events.logs.push({ message, level });
  16. },
  17. appendAccountRunRecord: async () => null,
  18. batchUpdateLuckmailPurchases: async () => {},
  19. buildLocalhostCleanupPrefix: () => '',
  20. buildLuckmailSessionSettingsPayload: () => ({}),
  21. buildPersistentSettingsPayload: () => ({}),
  22. broadcastDataUpdate: () => {},
  23. cancelScheduledAutoRun: async () => {},
  24. checkIcloudSession: async () => {},
  25. clearAutoRunTimerAlarm: async () => {},
  26. clearLuckmailRuntimeState: async () => {},
  27. clearStopRequest: () => {},
  28. closeLocalhostCallbackTabs: async () => {},
  29. closeTabsByUrlPrefix: async () => {},
  30. deleteHotmailAccount: async () => {},
  31. deleteHotmailAccounts: async () => {},
  32. deleteIcloudAlias: async () => {},
  33. deleteUsedIcloudAliases: async () => {},
  34. disableUsedLuckmailPurchases: async () => {},
  35. doesStepUseCompletionSignal: () => false,
  36. ensureManualInteractionAllowed: async () => ({}),
  37. executeStep: async () => {},
  38. executeStepViaCompletionSignal: async () => {},
  39. exportSettingsBundle: async () => ({}),
  40. fetchGeneratedEmail: async () => '',
  41. finalizeIcloudAliasAfterSuccessfulFlow: async () => {},
  42. findHotmailAccount: async () => null,
  43. flushCommand: async () => {},
  44. getCurrentLuckmailPurchase: () => null,
  45. getPendingAutoRunTimerPlan: () => null,
  46. getSourceLabel: () => '',
  47. getState: async () => overrides.state || { stepStatuses: { 3: 'pending' } },
  48. getStopRequested: () => false,
  49. handleAutoRunLoopUnhandledError: async () => {},
  50. importSettingsBundle: async () => {},
  51. invalidateDownstreamAfterStepRestart: async () => {},
  52. isAutoRunLockedState: () => false,
  53. isHotmailProvider: () => false,
  54. isLocalhostOAuthCallbackUrl: () => true,
  55. isLuckmailProvider: () => false,
  56. isStopError: () => false,
  57. launchAutoRunTimerPlan: async () => {},
  58. listIcloudAliases: async () => [],
  59. listLuckmailPurchasesForManagement: async () => [],
  60. normalizeHotmailAccounts: (items) => items,
  61. normalizeRunCount: (value) => value,
  62. AUTO_RUN_TIMER_KIND_SCHEDULED_START: 'scheduled',
  63. notifyStepComplete: () => {},
  64. notifyStepError: () => {},
  65. patchHotmailAccount: async () => {},
  66. registerTab: async () => {},
  67. requestStop: async () => {},
  68. resetState: async () => {},
  69. resumeAutoRun: async () => {},
  70. scheduleAutoRun: async () => {},
  71. selectLuckmailPurchase: async () => {},
  72. setCurrentHotmailAccount: async () => {},
  73. setEmailState: async (email) => {
  74. events.emailStates.push(email);
  75. },
  76. setEmailStateSilently: async () => {},
  77. setIcloudAliasPreservedState: async () => {},
  78. setIcloudAliasUsedState: async () => {},
  79. setLuckmailPurchaseDisabledState: async () => {},
  80. setLuckmailPurchasePreservedState: async () => {},
  81. setLuckmailPurchaseUsedState: async () => {},
  82. setPersistentSettings: async () => {},
  83. setState: async () => {},
  84. setStepStatus: async (step, status) => {
  85. events.stepStatuses.push({ step, status });
  86. },
  87. skipAutoRunCountdown: async () => false,
  88. skipStep: async () => {},
  89. startAutoRunLoop: async () => {},
  90. syncHotmailAccounts: async () => {},
  91. testHotmailAccountMailAccess: async () => {},
  92. upsertHotmailAccount: async () => {},
  93. verifyHotmailAccount: async () => {},
  94. });
  95. return { router, events };
  96. }
  97. test('message router skips step 3 when step 2 lands on verification page', async () => {
  98. const { router, events } = createRouter({
  99. state: { stepStatuses: { 3: 'pending' } },
  100. });
  101. await router.handleStepData(2, {
  102. email: 'user@example.com',
  103. skippedPasswordStep: true,
  104. });
  105. assert.deepStrictEqual(events.emailStates, ['user@example.com']);
  106. assert.deepStrictEqual(events.stepStatuses, [{ step: 3, status: 'skipped' }]);
  107. assert.equal(events.logs[0]?.message, '步骤 2:提交邮箱后页面直接进入邮箱验证码页,已自动跳过步骤 3。');
  108. });
  109. test('message router does not overwrite a completed step 3 when step 2 is replayed', async () => {
  110. const { router, events } = createRouter({
  111. state: { stepStatuses: { 3: 'completed' } },
  112. });
  113. await router.handleStepData(2, {
  114. skippedPasswordStep: true,
  115. });
  116. assert.deepStrictEqual(events.stepStatuses, []);
  117. });