From 6a67b8061901a544a13bc6ac36da7dca7fbb36b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliv=C3=A9r=20Falvai?= Date: Tue, 25 Aug 2026 16:23:38 +0200 Subject: [PATCH] Add regression test for sync() reporting pending update as UP_TO_DATE Add a scenario that calls sync() twice with ON_NEXT_RESTART, without any restart in between, and assert both calls report UPDATE_INSTALLED. This covers the case getUpdateMetadata()/getCurrentPackage().isPending must reflect a still-pending install, which was silently broken by the attachLocalPackageMethods regression (see PR #39 review comment). --- .../scenarios/scenarioSyncRestart2x.js | 22 ++++++++++++++++ test/test.ts | 26 +++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 test/template/scenarios/scenarioSyncRestart2x.js diff --git a/test/template/scenarios/scenarioSyncRestart2x.js b/test/template/scenarios/scenarioSyncRestart2x.js new file mode 100644 index 00000000..9094a0d9 --- /dev/null +++ b/test/template/scenarios/scenarioSyncRestart2x.js @@ -0,0 +1,22 @@ +var CodePushWrapper = require("../codePushWrapper.js"); +import CodePush from "@bitrise/code-push-sdk"; + +module.exports = { + startTest: function (testApp) { + testApp.sendCurrentAndPendingPackage() + .then(() => { + CodePushWrapper.sync(testApp, (status) => { + if (status === CodePush.SyncStatus.UPDATE_INSTALLED) { + testApp.sendCurrentAndPendingPackage().then(() => { + // Call sync() again without restarting: the update from the first call is still pending. + CodePushWrapper.sync(testApp, () => {}, undefined, { installMode: CodePush.InstallMode.ON_NEXT_RESTART }); + }); + } + }, undefined, { installMode: CodePush.InstallMode.ON_NEXT_RESTART }); + }); + }, + + getScenarioName: function () { + return "Sync Restart 2x (no restart in between)"; + } +}; diff --git a/test/test.ts b/test/test.ts index c117014f..c4dd91ec 100644 --- a/test/test.ts +++ b/test/test.ts @@ -616,6 +616,7 @@ const ScenarioSyncResumeDelay = "scenarioSyncResumeDelay.js"; const ScenarioSyncRestartDelay = "scenarioSyncRestartDelay.js"; const ScenarioSyncSuspendDelay = "scenarioSyncSuspendDelay.js"; const ScenarioSync2x = "scenarioSync2x.js"; +const ScenarioSyncRestart2x = "scenarioSyncRestart2x.js"; const ScenarioRestart = "scenarioRestart.js"; const ScenarioRestart2x = "scenarioRestart2x.js"; const ScenarioSyncMandatoryDefault = "scenarioSyncMandatoryDefault.js"; @@ -1538,6 +1539,31 @@ PluginTestingFramework.initializeTests(new RNProjectManager(), supportedTargetPl }, ScenarioSync2x); }); + TestBuilder.describe("#window.codePush.sync restart 2x", + () => { + // Regression test: a sync() called again while a previous ON_NEXT_RESTART install is + // still pending (i.e. no actual restart happened in between) must report UPDATE_INSTALLED, + // not UP_TO_DATE. getCurrentPackage().isPending must reflect that pending state. + TestBuilder.it("window.codePush.sync.restart2x.stillpending", false, + (done: Mocha.Done) => { + ServerUtil.updateResponse = { update_info: ServerUtil.createUpdateResponse(false, targetPlatform) }; + + setupUpdateScenario(projectManager, targetPlatform, UpdateDeviceReady, "Update 1 (good update)") + .then((updatePath: string) => { + ServerUtil.updatePackagePath = updatePath; + projectManager.runApplication(TestConfig.testRunDirectory, targetPlatform); + return ServerUtil.expectTestMessages([ + new ServerUtil.AppMessage(ServerUtil.TestMessage.PENDING_PACKAGE, [null]), + new ServerUtil.AppMessage(ServerUtil.TestMessage.CURRENT_PACKAGE, [null]), + new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_UPDATE_INSTALLED]), + new ServerUtil.AppMessage(ServerUtil.TestMessage.PENDING_PACKAGE, [ServerUtil.updateResponse.update_info.package_hash]), + new ServerUtil.AppMessage(ServerUtil.TestMessage.CURRENT_PACKAGE, [null]), + new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_UPDATE_INSTALLED])]); + }) + .done(() => { done(); }, (e) => { done(e); }); + }); + }, ScenarioSyncRestart2x); + TestBuilder.describe("#window.codePush.sync minimum background duration tests", () => { TestBuilder.it("defaults to no minimum for Resume mode", false,