From 9c5a42a7c9c6324a42b94e61908f42a529b06a02 Mon Sep 17 00:00:00 2001
From: Sankalp Kotewar <98868223+kotewar@users.noreply.github.com>
Date: Wed, 30 Nov 2022 08:11:55 +0000
Subject: [PATCH] Added test cases

---
 __tests__/restore.test.ts | 110 ++++++++++++++++++++++++++++++++++++++
 dist/restore/index.js     |  13 ++---
 src/restore.ts            |  17 +++---
 src/utils/testUtils.ts    |   9 ++++
 4 files changed, 137 insertions(+), 12 deletions(-)

diff --git a/__tests__/restore.test.ts b/__tests__/restore.test.ts
index e9a505b..e05c321 100644
--- a/__tests__/restore.test.ts
+++ b/__tests__/restore.test.ts
@@ -324,3 +324,113 @@ test("restore with cache found for restore key", async () => {
     );
     expect(failedMock).toHaveBeenCalledTimes(0);
 });
+
+test("restore with enabling save on any failure feature", async () => {
+    const path = "node_modules";
+    const key = "node-test";
+    const restoreKey = "node-";
+    testUtils.setInputs({
+        path: path,
+        key,
+        restoreKeys: [restoreKey],
+        saveOnAnyFailure: "true"
+    });
+
+    const debugMock = jest.spyOn(core, "debug");
+    const infoMock = jest.spyOn(core, "info");
+    const failedMock = jest.spyOn(core, "setFailed");
+    const stateMock = jest.spyOn(core, "saveState");
+    const setCacheHitOutputMock = jest.spyOn(actionUtils, "setCacheHitOutput");
+    const restoreCacheMock = jest
+        .spyOn(cache, "restoreCache")
+        .mockImplementationOnce(() => {
+            return Promise.resolve(restoreKey);
+        });
+
+    await run();
+
+    expect(restoreCacheMock).toHaveBeenCalledTimes(1);
+    expect(restoreCacheMock).toHaveBeenCalledWith([path], key, [restoreKey]);
+
+    expect(stateMock).toHaveBeenCalledWith("CACHE_KEY", key);
+    expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1);
+    expect(setCacheHitOutputMock).toHaveBeenCalledWith(false);
+
+    expect(debugMock).toHaveBeenCalledWith(
+        `Exporting environment variable SAVE_CACHE_ON_ANY_FAILURE`
+    );
+
+    expect(infoMock).toHaveBeenCalledWith(
+        `Input Variable SAVE_CACHE_ON_ANY_FAILURE is set to true, the cache will be saved despite of any failure in the build.`
+    );
+    expect(failedMock).toHaveBeenCalledTimes(0);
+});
+
+test("Fail restore with strict restore enabled when primary key not found", async () => {
+    const path = "node_modules";
+    const key = "node-test";
+    const restoreKey = "node-";
+    testUtils.setInputs({
+        path: path,
+        key,
+        restoreKeys: [restoreKey],
+        strictRestore: "true"
+    });
+
+    const failedMock = jest.spyOn(core, "setFailed");
+    const stateMock = jest.spyOn(core, "saveState");
+    const setCacheHitOutputMock = jest.spyOn(actionUtils, "setCacheHitOutput");
+    const restoreCacheMock = jest
+        .spyOn(cache, "restoreCache")
+        .mockImplementationOnce(() => {
+            return Promise.resolve(undefined);
+        });
+
+    await run();
+
+    expect(restoreCacheMock).toHaveBeenCalledTimes(1);
+    expect(restoreCacheMock).toHaveBeenCalledWith([path], key, [restoreKey]);
+
+    expect(stateMock).toHaveBeenCalledWith("CACHE_KEY", key);
+    expect(setCacheHitOutputMock).toHaveBeenCalledTimes(0);
+
+    expect(failedMock).toHaveBeenCalledWith(
+        `Cache with the given input key ${key} is not found, hence exiting the workflow as the strict-restore requirement is not met.`
+    );
+    expect(failedMock).toHaveBeenCalledTimes(1);
+});
+
+test("Fail restore with strict restore enabled when primary key doesn't match restored key", async () => {
+    const path = "node_modules";
+    const key = "node-test";
+    const restoreKey = "node-";
+    testUtils.setInputs({
+        path: path,
+        key,
+        restoreKeys: [restoreKey],
+        strictRestore: "true"
+    });
+
+    const failedMock = jest.spyOn(core, "setFailed");
+    const stateMock = jest.spyOn(core, "saveState");
+    const setCacheHitOutputMock = jest.spyOn(actionUtils, "setCacheHitOutput");
+    const restoreCacheMock = jest
+        .spyOn(cache, "restoreCache")
+        .mockImplementationOnce(() => {
+            return Promise.resolve(restoreKey);
+        });
+
+    await run();
+
+    expect(restoreCacheMock).toHaveBeenCalledTimes(1);
+    expect(restoreCacheMock).toHaveBeenCalledWith([path], key, [restoreKey]);
+
+    expect(stateMock).toHaveBeenCalledWith("CACHE_KEY", key);
+    expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1);
+    expect(setCacheHitOutputMock).toHaveBeenCalledWith(false);
+
+    expect(failedMock).toHaveBeenCalledWith(
+        `Restored cache key doesn't match the given input key ${key}, hence exiting the workflow as the strict-restore requirement is not met.`
+    );
+    expect(failedMock).toHaveBeenCalledTimes(1);
+});
diff --git a/dist/restore/index.js b/dist/restore/index.js
index b5ed08c..c73366a 100644
--- a/dist/restore/index.js
+++ b/dist/restore/index.js
@@ -49015,14 +49015,14 @@ function run() {
             });
             const cacheKey = yield cache.restoreCache(cachePaths, primaryKey, restoreKeys);
             //Check if user wants to save cache despite of failure in any previous job
