Something went wrong. Try again.
[READ-ONLY] Mirror of https://github.com/FoxxMD/multi-scrobbler. Scrobble plays from multiple sources to multiple clients docs.multi-scrobbler.app
deezer docker jellyfin koito lastfm listenbrainz maloja mopidy mpris music music-assistant plex scrobble self-hosted spotify subsonic tautulli youtube-music
Something went wrong. Try again.
12 kB · 216 lines
TypeScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216import { assert, expect } from 'chai';import { describe, it } from 'mocha';import { generateBaseURL, joinedUrl, normalizeWebAddress } from "../../utils/NetworkUtils.ts";import { httpUrl, wsUrl } from '../../utils/ZodUtils.ts';
describe('URL Parsing', function () { describe('Base URL', function () {
it('should return http://localhost:9078 if no url is specified', function () { assert.equal(generateBaseURL(undefined, 9078).toString(), 'http://localhost:9078/'); });
it('should normalize URL without protocol to HTTP', function () { assert.include(generateBaseURL('192.168.0.1', 9078).toString(), 'http://192.168.0.1'); assert.include(generateBaseURL('my.domain.local', 9078).toString(), 'http://my.domain.local'); });
it('should use 443 for port, instead of default port, if protocol is https and no port is specified', function () { assert.include(generateBaseURL('https://192.168.0.1', 9078).toString(), 'https://192.168.0.1'); assert.include(generateBaseURL('https://my.domain.local', 9078).toString(), 'https://my.domain.local'); });
it('should preserve port if explicitly specified', function () { assert.include(generateBaseURL('http://my.domain.local:80', 9078).toString(), 'http://my.domain.local'); assert.include(generateBaseURL('192.168.0.1:80', 9078).toString(), 'http://192.168.0.1'); assert.include(generateBaseURL('192.168.0.1:8000', 9078).toString(), 'http://192.168.0.1:8000'); assert.include(generateBaseURL('my.domain.local:9075', 9078).toString(), 'http://my.domain.local:9075'); assert.include(generateBaseURL('https://my.domain.local:9075', 9078).toString(), 'https://my.domain.local:9075'); });
it('should use default port if protocol is HTTP and port is not specified', function () { assert.include(generateBaseURL('192.168.0.1', 9078).toString(), 'http://192.168.0.1:9078'); assert.include(generateBaseURL('http://my.domain.local', 9078).toString(), 'http://my.domain.local:9078'); });
it('should preserve pathname for subfolder usage', function () { assert.include(generateBaseURL('192.168.0.1/my/subfolder', 9078).toString(), 'http://192.168.0.1:9078/my/subfolder'); assert.include(generateBaseURL('http://my.domain.local/my/subfolder', 9078).toString(), 'http://my.domain.local:9078/my/subfolder'); assert.include(generateBaseURL('http://my.domain.local:5000/my/subfolder', 9078).toString(), 'http://my.domain.local:5000/my/subfolder'); assert.include(generateBaseURL('https://my.domain.local/my/subfolder', 9078).toString(), 'https://my.domain.local/my/subfolder'); });
it('should should strip wrapping quotes', function () { assert.equal(generateBaseURL(`"http://192.168.3.120:9078"`, 9078).toString(), 'http://192.168.3.120:9078/'); }); });
describe('URL Path Joining', function() { it('should join a path to a base URL without erasing base pathname', function() { const baseUrl = generateBaseURL('192.168.0.1/my/subfolder', 9078); assert.equal(joinedUrl(baseUrl, 'lastfm/callback').toString(), 'http://192.168.0.1:9078/my/subfolder/lastfm/callback'); }); it('should join a path to a base URL while handling leading and trailing slashes', function() { const baseUrl = generateBaseURL('192.168.0.1/my/subfolder', 9078); assert.equal(joinedUrl(baseUrl, '/lastfm/callback').toString(), 'http://192.168.0.1:9078/my/subfolder/lastfm/callback'); assert.equal(joinedUrl(baseUrl, 'lastfm/callback/').toString(), 'http://192.168.0.1:9078/my/subfolder/lastfm/callback/');
const baseUrlNoSub = generateBaseURL('192.168.0.1', 9078); assert.equal(joinedUrl(baseUrlNoSub, '/lastfm/callback').toString(), 'http://192.168.0.1:9078/lastfm/callback'); assert.equal(joinedUrl(baseUrlNoSub, 'lastfm/callback/').toString(), 'http://192.168.0.1:9078/lastfm/callback/'); }); });
describe('Normalizing', function() {
describe('IP Address', function () {
const anIP = '192.168.0.100';
it('Should unwrap a quoted value', function () { expect(normalizeWebAddress(`"${anIP}"`).url.hostname).to.eq(anIP); });
it('Should normalize an IP to HTTP protocol', function () { expect(normalizeWebAddress(anIP).url.protocol).to.eq('http:'); });
it('Should normalize an IP without a port to port 80', function () { expect(normalizeWebAddress(anIP).port).to.eq(80); });
it('Should normalize an IP to an HTTP URL', function () { expect(normalizeWebAddress(anIP).normal).to.eq(`http://${anIP}`); });
it('Should normalize an IP with port 443 to an HTTPS URL', function () { expect(normalizeWebAddress(`${anIP}:443`).url.protocol).to.eq(`https:`); expect(normalizeWebAddress(`${anIP}:443`).url.toString()).to.include(`https:`); expect(normalizeWebAddress(`${anIP}:443`).normal).to.include(`https:`); expect(normalizeWebAddress(`${anIP}:443`).port).to.eq(443); });
it('Should not normalize an IP with port 443 if protocol is specified', function () { expect(normalizeWebAddress(`http://${anIP}:443`).url.protocol).to.eq(`http:`); expect(normalizeWebAddress(`http://${anIP}:443`).url.toString()).to.include(`http:`); expect(normalizeWebAddress(`http://${anIP}:443`).normal).to.include(`http:`); expect(normalizeWebAddress(`http://${anIP}:443`).port).to.eq(443); });
it('Should normalize an IP with a port and preserve port', function () { expect(normalizeWebAddress(`${anIP}:5000`).port).to.eq(5000); expect(normalizeWebAddress(`${anIP}:5000`).normal).to.eq(`http://${anIP}:5000`); expect(normalizeWebAddress(`${anIP}:5000`).url.protocol).to.eq('http:'); expect(normalizeWebAddress(`${anIP}:5000`).url.port).to.eq('5000'); });
it('Should remove trailing slash', function () { expect(normalizeWebAddress(`${anIP}:5000/`).normal).to.eq(`http://${anIP}:5000`); }); });
describe('Domain', function () {
const domain = 'subdomain.mydomain.test';
describe('No Port', function () {
it('Should normalize an address without protocol to HTTP protocol', function () { expect(normalizeWebAddress(domain).url.protocol).to.eq('http:'); });
it('Should normalize an address without protocol to port 80', function () { expect(normalizeWebAddress(domain).port).to.eq(80); });
it('Should normalize an address with http to HTTP protocol', function () { expect(normalizeWebAddress(`http://${domain}`).url.protocol).to.eq('http:'); });
it('Should normalize an address with http to port 80', function () { expect(normalizeWebAddress(`http://${domain}`).port).to.eq(80); });
it('Should normalize an address with https to HTTPS protocol', function () { expect(normalizeWebAddress(`https://${domain}`).url.protocol).to.eq('https:'); });
it('Should normalize an address with https to port 443', function () { expect(normalizeWebAddress(`https://${domain}`).port).to.eq(443); });
it('Should normalize a domain without TLD to http', function () { expect(normalizeWebAddress('myDomain').url.protocol).to.eq('http:'); });
});
describe('With Port', function () {
it('Should normalize an address without protocol and with port to specified port and HTTP', function () { expect(normalizeWebAddress(`${domain}:1068`).port).to.eq(1068); expect(normalizeWebAddress(`${domain}:1068`).url.protocol).to.eq('http:'); });
it('Should normalize an address without protocol and with port 443 to specified port and HTTPS', function () { expect(normalizeWebAddress(`${domain}:443`).port).to.eq(443); expect(normalizeWebAddress(`${domain}:443`).url.protocol).to.eq('https:'); });
it('Should normalize an address with protocol and with port to specified port and protocol', function () { expect(normalizeWebAddress(`https://${domain}:1055`).port).to.eq(1055); expect(normalizeWebAddress(`https://${domain}:1055`).url.protocol).to.eq('https:'); });
it('Should normalize a domain without TLD but with port to that port', function () { const normal = normalizeWebAddress('myDomain:881'); expect(normal.url.protocol).to.eq('http:'); expect(normal.port).to.eq(881); });
});
});
});
describe('Zod URL Validation', function () { it('should not throw on normalizable http URLs', function () { expect(() => httpUrl.parse('http://my.domain.local:90')).to.not.throw(); expect(() => httpUrl.parse('http://my.domain.local')).to.not.throw(); expect(() => httpUrl.parse('https://my.domain.local')).to.not.throw(); expect(() => httpUrl.parse('https://my.domain.local:91')).to.not.throw(); expect(() => httpUrl.parse('my.domain.local:80')).to.not.throw(); expect(() => httpUrl.parse('my.domain.local:81')).to.not.throw(); expect(() => httpUrl.parse('http://domain')).to.not.throw(); expect(() => httpUrl.parse('domain:81')).to.not.throw(); expect(() => httpUrl.parse('domain')).to.not.throw(); });
it('should throw on non-normalizable http URLs', function () { expect(() => httpUrl.parse('http://')).to.throw(); expect(() => httpUrl.parse('domain:')).to.throw(); expect(() => httpUrl.parse('file://path.txt')).to.throw(); expect(() => httpUrl.parse('ws://mydomain')).to.throw(); });
it('should not throw on normalizable ws URLs', function () { expect(() => wsUrl.parse('information:14585')).to.not.throw(); expect(() => wsUrl.parse('ws://my.domain.local')).to.not.throw(); expect(() => wsUrl.parse('wss://my.domain.local')).to.not.throw(); expect(() => wsUrl.parse('wss://my.domain.local:91')).to.not.throw(); expect(() => wsUrl.parse('my.domain.local:80')).to.not.throw(); expect(() => wsUrl.parse('my.domain.local:81')).to.not.throw(); expect(() => wsUrl.parse('domain:81')).to.not.throw(); expect(() => wsUrl.parse('domain')).to.not.throw(); });
it('should throw on non-normalizable ws URLs', function () { expect(() => httpUrl.parse('ws://')).to.throw(); expect(() => httpUrl.parse('domain:')).to.throw(); expect(() => httpUrl.parse('file://path.txt')).to.throw(); }); });
});