finalmask.test.ts 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. /// <reference types="vite/client" />
  2. import { describe, expect, it } from 'vitest';
  3. import { migrateXmcSettings, parseGeckoPacketSize } from '@/lib/xray/forms/transport/FinalMaskForm';
  4. import { FinalMaskStreamSettingsSchema } from '@/schemas/protocols/stream';
  5. const fixtures = import.meta.glob<unknown>('./golden/fixtures/finalmask/*.json', {
  6. eager: true,
  7. import: 'default',
  8. });
  9. function fixtureName(path: string): string {
  10. const file = path.split('/').pop() ?? path;
  11. return file.replace(/\.json$/, '');
  12. }
  13. describe('FinalMaskStreamSettingsSchema fixtures', () => {
  14. const entries = Object.entries(fixtures).sort(([a], [b]) => a.localeCompare(b));
  15. expect(
  16. entries.length,
  17. 'expected at least one fixture under golden/fixtures/finalmask',
  18. ).toBeGreaterThan(0);
  19. for (const [path, raw] of entries) {
  20. it(`parses ${fixtureName(path)} byte-stably`, () => {
  21. const parsed = FinalMaskStreamSettingsSchema.parse(raw);
  22. expect(parsed).toMatchSnapshot();
  23. });
  24. }
  25. });
  26. describe('migrateXmcSettings', () => {
  27. it('carries legacy usernames into profile stubs and drops the dead key', () => {
  28. const { next, changed } = migrateXmcSettings({
  29. hostname: 'mc.example.com',
  30. usernames: ['Dream', 'Notch'],
  31. password: 'pw',
  32. });
  33. expect(changed).toBe(true);
  34. expect(next.usernames).toBeUndefined();
  35. expect(next.hostname).toBe('mc.example.com');
  36. expect(next.password).toBe('pw');
  37. expect(next.profiles).toEqual([
  38. { username: 'Dream', uuid: '', texturesValue: '', texturesSignature: '' },
  39. { username: 'Notch', uuid: '', texturesValue: '', texturesSignature: '' },
  40. ]);
  41. });
  42. it('gives a mask with neither key an empty profiles list', () => {
  43. const { next, changed } = migrateXmcSettings({ hostname: '', password: 'pw' });
  44. expect(changed).toBe(true);
  45. expect(next.profiles).toEqual([]);
  46. });
  47. it('leaves an already migrated mask untouched', () => {
  48. const profiles = [
  49. {
  50. username: 'Notch',
  51. uuid: '069a79f4-44e9-4726-a5be-fca90e38aaf5',
  52. texturesValue: 'dmFsdWU=',
  53. texturesSignature: 'c2ln',
  54. },
  55. ];
  56. const { next, changed } = migrateXmcSettings({ hostname: '', password: 'pw', profiles });
  57. expect(changed).toBe(false);
  58. expect(next.profiles).toEqual(profiles);
  59. });
  60. it('discards blank legacy usernames rather than seeding unfixable stubs', () => {
  61. const { next } = migrateXmcSettings({ usernames: ['Dream', '', ' '], password: 'pw' });
  62. expect(next.profiles).toEqual([
  63. { username: 'Dream', uuid: '', texturesValue: '', texturesSignature: '' },
  64. ]);
  65. });
  66. });
  67. describe('parseGeckoPacketSize', () => {
  68. it('accepts positive ordered packet size ranges', () => {
  69. expect(parseGeckoPacketSize('512-1200')).toEqual({ min: 512, max: 1200 });
  70. expect(parseGeckoPacketSize('1200-1200')).toEqual({ min: 1200, max: 1200 });
  71. expect(parseGeckoPacketSize('1-2048')).toEqual({ min: 1, max: 2048 });
  72. });
  73. it('rejects invalid packet size ranges', () => {
  74. expect(parseGeckoPacketSize('')).toBeNull();
  75. expect(parseGeckoPacketSize('0-1200')).toBeNull();
  76. expect(parseGeckoPacketSize('1200-512')).toBeNull();
  77. expect(parseGeckoPacketSize('512')).toBeNull();
  78. expect(parseGeckoPacketSize('512-abc')).toBeNull();
  79. // exceeds xray-core's gecko buffer (max 2048)
  80. expect(parseGeckoPacketSize('512-2049')).toBeNull();
  81. expect(parseGeckoPacketSize('512-9999')).toBeNull();
  82. });
  83. });