@hot-updater/test-utils 1.0.0-rc.43 → 1.0.0-rc.44
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -4
- package/dist/index.d.mts +6 -5
- package/dist/index.mjs +19 -23
- package/package.json +10 -10
package/README.md
CHANGED
|
@@ -37,12 +37,10 @@ Connect your database's lifecycle and the real server:
|
|
|
37
37
|
|
|
38
38
|
```ts
|
|
39
39
|
import { createHotUpdater } from "@hot-updater/server";
|
|
40
|
-
import {
|
|
41
|
-
createInsightsModel,
|
|
42
|
-
insights,
|
|
43
|
-
} from "@hot-updater/server/plugins/insights";
|
|
40
|
+
import { createInsightsModel, insights } from "@hot-updater/server/plugins";
|
|
44
41
|
|
|
45
42
|
import {
|
|
43
|
+
createReleaseCatalogTestStorage,
|
|
46
44
|
insightsTestSuite,
|
|
47
45
|
setupDatabaseTestSuite,
|
|
48
46
|
startHttpTestServer,
|
|
@@ -77,6 +75,7 @@ setupDatabaseTestSuite({
|
|
|
77
75
|
createInsightsModel(
|
|
78
76
|
createHotUpdater({
|
|
79
77
|
database,
|
|
78
|
+
storage: createReleaseCatalogTestStorage(),
|
|
80
79
|
plugins: [insights()],
|
|
81
80
|
clientAccess: "public",
|
|
82
81
|
}).api.insights,
|
package/dist/index.d.mts
CHANGED
|
@@ -128,7 +128,7 @@ type DatabaseTestSuiteOptions<TDatabase extends EngineDatabase = EngineDatabase>
|
|
|
128
128
|
*/
|
|
129
129
|
readonly createHttpClient: (options: {
|
|
130
130
|
readonly database: TDatabase;
|
|
131
|
-
readonly storage:
|
|
131
|
+
readonly storage: StorageAdapter;
|
|
132
132
|
}) => HttpTestServer | Promise<HttpTestServer>;
|
|
133
133
|
/** The suites of the server plugins the provider opts in to test. */
|
|
134
134
|
readonly plugins?: readonly DatabasePluginTestSuite<TDatabase>[];
|
|
@@ -464,8 +464,9 @@ declare const setupInsightsHttpTestSuite: (options: {
|
|
|
464
464
|
//#region src/insights/setupInsightsModelTestSuite.d.ts
|
|
465
465
|
/**
|
|
466
466
|
* The Insights report contract on one database: pass the Insights plugin's
|
|
467
|
-
* model over it, `createInsightsModel(createHotUpdater({ database,
|
|
468
|
-
* [insights()], clientAccess: "public" }).api.insights)`, as
|
|
467
|
+
* model over it, `createInsightsModel(createHotUpdater({ database, storage,
|
|
468
|
+
* plugins: [insights()], clientAccess: "public" }).api.insights)`, as
|
|
469
|
+
* `createDatabase`.
|
|
469
470
|
*/
|
|
470
471
|
declare const setupInsightsModelTestSuite: (lifecycle: DatabaseTestLifecycle<InsightsModel>) => void;
|
|
471
472
|
//#endregion
|
|
@@ -474,8 +475,8 @@ declare const setupInsightsModelTestSuite: (lifecycle: DatabaseTestLifecycle<Ins
|
|
|
474
475
|
* The Insights plugin's tests, for `setupDatabaseTestSuite`'s `plugins`: its
|
|
475
476
|
* HTTP routes on the provider's server, which must run `insights()`, and
|
|
476
477
|
* with `createModel` its report contract on the provider's database, such as
|
|
477
|
-
* `(database) => createInsightsModel(createHotUpdater({ database,
|
|
478
|
-
* [insights()], clientAccess: "public" }).api.insights)`.
|
|
478
|
+
* `(database) => createInsightsModel(createHotUpdater({ database, storage,
|
|
479
|
+
* plugins: [insights()], clientAccess: "public" }).api.insights)`.
|
|
479
480
|
*/
|
|
480
481
|
declare const insightsTestSuite: <TDatabase = EngineDatabase>(options?: {
|
|
481
482
|
readonly createModel?: (database: TDatabase) => InsightsModel;
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
|
2
2
|
import { NIL_UUID, createReleaseCatalogScopeKey, encodeChannelKey, selectDesiredRelease } from "@hot-updater/protocol";
|
|
3
|
-
import { DATABASE_VERSION_COLUMN, DatabaseAdapterContractError, SETTINGS_TABLE, addDistinct, aggregateBatchingTables, assertStorageOperations, bundleToPatchRows, bundleToRow, compareUtf8, coreSchema, countDistinct, createBundleStorageKey, createEngine, createMemoryAdapter, createStorageKeyBuilder, createStorageRootUriWithPath, createStorageUri, createStorageUriWithRelativePath, findPhysicalIndex, getBundleArchiveStorageUri, getContentAddressedAssetStoragePath, indexOrderColumns, meterReads,
|
|
3
|
+
import { DATABASE_VERSION_COLUMN, DatabaseAdapterContractError, SETTINGS_TABLE, addDistinct, aggregateBatchingTables, assertStorageOperations, bundleToPatchRows, bundleToRow, compareUtf8, coreSchema, countDistinct, createBundleStorageKey, createEngine, createMemoryAdapter, createStorageKeyBuilder, createStorageRootUriWithPath, createStorageUri, createStorageUriWithRelativePath, findPhysicalIndex, getBundleArchiveStorageUri, getContentAddressedAssetStoragePath, indexOrderColumns, meterReads, parseStorageUri, targetBaseCandidateKey, toolingTargetOf, verifyAdapter } from "@hot-updater/plugin-core";
|
|
4
4
|
import { createServer } from "node:http";
|
|
5
5
|
//#region src/adminApiTestClient.ts
|
|
6
6
|
const jsonRequest = (method, body) => ({
|
|
@@ -1357,7 +1357,7 @@ const setupDatabaseTestSuite = (options) => {
|
|
|
1357
1357
|
beforeEach(async () => {
|
|
1358
1358
|
client = await options.createHttpClient({
|
|
1359
1359
|
database: getDatabase(),
|
|
1360
|
-
storage:
|
|
1360
|
+
storage: createReleaseCatalogTestStorage()
|
|
1361
1361
|
});
|
|
1362
1362
|
});
|
|
1363
1363
|
afterEach(async () => {
|
|
@@ -2469,7 +2469,7 @@ const storageCase = (title, operations, run) => ({
|
|
|
2469
2469
|
/**
|
|
2470
2470
|
* The storage adapter contract, from what its consumers rely on: deploy and
|
|
2471
2471
|
* patch (`put`, `get`, `exists`, `delete`), the Console, the server's update
|
|
2472
|
-
* responses and
|
|
2472
|
+
* responses and the URLs devices download from (`get`, `getDownloadUrl`), and
|
|
2473
2473
|
* `storage prune` (`listObjects`, `deleteObjects`).
|
|
2474
2474
|
*/
|
|
2475
2475
|
const storageAdapterTestCases = [
|
|
@@ -2639,17 +2639,13 @@ const storageAdapterTestCases = [
|
|
|
2639
2639
|
const { url } = await storage.getDownloadUrl({ storageUri });
|
|
2640
2640
|
const label = `getDownloadUrl("${storageUri}") returned "${url}"`;
|
|
2641
2641
|
expect(typeof url, label).toBe("string");
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
}
|
|
2649
|
-
continue;
|
|
2642
|
+
expect(/^https?:\/\//i.test(url), `${label}; a download URL must be an absolute http(s) URL`).toBe(true);
|
|
2643
|
+
expect(() => new URL(url), label).not.toThrow();
|
|
2644
|
+
if (fetchDownloadUrls) {
|
|
2645
|
+
const response = await fetch(url);
|
|
2646
|
+
expect(response.status, `${label}, which answered`).toBe(200);
|
|
2647
|
+
expectBytes(new Uint8Array(await response.arrayBuffer()), bytes, `${label}, whose download`);
|
|
2650
2648
|
}
|
|
2651
|
-
expect(parseStorageDownloadPath(url)?.storageUri, `${label}; a path must be the /storage/ path of the same URI`).toBe(storageUri);
|
|
2652
|
-
expect((await storage.getDownloadUrl({ storageUri })).url, `${label}, then another path`).toBe(url);
|
|
2653
2649
|
}
|
|
2654
2650
|
}),
|
|
2655
2651
|
storageCase("lists every object with its key relative to the base path", ["listObjects"], async ({ storage, basePath }) => {
|
|
@@ -2786,7 +2782,10 @@ const createMeasuredDatabase = async (adapter, plugins, options = {}) => {
|
|
|
2786
2782
|
});
|
|
2787
2783
|
const hotUpdater = createHotUpdater({
|
|
2788
2784
|
database,
|
|
2789
|
-
storage: options.storage === void 0 ?
|
|
2785
|
+
storage: options.storage === void 0 ? {
|
|
2786
|
+
name: "measuredStorage",
|
|
2787
|
+
protocol: "none"
|
|
2788
|
+
} : storageOf(options.storage),
|
|
2790
2789
|
plugins: observed,
|
|
2791
2790
|
...plugins.some((plugin) => plugin.provides?.clientAuth === true) ? {} : { clientAccess: "public" }
|
|
2792
2791
|
});
|
|
@@ -3481,11 +3480,7 @@ const setupReadBudgetTestSuite = (options) => {
|
|
|
3481
3480
|
let seeded;
|
|
3482
3481
|
let writes = 0;
|
|
3483
3482
|
beforeAll(async () => {
|
|
3484
|
-
const
|
|
3485
|
-
import("@hot-updater/server/plugins/insights"),
|
|
3486
|
-
import("@hot-updater/server/plugins/api-keys"),
|
|
3487
|
-
import("@hot-updater/server/plugins/remote-config")
|
|
3488
|
-
]);
|
|
3483
|
+
const { insights, apiKeys, remoteConfig } = await import("@hot-updater/server/plugins");
|
|
3489
3484
|
const plugins = [
|
|
3490
3485
|
insights(),
|
|
3491
3486
|
apiKeys(),
|
|
@@ -5206,8 +5201,9 @@ const setupInsightsHttpTestSuite = (options) => {
|
|
|
5206
5201
|
//#region src/insights/setupInsightsModelTestSuite.ts
|
|
5207
5202
|
/**
|
|
5208
5203
|
* The Insights report contract on one database: pass the Insights plugin's
|
|
5209
|
-
* model over it, `createInsightsModel(createHotUpdater({ database,
|
|
5210
|
-
* [insights()], clientAccess: "public" }).api.insights)`, as
|
|
5204
|
+
* model over it, `createInsightsModel(createHotUpdater({ database, storage,
|
|
5205
|
+
* plugins: [insights()], clientAccess: "public" }).api.insights)`, as
|
|
5206
|
+
* `createDatabase`.
|
|
5211
5207
|
*/
|
|
5212
5208
|
const setupInsightsModelTestSuite = (lifecycle) => {
|
|
5213
5209
|
describe(lifecycle.name, () => {
|
|
@@ -5236,8 +5232,8 @@ const setupInsightsModelTestSuite = (lifecycle) => {
|
|
|
5236
5232
|
* The Insights plugin's tests, for `setupDatabaseTestSuite`'s `plugins`: its
|
|
5237
5233
|
* HTTP routes on the provider's server, which must run `insights()`, and
|
|
5238
5234
|
* with `createModel` its report contract on the provider's database, such as
|
|
5239
|
-
* `(database) => createInsightsModel(createHotUpdater({ database,
|
|
5240
|
-
* [insights()], clientAccess: "public" }).api.insights)`.
|
|
5235
|
+
* `(database) => createInsightsModel(createHotUpdater({ database, storage,
|
|
5236
|
+
* plugins: [insights()], clientAccess: "public" }).api.insights)`.
|
|
5241
5237
|
*/
|
|
5242
5238
|
const insightsTestSuite = (options = {}) => ({
|
|
5243
5239
|
name: "Insights plugin",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hot-updater/test-utils",
|
|
3
|
-
"version": "1.0.0-rc.
|
|
3
|
+
"version": "1.0.0-rc.44",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Test utilities for Hot Updater packages",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -50,10 +50,10 @@
|
|
|
50
50
|
"mysql2": "*",
|
|
51
51
|
"pg": "*",
|
|
52
52
|
"vitest": "^4.0.0",
|
|
53
|
-
"@hot-updater/plugin-
|
|
54
|
-
"@hot-updater/protocol": "^1.0.0-rc.
|
|
55
|
-
"@hot-updater/
|
|
56
|
-
"@hot-updater/
|
|
53
|
+
"@hot-updater/plugin-core": "^1.0.0-rc.44",
|
|
54
|
+
"@hot-updater/protocol": "^1.0.0-rc.44",
|
|
55
|
+
"@hot-updater/server": "^1.0.0-rc.44",
|
|
56
|
+
"@hot-updater/plugin-insights": "^1.0.0-rc.44"
|
|
57
57
|
},
|
|
58
58
|
"peerDependenciesMeta": {
|
|
59
59
|
"@electric-sql/pglite": {
|
|
@@ -83,11 +83,11 @@
|
|
|
83
83
|
"typescript": "npm:@typescript/typescript6@6.0.2",
|
|
84
84
|
"vitest": "4.1.4",
|
|
85
85
|
"workspace-tools": "^0.41.7",
|
|
86
|
-
"@hot-updater/plugin-insights": "1.0.0-rc.
|
|
87
|
-
"@hot-updater/protocol": "1.0.0-rc.
|
|
88
|
-
"@hot-updater/
|
|
89
|
-
"@hot-updater/
|
|
90
|
-
"@hot-updater/
|
|
86
|
+
"@hot-updater/plugin-insights": "1.0.0-rc.44",
|
|
87
|
+
"@hot-updater/protocol": "1.0.0-rc.44",
|
|
88
|
+
"@hot-updater/js": "1.0.0-rc.44",
|
|
89
|
+
"@hot-updater/server": "1.0.0-rc.44",
|
|
90
|
+
"@hot-updater/plugin-core": "1.0.0-rc.44"
|
|
91
91
|
},
|
|
92
92
|
"inlinedDependencies": {
|
|
93
93
|
"@nodelib/fs.scandir": "2.1.5",
|