Add comprehensive tests for role middleware and fix package dependencies
Some checks are pending
Docker Test / test (push) Waiting to run

This commit is contained in:
BibaBot 2026-03-16 20:07:22 +00:00
parent 64aa924270
commit bfd432d094
1884 changed files with 384668 additions and 84 deletions

View file

@ -0,0 +1,20 @@
"use strict";
module.exports = {
injectInto: null,
properties: [
"spy",
"stub",
"mock",
"clock",
"server",
"requests",
"fake",
"replace",
"replaceSetter",
"replaceGetter",
"createStubInstance",
],
useFakeTimers: true,
useFakeServer: true,
};

View file

@ -0,0 +1,25 @@
"use strict";
const arrayProto = require("@sinonjs/commons").prototypes.array;
const reduce = arrayProto.reduce;
module.exports = function exportAsyncBehaviors(behaviorMethods) {
return reduce(
Object.keys(behaviorMethods),
function (acc, method) {
// need to avoid creating another async versions of the newly added async methods
if (method.match(/^(callsArg|yields)/) && !method.match(/Async/)) {
acc[`${method}Async`] = function () {
const result = behaviorMethods[method].apply(
this,
arguments
);
this.callbackAsync = true;
return result;
};
}
return acc;
},
{}
);
};

161
node_modules/sinon/lib/sinon/util/core/extend.js generated vendored Normal file
View file

@ -0,0 +1,161 @@
"use strict";
const arrayProto = require("@sinonjs/commons").prototypes.array;
const hasOwnProperty =
require("@sinonjs/commons").prototypes.object.hasOwnProperty;
const join = arrayProto.join;
const push = arrayProto.push;
// Adapted from https://developer.mozilla.org/en/docs/ECMAScript_DontEnum_attribute#JScript_DontEnum_Bug
const hasDontEnumBug = (function () {
const obj = {
constructor: function () {
return "0";
},
toString: function () {
return "1";
},
valueOf: function () {
return "2";
},
toLocaleString: function () {
return "3";
},
prototype: function () {
return "4";
},
isPrototypeOf: function () {
return "5";
},
propertyIsEnumerable: function () {
return "6";
},
hasOwnProperty: function () {
return "7";
},
length: function () {
return "8";
},
unique: function () {
return "9";
},
};
const result = [];
for (const prop in obj) {
if (hasOwnProperty(obj, prop)) {
push(result, obj[prop]());
}
}
return join(result, "") !== "0123456789";
})();
/**
*
* @param target
* @param sources
* @param doCopy
* @returns {*} target
*/
function extendCommon(target, sources, doCopy) {
let source, i, prop;
for (i = 0; i < sources.length; i++) {
source = sources[i];
for (prop in source) {
if (hasOwnProperty(source, prop)) {
doCopy(target, source, prop);
}
}
// Make sure we copy (own) toString method even when in JScript with DontEnum bug
// See https://developer.mozilla.org/en/docs/ECMAScript_DontEnum_attribute#JScript_DontEnum_Bug
if (
hasDontEnumBug &&
hasOwnProperty(source, "toString") &&
source.toString !== target.toString
) {
target.toString = source.toString;
}
}
return target;
}
/**
* Public: Extend target in place with all (own) properties, except 'name' when [[writable]] is false,
* from sources in-order. Thus, last source will override properties in previous sources.
*
* @param {object} target - The Object to extend
* @param {object[]} sources - Objects to copy properties from.
* @returns {object} the extended target
*/
module.exports = function extend(target, ...sources) {
return extendCommon(
target,
sources,
function copyValue(dest, source, prop) {
const destOwnPropertyDescriptor = Object.getOwnPropertyDescriptor(
dest,
prop
);
const sourceOwnPropertyDescriptor = Object.getOwnPropertyDescriptor(
source,
prop
);
if (prop === "name" && !destOwnPropertyDescriptor.writable) {
return;
}
const descriptors = {
configurable: sourceOwnPropertyDescriptor.configurable,
enumerable: sourceOwnPropertyDescriptor.enumerable,
};
/*
if the sorce has an Accessor property copy over the accessor functions (get and set)
data properties has writable attribute where as accessor property don't
REF: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#properties
*/
if (hasOwnProperty(sourceOwnPropertyDescriptor, "writable")) {
descriptors.writable = sourceOwnPropertyDescriptor.writable;
descriptors.value = sourceOwnPropertyDescriptor.value;
} else {
if (sourceOwnPropertyDescriptor.get) {
descriptors.get =
sourceOwnPropertyDescriptor.get.bind(dest);
}
if (sourceOwnPropertyDescriptor.set) {
descriptors.set =
sourceOwnPropertyDescriptor.set.bind(dest);
}
}
Object.defineProperty(dest, prop, descriptors);
}
);
};
/**
* Public: Extend target in place with all (own) properties from sources in-order. Thus, last source will
* override properties in previous sources. Define the properties as non enumerable.
*
* @param {object} target - The Object to extend
* @param {object[]} sources - Objects to copy properties from.
* @returns {object} the extended target
*/
module.exports.nonEnum = function extendNonEnum(target, ...sources) {
return extendCommon(
target,
sources,
function copyProperty(dest, source, prop) {
Object.defineProperty(dest, prop, {
value: source[prop],
enumerable: false,
configurable: true,
writable: true,
});
}
);
};

