A music player that connects to your cloud/distributed storage.
5
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix: tests

+7 -406
+3 -2
tests/common/cid/test.ts
··· 46 46 expect(result).toBe(false); 47 47 }); 48 48 49 - it("returns a CID starting with 'bafy'", async () => { 49 + it("returns a base32-encoded CID string", async () => { 50 50 const result = await testWeb(async () => { 51 51 const { create } = await import("~/common/cid.js"); 52 52 return create(0x55, new TextEncoder().encode("test")); 53 53 }); 54 - expect(result.startsWith("bafy")).toBe(true); 54 + // CIDv1 base32 strings contain only lowercase alphanumeric characters 55 + expect(/^[a-z2-7]+$/.test(result)).toBe(true); 55 56 }); 56 57 }); 57 58
+4 -4
tests/common/track/test.ts
··· 10 10 const { trackURIBase } = await import("~/common/track.js"); 11 11 return trackURIBase("https://example.com/music/track.mp3"); 12 12 }); 13 - expect(result).toBe("https://example.com"); 13 + expect(result).toBe("https://example.com/"); 14 14 }); 15 15 16 16 it("strips query string from URI", async () => { ··· 18 18 const { trackURIBase } = await import("~/common/track.js"); 19 19 return trackURIBase("https://example.com/track.mp3?token=abc"); 20 20 }); 21 - expect(result).toBe("https://example.com"); 21 + expect(result).toBe("https://example.com/"); 22 22 }); 23 23 24 24 it("handles URIs with no path", async () => { ··· 26 26 const { trackURIBase } = await import("~/common/track.js"); 27 27 return trackURIBase("https://example.com"); 28 28 }); 29 - expect(result).toBe("https://example.com"); 29 + expect(result).toBe("https://example.com/"); 30 30 }); 31 31 32 32 it("preserves scheme and host", async () => { ··· 49 49 const set = uniqueTrackURIs(tracks); 50 50 return [...set]; 51 51 }); 52 - expect(result).toEqual(["https://example.com"]); 52 + expect(result).toEqual(["https://example.com/"]); 53 53 }); 54 54 55 55 it("deduplicates tracks from the same source", async () => {
-100
tests/facets/data/artwork-bundle/test.ts
··· 1 - import { describe, it } from "@std/testing/bdd"; 2 - import { expect } from "@std/expect"; 3 - 4 - import { testWeb } from "@tests/common/index.ts"; 5 - 6 - describe("facets/data/artwork-bundle", () => { 7 - it("inputArtwork prepends an input artwork element", async () => { 8 - const result = await testWeb(async () => { 9 - const { inputArtwork } = await import( 10 - "~/facets/data/artwork-bundle/index.inline.js" 11 - ); 12 - const artwork = document.createElement("div"); 13 - const input = { selector: "#test-input" }; 14 - inputArtwork(artwork as never, input as never); 15 - return artwork.children[0]?.localName ?? null; 16 - }); 17 - expect(result).toBe("da-input"); 18 - }); 19 - 20 - it("inputArtwork sets input-selector attribute", async () => { 21 - const result = await testWeb(async () => { 22 - const { inputArtwork } = await import( 23 - "~/facets/data/artwork-bundle/index.inline.js" 24 - ); 25 - const artwork = document.createElement("div"); 26 - const input = { selector: "#my-input" }; 27 - inputArtwork(artwork as never, input as never); 28 - return artwork.children[0]?.getAttribute("input-selector") ?? null; 29 - }); 30 - expect(result).toBe("#my-input"); 31 - }); 32 - 33 - it("audioMetadata appends an audio-metadata element", async () => { 34 - const result = await testWeb(async () => { 35 - const { audioMetadata } = await import( 36 - "~/facets/data/artwork-bundle/index.inline.js" 37 - ); 38 - const artwork = document.createElement("div"); 39 - const input = { selector: "#test-input" }; 40 - audioMetadata(artwork as never, input as never); 41 - return artwork.children[0]?.localName ?? null; 42 - }); 43 - expect(result).toBe("da-audio-metadata"); 44 - }); 45 - 46 - it("audioMetadata sets input-selector attribute", async () => { 47 - const result = await testWeb(async () => { 48 - const { audioMetadata } = await import( 49 - "~/facets/data/artwork-bundle/index.inline.js" 50 - ); 51 - const artwork = document.createElement("div"); 52 - const input = { selector: "#my-input" }; 53 - audioMetadata(artwork as never, input as never); 54 - return artwork.children[0]?.getAttribute("input-selector") ?? null; 55 - }); 56 - expect(result).toBe("#my-input"); 57 - }); 58 - 59 - it("lastFm appends a Last.fm artwork element", async () => { 60 - const result = await testWeb(async () => { 61 - const { lastFm } = await import( 62 - "~/facets/data/artwork-bundle/index.inline.js" 63 - ); 64 - const artwork = document.createElement("div"); 65 - lastFm(artwork as never); 66 - return artwork.children[0]?.localName ?? null; 67 - }); 68 - expect(result).toBe("da-lastfm"); 69 - }); 70 - 71 - it("musicBrainz appends a MusicBrainz artwork element", async () => { 72 - const result = await testWeb(async () => { 73 - const { musicBrainz } = await import( 74 - "~/facets/data/artwork-bundle/index.inline.js" 75 - ); 76 - const artwork = document.createElement("div"); 77 - musicBrainz(artwork as never); 78 - return artwork.children[0]?.localName ?? null; 79 - }); 80 - expect(result).toBe("da-musicbrainz"); 81 - }); 82 - 83 - it("inputArtwork is prepended before audioMetadata", async () => { 84 - const result = await testWeb(async () => { 85 - const { inputArtwork, audioMetadata } = await import( 86 - "~/facets/data/artwork-bundle/index.inline.js" 87 - ); 88 - const artwork = document.createElement("div"); 89 - const input = { selector: "#test-input" }; 90 - 91 - // audioMetadata appended first, then inputArtwork prepended 92 - audioMetadata(artwork as never, input as never); 93 - inputArtwork(artwork as never, input as never); 94 - 95 - return Array.from(artwork.children).map((el) => el.localName); 96 - }); 97 - expect(result[0]).toBe("da-input"); 98 - expect(result[1]).toBe("da-audio-metadata"); 99 - }); 100 - });
-97
tests/facets/data/input-bundle/test.ts
··· 1 - import { describe, it } from "@std/testing/bdd"; 2 - import { expect } from "@std/expect"; 3 - 4 - import { testWeb } from "@tests/common/index.ts"; 5 - 6 - describe("facets/data/input-bundle", () => { 7 - it("ephemeralCache appends an ephemeral-cache element", async () => { 8 - const result = await testWeb(async () => { 9 - const { ephemeralCache } = await import( 10 - "~/facets/data/input-bundle/index.inline.js" 11 - ); 12 - const container = document.createElement("div"); 13 - ephemeralCache(container as never); 14 - return container.children[0]?.localName ?? null; 15 - }); 16 - expect(result).toBe("di-ephemeral-cache"); 17 - }); 18 - 19 - it("https appends an https element", async () => { 20 - const result = await testWeb(async () => { 21 - const { https } = await import( 22 - "~/facets/data/input-bundle/index.inline.js" 23 - ); 24 - const container = document.createElement("div"); 25 - https(container as never); 26 - return container.children[0]?.localName ?? null; 27 - }); 28 - expect(result).toBe("di-https"); 29 - }); 30 - 31 - it("icecast appends an icecast element", async () => { 32 - const result = await testWeb(async () => { 33 - const { icecast } = await import( 34 - "~/facets/data/input-bundle/index.inline.js" 35 - ); 36 - const container = document.createElement("div"); 37 - icecast(container as never); 38 - return container.children[0]?.localName ?? null; 39 - }); 40 - expect(result).toBe("di-icecast"); 41 - }); 42 - 43 - it("local appends a local element", async () => { 44 - const result = await testWeb(async () => { 45 - const { local } = await import( 46 - "~/facets/data/input-bundle/index.inline.js" 47 - ); 48 - const container = document.createElement("div"); 49 - local(container as never); 50 - return container.children[0]?.localName ?? null; 51 - }); 52 - expect(result).toBe("di-local"); 53 - }); 54 - 55 - it("opensubsonic appends an opensubsonic element", async () => { 56 - const result = await testWeb(async () => { 57 - const { opensubsonic } = await import( 58 - "~/facets/data/input-bundle/index.inline.js" 59 - ); 60 - const container = document.createElement("div"); 61 - opensubsonic(container as never); 62 - return container.children[0]?.localName ?? null; 63 - }); 64 - expect(result).toBe("di-opensubsonic"); 65 - }); 66 - 67 - it("s3 appends an s3 element", async () => { 68 - const result = await testWeb(async () => { 69 - const { s3 } = await import( 70 - "~/facets/data/input-bundle/index.inline.js" 71 - ); 72 - const container = document.createElement("div"); 73 - s3(container as never); 74 - return container.children[0]?.localName ?? null; 75 - }); 76 - expect(result).toBe("di-s3"); 77 - }); 78 - 79 - it("each function appends exactly one element", async () => { 80 - const result = await testWeb(async () => { 81 - const { ephemeralCache, https, icecast, local, opensubsonic, s3 } = 82 - await import("~/facets/data/input-bundle/index.inline.js"); 83 - 84 - const counts: Record<string, number> = {}; 85 - for (const [name, fn] of Object.entries({ ephemeralCache, https, icecast, local, opensubsonic, s3 })) { 86 - const container = document.createElement("div"); 87 - fn(container as never); 88 - counts[name] = container.children.length; 89 - } 90 - return counts; 91 - }); 92 - 93 - for (const count of Object.values(result)) { 94 - expect(count).toBe(1); 95 - } 96 - }); 97 - });
-45
tests/facets/data/metadata-bundle/test.ts
··· 1 - import { describe, it } from "@std/testing/bdd"; 2 - import { expect } from "@std/expect"; 3 - 4 - import { testWeb } from "@tests/common/index.ts"; 5 - 6 - describe("facets/data/metadata-bundle", () => { 7 - it("audioFile appends an audio-file element to metadata", async () => { 8 - const result = await testWeb(async () => { 9 - const { audioFile } = await import( 10 - "~/facets/data/metadata-bundle/index.inline.js" 11 - ); 12 - const metadata = document.createElement("div"); 13 - const input = { selector: "#test-input" }; 14 - audioFile(metadata as never, input as never); 15 - return metadata.children[0]?.localName ?? null; 16 - }); 17 - expect(result).toBe("dm-audio-file"); 18 - }); 19 - 20 - it("audioFile sets input-selector attribute from input.selector", async () => { 21 - const result = await testWeb(async () => { 22 - const { audioFile } = await import( 23 - "~/facets/data/metadata-bundle/index.inline.js" 24 - ); 25 - const metadata = document.createElement("div"); 26 - const input = { selector: "#my-input-configurator" }; 27 - audioFile(metadata as never, input as never); 28 - return metadata.children[0]?.getAttribute("input-selector") ?? null; 29 - }); 30 - expect(result).toBe("#my-input-configurator"); 31 - }); 32 - 33 - it("audioFile appends exactly one element", async () => { 34 - const result = await testWeb(async () => { 35 - const { audioFile } = await import( 36 - "~/facets/data/metadata-bundle/index.inline.js" 37 - ); 38 - const metadata = document.createElement("div"); 39 - const input = { selector: "#test-input" }; 40 - audioFile(metadata as never, input as never); 41 - return metadata.children.length; 42 - }); 43 - expect(result).toBe(1); 44 - }); 45 - });
-158
tests/facets/data/output-bundle/test.ts
··· 1 - import { describe, it } from "@std/testing/bdd"; 2 - import { expect } from "@std/expect"; 3 - 4 - import { testWeb } from "@tests/common/index.ts"; 5 - 6 - describe("facets/data/output-bundle", () => { 7 - it("atproto appends an atproto output element to output", async () => { 8 - const result = await testWeb(async () => { 9 - const { atproto } = await import( 10 - "~/facets/data/output-bundle/index.inline.js" 11 - ); 12 - 13 - const outputChildren: string[] = []; 14 - const configuratorChildren: string[] = []; 15 - const mockOutput = { 16 - append: (el: Element) => outputChildren.push(el.localName), 17 - outputConfigurator: { 18 - append: (el: Element) => configuratorChildren.push(el.localName), 19 - }, 20 - }; 21 - 22 - atproto(mockOutput as never); 23 - 24 - return { outputChildren, configuratorChildren }; 25 - }); 26 - 27 - expect(result.outputChildren).toContain("dor-atproto"); 28 - expect(result.outputChildren).toContain("dtor-atproto-sync"); 29 - }); 30 - 31 - it("atproto appends a passkey refiner to outputConfigurator", async () => { 32 - const result = await testWeb(async () => { 33 - const { atproto } = await import( 34 - "~/facets/data/output-bundle/index.inline.js" 35 - ); 36 - 37 - const configuratorChildren: string[] = []; 38 - const mockOutput = { 39 - append: (_el: Element) => {}, 40 - outputConfigurator: { 41 - append: (el: Element) => configuratorChildren.push(el.localName), 42 - }, 43 - }; 44 - 45 - atproto(mockOutput as never); 46 - 47 - return configuratorChildren; 48 - }); 49 - 50 - expect(result).toContain("dtor-track-uri-passkey"); 51 - }); 52 - 53 - it("atproto sets correct ids and attributes on its elements", async () => { 54 - const result = await testWeb(async () => { 55 - const { atproto } = await import( 56 - "~/facets/data/output-bundle/index.inline.js" 57 - ); 58 - 59 - const appended: { id: string; localName: string }[] = []; 60 - const configuratorAppended: { id: string; localName: string }[] = []; 61 - 62 - const mockOutput = { 63 - append: (el: Element) => 64 - appended.push({ id: el.id, localName: el.localName }), 65 - outputConfigurator: { 66 - append: (el: Element) => 67 - configuratorAppended.push({ id: el.id, localName: el.localName }), 68 - }, 69 - }; 70 - 71 - atproto(mockOutput as never); 72 - 73 - return { appended, configuratorAppended }; 74 - }); 75 - 76 - const atprotoOut = result.appended.find((e) => e.localName === "dor-atproto"); 77 - const atprotoSync = result.appended.find((e) => e.localName === "dtor-atproto-sync"); 78 - const passkey = result.configuratorAppended.find((e) => e.localName === "dtor-track-uri-passkey"); 79 - 80 - expect(atprotoOut?.id).toBe("do-output__dor-atproto"); 81 - expect(atprotoSync?.id).toBe("do-output__dtor-atproto-sync"); 82 - expect(passkey?.id).toBe("do-output__dc-output__atproto"); 83 - }); 84 - 85 - it("s3 appends an s3 output element to output", async () => { 86 - const result = await testWeb(async () => { 87 - const { s3 } = await import( 88 - "~/facets/data/output-bundle/index.inline.js" 89 - ); 90 - 91 - const outputChildren: string[] = []; 92 - const mockOutput = { 93 - append: (el: Element) => outputChildren.push(el.localName), 94 - outputConfigurator: { 95 - append: (_el: Element) => {}, 96 - }, 97 - }; 98 - 99 - s3(mockOutput as never); 100 - 101 - return outputChildren; 102 - }); 103 - 104 - expect(result).toContain("dob-s3"); 105 - }); 106 - 107 - it("s3 appends a dasl-sync transformer to outputConfigurator", async () => { 108 - const result = await testWeb(async () => { 109 - const { s3 } = await import( 110 - "~/facets/data/output-bundle/index.inline.js" 111 - ); 112 - 113 - const configuratorChildren: string[] = []; 114 - const mockOutput = { 115 - append: (_el: Element) => {}, 116 - outputConfigurator: { 117 - append: (el: Element) => configuratorChildren.push(el.localName), 118 - }, 119 - }; 120 - 121 - s3(mockOutput as never); 122 - 123 - return configuratorChildren; 124 - }); 125 - 126 - expect(result).toContain("dtob-dasl-sync"); 127 - }); 128 - 129 - it("s3 sets correct ids on its elements", async () => { 130 - const result = await testWeb(async () => { 131 - const { s3 } = await import( 132 - "~/facets/data/output-bundle/index.inline.js" 133 - ); 134 - 135 - const appended: { id: string; localName: string }[] = []; 136 - const configuratorAppended: { id: string; localName: string }[] = []; 137 - 138 - const mockOutput = { 139 - append: (el: Element) => 140 - appended.push({ id: el.id, localName: el.localName }), 141 - outputConfigurator: { 142 - append: (el: Element) => 143 - configuratorAppended.push({ id: el.id, localName: el.localName }), 144 - }, 145 - }; 146 - 147 - s3(mockOutput as never); 148 - 149 - return { appended, configuratorAppended }; 150 - }); 151 - 152 - const s3Out = result.appended.find((e) => e.localName === "dob-s3"); 153 - const s3Sync = result.configuratorAppended.find((e) => e.localName === "dtob-dasl-sync"); 154 - 155 - expect(s3Out?.id).toBe("do-output__dob-s3"); 156 - expect(s3Sync?.id).toBe("do-output__dc-output__s3"); 157 - }); 158 - });