Felipe97/llama-cpp-compiled
01.2k
1import { parseHeadersToArray, serializeHeaders } from '$lib/utils/headers';2import { describe, expect, it } from 'vitest';3 4/**5 * Tests for the header serialization helpers used by the MCP server form6 * (custom header rows) and the new Authorization/Bearer-token flow.7 */8describe('parseHeadersToArray', () => {9 it('returns an empty array for empty or whitespace-only input', () => {10 expect(parseHeadersToArray('')).toEqual([]);11 expect(parseHeadersToArray(' ')).toEqual([]);12 expect(parseHeadersToArray(undefined as unknown as string)).toEqual([]);13 });14 15 it('returns an empty array for invalid JSON input', () => {16 expect(parseHeadersToArray('{not-json')).toEqual([]);17 expect(parseHeadersToArray('[]')).toEqual([]);18 expect(parseHeadersToArray('"plain-string"')).toEqual([]);19 });20 21 it('converts an object into ordered key/value pairs', () => {22 expect(parseHeadersToArray('{"X-Foo":"bar","Authorization":"Bearer abc"}')).toEqual([23 { key: 'X-Foo', value: 'bar' },24 { key: 'Authorization', value: 'Bearer abc' }25 ]);26 });27 28 it('stringifies non-string values', () => {29 expect(parseHeadersToArray('{"count":"42","flag":"true"}')).toEqual([30 { key: 'count', value: '42' },31 { key: 'flag', value: 'true' }32 ]);33 });34});35 36describe('serializeHeaders', () => {37 it('returns an empty string when there are no valid pairs', () => {38 expect(serializeHeaders([])).toBe('');39 expect(serializeHeaders([{ key: '', value: 'value' }])).toBe('');40 expect(serializeHeaders([{ key: ' ', value: 'value' }])).toBe('');41 });42 43 it('returns an empty string when every pair has a blank key', () => {44 expect(45 serializeHeaders([46 { key: '', value: 'drop-me' },47 { key: ' ', value: 'drop-me-too' },48 { key: '\t', value: 'tab-key' }49 ])50 ).toBe('');51 });52 53 it('drops pairs with empty keys but keeps the rest', () => {54 expect(55 serializeHeaders([56 { key: '', value: 'drop-me' },57 { key: 'X-Keep', value: 'ok' }58 ])59 ).toBe('{"X-Keep":"ok"}');60 });61 62 it('trims keys before serializing', () => {63 expect(serializeHeaders([{ key: ' X-Space ', value: 'ok' }])).toBe('{"X-Space":"ok"}');64 });65 66 it('preserves the input order of surviving pairs', () => {67 const serialized = serializeHeaders([68 { key: 'X-C', value: '3' },69 { key: 'X-A', value: '1' },70 { key: 'X-B', value: '2' }71 ]);72 73 // Object key order follows insertion order in modern JS engines, so74 // the serialized JSON writes keys in our input order.75 expect(JSON.parse(serialized)).toEqual({ 'X-A': '1', 'X-B': '2', 'X-C': '3' });76 });77});78 79describe('parseHeadersToArray / serializeHeaders roundtrip', () => {80 it('serializes back to an equal header object after a parse', () => {81 const original = JSON.stringify({82 'Content-Type': 'application/json',83 'X-Trace-Id': 'abc-123'84 });85 const roundtrip = serializeHeaders(parseHeadersToArray(original));86 87 expect(JSON.parse(roundtrip)).toEqual(JSON.parse(original));88 });89 90 it('drops rows whose keys are blank after trimming during serialization', () => {91 const pairs = parseHeadersToArray('{"X-Keep":"ok","":"drop-me"}');92 93 // parseHeadersToArray keeps raw key strings (the consumer is expected to94 // filter blanks, not the parser); serialization must strip them.95 expect(pairs).toEqual([96 { key: 'X-Keep', value: 'ok' },97 { key: '', value: 'drop-me' }98 ]);99 expect(serializeHeaders(pairs)).toBe('{"X-Keep":"ok"}');100 });101 102 it('preserves upstream keys untouched (does not lowercase them)', () => {103 const upperCased = '{"Authorization":"Bearer xyz"}';104 const parsed = parseHeadersToArray(upperCased);105 106 expect(parsed).toEqual([{ key: 'Authorization', value: 'Bearer xyz' }]);107 });108 109 it('bearer-token write survives a re-parse when paired with regular custom headers', () => {110 // The McpServerForm bearer UI writes {Authorization: `Bearer <token>`}111 // into the same headers string as the custom KV section. The round112 // trip below mirrors the exact shape the form produces so a future113 // refactor of either code path cannot silently change the on-disk key.114 const pairs = [115 { key: 'X-Trace-Id', value: 'abc-123' },116 { key: 'Authorization', value: 'Bearer super-secret' }117 ];118 const serialized = serializeHeaders(pairs);119 120 expect(serialized).toBe('{"X-Trace-Id":"abc-123","Authorization":"Bearer super-secret"}');121 expect(parseHeadersToArray(serialized)).toEqual(pairs);122 });123});124 