Skip to content

Commit

Permalink
Standardize timestamp creation (#8892)
Browse files Browse the repository at this point in the history
  • Loading branch information
twschiller authored Jul 22, 2024
1 parent 3992a23 commit 56f71c0
Show file tree
Hide file tree
Showing 26 changed files with 113 additions and 78 deletions.
1 change: 1 addition & 0 deletions scripts/manifest.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ function getVersionName(env, isProduction) {
return `${env.npm_package_version}`;
}

// Can't use nowTimestamp helper in webpack helpers
return `${env.npm_package_version}-local+${new Date().toISOString()}`;
}

Expand Down
7 changes: 4 additions & 3 deletions src/activation/getActivatedModComponentFromDefinition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import type {
import type { Deployment } from "@/types/contract";
import type { OptionsArgs } from "@/types/runtimeTypes";
import type { IntegrationDependency } from "@/integrations/integrationTypes";
import { nowTimestamp } from "@/utils/timeUtils";

export type ActivateModComponentParam = {
modComponentDefinition: ModComponentDefinition;
Expand Down Expand Up @@ -55,7 +56,7 @@ export function getActivatedModComponentFromDefinition<
optionsArgs,
integrationDependencies,
}: ActivateModComponentParam): ActivatedModComponent<Config> {
const nowTimestamp = new Date().toISOString();
const timestamp = nowTimestamp();

const activatedModComponent = {
id: uuidv4(),
Expand All @@ -70,8 +71,8 @@ export function getActivatedModComponentFromDefinition<
extensionPointId: modComponentDefinition.id,
config: modComponentDefinition.config as Config,
active: true,
createTimestamp: nowTimestamp,
updateTimestamp: nowTimestamp,
createTimestamp: timestamp,
updateTimestamp: timestamp,
} as ActivatedModComponent<Config>;

// Set optional fields only if the source mod component has a value. Normalizing the values
Expand Down
3 changes: 2 additions & 1 deletion src/bricks/readers/DocumentReader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import { ReaderABC } from "@/types/bricks/readerTypes";
import { type Schema } from "@/types/schemaTypes";
import { isLoadedInIframe } from "@/utils/iframeUtils";
import { nowTimestamp } from "@/utils/timeUtils";

class DocumentReader extends ReaderABC {
override defaultOutputKey = "context";
Expand All @@ -34,7 +35,7 @@ class DocumentReader extends ReaderABC {
return {
url: document.location.href,
title: document.title,
timestamp: new Date().toISOString(),
timestamp: nowTimestamp(),
isFrame: isLoadedInIframe(),
};
}
Expand Down
9 changes: 6 additions & 3 deletions src/contentScript/lifecycle.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ import { RootReader, tick } from "@/starterBricks/starterBrickTestUtils";
import brickRegistry from "@/bricks/registry";
import { hydrateModComponentInnerDefinitions } from "@/registry/hydrateInnerDefinitions";

import { uuidSequence } from "@/testUtils/factories/stringFactories";
import {
timestampFactory,
uuidSequence,
} from "@/testUtils/factories/stringFactories";
import { type getModComponentState } from "@/store/extensionsStorage";
import { getPlatform } from "@/platform/platformContext";
import { StarterBrickTypes } from "@/types/starterBrickTypes";
Expand Down Expand Up @@ -79,8 +82,8 @@ const activatedModComponentFactory = define<
action: () => [] as BrickPipeline,
}),
_serializedModComponentBrand: null,
createTimestamp: new Date().toISOString(),
updateTimestamp: new Date().toISOString(),
createTimestamp: timestampFactory,
updateTimestamp: timestampFactory,
active: true,
});

Expand Down
11 changes: 8 additions & 3 deletions src/contrib/automationanywhere/RunApiTask.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,14 @@ import { autoUUIDSequence } from "@/testUtils/factories/stringFactories";
import { sleep } from "@/utils/timeUtils";
import { type NetworkRequestConfig } from "@/types/networkTypes";

jest.mock("@/utils/timeUtils", () => ({
sleep: jest.fn(() => {}),
}));
jest.mock("@/utils/timeUtils", () => {
const actual = jest.requireActual("@/utils/timeUtils");

return {
...actual,
sleep: jest.fn(() => {}),
};
});

const sleepMock = jest.mocked(sleep);

Expand Down
4 changes: 2 additions & 2 deletions src/data/service/errorService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,10 @@ import { type SerializedError } from "@/types/messengerTypes";
import { type SemVerString } from "@/types/registryTypes";
import { type MessageContext } from "@/types/loggerTypes";
import { isObject } from "@/utils/objectUtils";
import type { Timestamp } from "@/types/stringTypes";
import { flagOn } from "@/auth/featureFlagStorage";
import { selectAbsoluteUrl } from "@/utils/urlUtils";
import { getExtensionVersion } from "@/utils/extensionUtils";
import { nowTimestamp } from "@/utils/timeUtils";

