Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
b71929d
Improve test coverage to ~100% for @azure/core-amqp
Apr 16, 2026
c38c099
Remove 'coverage' from test describe block names
Apr 17, 2026
e82f9dd
Clean up describe block names
Apr 17, 2026
b7c9744
Strengthen isDefined-only assertions with value checks
Apr 17, 2026
fca5a36
Extract repeated test constants into shared variables
Apr 17, 2026
ccc3967
Move imports to top level (vitest hoists vi.mock automatically)
Apr 17, 2026
bbfbe78
Format context.spec.ts
Apr 17, 2026
c02d0d8
Fix CI: remove intersection with private fields, fix unused imports
Apr 18, 2026
2acac63
fix: merge main and remove tests for deleted utils functions
Apr 18, 2026
cfdb9d1
fix: resolve no-shadow lint errors in test files
Apr 18, 2026
6a63caa
fix: strengthen assertions and remove line numbers in test names
Apr 18, 2026
fecc659
fix: improve assertion precision in core-amqp tests
Apr 18, 2026
c6d59eb
refactor: replace non-null assertions with safe const extraction in c…
Apr 19, 2026
294db6b
refactor: modernize error assertions and spy patterns in core-client-…
Apr 19, 2026
3147a81
refactor: modernize spy and error patterns in core-amqp tests
Apr 19, 2026
7445146
refactor: third pass modernization in core-amqp tests
Apr 19, 2026
d8ad111
fix: remove foreign package files from core-amqp branch
Apr 19, 2026
0944088
refactor: remove unnecessary type casts in core-rest-pipeline tests
Apr 20, 2026
7b9ea2a
refactor: remove unnecessary type casts in core-amqp tests
Apr 20, 2026
c5689ae
Eliminate unnecessary type casts from core-amqp test files
Apr 20, 2026
a9bcd33
fix: restore foreign pipeline.spec.ts to main version
Apr 20, 2026
c5e6ca9
fix: resolve lint errors from cast elimination
Apr 20, 2026
c53141b
address PR feedback: skipIf(isBrowser), restore prototype spies, fix …
Apr 20, 2026
9f81b9a
move node-only requestResponse tests to test/internal/node/
Apr 20, 2026
e1c24bc
rename duplicate test names in cbs.spec.ts for clarity
Apr 20, 2026
cf4466e
trigger CI re-run
Apr 20, 2026
424dc33
fix: align test title to cover all three methods tested in context.sp…
Apr 21, 2026
f524a11
fix: remove foreign core-client files from amqp branch
Apr 21, 2026
6fc4b1d
Fix test titles to match actual assertions in cbs and retry tests
Apr 21, 2026
59472f2
Replace isAbove(x.length, 0) with isNotEmpty/toHaveBeenCalled
Apr 21, 2026
e52267f
Address Jeremy review feedback on core-amqp tests
Apr 23, 2026
ca8b316
Apply broad feedback patterns across amqp tests
Apr 23, 2026
63dadbc
Strengthen abort listener removal assertion per review feedback
Apr 23, 2026
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import { describe, it, assert } from "vitest";
import { checkNetworkConnection } from "../../../src/util/checkNetworkConnection.common.js";

describe("checkNetworkConnection (browser)", function () {
it("returns a boolean reflecting navigator.onLine", async function () {
const result = await checkNetworkConnection("hostname.example.com");
assert.isBoolean(result);
// In a browser test environment, navigator.onLine should be true
assert.equal(result, self.navigator.onLine);
});
});
28 changes: 28 additions & 0 deletions sdk/core/core-amqp/test/internal/browser/errors.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import { describe, it, assert } from "vitest";
import { translate, MessagingError } from "../../../src/errors.js";

