import chai, { expect } from 'chai'; import asPromised from 'chai-as-promised'; import { before, describe, it } from 'mocha'; import { generateArtistCredits, generatePlay, generateTealPlayRecord, withBrainz } from "../../../core/tests/utils/PlayTestUtils.ts"; import { listRecordToPlay } from "../../common/vendor/teal/TealApiClient.ts"; import { playToRecord } from "../../common/vendor/teal/TealApiClient.ts"; import dayjs from 'dayjs'; import { artistCreditsToNames } from '../../../core/StringUtils.ts'; import TealScrobbler from '../../scrobblers/TealfmScrobbler.ts'; import { EventEmitter } from "events"; import path from 'node:path'; import { getConfigDir } from '../../common/index.ts'; import { loggerDebug } from '@foxxmd/logging'; chai.use(asPromised); describe('#tealfm Record to Play', function() { it('Parses basic record data', function() { const [rec, {tid, did}] = generateTealPlayRecord(); const play = listRecordToPlay(rec); expect(play.data.track).eq(rec.value.trackName); expect(play.data.album).eq(rec.value.releaseName); expect(play.data.playDate.unix()).eq(dayjs(rec.value.playedTime).unix()); expect(play.data.duration).eq(rec.value.duration); expect(artistCreditsToNames(play.data.artists)).eql(rec.value.artists.map(x => x.artistName)); expect(play.meta.user).eq(`did:plc:${did}`); expect(play.meta.playId).eq(tid); }); it('Parses mbids and isrc', function() { const [rec, {tid, did}] = generateTealPlayRecord(); const play = listRecordToPlay(rec); expect(play.data.meta.brainz).to.not.be.undefined; expect(play.data.meta.brainz.album).eq(rec.value.releaseMbId); expect(play.data.meta.brainz.recording).eq(rec.value.recordingMbId); expect(play.data.meta.brainz.artist).eql(rec.value.artists.map(x => x.artistMbId)); expect(play.data.isrc).eq(rec.value.isrc); }); it('Removes brainz if no mbids', function() { const [rec, {tid, did}] = generateTealPlayRecord({ withMbids : false}); const play = listRecordToPlay(rec); expect(play.data.meta?.brainz).to.be.undefined; }); it('Leaves brainz artists undefined if no artist mbids', function() { const [rec, {tid, did}] = generateTealPlayRecord(); rec.value.artists = rec.value.artists.map(x => ({artistName: x.artistName})); const play = listRecordToPlay(rec); expect(play.data.meta?.brainz).to.not.be.undefined; expect(play.data.meta?.brainz.artist).to.be.undefined; }); it('Parses production namespace records', function() { const [legacyRecord] = generateTealPlayRecord(); const productionRecord = { ...legacyRecord, uri: legacyRecord.uri.replace('fm.teal.feed.play', 'fm.teal.feed.play'), value: { ...legacyRecord.value, $type: 'fm.teal.feed.play' as const, musicServiceUri: 'https://spotify.com' as `${string}:${string}`, originUri: 'https://example.com/track' as `${string}:${string}` } }; const play = listRecordToPlay(productionRecord); expect(play.meta.musicService).eq('https://spotify.com'); expect(play.meta.url.origin).eq('https://example.com/track'); }); }); describe('#tealfm Play To Record', function () { it('Adds mbids with uri format', function () { const play = withBrainz(generatePlay({artists: generateArtistCredits(2)}, {musicService: 'Spotify'}), {include: ['recording']}); const record = playToRecord(play); expect(record.$type).to.eq('fm.teal.feed.play'); expect(record.recordingMbId).to.eq(`mbid:${play.data.meta.brainz.recording}`); expect(record.releaseMbId).is.undefined; expect(record.artists).length(2); expect(record.artists[0].artistName).eq(play.data.artists[0].name); expect(record.artists[0].artistMbId).eq(`mbid:${play.data.artists[0].mbid}`); expect(record.musicServiceUri).eq('https://spotify.com'); expect(record.originUri).eq(play.meta.url.origin); }); }); describe('#tealfm Play To Record', function () { it('Adds mbids with uri format', function () { const play = withBrainz(generatePlay({artists: generateArtistCredits(2)}), {include: ['recording']}); const record = playToRecord(play); expect(record.recordingMbId).to.eq(`mbid:${play.data.meta.brainz.recording}`); expect(record.releaseMbId).is.undefined; expect(record.artists).length(2); expect(record.artists[0].artistName).eq(play.data.artists[0].name); expect(record.artists[0].artistMbId).eq(`mbid:${play.data.artists[0].mbid}`); }); }); describe('#tealfmCar', function() { before(function () { if (process.env.TEAL_CAR_TEST !== 'true') { this.skip(); } }); it('Parses car file', async function() { this.timeout(100000); const tfm = new TealScrobbler('test', {id: `test-${Date.now()}`, name: 'test', data: {identifier: 'test', appPassword: 'test'}}, {configDir: 'test', localUrl: new URL('https://example.com'), version: 'test'}, new EventEmitter(), loggerDebug ); await tfm.buildDatabase(); await tfm.parseScrobblesFromCar(path.resolve(getConfigDir(), 'tealfm-myteal-1778870858.car'), 100); }); });