mirror of
https://github.com/orangecoding/fredy.git
synced 2026-06-16 12:31:07 +00:00
133 lines
4.3 KiB
JavaScript
133 lines
4.3 KiB
JavaScript
/*
|
|
* Copyright (c) 2026 by Christian Kellner.
|
|
* Licensed under Apache-2.0 with Commons Clause and Attribution/Naming Clause
|
|
*/
|
|
|
|
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
|
|
vi.mock('fs');
|
|
vi.mock('os');
|
|
|
|
import * as fsMock from 'fs';
|
|
import * as osMock from 'os';
|
|
import { isRunningInDocker, detectLocalIp, guessBaseUrl } from '../../lib/utils/detectBaseUrl.js';
|
|
|
|
describe('detectBaseUrl', () => {
|
|
let originalEnv;
|
|
|
|
beforeEach(() => {
|
|
originalEnv = { ...process.env };
|
|
vi.clearAllMocks();
|
|
delete process.env.FREDY_DOCKER;
|
|
delete process.env.FREDY_HOST_IP;
|
|
});
|
|
|
|
afterEach(() => {
|
|
process.env = originalEnv;
|
|
});
|
|
|
|
describe('isRunningInDocker', () => {
|
|
it('returns true when FREDY_DOCKER=1', () => {
|
|
process.env.FREDY_DOCKER = '1';
|
|
expect(isRunningInDocker()).toBe(true);
|
|
});
|
|
|
|
it('returns false when no Docker signals present', () => {
|
|
vi.mocked(fsMock.accessSync).mockImplementation(() => {
|
|
throw new Error('not found');
|
|
});
|
|
vi.mocked(fsMock.readFileSync).mockImplementation(() => {
|
|
throw new Error('not found');
|
|
});
|
|
expect(isRunningInDocker()).toBe(false);
|
|
});
|
|
|
|
it('returns true when /.dockerenv is accessible', () => {
|
|
vi.mocked(fsMock.accessSync).mockReturnValue(undefined);
|
|
expect(isRunningInDocker()).toBe(true);
|
|
});
|
|
|
|
it('returns true when /proc/self/cgroup contains docker', () => {
|
|
vi.mocked(fsMock.accessSync).mockImplementation(() => {
|
|
throw new Error('not found');
|
|
});
|
|
vi.mocked(fsMock.readFileSync).mockReturnValue('12:cpu:/docker/abc123');
|
|
expect(isRunningInDocker()).toBe(true);
|
|
});
|
|
|
|
it('returns true when /proc/self/cgroup contains containerd', () => {
|
|
vi.mocked(fsMock.accessSync).mockImplementation(() => {
|
|
throw new Error('not found');
|
|
});
|
|
vi.mocked(fsMock.readFileSync).mockReturnValue('0::/../containerd/abc');
|
|
expect(isRunningInDocker()).toBe(true);
|
|
});
|
|
});
|
|
|
|
describe('detectLocalIp', () => {
|
|
it('returns 172.17.0.1 when running in Docker (default)', () => {
|
|
process.env.FREDY_DOCKER = '1';
|
|
expect(detectLocalIp()).toBe('172.17.0.1');
|
|
});
|
|
|
|
it('returns FREDY_HOST_IP when set in Docker', () => {
|
|
process.env.FREDY_DOCKER = '1';
|
|
process.env.FREDY_HOST_IP = '192.168.1.50';
|
|
expect(detectLocalIp()).toBe('192.168.1.50');
|
|
});
|
|
|
|
it('skips docker bridge IPs and returns real LAN IP', () => {
|
|
vi.mocked(fsMock.accessSync).mockImplementation(() => {
|
|
throw new Error();
|
|
});
|
|
vi.mocked(fsMock.readFileSync).mockImplementation(() => {
|
|
throw new Error();
|
|
});
|
|
vi.mocked(osMock.networkInterfaces).mockReturnValue({
|
|
docker0: [{ family: 'IPv4', address: '172.17.0.1', internal: false }],
|
|
en0: [{ family: 'IPv4', address: '192.168.1.100', internal: false }],
|
|
});
|
|
expect(detectLocalIp()).toBe('192.168.1.100');
|
|
});
|
|
|
|
it('prefers en0 over arbitrary interfaces', () => {
|
|
vi.mocked(fsMock.accessSync).mockImplementation(() => {
|
|
throw new Error();
|
|
});
|
|
vi.mocked(fsMock.readFileSync).mockImplementation(() => {
|
|
throw new Error();
|
|
});
|
|
vi.mocked(osMock.networkInterfaces).mockReturnValue({
|
|
utun3: [{ family: 'IPv4', address: '10.8.0.1', internal: false }],
|
|
en0: [{ family: 'IPv4', address: '192.168.178.50', internal: false }],
|
|
});
|
|
expect(detectLocalIp()).toBe('192.168.178.50');
|
|
});
|
|
|
|
it('falls back to localhost when no suitable interface found', () => {
|
|
vi.mocked(fsMock.accessSync).mockImplementation(() => {
|
|
throw new Error();
|
|
});
|
|
vi.mocked(fsMock.readFileSync).mockImplementation(() => {
|
|
throw new Error();
|
|
});
|
|
vi.mocked(osMock.networkInterfaces).mockReturnValue({
|
|
lo: [{ family: 'IPv4', address: '127.0.0.1', internal: true }],
|
|
});
|
|
expect(detectLocalIp()).toBe('localhost');
|
|
});
|
|
});
|
|
|
|
describe('guessBaseUrl', () => {
|
|
it('returns correctly formatted URL', () => {
|
|
process.env.FREDY_DOCKER = '1';
|
|
expect(guessBaseUrl(9998)).toBe('http://172.17.0.1:9998');
|
|
});
|
|
|
|
it('includes custom port', () => {
|
|
process.env.FREDY_DOCKER = '1';
|
|
expect(guessBaseUrl(8080)).toBe('http://172.17.0.1:8080');
|
|
});
|
|
});
|
|
});
|