Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/components/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/components/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@labkey/components",
"version": "7.39.1",
"version": "7.39.2-fb-dropCrossFolder.0",
"description": "Components, models, actions, and utility functions for LabKey applications and pages",
"sideEffects": false,
"files": [
Expand Down
4 changes: 4 additions & 0 deletions packages/components/releaseNotes/components.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# @labkey/components
Components, models, actions, and utility functions for LabKey applications and pages

### version 7.X
*Released*: X May 2026
- GitHub Issue 903: Remove Cross-Container Sample and Data Class Import Feature

### version TBD
*Released*: TBD
- Misc. accessibility improvements
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,6 @@ export interface EntityDataType {
ancestorColumnName?: string;
appUrlPrefixParts?: string[];
containerFilter?: Query.ContainerFilter;
crossFolderImportForbidden?: boolean;
deleteHelpLinkTopic: string;
dependencyText: Function | string;
descriptionPlural: string;
Expand Down
8 changes: 8 additions & 0 deletions packages/test/config/integration.setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,3 +139,11 @@ process.env.INTEGRATION_SERVER = `${protocol}://${server}:${port}`;
process.env.INTEGRATION_CONTEXT_PATH = contextPath;
process.env.INTEGRATION_AUTH_USER = user;
process.env.INTEGRATION_AUTH_PASS = pass;

// Seed configuration for reproducible random test data.
// Each Jest worker inherits TEST_SEED from the environment; if absent, generate
// from Date.now() and write back so utils.ts (loaded after setupFiles) sees it.
if (!process.env.TEST_SEED) {
process.env.TEST_SEED = String(Date.now() >>> 0);
}
console.log(`[LabKey Test] Random seed: ${process.env.TEST_SEED} (rerun with: TEST_SEED=${process.env.TEST_SEED})`);
4 changes: 2 additions & 2 deletions packages/test/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/test/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@labkey/test",
"version": "1.13.2",
"version": "1.14.0-fb-dropCrossFolder.1",
"description": "Configurations and utilities for JavaScript-based testing",
"main": "dist/test.js",
"module": "dist/test.js",
Expand Down
4 changes: 2 additions & 2 deletions packages/test/src/ExperimentCrudUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ export async function importData(server, importText: string, queryName: string,
let errorResp = null;
const response = await server.request('experiment', isSamples ? 'importSamples' : 'importData', (agent, url) => {
return agent
.post(url + '?auditBehavior=DETAILED&crossFolderImport=true')
.post(url + '?auditBehavior=DETAILED')
.type('form')
.send({
schemaName: isSamples ? 'samples' : 'exp.data',
Expand Down Expand Up @@ -210,7 +210,7 @@ export async function importCrossTypeData(
isSamples ? 'importSamples' : 'importData',
(agent, url) => {
return agent
.post(url + '?auditBehavior=DETAILED&crossFolderImport=true&crossTypeImport=true')
.post(url + '?auditBehavior=DETAILED&crossTypeImport=true')
.type('form')
.send({
schemaName: undefined,
Expand Down
4 changes: 4 additions & 0 deletions packages/test/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import {
} from './integrationUtils';
import {
sleep,
random,
testSeed,
shuffleArray,
selectRandomN,
generateDomainName,
Expand Down Expand Up @@ -83,6 +85,8 @@ export {
IntegrationTestServer,
RequestOptions,
sleep,
random,
testSeed,
successfulResponse,
TestUser,
ExperimentCRUDUtils,
Expand Down
34 changes: 32 additions & 2 deletions packages/test/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,36 @@
* @param ms number of milliseconds to sleep.
*/

// Seeded PRNG (mulberry32). Reads TEST_SEED at module load time;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: The sleep comment above this got separated from the sleep() method with a previous PR. Made worse by this. Please co-locate the comment/description with the function.

// falls back to Date.now() if not set.
function _mulberry32(seed: number): () => number {
return function () {
seed |= 0;
seed = seed + 0x6D2B79F5 | 0;
let t = Math.imul(seed ^ (seed >>> 15), 1 | seed);
t = t + Math.imul(t ^ (t >>> 7), 61 | t) ^ t;
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
};
}

const _seedStr = typeof process !== 'undefined' ? process.env?.TEST_SEED : undefined;
const _seed = _seedStr !== undefined ? (parseInt(_seedStr, 10) >>> 0) : (Date.now() >>> 0);

/** Seeded drop-in for Math.random(). Use in tests instead of Math.random()
* so runs are reproducible via the TEST_SEED environment variable.
*
* Note: this is a module-level singleton — all test files loaded in the same Jest worker share
* one sequence. With --maxWorkers 1 (the default for integration tests) this means full
* reproducibility: the same seed always produces the same sequence regardless of which file
* calls random() and in what order. If --maxWorkers is increased, each worker gets its own
* copy of this module initialized from the same TEST_SEED, so files on different workers draw
* from independent sequences — a multi-worker run may not reproduce identically under
* --maxWorkers 1 even with the same seed. */
export const random = _mulberry32(_seed);

/** The seed used for this test run. Log it so failures can be reproduced with TEST_SEED=<value>. */
export const testSeed = _seed;

const QUERY_KEY_CHARSET = '$/&}~,.';
const ALPHA = 'ABCDabcvxyz';
const NUMERIC = '0123456789';
Expand All @@ -38,7 +68,7 @@ export const sleep = (ms = 0): Promise<void> => {
export function shuffleArray<T>(original: T[]) : T[] {
const array = [...original];
for (let i = array.length - 1; i >= 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
const j = Math.floor(random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
return array;
Expand All @@ -56,7 +86,7 @@ export function generateRandomStr(length: number = 8, charset: string = STRING_C
const charsetLength = charset.length;

while (result.length < length) {
const randomIndex = Math.floor(Math.random() * charsetLength);
const randomIndex = Math.floor(random() * charsetLength);
const select = charset[randomIndex];
if (!excluded || excluded.indexOf(select) === -1)
result += charset[randomIndex];
Expand Down