-            const saveCache = core.getInput(constants_1.Inputs.SaveOnAnyFailure);
-            if (saveCache === "yes") {
-                core.debug(`save cache input variable is set to yes`);
+            const saveCache = core.getBooleanInput(constants_1.Inputs.SaveOnAnyFailure);
+            if (saveCache == true) {
+                core.debug(`Exporting environment variable ${constants_1.Variables.SaveCacheOnAnyFailure}`);
                 core.exportVariable(constants_1.Variables.SaveCacheOnAnyFailure, saveCache);
-                core.info(`Input Variable ${constants_1.Variables.SaveCacheOnAnyFailure} is set to yes, the cache will be saved despite of any failure in the build.`);
+                core.info(`Input Variable ${constants_1.Variables.SaveCacheOnAnyFailure} is set to true, the cache will be saved despite of any failure in the build.`);
             }
             if (!cacheKey) {
-                if (core.getInput(constants_1.Inputs.StrictRestore) == "yes") {
+                if (core.getBooleanInput(constants_1.Inputs.StrictRestore) == true) {
                     throw new Error(`Cache with the given input key ${primaryKey} is not found, hence exiting the workflow as the strict-restore requirement is not met.`);
                 }
                 core.info(`Cache not found for input keys: ${[
@@ -49035,7 +49035,8 @@ function run() {
             utils.setCacheState(cacheKey);
             const isExactKeyMatch = utils.isExactKeyMatch(primaryKey, cacheKey);
             utils.setCacheHitOutput(isExactKeyMatch);
-            if (!isExactKeyMatch && core.getInput(constants_1.Inputs.StrictRestore) == "yes") {
+            if (!isExactKeyMatch &&
+                core.getBooleanInput(constants_1.Inputs.StrictRestore) == true) {
                 throw new Error(`Restored cache key doesn't match the given input key ${primaryKey}, hence exiting the workflow as the strict-restore requirement is not met.`);
             }
             core.info(`Cache restored from key: ${cacheKey}`);
diff --git a/src/restore.ts b/src/restore.ts
index 302bc93..c27bbf0 100644
--- a/src/restore.ts
+++ b/src/restore.ts
@@ -36,17 +36,19 @@ async function run(): Promise<void> {
         );
 
         //Check if user wants to save cache despite of failure in any previous job
-        const saveCache = core.getInput(Inputs.SaveOnAnyFailure);
-        if (saveCache === "yes") {
-            core.debug(`save cache input variable is set to yes`);
+        const saveCache = core.getBooleanInput(Inputs.SaveOnAnyFailure);
+        if (saveCache == true) {
+            core.debug(
+                `Exporting environment variable ${Variables.SaveCacheOnAnyFailure}`
+            );
             core.exportVariable(Variables.SaveCacheOnAnyFailure, saveCache);
             core.info(
-                `Input Variable ${Variables.SaveCacheOnAnyFailure} is set to yes, the cache will be saved despite of any failure in the build.`
+                `Input Variable ${Variables.SaveCacheOnAnyFailure} is set to true, the cache will be saved despite of any failure in the build.`
             );
         }
 
         if (!cacheKey) {
-            if (core.getInput(Inputs.StrictRestore) == "yes") {
+            if (core.getBooleanInput(Inputs.StrictRestore) == true) {
                 throw new Error(
                     `Cache with the given input key ${primaryKey} is not found, hence exiting the workflow as the strict-restore requirement is not met.`
                 );
@@ -65,7 +67,10 @@ async function run(): Promise<void> {
         const isExactKeyMatch = utils.isExactKeyMatch(primaryKey, cacheKey);
         utils.setCacheHitOutput(isExactKeyMatch);
 
-        if (!isExactKeyMatch && core.getInput(Inputs.StrictRestore) == "yes") {
+        if (
+            !isExactKeyMatch &&
+            core.getBooleanInput(Inputs.StrictRestore) == true
+        ) {
             throw new Error(
                 `Restored cache key doesn't match the given input key ${primaryKey}, hence exiting the workflow as the strict-restore requirement is not met.`
             );
diff --git a/src/utils/testUtils.ts b/src/utils/testUtils.ts
index 9e2134f..e7fbed2 100644
--- a/src/utils/testUtils.ts
+++ b/src/utils/testUtils.ts
@@ -13,18 +13,27 @@ interface CacheInput {
     path: string;
     key: string;
     restoreKeys?: string[];
+    strictRestore?: string;
+    saveOnAnyFailure?: string;
 }
 
 export function setInputs(input: CacheInput): void {
     setInput(Inputs.Path, input.path);
     setInput(Inputs.Key, input.key);
+    setInput(Inputs.SaveOnAnyFailure, "false");
+    setInput(Inputs.StrictRestore, "false");
     input.restoreKeys &&
         setInput(Inputs.RestoreKeys, input.restoreKeys.join("\n"));
+    input.strictRestore && setInput(Inputs.StrictRestore, input.strictRestore);
+    input.saveOnAnyFailure &&
+        setInput(Inputs.SaveOnAnyFailure, input.saveOnAnyFailure);
 }
 
 export function clearInputs(): void {
     delete process.env[getInputName(Inputs.Path)];
     delete process.env[getInputName(Inputs.Key)];
     delete process.env[getInputName(Inputs.RestoreKeys)];
+    delete process.env[getInputName(Inputs.StrictRestore)];
+    delete process.env[getInputName(Inputs.SaveOnAnyFailure)];
     delete process.env[getInputName(Inputs.UploadChunkSize)];
 }