Skip to content

Conversation

@dfrankland
Copy link
Member

Testing for fetches is a bit difficult with "normal" mocks since we there's no built-in way of mocking some read-only properties of the Response class. In our case, redirects add a property url which cannot be generated without mocking the entire class, but msw already does this for us and is a better way of mocking in general.

Copy link
Member Author

Choose a reason for hiding this comment

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

I just improved the type inference for all these mocks. I was having issues when trying to mock things properly without them.

repo: {
owner: "repo-owner",
name: "repo-name",
repo: "repo-name",
Copy link
Member Author

@dfrankland dfrankland Jan 16, 2026

Choose a reason for hiding this comment

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

This wasn't mocked correctly, and the tests didn't catch it. I added tests for it now in telemetry.test.ts

Comment on lines +43 to +52
export interface MockResponseBuilder<T extends unknown[], U extends unknown[]> {
addSuccessfulResponse: (...options: T) => MockResponseBuilder<T, U>;
addErrorResponse: (...options: U) => MockResponseBuilder<T, U>;
build: () => {
handler: HttpHandler;
mock: jest.Mock<(request: Request) => void>;
};
}

const mockResponseBuilder = <T extends unknown[], U extends unknown[]>({
Copy link
Member Author

Choose a reason for hiding this comment

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

This is a little fancy, but it make writing msw mocks so much nicer

Comment on lines -40 to -87
describe("fetchApiAddress", () => {
const oldEnv = process.env;

beforeEach(() => {
jest.resetModules();
process.env = oldEnv;
});

afterEach(() => {
process.env = oldEnv;
});

it("defaults to prod if there is no address", () => {
delete process.env.TRUNK_PUBLIC_API_ADDRESS;
expect(fetchApiAddress()).toBe("https://api.trunk.io");
});

it("uses the provided address", () => {
process.env.TRUNK_PUBLIC_API_ADDRESS = "https://myFancyDeploy.trunk.ca";
expect(fetchApiAddress()).toBe("https://myFancyDeploy.trunk.ca");
});
});

describe("convertToTelemetry", () => {
it("falls back to prod when given an invalid address", () => {
expect(convertToTelemetry("html://notADomain.oops")).toBe(
"https://telemetry.api.trunk.io/v1/flakytests-uploader/upload-metrics",
);
});

it("adapts a prod address", () => {
expect(convertToTelemetry("https://api.trunk.io")).toBe(
"https://telemetry.api.trunk.io/v1/flakytests-uploader/upload-metrics",
);
});

it("adapts a prod address with an extra slash", () => {
expect(convertToTelemetry("https://api.trunk.io/")).toBe(
"https://telemetry.api.trunk.io/v1/flakytests-uploader/upload-metrics",
);
});

it("adapts a devenv", () => {
expect(convertToTelemetry("https://api.dev1.trunk-staging.io")).toBe(
"https://telemetry.api.dev1.trunk-staging.io/v1/flakytests-uploader/upload-metrics",
);
});
});
Copy link
Member Author

Choose a reason for hiding this comment

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

Moved to telemetry.test.ts

Copy link
Member Author

Choose a reason for hiding this comment

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

Why the massive decrease in size? I added a minify flag. This should greatly improve the time it takes to download the repo

"type": "module",
"scripts": {
"build": "rm -rf dist && ncc build src/index.ts -o dist",
"build": "rm -rf dist && ncc build -m src/index.ts -o dist",
Copy link
Member Author

Choose a reason for hiding this comment

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

this is a flag for minifying

Comment on lines -16 to -17
"@jest/globals": "^29.7.0",
"@vercel/ncc": "^0.38.3",
Copy link
Member Author

Choose a reason for hiding this comment

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

moved to devDependencies

Comment on lines -18 to -21
"promise-retry": "^2.0.1",
"protobufjs": "^7.5.3",
"retry": "^0.13.1",
"ts-protoc-gen": "^0.15.0"
Copy link
Member Author

Choose a reason for hiding this comment

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

  • exponential-backoff replaced promise-retry and retry
  • ts-protoc-gen was unused

"eslint-plugin-jest": "^28.9.0",
"jest": "^29.7.0",
"jest-junit": "^16.0.0",
"protoc-gen-js": "3.21.4-4",
Copy link
Member Author

Choose a reason for hiding this comment

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

unused

"protoc-gen-js": "3.21.4-4",
"msw": "^2.12.7",
"ts-jest": "^29.2.5",
"ts-node": "^10.9.2",
Copy link
Member Author

Choose a reason for hiding this comment

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

unused

@dfrankland dfrankland force-pushed the dylan/add-fetch-retries branch from 6b9df9f to 7d35426 Compare January 16, 2026 20:29
jest.unstable_mockModule("@actions/core", () => core);
jest.unstable_mockModule("@actions/github", () => github);

const { sendTelemetry } = await import("../src/telemetry/index.js");
Copy link
Member Author

Choose a reason for hiding this comment

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

IMO we should only test the interfaces defined in the application. This provides more coverage and realistic testing

Copy link
Member Author

Choose a reason for hiding this comment

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

combined into telemetry.test.ts

Comment on lines +185 to +199
telemetryUploadMock.mock.calls.map(async ([request]) => {
const buffer = await request.arrayBuffer();
const message = UploaderUploadMetrics.decode(
new Uint8Array(buffer),
).toJSON();
expect(message).toStrictEqual({
failed: false,
repo: {
owner: github.context.repo.owner,
name: github.context.repo.repo,
host: "github.com",
},
uploader_version: expectedUploaderVersion,
});
}),
Copy link
Member Author

Choose a reason for hiding this comment

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

woo, testing payloads!

Copy link
Member Author

Choose a reason for hiding this comment

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

Mostly moved from telemetry.ts. I split out protos.ts because we don't need to define the schema during call execution and reusing the schema in tests is needed

@dfrankland dfrankland merged commit 293e9b1 into main Jan 16, 2026
8 checks passed
@dfrankland dfrankland deleted the dylan/add-fetch-retries branch January 16, 2026 23:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants