Files
heygo/tests/templates.test.ts

133 lines
4.2 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import { resolveTemplateUrl, TemplateResolutionError } from '../worker/lib/templates';
function params(query = ''): URLSearchParams {
return new URLSearchParams(query);
}
describe('resolveTemplateUrl', () => {
it('returns a URL without template placeholders unchanged', () => {
expect(
resolveTemplateUrl({
targetUrl: 'https://example.com/static/path?x=1#hash',
query: params(),
}),
).toBe('https://example.com/static/path?x=1#hash');
});
it('uses a default value when no override is provided', () => {
expect(
resolveTemplateUrl({
targetUrl: 'https://google.com/search?q={query,default=hello}',
query: params(),
}),
).toBe('https://google.com/search?q=hello');
});
it('uses pathParam for the first template variable', () => {
expect(
resolveTemplateUrl({
targetUrl: 'https://en.wikipedia.org/wiki/{topic,default=Python}',
pathParam: 'Django',
query: params(),
}),
).toBe('https://en.wikipedia.org/wiki/Django');
});
it('reuses pathParam for repeated occurrences of the first template variable', () => {
expect(
resolveTemplateUrl({
targetUrl: 'https://example.com/{query}/{query}',
pathParam: 'foo bar',
query: params(),
}),
).toBe('https://example.com/foo%20bar/foo%20bar');
});
it('lets matching query params override pathParam for all repeated occurrences', () => {
expect(
resolveTemplateUrl({
targetUrl: 'https://example.com/{query}/{query}',
pathParam: 'from-path',
query: params('query=from query'),
}),
).toBe('https://example.com/from%20query/from%20query');
});
it('reuses a default value for repeated occurrences of the same template variable', () => {
expect(
resolveTemplateUrl({
targetUrl: 'https://example.com/{query,default=hello world}/{query,default=hello world}',
query: params(),
}),
).toBe('https://example.com/hello%20world/hello%20world');
});
it('lets matching query params override pathParam and defaults', () => {
expect(
resolveTemplateUrl({
targetUrl: 'https://example.com/search?q={query,default=hello}',
pathParam: 'from-path',
query: params('query=from query'),
}),
).toBe('https://example.com/search?q=from%20query');
});
it('resolves multiple params from query/default values', () => {
expect(
resolveTemplateUrl({
targetUrl: 'https://example.com/{locale,default=en}/search?q={query}&page={page,default=1}',
query: params('query=Django tips&page=2'),
}),
).toBe('https://example.com/en/search?q=Django%20tips&page=2');
});
it('throws a typed error for a missing required param', () => {
expect(() =>
resolveTemplateUrl({
targetUrl: 'https://example.com/search?q={query}',
query: params(),
}),
).toThrow(TemplateResolutionError);
expect(() =>
resolveTemplateUrl({
targetUrl: 'https://example.com/search?q={query}',
query: params(),
}),
).toThrow('No value provided for template parameter "query"');
});
it('throws a typed error for invalid parameter names', () => {
expect(() =>
resolveTemplateUrl({
targetUrl: 'https://example.com/search?q={bad-name,default=hello}',
query: params(),
}),
).toThrow(TemplateResolutionError);
expect(() =>
resolveTemplateUrl({
targetUrl: 'https://example.com/search?q={bad-name,default=hello}',
query: params(),
}),
).toThrow('Invalid template parameter name "bad-name"');
});
it('preserves static Chinese text around params and encodes only substituted values', () => {
expect(
resolveTemplateUrl({
targetUrl: 'https://chatgpt.com/?q=翻译: {query,default=hello} 保证真实性',
query: params('query=cool beans'),
}),
).toBe('https://chatgpt.com/?q=翻译: cool%20beans 保证真实性');
});
it('splits defaults only on the first comma', () => {
expect(
resolveTemplateUrl({
targetUrl: 'https://google.com/search?q={query,default=hello,world}',
query: params(),
}),
).toBe('https://google.com/search?q=hello%2Cworld');
});
});