Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 11 additions & 39 deletions src/extensionsIntegrated/MigrateAssist/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,12 @@
/**
* Shared configuration for the one time move off the legacy web origin onto web.phcode.dev.
*
* Everything that has to change when the rollout moves forward lives here: the two origins and the
* sunset date. `LEGACY_ORIGIN` points at staging while the flow is being validated end to end;
* flipping it to https://phcode.dev is the only edit needed to go live.
* Everything that has to change when the rollout moves forward lives here, which is the two
* origins. `LEGACY_ORIGIN` is live and points at phcode.dev, which serves migrateAssist.html and
* still holds the data of everyone who has not moved across yet.
*
* There is deliberately no retirement date. The move has no announced cutoff, and the runaway
* probe case the date used to guard is already bounded per user by MAX_AUTO_ATTEMPTS.
*
* @module extensionsIntegrated/MigrateAssist/constants
*/
Expand All @@ -33,11 +36,11 @@ define(function (require, exports, module) {
// render identically in every locale, so they stay here instead of going through strings.js.

/**
* The origin we are migrating away from. Switch to "https://phcode.dev" once the flow has been
* validated against staging.
* The origin we are migrating away from. It must keep serving migrateAssist.html for as long as
* migration is offered, since that page is what reads the old storage.
* @type {string}
*/
const LEGACY_ORIGIN = "https://staging.phcode.dev";
const LEGACY_ORIGIN = "https://phcode.dev";

/**
* The origin we are migrating to.
Expand All @@ -51,12 +54,6 @@ define(function (require, exports, module) {
*/
const NEW_DOMAIN_NAME = "web.phcode.dev";

/**
* The day the legacy origin stops serving. Month is 0 based, so 8 is September.
* @type {number}
*/
const SUNSET_DATE = Date.UTC(2026, 8, 1);

/**
* PhStore key recording that the migration already ran. Once set, the automatic path never runs
* again and the user has to ask for it from the Help menu.
Expand Down Expand Up @@ -143,8 +140,8 @@ define(function (require, exports, module) {

/**
* Hostname of the origin being retired, for use inside user facing sentences. Derived from the
* origin rather than written out separately so the two can never disagree, which matters while
* the legacy origin still points at staging.
* origin rather than written out separately so the two can never disagree, which matters because
* the dev override below can repoint the legacy origin.
* @return {string}
*/
function getLegacyDomainName() {
Expand Down Expand Up @@ -174,30 +171,7 @@ define(function (require, exports, module) {
return !(Phoenix.browser.desktop.isSafari || Phoenix.browser.mobile.isIos);
}

/**
* Whole days left before the legacy origin is retired, floored at 0.
* @param {number} [now] current time in ms, for tests
* @return {number}
*/
function daysToSunset(now) {
const millisPerDay = 24 * 60 * 60 * 1000;
const remaining = SUNSET_DATE - (typeof now === "number" ? now : Date.now());
if (remaining <= 0) {
return 0;
}
return Math.ceil(remaining / millisPerDay);
}

/**
* @param {number} [now] current time in ms, for tests
* @return {boolean} true once the legacy origin is expected to be gone
*/
function isPastSunset(now) {
return (typeof now === "number" ? now : Date.now()) >= SUNSET_DATE;
}

exports.NEW_DOMAIN_NAME = NEW_DOMAIN_NAME;
exports.SUNSET_DATE = SUNSET_DATE;
exports.MIGRATION_DONE_KEY = MIGRATION_DONE_KEY;
exports.MIGRATION_ATTEMPTS_KEY = MIGRATION_ATTEMPTS_KEY;
exports.MAX_AUTO_ATTEMPTS = MAX_AUTO_ATTEMPTS;
Expand All @@ -208,6 +182,4 @@ define(function (require, exports, module) {
exports.isLegacyOrigin = isLegacyOrigin;
exports.isNewOrigin = isNewOrigin;
exports.isMigrationSupportedBrowser = isMigrationSupportedBrowser;
exports.daysToSunset = daysToSunset;
exports.isPastSunset = isPastSunset;
});
9 changes: 1 addition & 8 deletions src/extensionsIntegrated/MigrateAssist/migrator.js
Original file line number Diff line number Diff line change
Expand Up @@ -582,19 +582,12 @@ define(function (require, exports, module) {
Metrics.countEvent(Metrics.EVENT_TYPE.PLATFORM, "migrateAssist", "skipOutOfAttempts");
return;
}
// Once the legacy origin is gone there is nothing to probe, so the feature disables itself
// rather than opening a doomed iframe on every boot forever.
if (Constants.isPastSunset()) {
Metrics.countEvent(Metrics.EVENT_TYPE.PLATFORM, "migrateAssist", "skipPastSunset");
return;
}
Metrics.countEvent(Metrics.EVENT_TYPE.PLATFORM, "migrateAssist", "autoProbe");
run(false);
}

/**
* Help menu entry point. Ignores the done flag and the sunset date, and always says what
* happened.
* Help menu entry point. Ignores the done flag and always says what happened.
*/
async function runManually() {
Metrics.countEvent(Metrics.EVENT_TYPE.PLATFORM, "migrateAssist", "manualInvoked");
Expand Down
10 changes: 3 additions & 7 deletions src/extensionsIntegrated/MigrateAssist/sunset-dialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
/**
* The "we are moving" dialog, shown on the origin being retired on every boot.
*
* It states that the move is happening, with no countdown and no cutoff date: the move is under way
* now, and naming a date we might not hold to would be worse than naming none.
*
* Three variants, differing only in the primary button and the closing sentence:
* - default, sends the user to the new site where their data migrates automatically;
* - Trusted Web Activity, sends the user to the Play Store instead, because the installed app only
Expand Down Expand Up @@ -56,13 +59,6 @@ define(function (require, exports, module) {
paragraphs.push(StringUtils.format(Strings.MIGRATE_MOVING_MESSAGE,
Constants.getLegacyDomainName(), Constants.NEW_DOMAIN_NAME));

if (!Constants.isPastSunset()) {
const days = Constants.daysToSunset();
paragraphs.push(StringUtils.format(
days === 1 ? Strings.MIGRATE_SUNSET_COUNTDOWN_ONE : Strings.MIGRATE_SUNSET_COUNTDOWN,
days, Constants.getLegacyDomainName()));
}

if (!Constants.isMigrationSupportedBrowser()) {
paragraphs.push(Strings.MIGRATE_MANUAL_DOWNLOAD_NOTE);
} else {
Expand Down
4 changes: 1 addition & 3 deletions src/nls/root/strings.js
Original file line number Diff line number Diff line change
Expand Up @@ -2925,10 +2925,8 @@ define({
// Migration off the legacy web origin onto the new home
"MIGRATE_MOVING_TITLE": "{0} is moving",
"MIGRATE_MOVING_MESSAGE": "{APP_NAME} on {0} is moving to a new home at <strong>{1}</strong>. Everything works the same, only the address changes.",
"MIGRATE_SUNSET_COUNTDOWN": "You have <strong>{0} days</strong> left before {1} stops working.",
"MIGRATE_SUNSET_COUNTDOWN_ONE": "You have <strong>{0} day</strong> left before {1} stops working.",
"MIGRATE_DATA_SAFE_NOTE": "Your projects, settings and extensions will be copied over for you the first time you open {0}. Nothing is deleted from this site.",
"MIGRATE_MANUAL_DOWNLOAD_NOTE": "Automatic transfer is not available in this browser. If you have projects saved here, please download them before the date above so you can open them again on the new site.",
"MIGRATE_MANUAL_DOWNLOAD_NOTE": "Automatic transfer is not available in this browser. If you have projects saved here, please download them so you can open them again on the new site.",
"MIGRATE_GO_TO_NEW_SITE": "Take me to the new site",
"MIGRATE_STAY_HERE": "Stay here",
"MIGRATE_PROGRESS_TITLE": "Bringing your data over",
Expand Down
34 changes: 3 additions & 31 deletions test/spec/Extn-MigrateAssist-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,44 +34,16 @@ define(function (require, exports, module) {

describe("unit:MigrateAssist", function () {

const DAY = 24 * 60 * 60 * 1000;

describe("constants", function () {

describe("daysToSunset", function () {

it("should count whole days remaining", function () {
expect(Constants.daysToSunset(Constants.SUNSET_DATE - (10 * DAY))).toBe(10);
expect(Constants.daysToSunset(Constants.SUNSET_DATE - DAY)).toBe(1);
});

it("should round a part day up, so the last day never reads as zero", function () {
expect(Constants.daysToSunset(Constants.SUNSET_DATE - 1)).toBe(1);
expect(Constants.daysToSunset(Constants.SUNSET_DATE - (DAY + 1))).toBe(2);
});

it("should floor at zero on and after the sunset date", function () {
expect(Constants.daysToSunset(Constants.SUNSET_DATE)).toBe(0);
expect(Constants.daysToSunset(Constants.SUNSET_DATE + DAY)).toBe(0);
});
});

describe("isPastSunset", function () {

it("should be false before the date and true on or after it", function () {
expect(Constants.isPastSunset(Constants.SUNSET_DATE - 1)).toBe(false);
expect(Constants.isPastSunset(Constants.SUNSET_DATE)).toBe(true);
expect(Constants.isPastSunset(Constants.SUNSET_DATE + DAY)).toBe(true);
});
});

describe("origins", function () {

it("should ignore the dev override inside test windows", function () {
// The override exists so the flow can be exercised locally. It must never apply in
// a test window, otherwise a stray localStorage value could repoint a real
// migration.
expect(Constants.getLegacyOrigin()).toBe("https://staging.phcode.dev");
// migration. Pinning the literals also catches a staging origin being shipped to
// production, which would point the migration at the wrong storage.
expect(Constants.getLegacyOrigin()).toBe("https://phcode.dev");
expect(Constants.getNewOrigin()).toBe("https://web.phcode.dev");
});

Expand Down
Loading