View file

@ -0,0 +1,25 @@
"use strict";
module.exports = function toString() {
let i, prop, thisValue;
if (this.getCall && this.callCount) {
i = this.callCount;
while (i--) {
thisValue = this.getCall(i).thisValue;
// eslint-disable-next-line guard-for-in
for (prop in thisValue) {
try {
if (thisValue[prop] === this) {
return prop;
}
} catch (e) {
// no-op - accessing props can throw an error, nothing to do here
}
}
}
}
return this.displayName || "sinon fake";
};

View file

@ -0,0 +1,18 @@
"use strict";
/* istanbul ignore next : not testing that setTimeout works */
function nextTick(callback) {
setTimeout(callback, 0);
}
module.exports = function getNextTick(process, setImmediate) {
if (typeof process === "object" && typeof process.nextTick === "function") {
return process.nextTick;
}
if (typeof setImmediate === "function") {
return setImmediate;
}
return nextTick;
};

View file

@ -0,0 +1,22 @@
"use strict";
module.exports = function getPropertyDescriptor(object, property) {
let proto = object;
let descriptor;
const isOwn = Boolean(
object && Object.getOwnPropertyDescriptor(object, property)
);
while (
proto &&
!(descriptor = Object.getOwnPropertyDescriptor(proto, property))
) {
proto = Object.getPrototypeOf(proto);
}
if (descriptor) {
descriptor.isOwn = isOwn;
}
return descriptor;
};

20
node_modules/sinon/lib/sinon/util/core/is-es-module.js generated vendored Normal file
View file

@ -0,0 +1,20 @@
"use strict";
/**
* Verify if an object is a ECMAScript Module
*
* As the exports from a module is immutable we cannot alter the exports
* using spies or stubs. Let the consumer know this to avoid bug reports
* on weird error messages.
*
* @param {object} object The object to examine
* @returns {boolean} true when the object is a module
*/
module.exports = function (object) {
return (
object &&
typeof Symbol !== "undefined" &&
object[Symbol.toStringTag] === "Module" &&
Object.isSealed(object)
);
};

View file

@ -0,0 +1,14 @@
"use strict";
/**
* @param {*} object
* @param {string} property
* @returns {boolean} whether a prop exists in the prototype chain
*/
function isNonExistentProperty(object, property) {
return Boolean(
object && typeof property !== "undefined" && !(property in object)
);
}
module.exports = isNonExistentProperty;

View file

@ -0,0 +1,11 @@
"use strict";
const getPropertyDescriptor = require("./get-property-descriptor");
function isPropertyConfigurable(obj, propName) {
const propertyDescriptor = getPropertyDescriptor(obj, propName);
return propertyDescriptor ? propertyDescriptor.configurable : true;
}
module.exports = isPropertyConfigurable;

View file

@ -0,0 +1,11 @@
"use strict";
function isRestorable(obj) {
return (
typeof obj === "function" &&
typeof obj.restore === "function" &&
obj.restore.sinon
);
}
module.exports = isRestorable;

6
node_modules/sinon/lib/sinon/util/core/next-tick.js generated vendored Normal file
View file

@ -0,0 +1,6 @@
"use strict";
const globalObject = require("@sinonjs/commons").global;
const getNextTick = require("./get-next-tick");
module.exports = getNextTick(globalObject.process, globalObject.setImmediate);

22
node_modules/sinon/lib/sinon/util/core/sinon-type.js generated vendored Normal file
View file

