Skip to content

Commit

Permalink
introduce indirection to be able to mock UrlFetchApp methods
Browse files Browse the repository at this point in the history
  • Loading branch information
diosmosis committed Oct 2, 2024
1 parent f282258 commit 00a0a4f
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 17 deletions.
4 changes: 2 additions & 2 deletions src-test/callFunctionInTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export function callFunctionInTest(functionName: string, testName: string, ...pa
console.log(`calling ${functionName} in test "${testName}"`);

// there is no global object (like window) in apps script, so this is how we get a global function by name
const fn = eval(functionName);
const fn = (new Function(`return ${functionName};`))();
const result = fn(...params);
return JSON.stringify(result);
} catch (e) {
Expand All @@ -29,7 +29,7 @@ export function callFunctionInTestWithMockFixture(
const fixtureInstance = (ALL_FIXTURES[fixture.name])(...params);
console.log(fixture.name);
console.log(ALL_FIXTURES[fixture.name].toString());
console.log(UrlFetchApp.fetchAll.toString());
console.log((new Function('return getServices;'))()().UrlFetchApp.fetchAll);
fixtureInstance.setUp();
try {
return callFunctionInTest(functionName, testName, ...params);
Expand Down
38 changes: 24 additions & 14 deletions src-test/mock-fixtures/urlfetchapp-mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,37 @@
*/

export default function urlFetchAppMock(errorToThrow: string, throwAsString: boolean = false) {
const previousFetchAll = UrlFetchApp.fetchAll;
let isThrown = false;

return {
setUp() {
UrlFetchApp.fetchAll = function (...args) {
if (!isThrown) {
isThrown = true;
const mockUrlFetchApp = new Proxy(UrlFetchApp, {
get(target, prop) {
if (prop === 'fetchAll') {
return function (...args) {
if (!isThrown) {
isThrown = true;

if (throwAsString) {
throw errorToThrow;
if (throwAsString) {
throw errorToThrow;
} else {
throw new Error(errorToThrow);
}
} else {
throw new Error(errorToThrow);
return target[prop].call(this, ...args);
}
} else {
return previousFetchAll.call(this, ...args);
}
};
};
}
return target[prop];
}
});

return {
setUp() {
const getServices = (new Function('return getServices;'))();
getServices().UrlFetchApp = mockUrlFetchApp;
},
tearDown() {
UrlFetchApp.fetchAll = previousFetchAll;
const getServices = (new Function('return getServices;'))();
getServices().UrlFetchApp = UrlFetchApp;
},
};
}
3 changes: 2 additions & 1 deletion src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { getScriptElapsedTime } from './connector';
import { throwUnexpectedError, throwUserError } from './error';
import URLFetchRequest = GoogleAppsScript.URL_Fetch.URLFetchRequest;
import { debugLog, log, logError } from './log';
import { getServices } from './services';

const SCRIPT_RUNTIME_LIMIT = parseInt(env.SCRIPT_RUNTIME_LIMIT) || 0;
const API_REQUEST_RETRY_LIMIT_IN_SECS = parseInt(env.API_REQUEST_RETRY_LIMIT_IN_SECS) || 0;
Expand Down Expand Up @@ -212,7 +213,7 @@ export function fetchAll(requests: MatomoRequestParams[], options: ApiFetchOptio

let responses = [];
try {
responses = UrlFetchApp.fetchAll(urlsToFetch);
responses = getServices().UrlFetchApp.fetchAll(urlsToFetch);
} catch (e) {
const errorMessage = e.message || e;

Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ export { extractBasicAuthFromUrl, fetchAll, isApiErrorNonRandom } from './api';
export * from './auth';
export * from './config';
export * from './data';
export * from './services';
14 changes: 14 additions & 0 deletions src/services.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* Matomo - free/libre analytics platform
*
* @link https://matomo.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/

const SERVICES = {
UrlFetchApp,
};

export function getServices() {
return SERVICES;
}

0 comments on commit 00a0a4f

Please sign in to comment.