describe("translate - isBrowserWebsocketError (browser)", function () {
it("translates a WebSocket error event into a MessagingError", function () {
const ws = Object.create(WebSocket.prototype);
const errorEvent = new Event("error");
Object.defineProperty(errorEvent, "target", { value: ws, writable: false });

const result = translate(errorEvent);

assert.instanceOf(result, MessagingError);
assert.equal(result.code, "ServiceCommunicationError");
assert.isFalse(result.retryable);
assert.include(result.message, "Websocket");
});

it("does not treat a plain error as a browser websocket error", function () {
const plainError = new Error("not a websocket error");
const result = translate(plainError);

// A plain Error should be returned as-is, not wrapped as ServiceCommunicationError
assert.equal(result, plainError);
});
});
28 changes: 28 additions & 0 deletions sdk/core/core-amqp/test/internal/browser/hmacSha256.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import { describe, it, assert } from "vitest";
import { signString } from "../../../src/util/hmacSha256.common.js";

describe("signString (browser - Web Crypto)", function () {
it("produces a URL-encoded base64 HMAC-SHA256 signature", async function () {
const signature = await signString("testKey", "testMessage");
assert.strictEqual(signature, "8N7PlLvnGgnE2gFU7%2BAkSxmAc02cXFkOLlFD5gTuOjo%3D");
assert.strictEqual(
decodeURIComponent(signature),
"8N7PlLvnGgnE2gFU7+AkSxmAc02cXFkOLlFD5gTuOjo=",
);
});

it("returns consistent results for the same inputs", async function () {
const sig1 = await signString("key", "data");
const sig2 = await signString("key", "data");
assert.equal(sig1, sig2);
});

it("returns different results for different keys", async function () {
const sig1 = await signString("key1", "data");
const sig2 = await signString("key2", "data");
assert.notEqual(sig1, sig2);
});
});
18 changes: 18 additions & 0 deletions sdk/core/core-amqp/test/internal/browser/runtimeInfo.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import { describe, it, assert } from "vitest";
import { getPlatformInfo, getFrameworkInfo } from "../../../src/util/runtimeInfo-browser.mjs";