@ -0,0 +1,22 @@
"use strict";
const sinonTypeSymbolProperty = Symbol("SinonType");
module.exports = {
/**
* Set the type of a Sinon object to make it possible to identify it later at runtime
*
* @param {object|Function} object object/function to set the type on
* @param {string} type the named type of the object/function
*/
set(object, type) {
Object.defineProperty(object, sinonTypeSymbolProperty, {
value: type,
configurable: false,
enumerable: false,
});
},
get(object) {
return object && object[sinonTypeSymbolProperty];
},
};

View file

@ -0,0 +1,7 @@
"use strict";
const array = [null, "once", "twice", "thrice"];
module.exports = function timesInWords(count) {
return array[count] || `${count || 0} times`;
};

View file

@ -0,0 +1,21 @@
"use strict";
const forEach = Array.prototype.forEach;
function usePromiseLibrary(library, fakes) {
if (typeof library === "undefined") {
return;
}
if (Array.isArray(fakes)) {
forEach.call(fakes, usePromiseLibrary.bind(null, library));
return;
}
if (typeof fakes.usingPromise === "function") {
fakes.usingPromise(library);
}
}
module.exports = usePromiseLibrary;

55
node_modules/sinon/lib/sinon/util/core/walk-object.js generated vendored Normal file
View file

@ -0,0 +1,55 @@
"use strict";
const functionName = require("@sinonjs/commons").functionName;
const getPropertyDescriptor = require("./get-property-descriptor");
const walk = require("./walk");
/**
* A utility that allows traversing an object, applying mutating functions on the properties
*
* @param {Function} mutator called on each property
* @param {object} object the object we are walking over
* @param {Function} filter a predicate (boolean function) that will decide whether or not to apply the mutator to the current property
* @returns {void} nothing
*/
function walkObject(mutator, object, filter) {
let called = false;
const name = functionName(mutator);
if (!object) {
throw new Error(
`Trying to ${name} object but received ${String(object)}`
);
}
walk(object, function (prop, propOwner) {
// we don't want to stub things like toString(), valueOf(), etc. so we only stub if the object
// is not Object.prototype
if (
propOwner !== Object.prototype &&
prop !== "constructor" &&
typeof getPropertyDescriptor(propOwner, prop).value === "function"
) {
if (filter) {
if (filter(object, prop)) {
called = true;
mutator(object, prop);
}
} else {
called = true;
mutator(object, prop);
}
}
});
if (!called) {
throw new Error(
`Found no methods on object to which we could apply mutations`
);
}
return object;
}
module.exports = walkObject;

49
node_modules/sinon/lib/sinon/util/core/walk.js generated vendored Normal file
View file

@ -0,0 +1,49 @@
"use strict";
const forEach = require("@sinonjs/commons").prototypes.array.forEach;
function walkInternal(obj, iterator, context, originalObj, seen) {
let prop;
const proto = Object.getPrototypeOf(obj);
if (typeof Object.getOwnPropertyNames !== "function") {
// We explicitly want to enumerate through all of the prototype's properties
// in this case, therefore we deliberately leave out an own property check.
/* eslint-disable-next-line guard-for-in */
for (prop in obj) {
iterator.call(context, obj[prop], prop, obj);
}
return;
}
forEach(Object.getOwnPropertyNames(obj), function (k) {
if (seen[k] !== true) {
seen[k] = true;
const target =
typeof Object.getOwnPropertyDescriptor(obj, k).get ===
"function"
? originalObj
: obj;
iterator.call(context, k, target);
}
});
if (proto) {
walkInternal(proto, iterator, context, originalObj, seen);
}
}
/* Walks the prototype chain of an object and iterates over every own property
* name encountered. The iterator is called in the same fashion that Array.prototype.forEach
* works, where it is passed the value, key, and own object as the 1st, 2nd, and 3rd positional
* argument, respectively. In cases where Object.getOwnPropertyNames is not available, walk will
* default to using a simple for..in loop.
*
* obj - The object to walk the prototype chain for.
* iterator - The function to be called on each pass of the walk.
* context - (Optional) When given, the iterator will be called with this object as the receiver.
*/
module.exports = function walk(obj, iterator, context) {
return walkInternal(obj, iterator, context, obj, {});
};

245
node_modules/sinon/lib/sinon/util/core/wrap-method.js generated vendored Normal file
View file

