Fixed two critical data loss bugs where user-added custom endpoints were discarded: 1. **AddProviderDialog**: Form submission ignored values.meta from ProviderForm and re-inferred URLs only from presets/config, causing loss of endpoints added via speed test modal. Now prioritizes form-collected meta and uses fallback inference only when custom_endpoints is missing. 2. **ProviderForm**: Edit mode always returned initialData.meta, discarding any changes made in the speed test modal. Now uses mergeProviderMeta to properly merge customEndpointsMap with existing meta fields. Changes: - Extract mergeProviderMeta utility to handle meta field merging logic - Preserve other meta fields (e.g., usage_script) during endpoint updates - Unify new/edit code paths to use consistent meta handling - Add comprehensive unit tests for meta merging scenarios - Add integration tests for AddProviderDialog submission flow Impact: - Third-party and custom providers can now reliably manage multiple endpoints - Edit operations correctly reflect user modifications - No data loss for existing meta fields like usage_script
81 lines
2.2 KiB
TypeScript
81 lines
2.2 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import type { ProviderMeta } from "@/types";
|
|
import { mergeProviderMeta } from "@/utils/providerMetaUtils";
|
|
|
|
const buildEndpoint = (url: string) => ({
|
|
url,
|
|
addedAt: 1,
|
|
});
|
|
|
|
describe("mergeProviderMeta", () => {
|
|
it("returns undefined when no initial meta and no endpoints", () => {
|
|
expect(mergeProviderMeta(undefined, null)).toBeUndefined();
|
|
expect(mergeProviderMeta(undefined, undefined)).toBeUndefined();
|
|
});
|
|
|
|
it("creates meta when endpoints are provided for new provider", () => {
|
|
const result = mergeProviderMeta(undefined, {
|
|
"https://example.com": buildEndpoint("https://example.com"),
|
|
});
|
|
|
|
expect(result).toEqual({
|
|
custom_endpoints: {
|
|
"https://example.com": buildEndpoint("https://example.com"),
|
|
},
|
|
});
|
|
});
|
|
|
|
it("overrides custom endpoints but preserves other fields", () => {
|
|
const initial: ProviderMeta = {
|
|
usage_script: {
|
|
enabled: true,
|
|
language: "javascript",
|
|
code: "console.log(1);",
|
|
},
|
|
custom_endpoints: {
|
|
"https://old.com": buildEndpoint("https://old.com"),
|
|
},
|
|
};
|
|
|
|
const result = mergeProviderMeta(initial, {
|
|
"https://new.com": buildEndpoint("https://new.com"),
|
|
});
|
|
|
|
expect(result).toEqual({
|
|
usage_script: initial.usage_script,
|
|
custom_endpoints: {
|
|
"https://new.com": buildEndpoint("https://new.com"),
|
|
},
|
|
});
|
|
});
|
|
|
|
it("removes custom endpoints when result is empty but keeps other meta", () => {
|
|
const initial: ProviderMeta = {
|
|
usage_script: {
|
|
enabled: true,
|
|
language: "javascript",
|
|
code: "console.log(1);",
|
|
},
|
|
custom_endpoints: {
|
|
"https://example.com": buildEndpoint("https://example.com"),
|
|
},
|
|
};
|
|
|
|
const result = mergeProviderMeta(initial, null);
|
|
|
|
expect(result).toEqual({
|
|
usage_script: initial.usage_script,
|
|
});
|
|
});
|
|
|
|
it("returns undefined when removing last field", () => {
|
|
const initial: ProviderMeta = {
|
|
custom_endpoints: {
|
|
"https://example.com": buildEndpoint("https://example.com"),
|
|
},
|
|
};
|
|
|
|
expect(mergeProviderMeta(initial, null)).toBeUndefined();
|
|
});
|
|
});
|