const EVENT_BUFFER_DEBOUNCE_MS = 2000;
const EVENT_BUFFER_MAX_MS = 10_000;
Expand Down Expand Up @@ -166,7 +166,7 @@ export async function reportToErrorService(
user_agent_extension_version: extensionVersion,
is_application_error: !selectSpecificError(error, BusinessError),
error_data: data,
timestamp: new Date().toISOString() as Timestamp,
timestamp: nowTimestamp(),
};

// For blueprint_version/service_version/brick_version the server can't handle null value. Must leave the property
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ import {
import { packageConfigDetailFactory } from "@/testUtils/factories/brickFactories";
import { ExtensionNotLinkedError } from "@/errors/genericErrors";
import extensionsSlice from "@/store/extensionsSlice";
import { validateTimestamp } from "@/types/helpers";
import { type ModDefinition } from "@/types/modDefinitionTypes";
import { type Deployment } from "@/types/contract";
import { validateTimestamp } from "@/utils/timeUtils";

const axiosMock = new MockAdapter(axios);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import {
import { type RootState } from "@/store/optionsStore";
import { authStateFactory } from "@/testUtils/factories/authFactories";
import { standaloneModDefinitionFactory } from "@/testUtils/factories/modComponentFactories";
import { timestampFactory } from "@/testUtils/factories/stringFactories";

jest.mock("@/modDefinitions/modDefinitionHooks", () => ({
useAllModDefinitions: jest.fn().mockReturnValue({ refetch: jest.fn() }),
Expand Down Expand Up @@ -135,7 +136,7 @@ describe("it renders", () => {
unwrap: jest.fn().mockResolvedValue({
public: false,
organizations: [],
updated_at: new Date().toISOString(),
updated_at: timestampFactory(),
}),
}),
] as any);
Expand Down
3 changes: 2 additions & 1 deletion src/extensionConsole/pages/settings/useDiagnostics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import useUserAction from "@/hooks/useUserAction";
import download from "downloadjs";
import filenamify from "filenamify";
import { getExtensionVersion } from "@/utils/extensionUtils";
import { nowTimestamp } from "@/utils/timeUtils";

async function collectDiagnostics({
extensions,
Expand Down Expand Up @@ -79,7 +80,7 @@ function useDiagnostics() {

download(
JSON.stringify(data),
filenamify(`diagnostics-${new Date().toISOString()}.json`),
filenamify(`diagnostics-${nowTimestamp()}.json`),
"application/json",
);
},
Expand Down
8 changes: 4 additions & 4 deletions src/mods/useMods.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
import { renderHook } from "@/extensionConsole/testHelpers";
import useMods from "@/mods/useMods";
import extensionsSlice from "@/store/extensionsSlice";
import { validateTimestamp } from "@/types/helpers";
import { useAllModDefinitions } from "@/modDefinitions/modDefinitionHooks";
import { range } from "lodash";
import { appApiMock } from "@/testUtils/appApiMock";
Expand All @@ -37,6 +36,7 @@ import {
DefinitionKinds,
type InnerDefinitionRef,
} from "@/types/registryTypes";
import { timestampFactory } from "@/testUtils/factories/stringFactories";

jest.mock("@/modDefinitions/modDefinitionHooks");

Expand Down Expand Up @@ -72,7 +72,7 @@ describe("useMods", () => {
activatedModComponentFactory({
_recipe: {
...metadataFactory(),
updated_at: validateTimestamp(new Date().toISOString()),
updated_at: timestampFactory(),
sharing: { public: false, organizations: [] },
},
}),
Expand Down Expand Up @@ -104,7 +104,7 @@ describe("useMods", () => {
activatedModComponentFactory({
_recipe: {
...metadata,
updated_at: validateTimestamp(new Date().toISOString()),
updated_at: timestampFactory(),
sharing: { public: false, organizations: [] },
},
}),
Expand Down Expand Up @@ -141,7 +141,7 @@ describe("useMods", () => {
activatedModComponentFactory({
_recipe: {
...metadata,
updated_at: validateTimestamp(new Date().toISOString()),
updated_at: timestampFactory(),
sharing: { public: false, organizations: [] },
},
}),
Expand Down
7 changes: 3 additions & 4 deletions src/pageEditor/hooks/useUpsertModComponentFormState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@ import { selectSessionId } from "@/pageEditor/store/session/sessionSelectors";
import { type ModComponentFormState } from "@/pageEditor/starterBricks/formStateTypes";
import { isSingleObjectBadRequestError } from "@/errors/networkErrorHelpers";
import { ensureModComponentFormStatePermissionsFromUserGesture } from "@/pageEditor/editorPermissionsHelpers";
import { type Timestamp, type UUID } from "@/types/stringTypes";

import { type UUID } from "@/types/stringTypes";
import { isInnerDefinitionRegistryId } from "@/types/helpers";
import { DefinitionKinds, type RegistryId } from "@/types/registryTypes";
import { reloadModsEveryTab } from "@/contentScript/messenger/api";
import { assertNotNullish } from "@/utils/nullishUtils";
import { adapterForComponent } from "@/pageEditor/starterBricks/adapter";
import { nowTimestamp } from "@/utils/timeUtils";

const { saveModComponent } = modComponentsSlice.actions;
const { markClean } = editorSlice.actions;
Expand Down Expand Up @@ -181,8 +181,7 @@ function useUpsertModComponentFormState(): SaveCallback {

try {
let modComponent = selectModComponent(modComponentFormState);
const updateTimestamp: Timestamp =
new Date().toISOString() as Timestamp;
const updateTimestamp = nowTimestamp();

if (hasInnerStarterBrick) {
const { definition } = selectStarterBrickDefinition(
Expand Down
3 changes: 2 additions & 1 deletion src/runtime/reducePipeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ import type { Brick } from "@/types/brickTypes";
import getType from "@/runtime/getType";
import { getPlatform } from "@/platform/platformContext";
import { type Nullishable, assertNotNullish } from "@/utils/nullishUtils";
import { nowTimestamp } from "@/utils/timeUtils";

// Introduce a layer of indirection to avoid cyclical dependency between runtime and registry
// eslint-disable-next-line local-rules/persistBackgroundData -- Static
Expand Down Expand Up @@ -715,7 +716,7 @@ export async function brickReducer(
// Always add the trace entry, even if the brick didn't run
getPlatform().debugger.traces.enter({
...traceMeta,
timestamp: new Date().toISOString(),
timestamp: nowTimestamp(),
templateContext: context as JsonObject,
renderError: renderError ? serializeError(renderError) : null,
// `renderedArgs` will be null if there's an error rendering args
Expand Down
4 changes: 2 additions & 2 deletions src/sidebar/DefaultContent.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ import DefaultPanel from "./DefaultPanel";
import extensionsSlice from "@/store/extensionsSlice";
import { type ActivatedModComponent } from "@/types/modComponentTypes";
import { modComponentFactory } from "@/testUtils/factories/modComponentFactories";
import { type Timestamp } from "@/types/stringTypes";
import { appApiMock } from "@/testUtils/appApiMock";
import { timestampFactory } from "@/testUtils/factories/stringFactories";

describe("renders DefaultPanel", () => {
it("renders Page Editor call to action", () => {
Expand All @@ -42,7 +42,7 @@ describe("renders DefaultPanel", () => {
extensionsSlice.actions.saveModComponent({
modComponent: {
...(modComponentFactory() as ActivatedModComponent),
updateTimestamp: new Date().toISOString() as Timestamp,
updateTimestamp: timestampFactory(),
},
}),
);
Expand Down
4 changes: 2 additions & 2 deletions src/store/enterprise/managedStorage.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {
readManagedStorage,
readManagedStorageByKey,
} from "@/store/enterprise/managedStorage";
import type { Timestamp } from "@/types/stringTypes";
import { timestampFactory } from "@/testUtils/factories/stringFactories";

beforeEach(async () => {
jest.clearAllMocks();
Expand All @@ -31,7 +31,7 @@ beforeEach(async () => {

describe("readManagedStorage", () => {
it("reads immediately if managed storage is already initialized", async () => {
await initializationTimestamp.set(new Date().toISOString() as Timestamp);
await initializationTimestamp.set(timestampFactory());
await expect(readManagedStorage()).resolves.toStrictEqual({});

// Should only be called once vs. polling
Expand Down
3 changes: 2 additions & 1 deletion src/store/enterprise/managedStorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import { mergeSignals, ReusableAbortController } from "abort-utils";
import { StorageItem } from "webext-storage";
import type { Timestamp } from "@/types/stringTypes";
import { PromiseCancelled } from "@/errors/genericErrors";
import { nowTimestamp } from "@/utils/timeUtils";

// 1.8.9: bumped to 4.5s because 2s was too short: https://github.com/pixiebrix/pixiebrix-extension/issues/7618
// Privacy Badger uses 4.5s timeout, but thinks policy should generally be available within 2.5s. In installer.ts,
Expand Down Expand Up @@ -216,7 +217,7 @@ const waitForInitialManagedStorage = pMemoize(async () => {
}

// Set timestamp so other callsites know they don't have to wait again. OK to set multiple times
await initializationTimestamp.set(new Date().toISOString() as Timestamp);
await initializationTimestamp.set(nowTimestamp());
}

managedStorageStateChange.emit(managedStorageSnapshot);
Expand Down
3 changes: 2 additions & 1 deletion src/store/extensionsMigrations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {
} from "@/store/extensionsTypes";
import { omit } from "lodash";
import { migrateIntegrationDependenciesV1toV2 } from "@/store/editorMigrations";
import { nowTimestamp } from "@/utils/timeUtils";

export const migrations: MigrationManifest = {
// Redux-persist defaults to version: -1; Initialize to 0-indexed
Expand Down Expand Up @@ -73,7 +74,7 @@ function migrateModComponentStateV0ToV1(
function migrateModComponentStateV1ToV2(
state: ModComponentStateV1 & PersistedState,
): ModComponentStateV2 & PersistedState {
const now = new Date().toISOString();
const now = nowTimestamp();
return {
...state,
extensions: state.extensions.map((x) => ({
Expand Down
10 changes: 6 additions & 4 deletions src/testUtils/factories/databaseFactories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@

import { define } from "cooky-cutter";
import { type Database } from "@/types/contract";
import { uuidSequence } from "@/testUtils/factories/stringFactories";
import type { Timestamp } from "@/types/stringTypes";
import {
timestampFactory,
uuidSequence,
} from "@/testUtils/factories/stringFactories";

export const databaseFactory = define<Database>({
id: uuidSequence,
name: (n: number) => `Test Database ${n}`,
created_at: () => new Date().toISOString() as Timestamp,
last_write_at: () => new Date().toISOString() as Timestamp,
created_at: timestampFactory,
last_write_at: timestampFactory,
});
7 changes: 2 additions & 5 deletions src/testUtils/factories/deploymentFactories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,10 @@ import { define, derive, type FactoryConfig } from "cooky-cutter";
import { type Deployment } from "@/types/contract";
import { type ActivatableDeployment } from "@/types/deploymentTypes";
import { uuidSequence } from "@/testUtils/factories/stringFactories";
import {
validateRegistryId,
normalizeSemVerString,
validateTimestamp,
} from "@/types/helpers";
import { validateRegistryId, normalizeSemVerString } from "@/types/helpers";
import { defaultModDefinitionFactory } from "@/testUtils/factories/modDefinitionFactories";
import { type ModDefinition } from "@/types/modDefinitionTypes";
import { validateTimestamp } from "@/utils/timeUtils";

// Deployments are returned from the API, but their shape is determined by the registry and ModDefinition type.

Expand Down
3 changes: 2 additions & 1 deletion src/testUtils/factories/modComponentFactories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import {
uuidSequence,
} from "@/testUtils/factories/stringFactories";
import { type ApiVersion } from "@/types/runtimeTypes";
import { validateRegistryId, validateTimestamp } from "@/types/helpers";
import { validateRegistryId } from "@/types/helpers";
import { type IntegrationDependency } from "@/integrations/integrationTypes";
import { sharingDefinitionFactory } from "@/testUtils/factories/registryFactories";
import { metadataFactory } from "@/testUtils/factories/metadataFactory";
Expand All @@ -41,6 +41,7 @@ import {
} from "@/types/registryTypes";
import { assertNotNullish } from "@/utils/nullishUtils";
import { getStandaloneModComponentRuntimeModId } from "@/utils/modUtils";
import { validateTimestamp } from "@/utils/timeUtils";

export const modComponentRefFactory = define<ModComponentRef>({
// Don't repeat UUIDs across contexts
Expand Down
3 changes: 2 additions & 1 deletion src/testUtils/factories/modDefinitionFactories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import { type Permissions } from "webextension-polyfill";
import { emptyPermissionsFactory } from "@/permissions/permissionsUtils";
import { type BrickPipeline } from "@/bricks/types";
import { sharingDefinitionFactory } from "@/testUtils/factories/registryFactories";
import { validateRegistryId, validateTimestamp } from "@/types/helpers";
import { validateRegistryId } from "@/types/helpers";
import {
type StarterBrickDefinitionLike,
type StarterBrickDefinitionProp,
Expand All @@ -46,6 +46,7 @@ import {
import { freshIdentifier } from "@/utils/variableUtils";
import { metadataFactory } from "@/testUtils/factories/metadataFactory";
import { type Availability } from "@/types/availabilityTypes";
import { validateTimestamp } from "@/utils/timeUtils";

export const modComponentDefinitionFactory = define<ModComponentDefinition>({
id: "extensionPoint" as InnerDefinitionRef,
Expand Down
Loading

0 comments on commit 56f71c0

Please sign in to comment.