@ -0,0 +1,245 @@
"use strict";
// eslint-disable-next-line no-empty-function
const noop = () => {};
const getPropertyDescriptor = require("./get-property-descriptor");
const extend = require("./extend");
const sinonType = require("./sinon-type");
const hasOwnProperty =
require("@sinonjs/commons").prototypes.object.hasOwnProperty;
const valueToString = require("@sinonjs/commons").valueToString;
const push = require("@sinonjs/commons").prototypes.array.push;
function isFunction(obj) {
return (
typeof obj === "function" ||
Boolean(obj && obj.constructor && obj.call && obj.apply)
);
}
function mirrorProperties(target, source) {
for (const prop in source) {
if (!hasOwnProperty(target, prop)) {
target[prop] = source[prop];
}
}
}
function getAccessor(object, property, method) {
const accessors = ["get", "set"];
const descriptor = getPropertyDescriptor(object, property);
for (let i = 0; i < accessors.length; i++) {
if (
descriptor[accessors[i]] &&
descriptor[accessors[i]].name === method.name
) {
return accessors[i];
}
}
return null;
}
// Cheap way to detect if we have ES5 support.
const hasES5Support = "keys" in Object;
module.exports = function wrapMethod(object, property, method) {
if (!object) {
throw new TypeError("Should wrap property of object");
}
if (typeof method !== "function" && typeof method !== "object") {
throw new TypeError(
"Method wrapper should be a function or a property descriptor"
);
}
function checkWrappedMethod(wrappedMethod) {
let error;
if (!isFunction(wrappedMethod)) {
error = new TypeError(
`Attempted to wrap ${typeof wrappedMethod} property ${valueToString(
property
)} as function`
);
} else if (wrappedMethod.restore && wrappedMethod.restore.sinon) {
error = new TypeError(
`Attempted to wrap ${valueToString(
property
)} which is already wrapped`
);
} else if (wrappedMethod.calledBefore) {
const verb = wrappedMethod.returns ? "stubbed" : "spied on";
error = new TypeError(
`Attempted to wrap ${valueToString(
property
)} which is already ${verb}`
);
}
if (error) {
if (wrappedMethod && wrappedMethod.stackTraceError) {
error.stack += `\n--------------\n${wrappedMethod.stackTraceError.stack}`;
}
throw error;
}
}
let error, wrappedMethod, i, wrappedMethodDesc, target, accessor;
const wrappedMethods = [];
function simplePropertyAssignment() {
wrappedMethod = object[property];
checkWrappedMethod(wrappedMethod);
object[property] = method;
method.displayName = property;
}
// Firefox has a problem when using hasOwn.call on objects from other frames.
const owned = object.hasOwnProperty
? object.hasOwnProperty(property) // eslint-disable-line @sinonjs/no-prototype-methods/no-prototype-methods
: hasOwnProperty(object, property);
if (hasES5Support) {
const methodDesc =
typeof method === "function" ? { value: method } : method;
wrappedMethodDesc = getPropertyDescriptor(object, property);
if (!wrappedMethodDesc) {
error = new TypeError(
`Attempted to wrap ${typeof wrappedMethod} property ${property} as function`
);
} else if (
wrappedMethodDesc.restore &&
wrappedMethodDesc.restore.sinon
) {
error = new TypeError(
`Attempted to wrap ${property} which is already wrapped`
);
}
if (error) {
if (wrappedMethodDesc && wrappedMethodDesc.stackTraceError) {
error.stack += `\n--------------\n${wrappedMethodDesc.stackTraceError.stack}`;
}
throw error;
}
const types = Object.keys(methodDesc);
for (i = 0; i < types.length; i++) {
wrappedMethod = wrappedMethodDesc[types[i]];
checkWrappedMethod(wrappedMethod);
push(wrappedMethods, wrappedMethod);
}
mirrorProperties(methodDesc, wrappedMethodDesc);
for (i = 0; i < types.length; i++) {
mirrorProperties(methodDesc[types[i]], wrappedMethodDesc[types[i]]);
}
// you are not allowed to flip the configurable prop on an
// existing descriptor to anything but false (#2514)
if (!owned) {
methodDesc.configurable = true;
}
Object.defineProperty(object, property, methodDesc);
// catch failing assignment
// this is the converse of the check in `.restore` below
if (typeof method === "function" && object[property] !== method) {
// correct any wrongdoings caused by the defineProperty call above,
// such as adding new items (if object was a Storage object)
delete object[property];
simplePropertyAssignment();
}
} else {
simplePropertyAssignment();
}
extendObjectWithWrappedMethods();
function extendObjectWithWrappedMethods() {
for (i = 0; i < wrappedMethods.length; i++) {
accessor = getAccessor(object, property, wrappedMethods[i]);
target = accessor ? method[accessor] : method;
extend.nonEnum(target, {
displayName: property,
wrappedMethod: wrappedMethods[i],
// Set up an Error object for a stack trace which can be used later to find what line of
// code the original method was created on.
stackTraceError: new Error("Stack Trace for original"),
restore: restore,
});
target.restore.sinon = true;
if (!hasES5Support) {
mirrorProperties(target, wrappedMethod);
}
}
}
function restore() {
accessor = getAccessor(object, property, this.wrappedMethod);
let descriptor;
// For prototype properties try to reset by delete first.
// If this fails (ex: localStorage on mobile safari) then force a reset
// via direct assignment.
if (accessor) {
if (!owned) {
try {
// In some cases `delete` may throw an error
delete object[property][accessor];
} catch (e) {} // eslint-disable-line no-empty
// For native code functions `delete` fails without throwing an error
// on Chrome < 43, PhantomJS, etc.
} else if (hasES5Support) {
descriptor = getPropertyDescriptor(object, property);
descriptor[accessor] = wrappedMethodDesc[accessor];
Object.defineProperty(object, property, descriptor);
}
if (hasES5Support) {
descriptor = getPropertyDescriptor(object, property);
if (descriptor && descriptor.value === target) {
object[property][accessor] = this.wrappedMethod;
}
} else {
// Use strict equality comparison to check failures then force a reset
// via direct assignment.
if (object[property][accessor] === target) {
object[property][accessor] = this.wrappedMethod;
}
}
} else {
if (!owned) {
try {
delete object[property];
} catch (e) {} // eslint-disable-line no-empty
} else if (hasES5Support) {
Object.defineProperty(object, property, wrappedMethodDesc);
}
if (hasES5Support) {
descriptor = getPropertyDescriptor(object, property);
if (descriptor && descriptor.value === target) {
object[property] = this.wrappedMethod;
}
} else {
if (object[property] === target) {
object[property] = this.wrappedMethod;
}
}
}
if (sinonType.get(object) === "stub-instance") {
// this is simply to avoid errors after restoring if something should
// traverse the object in a cleanup phase, ref #2477
object[property] = noop;
}
}
return method;
};

