|
|
|
@@ -2794,6 +2794,28 @@ test('phone verification helper immediately replaces number when page says the p
|
|
|
|
|
verificationResendCount: 1,
|
|
|
|
|
currentPhoneActivation: null,
|
|
|
|
|
reusablePhoneActivation: null,
|
|
|
|
|
phoneReusableActivationPool: [
|
|
|
|
|
{
|
|
|
|
|
activationId: 'pool-used-match',
|
|
|
|
|
phoneNumber: '+66 95 000 0011',
|
|
|
|
|
provider: 'hero-sms',
|
|
|
|
|
serviceCode: 'dr',
|
|
|
|
|
countryId: 52,
|
|
|
|
|
successfulUses: 1,
|
|
|
|
|
maxUses: 3,
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
freeReusablePhoneActivation: {
|
|
|
|
|
activationId: 'free-used-match',
|
|
|
|
|
phoneNumber: '+66 95 000 0011',
|
|
|
|
|
provider: 'hero-sms',
|
|
|
|
|
serviceCode: 'dr',
|
|
|
|
|
countryId: 52,
|
|
|
|
|
countryLabel: 'Thailand',
|
|
|
|
|
successfulUses: 0,
|
|
|
|
|
maxUses: 3,
|
|
|
|
|
source: 'free-manual-reuse',
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const numbers = [
|
|
|
|
@@ -2903,6 +2925,11 @@ test('phone verification helper immediately replaces number when page says the p
|
|
|
|
|
'SUBMIT_PHONE_NUMBER',
|
|
|
|
|
'SUBMIT_PHONE_VERIFICATION_CODE',
|
|
|
|
|
]);
|
|
|
|
|
assert.equal(currentState.freeReusablePhoneActivation, null);
|
|
|
|
|
assert.deepStrictEqual(
|
|
|
|
|
currentState.phoneReusableActivationPool.filter((activation) => activation.phoneNumber === '+66 95 000 0011'),
|
|
|
|
|
[]
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('phone verification helper treats phone_max_usage_exceeded as used-number and rotates immediately', async () => {
|
|
|
|
@@ -2913,6 +2940,28 @@ test('phone verification helper treats phone_max_usage_exceeded as used-number a
|
|
|
|
|
verificationResendCount: 1,
|
|
|
|
|
currentPhoneActivation: null,
|
|
|
|
|
reusablePhoneActivation: null,
|
|
|
|
|
phoneReusableActivationPool: [
|
|
|
|
|
{
|
|
|
|
|
activationId: 'pool-max-match',
|
|
|
|
|
phoneNumber: '+66 95 000 1011',
|
|
|
|
|
provider: 'hero-sms',
|
|
|
|
|
serviceCode: 'dr',
|
|
|
|
|
countryId: 52,
|
|
|
|
|
successfulUses: 1,
|
|
|
|
|
maxUses: 3,
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
freeReusablePhoneActivation: {
|
|
|
|
|
activationId: 'free-max-match',
|
|
|
|
|
phoneNumber: '+66 95 000 1011',
|
|
|
|
|
provider: 'hero-sms',
|
|
|
|
|
serviceCode: 'dr',
|
|
|
|
|
countryId: 52,
|
|
|
|
|
countryLabel: 'Thailand',
|
|
|
|
|
successfulUses: 0,
|
|
|
|
|
maxUses: 3,
|
|
|
|
|
source: 'free-manual-reuse',
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const numbers = [
|
|
|
|
@@ -3022,6 +3071,11 @@ test('phone verification helper treats phone_max_usage_exceeded as used-number a
|
|
|
|
|
'SUBMIT_PHONE_NUMBER',
|
|
|
|
|
'SUBMIT_PHONE_VERIFICATION_CODE',
|
|
|
|
|
]);
|
|
|
|
|
assert.equal(currentState.freeReusablePhoneActivation, null);
|
|
|
|
|
assert.deepStrictEqual(
|
|
|
|
|
currentState.phoneReusableActivationPool.filter((activation) => activation.phoneNumber === '+66 95 000 1011'),
|
|
|
|
|
[]
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('phone verification helper rotates number when submitPhoneVerificationCode throws phone_max_usage_exceeded', async () => {
|
|
|
|
@@ -3418,6 +3472,771 @@ test('phone verification helper keeps maxUses behavior for reused V2 activations
|
|
|
|
|
assert.deepStrictEqual(currentState.reusablePhoneActivation, null);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('phone verification helper gives automatic free reuse priority over paid reuse and new acquisition', async () => {
|
|
|
|
|
const requests = [];
|
|
|
|
|
let statusPollCount = 0;
|
|
|
|
|
let currentState = {
|
|
|
|
|
heroSmsApiKey: 'demo-key',
|
|
|
|
|
heroSmsReuseEnabled: true,
|
|
|
|
|
freePhoneReuseEnabled: true,
|
|
|
|
|
freePhoneReuseAutoEnabled: true,
|
|
|
|
|
verificationResendCount: 0,
|
|
|
|
|
currentPhoneActivation: null,
|
|
|
|
|
reusablePhoneActivation: {
|
|
|
|
|
activationId: 'paid-reuse',
|
|
|
|
|
phoneNumber: '66950003333',
|
|
|
|
|
provider: 'hero-sms',
|
|
|
|
|
serviceCode: 'dr',
|
|
|
|
|
countryId: 52,
|
|
|
|
|
countryLabel: 'Thailand',
|
|
|
|
|
successfulUses: 0,
|
|
|
|
|
maxUses: 3,
|
|
|
|
|
},
|
|
|
|
|
freeReusablePhoneActivation: {
|
|
|
|
|
activationId: 'free-priority',
|
|
|
|
|
phoneNumber: '66950004444',
|
|
|
|
|
provider: 'hero-sms',
|
|
|
|
|
serviceCode: 'dr',
|
|
|
|
|
countryId: 52,
|
|
|
|
|
countryLabel: 'Thailand',
|
|
|
|
|
successfulUses: 0,
|
|
|
|
|
maxUses: 3,
|
|
|
|
|
source: 'free-manual-reuse',
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const helpers = api.createPhoneVerificationHelpers({
|
|
|
|
|
addLog: async () => {},
|
|
|
|
|
ensureStep8SignupPageReady: async () => {},
|
|
|
|
|
fetchImpl: async (url) => {
|
|
|
|
|
const parsedUrl = new URL(url);
|
|
|
|
|
requests.push(parsedUrl);
|
|
|
|
|
const action = parsedUrl.searchParams.get('action');
|
|
|
|
|
const id = parsedUrl.searchParams.get('id');
|
|
|
|
|
if (action === 'reactivate' || action === 'getPrices' || action === 'getNumber' || action === 'getNumberV2') {
|
|
|
|
|
throw new Error(`${action} should not be called before automatic free reuse`);
|
|
|
|
|
}
|
|
|
|
|
if (action === 'setStatus' && id === 'free-priority') {
|
|
|
|
|
return { ok: true, text: async () => 'ACCESS_RETRY_GET' };
|
|
|
|
|
}
|
|
|
|
|
if (action === 'getStatus' && id === 'free-priority') {
|
|
|
|
|
statusPollCount += 1;
|
|
|
|
|
return { ok: true, text: async () => (statusPollCount === 1 ? 'STATUS_WAIT_CODE' : 'STATUS_OK:112233') };
|
|
|
|
|
}
|
|
|
|
|
throw new Error(`Unexpected HeroSMS action: ${action}:${id || ''}`);
|
|
|
|
|
},
|
|
|
|
|
getOAuthFlowStepTimeoutMs: async (defaultTimeoutMs) => defaultTimeoutMs,
|
|
|
|
|
getState: async () => ({ ...currentState }),
|
|
|
|
|
sendToContentScriptResilient: async (_source, message) => {
|
|
|
|
|
if (message.type === 'SUBMIT_PHONE_NUMBER') {
|
|
|
|
|
return { phoneVerificationPage: true, url: 'https://auth.openai.com/phone-verification' };
|
|
|
|
|
}
|
|
|
|
|
if (message.type === 'SUBMIT_PHONE_VERIFICATION_CODE') {
|
|
|
|
|
return { success: true, consentReady: true, url: 'https://auth.openai.com/authorize' };
|
|
|
|
|
}
|
|
|
|
|
throw new Error(`Unexpected content-script message: ${message.type}`);
|
|
|
|
|
},
|
|
|
|
|
setState: async (updates) => {
|
|
|
|
|
currentState = { ...currentState, ...updates };
|
|
|
|
|
},
|
|
|
|
|
sleepWithStop: async () => {},
|
|
|
|
|
throwIfStopped: () => {},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const result = await helpers.completePhoneVerificationFlow(1, {
|
|
|
|
|
addPhonePage: true,
|
|
|
|
|
phoneVerificationPage: false,
|
|
|
|
|
url: 'https://auth.openai.com/add-phone',
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
assert.deepStrictEqual(result, {
|
|
|
|
|
success: true,
|
|
|
|
|
consentReady: true,
|
|
|
|
|
url: 'https://auth.openai.com/authorize',
|
|
|
|
|
});
|
|
|
|
|
assert.deepStrictEqual(
|
|
|
|
|
requests.map((requestUrl) => requestUrl.searchParams.get('action')),
|
|
|
|
|
['setStatus', 'getStatus', 'getStatus']
|
|
|
|
|
);
|
|
|
|
|
assert.deepStrictEqual(
|
|
|
|
|
requests
|
|
|
|
|
.filter((requestUrl) => requestUrl.searchParams.get('action') === 'setStatus')
|
|
|
|
|
.map((requestUrl) => requestUrl.searchParams.get('status')),
|
|
|
|
|
['3']
|
|
|
|
|
);
|
|
|
|
|
assert.equal(currentState.freeReusablePhoneActivation.successfulUses, 1);
|
|
|
|
|
assert.equal(currentState.freeReusablePhoneActivation.activationId, 'free-priority');
|
|
|
|
|
assert.equal(currentState.reusablePhoneActivation.activationId, 'paid-reuse');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('phone verification helper accepts HeroSMS WAIT_RETRY as free-reuse ready without using its suffix as code', async () => {
|
|
|
|
|
const requests = [];
|
|
|
|
|
const events = [];
|
|
|
|
|
const submittedCodes = [];
|
|
|
|
|
let statusPollCount = 0;
|
|
|
|
|
let currentState = {
|
|
|
|
|
heroSmsApiKey: 'demo-key',
|
|
|
|
|
freePhoneReuseEnabled: true,
|
|
|
|
|
freePhoneReuseAutoEnabled: true,
|
|
|
|
|
verificationResendCount: 0,
|
|
|
|
|
currentPhoneActivation: null,
|
|
|
|
|
freeReusablePhoneActivation: {
|
|
|
|
|
activationId: 'retry-ready-free',
|
|
|
|
|
phoneNumber: '6283184934060',
|
|
|
|
|
provider: 'hero-sms',
|
|
|
|
|
serviceCode: 'dr',
|
|
|
|
|
countryId: 6,
|
|
|
|
|
countryLabel: 'Indonesia',
|
|
|
|
|
successfulUses: 0,
|
|
|
|
|
maxUses: 3,
|
|
|
|
|
source: 'free-manual-reuse',
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const helpers = api.createPhoneVerificationHelpers({
|
|
|
|
|
addLog: async () => {},
|
|
|
|
|
ensureStep8SignupPageReady: async () => {},
|
|
|
|
|
fetchImpl: async (url) => {
|
|
|
|
|
const parsedUrl = new URL(url);
|
|
|
|
|
requests.push(parsedUrl);
|
|
|
|
|
const action = parsedUrl.searchParams.get('action');
|
|
|
|
|
const id = parsedUrl.searchParams.get('id');
|
|
|
|
|
const status = parsedUrl.searchParams.get('status');
|
|
|
|
|
events.push(action === 'setStatus' ? `${action}:${status}` : action);
|
|
|
|
|
if (action === 'setStatus' && id === 'retry-ready-free' && status === '3') {
|
|
|
|
|
return { ok: true, text: async () => 'ACCESS_RETRY_GET' };
|
|
|
|
|
}
|
|
|
|
|
if (action === 'getStatus' && id === 'retry-ready-free') {
|
|
|
|
|
statusPollCount += 1;
|
|
|
|
|
return {
|
|
|
|
|
ok: true,
|
|
|
|
|
text: async () => (statusPollCount === 1 ? 'STATUS_WAIT_RETRY:100001' : 'STATUS_OK:654321'),
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
throw new Error(`Unexpected HeroSMS action: ${action}:${id || ''}:${status || ''}`);
|
|
|
|
|
},
|
|
|
|
|
getOAuthFlowStepTimeoutMs: async (defaultTimeoutMs) => defaultTimeoutMs,
|
|
|
|
|
getState: async () => ({ ...currentState }),
|
|
|
|
|
sendToContentScriptResilient: async (_source, message) => {
|
|
|
|
|
events.push(message.type);
|
|
|
|
|
if (message.type === 'SUBMIT_PHONE_NUMBER') {
|
|
|
|
|
assert.equal(message.payload.phoneNumber, '6283184934060');
|
|
|
|
|
return { phoneVerificationPage: true, url: 'https://auth.openai.com/phone-verification' };
|
|
|
|
|
}
|
|
|
|
|
if (message.type === 'SUBMIT_PHONE_VERIFICATION_CODE') {
|
|
|
|
|
submittedCodes.push(message.payload.code);
|
|
|
|
|
return { success: true, consentReady: true, url: 'https://auth.openai.com/authorize' };
|
|
|
|
|
}
|
|
|
|
|
throw new Error(`Unexpected content-script message: ${message.type}`);
|
|
|
|
|
},
|
|
|
|
|
setState: async (updates) => {
|
|
|
|
|
currentState = { ...currentState, ...updates };
|
|
|
|
|
},
|
|
|
|
|
sleepWithStop: async () => {
|
|
|
|
|
events.push('sleep');
|
|
|
|
|
},
|
|
|
|
|
throwIfStopped: () => {},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const result = await helpers.completePhoneVerificationFlow(1, {
|
|
|
|
|
addPhonePage: true,
|
|
|
|
|
phoneVerificationPage: false,
|
|
|
|
|
url: 'https://auth.openai.com/add-phone',
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
assert.deepStrictEqual(result, {
|
|
|
|
|
success: true,
|
|
|
|
|
consentReady: true,
|
|
|
|
|
url: 'https://auth.openai.com/authorize',
|
|
|
|
|
});
|
|
|
|
|
assert.deepStrictEqual(submittedCodes, ['654321']);
|
|
|
|
|
assert.equal(submittedCodes.includes('100001'), false);
|
|
|
|
|
assert.deepStrictEqual(
|
|
|
|
|
events.slice(0, 4),
|
|
|
|
|
['setStatus:3', 'sleep', 'getStatus', 'SUBMIT_PHONE_NUMBER']
|
|
|
|
|
);
|
|
|
|
|
assert.equal(currentState.freeReusablePhoneActivation.successfulUses, 1);
|
|
|
|
|
assert.equal(
|
|
|
|
|
requests.some((requestUrl) => ['reactivate', 'getPrices', 'getNumber', 'getNumberV2'].includes(requestUrl.searchParams.get('action'))),
|
|
|
|
|
false
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('phone verification helper stops failed automatic free reuse without buying a new number', async () => {
|
|
|
|
|
const requests = [];
|
|
|
|
|
const messages = [];
|
|
|
|
|
const stops = [];
|
|
|
|
|
let currentState = {
|
|
|
|
|
heroSmsApiKey: 'demo-key',
|
|
|
|
|
freePhoneReuseEnabled: true,
|
|
|
|
|
freePhoneReuseAutoEnabled: true,
|
|
|
|
|
verificationResendCount: 0,
|
|
|
|
|
currentPhoneActivation: null,
|
|
|
|
|
freeReusablePhoneActivation: {
|
|
|
|
|
activationId: 'cancelled-free',
|
|
|
|
|
phoneNumber: '66950007777',
|
|
|
|
|
provider: 'hero-sms',
|
|
|
|
|
serviceCode: 'dr',
|
|
|
|
|
countryId: 52,
|
|
|
|
|
countryLabel: 'Thailand',
|
|
|
|
|
successfulUses: 0,
|
|
|
|
|
maxUses: 3,
|
|
|
|
|
source: 'free-manual-reuse',
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const helpers = api.createPhoneVerificationHelpers({
|
|
|
|
|
addLog: async () => {},
|
|
|
|
|
ensureStep8SignupPageReady: async () => {},
|
|
|
|
|
fetchImpl: async (url) => {
|
|
|
|
|
const parsedUrl = new URL(url);
|
|
|
|
|
requests.push(parsedUrl);
|
|
|
|
|
const action = parsedUrl.searchParams.get('action');
|
|
|
|
|
const id = parsedUrl.searchParams.get('id');
|
|
|
|
|
if (action === 'setStatus' && id === 'cancelled-free') {
|
|
|
|
|
return { ok: true, text: async () => 'ACCESS_RETRY_GET' };
|
|
|
|
|
}
|
|
|
|
|
if (action === 'getStatus' && id === 'cancelled-free') {
|
|
|
|
|
return { ok: true, text: async () => 'STATUS_CANCEL' };
|
|
|
|
|
}
|
|
|
|
|
if (action === 'reactivate' || action === 'getPrices' || action === 'getNumber' || action === 'getNumberV2') {
|
|
|
|
|
throw new Error(`${action} should not be called after automatic free reuse preparation fails`);
|
|
|
|
|
}
|
|
|
|
|
throw new Error(`Unexpected HeroSMS action: ${action}:${id || ''}`);
|
|
|
|
|
},
|
|
|
|
|
getOAuthFlowStepTimeoutMs: async (defaultTimeoutMs) => defaultTimeoutMs,
|
|
|
|
|
getState: async () => ({ ...currentState }),
|
|
|
|
|
requestStop: async (payload) => {
|
|
|
|
|
stops.push(payload);
|
|
|
|
|
},
|
|
|
|
|
sendToContentScriptResilient: async (_source, message) => {
|
|
|
|
|
messages.push(message);
|
|
|
|
|
throw new Error(`Auth page should not be touched after failed free reuse: ${message.type}`);
|
|
|
|
|
},
|
|
|
|
|
setState: async (updates) => {
|
|
|
|
|
currentState = { ...currentState, ...updates };
|
|
|
|
|
},
|
|
|
|
|
sleepWithStop: async () => {},
|
|
|
|
|
throwIfStopped: () => {},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
await assert.rejects(
|
|
|
|
|
helpers.completePhoneVerificationFlow(1, {
|
|
|
|
|
addPhonePage: true,
|
|
|
|
|
phoneVerificationPage: false,
|
|
|
|
|
url: 'https://auth.openai.com/add-phone',
|
|
|
|
|
}),
|
|
|
|
|
/PHONE_AUTO_FREE_REUSE_PREPARE::/
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
assert.deepStrictEqual(messages, []);
|
|
|
|
|
assert.equal(stops.length, 1);
|
|
|
|
|
assert.match(stops[0].logMessage, /不购买新 HeroSMS 号码/);
|
|
|
|
|
assert.equal(currentState.freeReusablePhoneActivation, null);
|
|
|
|
|
assert.equal(
|
|
|
|
|
requests.some((requestUrl) => ['reactivate', 'getPrices', 'getNumber', 'getNumberV2'].includes(requestUrl.searchParams.get('action'))),
|
|
|
|
|
false
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('phone verification helper stops never-ready automatic free reuse without buying or reactivating', async () => {
|
|
|
|
|
const requests = [];
|
|
|
|
|
const messages = [];
|
|
|
|
|
const stops = [];
|
|
|
|
|
let currentState = {
|
|
|
|
|
heroSmsApiKey: 'demo-key',
|
|
|
|
|
heroSmsReuseEnabled: true,
|
|
|
|
|
freePhoneReuseEnabled: true,
|
|
|
|
|
freePhoneReuseAutoEnabled: true,
|
|
|
|
|
verificationResendCount: 0,
|
|
|
|
|
currentPhoneActivation: null,
|
|
|
|
|
freeReusablePhoneActivation: {
|
|
|
|
|
activationId: 'never-ready-free',
|
|
|
|
|
phoneNumber: '66950008888',
|
|
|
|
|
provider: 'hero-sms',
|
|
|
|
|
serviceCode: 'dr',
|
|
|
|
|
countryId: 52,
|
|
|
|
|
countryLabel: 'Thailand',
|
|
|
|
|
successfulUses: 0,
|
|
|
|
|
maxUses: 3,
|
|
|
|
|
source: 'free-manual-reuse',
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const helpers = api.createPhoneVerificationHelpers({
|
|
|
|
|
addLog: async () => {},
|
|
|
|
|
ensureStep8SignupPageReady: async () => {},
|
|
|
|
|
fetchImpl: async (url) => {
|
|
|
|
|
const parsedUrl = new URL(url);
|
|
|
|
|
requests.push(parsedUrl);
|
|
|
|
|
const action = parsedUrl.searchParams.get('action');
|
|
|
|
|
const id = parsedUrl.searchParams.get('id');
|
|
|
|
|
if (action === 'setStatus' && id === 'never-ready-free') {
|
|
|
|
|
return { ok: true, text: async () => 'ACCESS_RETRY_GET' };
|
|
|
|
|
}
|
|
|
|
|
if (action === 'getStatus' && id === 'never-ready-free') {
|
|
|
|
|
return { ok: true, text: async () => 'STATUS_OK:445566' };
|
|
|
|
|
}
|
|
|
|
|
if (action === 'reactivate' || action === 'getPrices' || action === 'getNumber' || action === 'getNumberV2') {
|
|
|
|
|
throw new Error(`${action} should not be called after automatic free reuse never becomes ready`);
|
|
|
|
|
}
|
|
|
|
|
throw new Error(`Unexpected HeroSMS action: ${action}:${id || ''}`);
|
|
|
|
|
},
|
|
|
|
|
getOAuthFlowStepTimeoutMs: async (defaultTimeoutMs) => defaultTimeoutMs,
|
|
|
|
|
getState: async () => ({ ...currentState }),
|
|
|
|
|
requestStop: async (payload) => {
|
|
|
|
|
stops.push(payload);
|
|
|
|
|
},
|
|
|
|
|
sendToContentScriptResilient: async (_source, message) => {
|
|
|
|
|
messages.push(message);
|
|
|
|
|
throw new Error(`Auth page should not be touched when automatic free reuse is never ready: ${message.type}`);
|
|
|
|
|
},
|
|
|
|
|
setState: async (updates) => {
|
|
|
|
|
currentState = { ...currentState, ...updates };
|
|
|
|
|
},
|
|
|
|
|
sleepWithStop: async () => {},
|
|
|
|
|
throwIfStopped: () => {},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
await assert.rejects(
|
|
|
|
|
helpers.completePhoneVerificationFlow(1, {
|
|
|
|
|
addPhonePage: true,
|
|
|
|
|
phoneVerificationPage: false,
|
|
|
|
|
url: 'https://auth.openai.com/add-phone',
|
|
|
|
|
}),
|
|
|
|
|
/PHONE_AUTO_FREE_REUSE_PREPARE::/
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
assert.deepStrictEqual(messages, []);
|
|
|
|
|
assert.equal(stops.length, 1);
|
|
|
|
|
assert.match(stops[0].logMessage, /不购买新 HeroSMS 号码/);
|
|
|
|
|
assert.equal(currentState.freeReusablePhoneActivation.activationId, 'never-ready-free');
|
|
|
|
|
assert.equal(
|
|
|
|
|
requests.some((requestUrl) => ['reactivate', 'getPrices', 'getNumber', 'getNumberV2'].includes(requestUrl.searchParams.get('action'))),
|
|
|
|
|
false
|
|
|
|
|
);
|
|
|
|
|
assert.equal(requests.every((requestUrl) => requestUrl.searchParams.get('id') === 'never-ready-free'), true);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('phone verification helper accepts HeroSMS WAIT_RESEND as free-reuse ready before submit', async () => {
|
|
|
|
|
const requests = [];
|
|
|
|
|
const messages = [];
|
|
|
|
|
let statusPollCount = 0;
|
|
|
|
|
let currentState = {
|
|
|
|
|
heroSmsApiKey: 'demo-key',
|
|
|
|
|
freePhoneReuseEnabled: true,
|
|
|
|
|
freePhoneReuseAutoEnabled: true,
|
|
|
|
|
verificationResendCount: 0,
|
|
|
|
|
currentPhoneActivation: null,
|
|
|
|
|
freeReusablePhoneActivation: {
|
|
|
|
|
activationId: 'not-waiting-free',
|
|
|
|
|
phoneNumber: '66950005555',
|
|
|
|
|
provider: 'hero-sms',
|
|
|
|
|
serviceCode: 'dr',
|
|
|
|
|
countryId: 52,
|
|
|
|
|
countryLabel: 'Thailand',
|
|
|
|
|
successfulUses: 0,
|
|
|
|
|
maxUses: 3,
|
|
|
|
|
source: 'free-manual-reuse',
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const helpers = api.createPhoneVerificationHelpers({
|
|
|
|
|
addLog: async () => {},
|
|
|
|
|
ensureStep8SignupPageReady: async () => {},
|
|
|
|
|
fetchImpl: async (url) => {
|
|
|
|
|
const parsedUrl = new URL(url);
|
|
|
|
|
requests.push(parsedUrl);
|
|
|
|
|
const action = parsedUrl.searchParams.get('action');
|
|
|
|
|
const id = parsedUrl.searchParams.get('id');
|
|
|
|
|
if (action === 'setStatus' && id === 'not-waiting-free') {
|
|
|
|
|
return { ok: true, text: async () => 'ACCESS_RETRY_GET' };
|
|
|
|
|
}
|
|
|
|
|
if (action === 'getStatus' && id === 'not-waiting-free') {
|
|
|
|
|
statusPollCount += 1;
|
|
|
|
|
return {
|
|
|
|
|
ok: true,
|
|
|
|
|
text: async () => (statusPollCount === 1 ? 'STATUS_WAIT_RESEND' : 'STATUS_OK:778899'),
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
if (action === 'reactivate' || action === 'getPrices' || action === 'getNumber' || action === 'getNumberV2') {
|
|
|
|
|
throw new Error(`${action} should not be called for accepted saved free reuse waiting state`);
|
|
|
|
|
}
|
|
|
|
|
throw new Error(`Unexpected HeroSMS action: ${action}:${id || ''}`);
|
|
|
|
|
},
|
|
|
|
|
getOAuthFlowStepTimeoutMs: async (defaultTimeoutMs) => defaultTimeoutMs,
|
|
|
|
|
getState: async () => ({ ...currentState }),
|
|
|
|
|
sendToContentScriptResilient: async (_source, message) => {
|
|
|
|
|
messages.push(message);
|
|
|
|
|
if (message.type === 'SUBMIT_PHONE_NUMBER') {
|
|
|
|
|
return { phoneVerificationPage: true, url: 'https://auth.openai.com/phone-verification' };
|
|
|
|
|
}
|
|
|
|
|
if (message.type === 'SUBMIT_PHONE_VERIFICATION_CODE') {
|
|
|
|
|
return { success: true, consentReady: true, url: 'https://auth.openai.com/authorize' };
|
|
|
|
|
}
|
|
|
|
|
throw new Error(`Unexpected content-script message: ${message.type}`);
|
|
|
|
|
},
|
|
|
|
|
setState: async (updates) => {
|
|
|
|
|
currentState = { ...currentState, ...updates };
|
|
|
|
|
},
|
|
|
|
|
sleepWithStop: async () => {},
|
|
|
|
|
throwIfStopped: () => {},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const result = await helpers.completePhoneVerificationFlow(1, {
|
|
|
|
|
addPhonePage: true,
|
|
|
|
|
phoneVerificationPage: false,
|
|
|
|
|
url: 'https://auth.openai.com/add-phone',
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
assert.deepStrictEqual(result, {
|
|
|
|
|
success: true,
|
|
|
|
|
consentReady: true,
|
|
|
|
|
url: 'https://auth.openai.com/authorize',
|
|
|
|
|
});
|
|
|
|
|
assert.deepStrictEqual(
|
|
|
|
|
messages.map((message) => message.type),
|
|
|
|
|
['SUBMIT_PHONE_NUMBER', 'SUBMIT_PHONE_VERIFICATION_CODE']
|
|
|
|
|
);
|
|
|
|
|
assert.deepStrictEqual(
|
|
|
|
|
requests
|
|
|
|
|
.filter((requestUrl) => requestUrl.searchParams.get('action') === 'setStatus')
|
|
|
|
|
.map((requestUrl) => requestUrl.searchParams.get('status')),
|
|
|
|
|
['3']
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('phone verification helper accepts HeroSMS WAIT_RESEND suffix as free-reuse ready before submit', async () => {
|
|
|
|
|
const requests = [];
|
|
|
|
|
const messages = [];
|
|
|
|
|
let statusPollCount = 0;
|
|
|
|
|
let currentState = {
|
|
|
|
|
heroSmsApiKey: 'demo-key',
|
|
|
|
|
freePhoneReuseEnabled: true,
|
|
|
|
|
freePhoneReuseAutoEnabled: true,
|
|
|
|
|
verificationResendCount: 0,
|
|
|
|
|
currentPhoneActivation: null,
|
|
|
|
|
freeReusablePhoneActivation: {
|
|
|
|
|
activationId: 'resend-info-free',
|
|
|
|
|
phoneNumber: '66950005656',
|
|
|
|
|
provider: 'hero-sms',
|
|
|
|
|
serviceCode: 'dr',
|
|
|
|
|
countryId: 52,
|
|
|
|
|
countryLabel: 'Thailand',
|
|
|
|
|
successfulUses: 0,
|
|
|
|
|
maxUses: 3,
|
|
|
|
|
source: 'free-manual-reuse',
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const helpers = api.createPhoneVerificationHelpers({
|
|
|
|
|
addLog: async () => {},
|
|
|
|
|
ensureStep8SignupPageReady: async () => {},
|
|
|
|
|
fetchImpl: async (url) => {
|
|
|
|
|
const parsedUrl = new URL(url);
|
|
|
|
|
requests.push(parsedUrl);
|
|
|
|
|
const action = parsedUrl.searchParams.get('action');
|
|
|
|
|
const id = parsedUrl.searchParams.get('id');
|
|
|
|
|
if (action === 'setStatus' && id === 'resend-info-free') {
|
|
|
|
|
return { ok: true, text: async () => 'ACCESS_RETRY_GET' };
|
|
|
|
|
}
|
|
|
|
|
if (action === 'getStatus' && id === 'resend-info-free') {
|
|
|
|
|
statusPollCount += 1;
|
|
|
|
|
return {
|
|
|
|
|
ok: true,
|
|
|
|
|
text: async () => (statusPollCount === 1 ? 'STATUS_WAIT_RESEND:100001' : 'STATUS_OK:887766'),
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
if (action === 'reactivate' || action === 'getPrices' || action === 'getNumber' || action === 'getNumberV2') {
|
|
|
|
|
throw new Error(`${action} should not be called for accepted saved free reuse resend state`);
|
|
|
|
|
}
|
|
|
|
|
throw new Error(`Unexpected HeroSMS action: ${action}:${id || ''}`);
|
|
|
|
|
},
|
|
|
|
|
getOAuthFlowStepTimeoutMs: async (defaultTimeoutMs) => defaultTimeoutMs,
|
|
|
|
|
getState: async () => ({ ...currentState }),
|
|
|
|
|
sendToContentScriptResilient: async (_source, message) => {
|
|
|
|
|
messages.push(message);
|
|
|
|
|
if (message.type === 'SUBMIT_PHONE_NUMBER') {
|
|
|
|
|
assert.equal(message.payload.phoneNumber, '66950005656');
|
|
|
|
|
return { phoneVerificationPage: true, url: 'https://auth.openai.com/phone-verification' };
|
|
|
|
|
}
|
|
|
|
|
if (message.type === 'SUBMIT_PHONE_VERIFICATION_CODE') {
|
|
|
|
|
assert.equal(message.payload.code, '887766');
|
|
|
|
|
return { success: true, consentReady: true, url: 'https://auth.openai.com/authorize' };
|
|
|
|
|
}
|
|
|
|
|
throw new Error(`Unexpected content-script message: ${message.type}`);
|
|
|
|
|
},
|
|
|
|
|
setState: async (updates) => {
|
|
|
|
|
currentState = { ...currentState, ...updates };
|
|
|
|
|
},
|
|
|
|
|
sleepWithStop: async () => {},
|
|
|
|
|
throwIfStopped: () => {},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const result = await helpers.completePhoneVerificationFlow(1, {
|
|
|
|
|
addPhonePage: true,
|
|
|
|
|
phoneVerificationPage: false,
|
|
|
|
|
url: 'https://auth.openai.com/add-phone',
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
assert.deepStrictEqual(result, {
|
|
|
|
|
success: true,
|
|
|
|
|
consentReady: true,
|
|
|
|
|
url: 'https://auth.openai.com/authorize',
|
|
|
|
|
});
|
|
|
|
|
assert.deepStrictEqual(
|
|
|
|
|
messages.map((message) => message.type),
|
|
|
|
|
['SUBMIT_PHONE_NUMBER', 'SUBMIT_PHONE_VERIFICATION_CODE']
|
|
|
|
|
);
|
|
|
|
|
assert.deepStrictEqual(
|
|
|
|
|
requests
|
|
|
|
|
.filter((requestUrl) => requestUrl.searchParams.get('action') === 'setStatus')
|
|
|
|
|
.map((requestUrl) => requestUrl.searchParams.get('status')),
|
|
|
|
|
['3']
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('phone verification helper retires automatic free reuse record at max uses', async () => {
|
|
|
|
|
const requests = [];
|
|
|
|
|
let statusPollCount = 0;
|
|
|
|
|
let currentState = {
|
|
|
|
|
heroSmsApiKey: 'demo-key',
|
|
|
|
|
freePhoneReuseEnabled: true,
|
|
|
|
|
freePhoneReuseAutoEnabled: true,
|
|
|
|
|
verificationResendCount: 0,
|
|
|
|
|
currentPhoneActivation: null,
|
|
|
|
|
freeReusablePhoneActivation: {
|
|
|
|
|
activationId: 'free-max',
|
|
|
|
|
phoneNumber: '66950009999',
|
|
|
|
|
provider: 'hero-sms',
|
|
|
|
|
serviceCode: 'dr',
|
|
|
|
|
countryId: 52,
|
|
|
|
|
countryLabel: 'Thailand',
|
|
|
|
|
successfulUses: 2,
|
|
|
|
|
maxUses: 3,
|
|
|
|
|
source: 'free-manual-reuse',
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const helpers = api.createPhoneVerificationHelpers({
|
|
|
|
|
addLog: async () => {},
|
|
|
|
|
ensureStep8SignupPageReady: async () => {},
|
|
|
|
|
fetchImpl: async (url) => {
|
|
|
|
|
const parsedUrl = new URL(url);
|
|
|
|
|
requests.push(parsedUrl);
|
|
|
|
|
const action = parsedUrl.searchParams.get('action');
|
|
|
|
|
const id = parsedUrl.searchParams.get('id');
|
|
|
|
|
if (action === 'setStatus' && id === 'free-max') {
|
|
|
|
|
return { ok: true, text: async () => 'ACCESS_RETRY_GET' };
|
|
|
|
|
}
|
|
|
|
|
if (action === 'getStatus' && id === 'free-max') {
|
|
|
|
|
statusPollCount += 1;
|
|
|
|
|
return { ok: true, text: async () => (statusPollCount === 1 ? 'STATUS_WAIT_CODE' : 'STATUS_OK:778899') };
|
|
|
|
|
}
|
|
|
|
|
throw new Error(`Unexpected HeroSMS action: ${action}:${id || ''}`);
|
|
|
|
|
},
|
|
|
|
|
getOAuthFlowStepTimeoutMs: async (defaultTimeoutMs) => defaultTimeoutMs,
|
|
|
|
|
getState: async () => ({ ...currentState }),
|
|
|
|
|
sendToContentScriptResilient: async (_source, message) => {
|
|
|
|
|
if (message.type === 'SUBMIT_PHONE_NUMBER') {
|
|
|
|
|
return { phoneVerificationPage: true, url: 'https://auth.openai.com/phone-verification' };
|
|
|
|
|
}
|
|
|
|
|
if (message.type === 'SUBMIT_PHONE_VERIFICATION_CODE') {
|
|
|
|
|
return { success: true, consentReady: true, url: 'https://auth.openai.com/authorize' };
|
|
|
|
|
}
|
|
|
|
|
throw new Error(`Unexpected content-script message: ${message.type}`);
|
|
|
|
|
},
|
|
|
|
|
setState: async (updates) => {
|
|
|
|
|
currentState = { ...currentState, ...updates };
|
|
|
|
|
},
|
|
|
|
|
sleepWithStop: async () => {},
|
|
|
|
|
throwIfStopped: () => {},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
await helpers.completePhoneVerificationFlow(1, {
|
|
|
|
|
addPhonePage: true,
|
|
|
|
|
phoneVerificationPage: false,
|
|
|
|
|
url: 'https://auth.openai.com/add-phone',
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
assert.equal(currentState.freeReusablePhoneActivation, null);
|
|
|
|
|
assert.deepStrictEqual(
|
|
|
|
|
requests.map((requestUrl) => requestUrl.searchParams.get('action')),
|
|
|
|
|
['setStatus', 'getStatus', 'getStatus']
|
|
|
|
|
);
|
|
|
|
|
assert.deepStrictEqual(
|
|
|
|
|
requests
|
|
|
|
|
.filter((requestUrl) => requestUrl.searchParams.get('action') === 'setStatus')
|
|
|
|
|
.map((requestUrl) => requestUrl.searchParams.get('status')),
|
|
|
|
|
['3']
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('phone verification helper preserves coded free-reuse activation when code submission errors', async () => {
|
|
|
|
|
const requests = [];
|
|
|
|
|
let currentState = {
|
|
|
|
|
heroSmsApiKey: 'demo-key',
|
|
|
|
|
heroSmsCountryId: 52,
|
|
|
|
|
heroSmsCountryLabel: 'Thailand',
|
|
|
|
|
freePhoneReuseEnabled: true,
|
|
|
|
|
verificationResendCount: 0,
|
|
|
|
|
currentPhoneActivation: null,
|
|
|
|
|
freeReusablePhoneActivation: null,
|
|
|
|
|
reusablePhoneActivation: null,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const helpers = api.createPhoneVerificationHelpers({
|
|
|
|
|
addLog: async () => {},
|
|
|
|
|
ensureStep8SignupPageReady: async () => {},
|
|
|
|
|
fetchImpl: async (url) => {
|
|
|
|
|
const parsedUrl = new URL(url);
|
|
|
|
|
requests.push(parsedUrl);
|
|
|
|
|
const action = parsedUrl.searchParams.get('action');
|
|
|
|
|
const id = parsedUrl.searchParams.get('id');
|
|
|
|
|
const status = parsedUrl.searchParams.get('status');
|
|
|
|
|
if (action === 'getPrices') {
|
|
|
|
|
return { ok: true, text: async () => buildHeroSmsPricesPayload() };
|
|
|
|
|
}
|
|
|
|
|
if (action === 'getNumber') {
|
|
|
|
|
return { ok: true, text: async () => 'ACCESS_NUMBER:new-free-save:66950006666' };
|
|
|
|
|
}
|
|
|
|
|
if (action === 'getStatus' && id === 'new-free-save') {
|
|
|
|
|
return { ok: true, text: async () => 'STATUS_OK:445566' };
|
|
|
|
|
}
|
|
|
|
|
if (action === 'setStatus' && id === 'new-free-save' && status === '8') {
|
|
|
|
|
throw new Error('free-reuse activation should not be cancelled after SMS code was received');
|
|
|
|
|
}
|
|
|
|
|
if (action === 'setStatus' && id === 'new-free-save' && status === '6') {
|
|
|
|
|
throw new Error('free-reuse activation should not be completed after SMS code was received');
|
|
|
|
|
}
|
|
|
|
|
throw new Error(`Unexpected HeroSMS action: ${action}:${id || ''}:${status || ''}`);
|
|
|
|
|
},
|
|
|
|
|
getOAuthFlowStepTimeoutMs: async (defaultTimeoutMs) => defaultTimeoutMs,
|
|
|
|
|
getState: async () => ({ ...currentState }),
|
|
|
|
|
sendToContentScriptResilient: async (_source, message) => {
|
|
|
|
|
if (message.type === 'SUBMIT_PHONE_NUMBER') {
|
|
|
|
|
return { phoneVerificationPage: true, url: 'https://auth.openai.com/phone-verification' };
|
|
|
|
|
}
|
|
|
|
|
if (message.type === 'SUBMIT_PHONE_VERIFICATION_CODE') {
|
|
|
|
|
throw new Error('simulated auth-page failure after code submit');
|
|
|
|
|
}
|
|
|
|
|
throw new Error(`Unexpected content-script message: ${message.type}`);
|
|
|
|
|
},
|
|
|
|
|
setState: async (updates) => {
|
|
|
|
|
currentState = { ...currentState, ...updates };
|
|
|
|
|
},
|
|
|
|
|
sleepWithStop: async () => {},
|
|
|
|
|
throwIfStopped: () => {},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
await assert.rejects(
|
|
|
|
|
helpers.completePhoneVerificationFlow(1, {
|
|
|
|
|
addPhonePage: true,
|
|
|
|
|
phoneVerificationPage: false,
|
|
|
|
|
url: 'https://auth.openai.com/add-phone',
|
|
|
|
|
}),
|
|
|
|
|
/simulated auth-page failure/
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
assert.equal(currentState.freeReusablePhoneActivation.activationId, 'new-free-save');
|
|
|
|
|
assert.equal(currentState.freeReusablePhoneActivation.phoneNumber, '66950006666');
|
|
|
|
|
assert.equal(
|
|
|
|
|
requests.some((requestUrl) => (
|
|
|
|
|
requestUrl.searchParams.get('action') === 'setStatus'
|
|
|
|
|
&& requestUrl.searchParams.get('id') === 'new-free-save'
|
|
|
|
|
&& ['6', '8'].includes(requestUrl.searchParams.get('status'))
|
|
|
|
|
)),
|
|
|
|
|
false
|
|
|
|
|
);
|
|
|
|
|
assert.deepStrictEqual(
|
|
|
|
|
requests
|
|
|
|
|
.filter((requestUrl) => (
|
|
|
|
|
requestUrl.searchParams.get('action') === 'setStatus'
|
|
|
|
|
&& requestUrl.searchParams.get('id') === 'new-free-save'
|
|
|
|
|
))
|
|
|
|
|
.map((requestUrl) => requestUrl.searchParams.get('status')),
|
|
|
|
|
[]
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('phone verification helper preserves newly saved free-reuse activation after OAuth success without source marker', async () => {
|
|
|
|
|
const requests = [];
|
|
|
|
|
let currentState = {
|
|
|
|
|
heroSmsApiKey: 'demo-key',
|
|
|
|
|
heroSmsCountryId: 52,
|
|
|
|
|
heroSmsCountryLabel: 'Thailand',
|
|
|
|
|
freePhoneReuseEnabled: true,
|
|
|
|
|
verificationResendCount: 0,
|
|
|
|
|
currentPhoneActivation: null,
|
|
|
|
|
freeReusablePhoneActivation: null,
|
|
|
|
|
reusablePhoneActivation: null,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const helpers = api.createPhoneVerificationHelpers({
|
|
|
|
|
addLog: async () => {},
|
|
|
|
|
ensureStep8SignupPageReady: async () => {},
|
|
|
|
|
fetchImpl: async (url) => {
|
|
|
|
|
const parsedUrl = new URL(url);
|
|
|
|
|
requests.push(parsedUrl);
|
|
|
|
|
const action = parsedUrl.searchParams.get('action');
|
|
|
|
|
const id = parsedUrl.searchParams.get('id');
|
|
|
|
|
const status = parsedUrl.searchParams.get('status');
|
|
|
|
|
if (action === 'getPrices') {
|
|
|
|
|
return { ok: true, text: async () => buildHeroSmsPricesPayload() };
|
|
|
|
|
}
|
|
|
|
|
if (action === 'getNumber') {
|
|
|
|
|
return { ok: true, text: async () => 'ACCESS_NUMBER:new-free-success:66950007777' };
|
|
|
|
|
}
|
|
|
|
|
if (action === 'getStatus' && id === 'new-free-success') {
|
|
|
|
|
return { ok: true, text: async () => 'STATUS_OK:778899' };
|
|
|
|
|
}
|
|
|
|
|
if (action === 'setStatus' && id === 'new-free-success' && ['6', '8'].includes(status)) {
|
|
|
|
|
throw new Error(`free-reuse activation should not receive terminal setStatus(${status}) after OAuth success`);
|
|
|
|
|
}
|
|
|
|
|
throw new Error(`Unexpected HeroSMS action: ${action}:${id || ''}:${status || ''}`);
|
|
|
|
|
},
|
|
|
|
|
getOAuthFlowStepTimeoutMs: async (defaultTimeoutMs) => defaultTimeoutMs,
|
|
|
|
|
getState: async () => ({ ...currentState }),
|
|
|
|
|
sendToContentScriptResilient: async (_source, message) => {
|
|
|
|
|
if (message.type === 'SUBMIT_PHONE_NUMBER') {
|
|
|
|
|
return { phoneVerificationPage: true, url: 'https://auth.openai.com/phone-verification' };
|
|
|
|
|
}
|
|
|
|
|
if (message.type === 'SUBMIT_PHONE_VERIFICATION_CODE') {
|
|
|
|
|
return { success: true, consentReady: true, url: 'https://auth.openai.com/authorize' };
|
|
|
|
|
}
|
|
|
|
|
throw new Error(`Unexpected content-script message: ${message.type}`);
|
|
|
|
|
},
|
|
|
|
|
setState: async (updates) => {
|
|
|
|
|
currentState = { ...currentState, ...updates };
|
|
|
|
|
},
|
|
|
|
|
sleepWithStop: async () => {},
|
|
|
|
|
throwIfStopped: () => {},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const result = await helpers.completePhoneVerificationFlow(1, {
|
|
|
|
|
addPhonePage: true,
|
|
|
|
|
phoneVerificationPage: false,
|
|
|
|
|
url: 'https://auth.openai.com/add-phone',
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
assert.deepStrictEqual(result, {
|
|
|
|
|
success: true,
|
|
|
|
|
consentReady: true,
|
|
|
|
|
url: 'https://auth.openai.com/authorize',
|
|
|
|
|
});
|
|
|
|
|
assert.equal(currentState.freeReusablePhoneActivation.activationId, 'new-free-success');
|
|
|
|
|
assert.equal(currentState.freeReusablePhoneActivation.phoneNumber, '66950007777');
|
|
|
|
|
assert.equal(currentState.freeReusablePhoneActivation.source, 'free-manual-reuse');
|
|
|
|
|
assert.equal(
|
|
|
|
|
requests.some((requestUrl) => (
|
|
|
|
|
requestUrl.searchParams.get('action') === 'setStatus'
|
|
|
|
|
&& requestUrl.searchParams.get('id') === 'new-free-success'
|
|
|
|
|
&& ['6', '8'].includes(requestUrl.searchParams.get('status'))
|
|
|
|
|
)),
|
|
|
|
|
false
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('phone verification helper replaces number immediately when resend is throttled and does not spam resend clicks', async () => {
|
|
|
|
|
const requests = [];
|
|
|
|
|
const messages = [];
|
|
|
|
|