diff --git a/fixtures/dump.sql b/fixtures/dump.sql index 5d224125..36a7388b 100644 Binary files a/fixtures/dump.sql and b/fixtures/dump.sql differ diff --git a/fixtures/system.tgz b/fixtures/system.tgz index c57330cc..aa84139d 100644 Binary files a/fixtures/system.tgz and b/fixtures/system.tgz differ diff --git a/routes/_components/status/StatusContent.html b/routes/_components/status/StatusContent.html index 94549344..bdc6e583 100644 --- a/routes/_components/status/StatusContent.html +++ b/routes/_components/status/StatusContent.html @@ -127,6 +127,11 @@ } } } + let externalLinks = Array.from(this.refs.node.querySelectorAll( + 'a[rel="nofollow noopener"]')) + for (let link of externalLinks) { + link.setAttribute('title', link.getAttribute('href')) + } stop('hydrateContent') } } diff --git a/tests/spec/16-external-links.js b/tests/spec/16-external-links.js new file mode 100644 index 00000000..7a89117e --- /dev/null +++ b/tests/spec/16-external-links.js @@ -0,0 +1,46 @@ +import { getNthStatus, getUrl } from '../utils' +import { foobarRole } from '../roles' +import { Selector as $ } from 'testcafe' + +fixture`16-external-links.js` + .page`http://localhost:4002` + +function getAnchor (nthStatus, nthAnchor) { + return getNthStatus(nthStatus).find('.status-content').find('a').nth(nthAnchor) +} + +function getAnchorInProfile (n) { + return $('.account-profile-note').find('a').nth(n) +} + +test('converts external links in statuses', async t => { + await t.useRole(foobarRole) + .hover(getNthStatus(0)) + .navigateTo('/accounts/4') + .expect(getUrl()).contains('/accounts/4') + .expect(getAnchor(0, 0).getAttribute('href')).eql('/accounts/1') + .expect(getAnchor(0, 1).getAttribute('href')).eql('/accounts/3') + .expect(getAnchor(1, 0).getAttribute('href')).eql('https://joinmastodon.org') + .expect(getAnchor(1, 0).getAttribute('title')).eql('https://joinmastodon.org') + .expect(getAnchor(1, 0).getAttribute('rel')).eql('nofollow noopener') + .expect(getAnchor(1, 1).getAttribute('href')).eql('https://github.com/tootsuite/mastodon') + .expect(getAnchor(1, 1).getAttribute('title')).eql('https://github.com/tootsuite/mastodon') + .expect(getAnchor(1, 1).getAttribute('rel')).eql('nofollow noopener') + .expect(getAnchor(2, 0).getAttribute('href')).eql('/tags/kitten') + .expect(getAnchor(2, 1).getAttribute('href')).eql('/tags/kitties') +}) + +test('converts external links in profiles', async t => { + await t.useRole(foobarRole) + .hover(getNthStatus(0)) + .navigateTo('/accounts/4') + .expect(getUrl()).contains('/accounts/4') + .expect($('.account-profile-name').innerText).eql('External Lonk') + .expect($('.account-profile-name a').getAttribute('href')).eql('http://localhost:3000/@ExternalLinks') + .expect($('.account-profile-name a').getAttribute('rel')).eql('nofollow noopener') + .expect(getAnchorInProfile(0).getAttribute('href')).eql('https://joinmastodon.org') + .expect(getAnchorInProfile(0).getAttribute('rel')).eql('nofollow noopener') + .expect(getAnchorInProfile(1).getAttribute('href')).eql('http://localhost:3000/tags/cat') + .expect(getAnchorInProfile(2).getAttribute('href')).eql('http://localhost:3000/tags/mastocats') + .expect(getAnchorInProfile(3).getAttribute('href')).eql('http://localhost:3000/@quux') +})