diff --git a/ui/src/artist/ArtistExternalLink.jsx b/ui/src/artist/ArtistExternalLink.jsx index a83972f17..6595d1fbc 100644 --- a/ui/src/artist/ArtistExternalLink.jsx +++ b/ui/src/artist/ArtistExternalLink.jsx @@ -38,15 +38,15 @@ const ArtistExternalLinks = ({ artistInfo, record }) => { } if (config.lastFMEnabled) { - if (lastFMlink && isLastFmURL(lastFMlink[2])) { + // No agent may be enabled to supply a canonical URL, so fall back to a name-based one. + const lastFMUrl = + (lastFMlink && isLastFmURL(lastFMlink[2]) && lastFMlink[2]) || + (isLastFmURL(artistInfo?.lastFmUrl) && artistInfo.lastFmUrl) || + (record.name && + `https://last.fm/music/${encodeURIComponent(record.name)}`) + if (lastFMUrl) { addLink( - lastFMlink[2], - 'message.openIn.lastfm', - , - ) - } else if (isLastFmURL(artistInfo?.lastFmUrl)) { - addLink( - artistInfo?.lastFmUrl, + lastFMUrl, 'message.openIn.lastfm', , ) diff --git a/ui/src/artist/ArtistExternalLink.test.jsx b/ui/src/artist/ArtistExternalLink.test.jsx new file mode 100644 index 000000000..4214c21ea --- /dev/null +++ b/ui/src/artist/ArtistExternalLink.test.jsx @@ -0,0 +1,60 @@ +import React from 'react' +import { render, screen } from '@testing-library/react' +import { describe, it, expect, beforeEach, vi } from 'vitest' +import { TestContext } from 'ra-test' +import ArtistExternalLinks from './ArtistExternalLink' + +const { mockConfig } = vi.hoisted(() => ({ + mockConfig: { lastFMEnabled: true }, +})) +vi.mock('../config', () => ({ default: mockConfig })) + +describe('ArtistExternalLinks', () => { + beforeEach(() => { + mockConfig.lastFMEnabled = true + }) + + const renderLinks = (artistInfo, record = { id: 'ar-1', name: 'Björk' }) => + render( + + + , + ) + + const lastFmHref = () => + screen.getByLabelText('message.openIn.lastfm').closest('a').href + + it('uses the URL returned by the server', () => { + renderLinks({ lastFmUrl: 'https://www.last.fm/music/Bjork' }) + expect(lastFmHref()).toBe('https://www.last.fm/music/Bjork') + }) + + it('uses the URL found in the biography', () => { + renderLinks({ + biography: 'Read more on ', + lastFmUrl: 'https://bjork.com', + }) + expect(lastFmHref()).toBe('https://www.last.fm/music/Bjork') + }) + + it('builds the URL from the artist name when the server has none', () => { + renderLinks({ lastFmUrl: 'https://bjork.com' }) + expect(lastFmHref()).toBe('https://last.fm/music/Bj%C3%B6rk') + }) + + it('builds the URL when there is no artist info at all', () => { + renderLinks(undefined) + expect(lastFmHref()).toBe('https://last.fm/music/Bj%C3%B6rk') + }) + + it('shows no Last.fm link when Last.fm is disabled', () => { + mockConfig.lastFMEnabled = false + renderLinks({ lastFmUrl: 'https://www.last.fm/music/Bjork' }) + expect(screen.queryByLabelText('message.openIn.lastfm')).toBeNull() + }) + + it('shows no Last.fm link when the artist has no name', () => { + renderLinks({}, { id: 'ar-1', name: '' }) + expect(screen.queryByLabelText('message.openIn.lastfm')).toBeNull() + }) +})