describe("runtimeInfo (browser)", function () {
it("getPlatformInfo returns a string containing 'javascript-Browser'", function () {
const info = getPlatformInfo();
assert.include(info, "javascript-Browser");
assert.match(info, /^\(javascript-Browser-.+\)$/);
});

it("getFrameworkInfo returns a string starting with 'Browser/'", function () {
const info = getFrameworkInfo();
assert.match(info, /^Browser\/.+/);
});
});
66 changes: 57 additions & 9 deletions sdk/core/core-amqp/test/internal/errors.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ describe("Errors", function () {
];

for (let i = 0; i < cases.length; i++) {
const translatedError = Errors.translate(cases[i].input as any);
const translatedError = Errors.translate(cases[i].input);

assert.equal(translatedError.name, "Error");
assert.equal(
Expand Down Expand Up @@ -68,20 +68,22 @@ describe("Errors", function () {
"'Error: getaddrinfo ENOTFOUND example.invalid\n at GetAddrInfoReqWrap.onlookupall [as oncomplete] (node:dns:118:26)\n at GetAddrInfoReqWrap.callbackTrampoline (node:internal/async_hooks:130:17)'",
},
};
const translatedError = Errors.translate(testError) as Errors.MessagingError;
const translatedError = Errors.translate(testError);
assert.instanceOf(translatedError, Errors.MessagingError);
assert.equal(testError.error.message, translatedError.message);
assert.equal(translatedError.name, "MessagingError");
assert.equal(translatedError.code, "ENOTFOUND");
assert.equal(translatedError.code, testError.error.code);
assert.equal(translatedError.message, testError.error.message);
assert.equal(translatedError.stack, testError.error.stack);
assert.equal(translatedError.retryable, false);
assert.isFalse(translatedError.retryable);
});

it("Sets retryable to true, if input is custom error and name is OperationTimeoutError", function () {
const err = new Error("error message");
err.name = "OperationTimeoutError";
const translatedError = Errors.translate(err) as Errors.MessagingError;
const translatedError = Errors.translate(err);
assert.instanceOf(translatedError, Errors.MessagingError);
assert.equal(translatedError.name, "MessagingError");
assert.equal(translatedError.code, "OperationTimeoutError");
assert.equal(translatedError.message, err.message);
Expand All @@ -92,7 +94,8 @@ describe("Errors", function () {
it("Sets retryable to true, if input is custom error and name is InsufficientCreditError", function () {
const err = new Error("error message");
err.name = "InsufficientCreditError";
const translatedError = Errors.translate(err) as Errors.MessagingError;
const translatedError = Errors.translate(err);
assert.instanceOf(translatedError, Errors.MessagingError);
assert.equal(translatedError.name, "MessagingError");
assert.equal(translatedError.code, "InsufficientCreditError");
assert.equal(translatedError.message, err.message);
Expand All @@ -103,7 +106,8 @@ describe("Errors", function () {
it("Does not sets retryable to true, if input is custom error and name is SendOperationFailedError", function () {
const err = new Error("error message");
err.name = "SendOperationFailedError";
const translatedError = Errors.translate(err) as Errors.MessagingError;
const translatedError = Errors.translate(err);
assert.instanceOf(translatedError, Errors.MessagingError);
assert.equal(translatedError.name, "MessagingError");
assert.equal(translatedError.code, "SendOperationFailedError");
assert.equal(translatedError.message, err.message);
Expand All @@ -117,7 +121,7 @@ describe("Errors", function () {
assert.equal(translatedError.name, "AbortError");
assert.equal(translatedError.message, err.message);
assert.equal(translatedError.stack, err.stack);
assert.isUndefined((translatedError as Errors.MessagingError).retryable);
assert.notInstanceOf(translatedError, Errors.MessagingError);
});

[
Expand All @@ -140,7 +144,8 @@ describe("Errors", function () {
].forEach(function (mapping) {
it("translates " + mapping.from + " into " + mapping.to, function () {
const err: any = new AMQPError(mapping.from, mapping.message);
const translatedError = Errors.translate(err) as Errors.MessagingError;
const translatedError = Errors.translate(err);
assert.instanceOf(translatedError, Errors.MessagingError);
// <unknown> won't have a code since it has no matching condition
if (translatedError.code) {
assert.equal(translatedError.code, mapping.to);
Expand Down Expand Up @@ -206,7 +211,8 @@ describe("Errors", function () {
it(
"SystemError from node.js with code: '" + mapping.code + "' to a MessagingError",
function () {
const translatedError = Errors.translate(mapping as any) as Errors.MessagingError;
const translatedError = Errors.translate(mapping);
assert.instanceOf(translatedError, Errors.MessagingError);
assert.equal(translatedError.name, "MessagingError");
assert.equal(translatedError.code, mapping.code);
if (
Expand All @@ -223,3 +229,45 @@ describe("Errors", function () {
});
});
});

describe("errors.ts", () => {
it("translate maps AMQP error with status-code: 404 in description to MessagingEntityNotFoundError", () => {
const err: any = {
name: "AmqpProtocolError",
condition: "amqp:not-found",
description: "The messaging entity blah could not be found. status-code: 404",
};
const translated = Errors.translate(err);
assert.instanceOf(translated, Errors.MessagingError);
assert.equal(translated.code, "MessagingEntityNotFoundError");
});

it("translate maps AMQP error with 'messaging entity could not be found' to MessagingEntityNotFoundError", () => {
const err: any = {
name: "AmqpProtocolError",
condition: "amqp:not-found",
description: "The messaging entity 'myentity' could not be found.",
};
const translated = Errors.translate(err);
assert.instanceOf(translated, Errors.MessagingError);
assert.equal(translated.code, "MessagingEntityNotFoundError");
});

it("translate handles already-translated MessagingError", () => {
const err = new Errors.MessagingError("already translated");
const translated = Errors.translate(err);
assert.strictEqual(translated, err);
});

it("translate handles MessageWaitTimeout condition", () => {
const err: any = {
name: "AmqpProtocolError",
condition: "com.microsoft:message-wait-timeout",
description: "No messages available",
};
const translated = Errors.translate(err);
assert.instanceOf(translated, Errors.MessagingError);
assert.equal(translated.name, "MessagingError");
assert.equal(translated.code, "MessageWaitTimeout");
});
});
Loading