diff --git a/lib/controllers/hosted-skill-controller/helper.js b/lib/controllers/hosted-skill-controller/helper.js index 49d0c747..bec595db 100644 --- a/lib/controllers/hosted-skill-controller/helper.js +++ b/lib/controllers/hosted-skill-controller/helper.js @@ -67,15 +67,18 @@ function pollingSkillStatus(smapiClient, skillId, callback) { response, ); } + + const empty = (data) => !data || R.isEmpty(data); + return ( - !statusTracker.manifest || - !statusTracker.interactionModel || - !statusTracker.hostedSkillProvisioning || - !( - statusTracker.manifest === CONSTANTS.HOSTED_SKILL.MANIFEST_STATUS.SUCCESS && - statusTracker.interactionModel === CONSTANTS.HOSTED_SKILL.INTERACTION_MODEL_STATUS.SUCCESS && - statusTracker.hostedSkillProvisioning === CONSTANTS.HOSTED_SKILL.PROVISIONING_STATUS.SUCCESS - ) + // retry if one of manifest, interaction model, provisioning don't exist + empty(statusTracker.manifest) || + empty(statusTracker.interactionModel) || + empty(statusTracker.hostedSkillProvisioning) || + // retry if one of manifest, interaction model, provisioning are in progress + statusTracker.manifest === CONSTANTS.HOSTED_SKILL.MANIFEST_STATUS.IN_PROGRESS || + statusTracker.interactionModel === CONSTANTS.HOSTED_SKILL.INTERACTION_MODEL_STATUS.IN_PROGRESS || + statusTracker.hostedSkillProvisioning === CONSTANTS.HOSTED_SKILL.PROVISIONING_STATUS.IN_PROGRESS ); }; retryUtils.retry(retryConfig, retryCall, shouldRetryCondition, (err) => callback(err, err ? null : statusTracker)); diff --git a/test/unit/controller/hosted-skill-controller/index-test.js b/test/unit/controller/hosted-skill-controller/index-test.js index b77a0b8a..d1bdca83 100644 --- a/test/unit/controller/hosted-skill-controller/index-test.js +++ b/test/unit/controller/hosted-skill-controller/index-test.js @@ -401,6 +401,58 @@ describe("Controller test - hosted skill controller test", () => { }); }); + it("| polling to get skill status until one resource FAILED, expect error thrown ", (done) => { + // setup + const TEST_STATUS_RESPONSE_0 = { + statusCode: 200, + headers: {}, + body: { + [CONSTANTS.HOSTED_SKILL.RESOURCES.MANIFEST]: { + lastUpdateRequest: { + status: "SUCCEEDED", + }, + }, + }, + }; + const TEST_STATUS_RESPONSE_1 = { + statusCode: 200, + headers: {}, + body: { + [CONSTANTS.HOSTED_SKILL.RESOURCES.MANIFEST]: { + lastUpdateRequest: { + status: "SUCCEEDED", + }, + }, + [CONSTANTS.HOSTED_SKILL.RESOURCES.INTERACTION_MODEL]: { + [TEST_LOCALE]: { + lastUpdateRequest: { + status: "SUCCEEDED", + }, + }, + }, + [CONSTANTS.HOSTED_SKILL.RESOURCES.PROVISIONING]: { + lastUpdateRequest: { + status: "FAILED", + }, + }, + }, + }; + const stubTestFunc = sinon.stub(httpClient, "request"); // stub getSkillStatus smapi request + stubTestFunc.onCall(0).callsArgWith(3, null, TEST_STATUS_RESPONSE_0); + stubTestFunc.onCall(1).callsArgWith(3, null, TEST_STATUS_RESPONSE_1); + sinon.useFakeTimers().tickAsync(CONSTANTS.CONFIGURATION.RETRY.MAX_RETRY_INTERVAL); + const callback = (err, res) => { + expect(err).equal( + "Check skill status failed for the following reason:\n" + + "Skill provisioning step failed.\nInfrastructure provision for the hosted skill failed. Please try again.", + ); + expect(res).equal(undefined); + done(); + }; + // call + hostedSkillController.checkSkillStatus(TEST_SKILL_ID, callback); + }); + it("| polling to get skill status response is null, expect error thrown ", (done) => { // setup const TEST_RESPONSE = null;