88
node_modules/sinon/lib/sinon/util/fake-timers.js generated vendored Normal file
View file

@ -0,0 +1,88 @@
"use strict";
const extend = require("./core/extend");
const FakeTimers = require("@sinonjs/fake-timers");
const globalObject = require("@sinonjs/commons").global;
/**
*
* @param config
* @param globalCtx
*/
function createClock(config, globalCtx) {
let FakeTimersCtx = FakeTimers;
if (globalCtx !== null && typeof globalCtx === "object") {
FakeTimersCtx = FakeTimers.withGlobal(globalCtx);
}
const clock = FakeTimersCtx.install(config);
clock.restore = clock.uninstall;
return clock;
}
/**
*
* @param obj
* @param globalPropName
*/
function addIfDefined(obj, globalPropName) {
const globalProp = globalObject[globalPropName];
if (typeof globalProp !== "undefined") {
obj[globalPropName] = globalProp;
}
}
/**
* @param {number|Date|object} dateOrConfig The unix epoch value to install with (default 0)
* @returns {object} Returns a lolex clock instance
*/
exports.useFakeTimers = function (dateOrConfig) {
const hasArguments = typeof dateOrConfig !== "undefined";
const argumentIsDateLike =
(typeof dateOrConfig === "number" || dateOrConfig instanceof Date) &&
arguments.length === 1;
const argumentIsObject =
dateOrConfig !== null &&
typeof dateOrConfig === "object" &&
arguments.length === 1;
if (!hasArguments) {
return createClock({
now: 0,
});
}
if (argumentIsDateLike) {
return createClock({
now: dateOrConfig,
});
}
if (argumentIsObject) {
const config = extend.nonEnum({}, dateOrConfig);
const globalCtx = config.global;
delete config.global;
return createClock(config, globalCtx);
}
throw new TypeError(
"useFakeTimers expected epoch or config object. See https://github.com/sinonjs/sinon"
);
};
exports.clock = {
create: function (now) {
return FakeTimers.createClock(now);
},
};
const timers = {
setTimeout: setTimeout,
clearTimeout: clearTimeout,
setInterval: setInterval,
clearInterval: clearInterval,
Date: Date,
};
addIfDefined(timers, "setImmediate");
addIfDefined(timers, "clearImmediate");
exports.timers = timers;