From 2f886bcc4edd121a50bbefb214bca4b395dbb5de Mon Sep 17 00:00:00 2001 From: Fabien O'Carroll Date: Wed, 16 Apr 2025 12:06:36 +0700 Subject: [PATCH 1/2] Created docker network & configured aliases for tests ref https://linear.app/ghost/issue/AP-963 ref b68297110e8108676a975fd90bcd9078a72191b2 Our WebFinger implementation validates that the incoming `acct` resource has a proper hostname, and we require there be a top level domain. In testing our hostnames were all mapped to docker compose service names and so they do not have a `.` in them and don't pass this test. This was also the case in the linked commits `isHandle` function which has a special branch for test mode. With docker compose we are able to specify aliases for services on a particular network. I've gone for a separate testing network here to completely isolate our testing stack, which is probably unecessary, especially because we're using the `.test` TLD which shouldn't interfere with our dev stack, but I think it's cleaner to have these on separate networks anyway and avoid any cross pollution. --- docker-compose.yml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index 1166ac6ae..83c05356d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -102,6 +102,8 @@ services: # Testing activitypub-testing: + networks: + - test_network build: . volumes: - ./src:/opt/activitypub/src @@ -138,6 +140,8 @@ services: start_period: 5s migrate-testing: + networks: + - test_network build: migrate volumes: - ./migrate/migrations:/migrations @@ -148,6 +152,8 @@ services: condition: service_healthy cucumber-tests: + networks: + - test_network build: . volumes: - ./features:/opt/activitypub/features @@ -170,6 +176,8 @@ services: condition: service_healthy mysql-testing: + networks: + - test_network image: mysql:8.0.31 environment: - MYSQL_ROOT_PASSWORD=root @@ -184,6 +192,8 @@ services: retries: 120 pubsub-testing: + networks: + - test_network image: gcr.io/google.com/cloudsdktool/google-cloud-cli:499.0.0-emulators ports: - "8086:8085" @@ -205,17 +215,33 @@ services: start_period: 5s fake-ghost-activitypub: + networks: + test_network: + aliases: + - fake-ghost-activitypub.test image: wiremock/wiremock:3.10.0-1 entrypoint: [ "/docker-entrypoint.sh", "--global-response-templating", "--disable-gzip", "--verbose", "--port=80", "--https-port=443" ] volumes: - ./wiremock/fake-ghost/mappings:/home/wiremock/mappings fake-external-activitypub: + networks: + test_network: + aliases: + - fake-external-activitypub.test image: wiremock/wiremock:3.10.0-1 entrypoint: [ "/docker-entrypoint.sh", "--global-response-templating", "--disable-gzip", "--verbose", "--port=80", "--https-port=443" ] fake-mastodon: + networks: + test_network: + aliases: + - fake-mastodon.test image: wiremock/wiremock:3.10.0-1 ports: - "8084:8080" entrypoint: [ "/docker-entrypoint.sh", "--global-response-templating", "--disable-gzip", "--verbose" ] + +networks: + test_network: + driver: bridge From 2852bcf0abcabe86db73a58fbb8147763a265265 Mon Sep 17 00:00:00 2001 From: Fabien O'Carroll Date: Wed, 16 Apr 2025 12:07:17 +0700 Subject: [PATCH 2/2] Used new aliases and removed test specific code Now that we have hostames which look like real hostnames in tests we're able to remove test specific handling for the `isHandle` function. This also switches us to use the new aliases everywhere in the tests for consistency --- features/account.feature | 4 +- features/step_definitions/stepdefs.js | 150 +++++++++++++------------- src/helpers/activitypub/actor.ts | 8 -- 3 files changed, 77 insertions(+), 85 deletions(-) diff --git a/features/account.feature b/features/account.feature index ceb2cfe38..9b74b979b 100644 --- a/features/account.feature +++ b/features/account.feature @@ -14,12 +14,12 @@ Feature: Account API And the response contains "Our" account details Scenario: Get account by handle - When an authenticated "get" request is made to "/.ghost/activitypub/account/@Alice@fake-external-activitypub" + When an authenticated "get" request is made to "/.ghost/activitypub/account/@Alice@fake-external-activitypub.test" Then the request is accepted with a 200 And the response contains "Alice" account details Scenario: Get non-existent account - When an authenticated "get" request is made to "/.ghost/activitypub/account/@nonexistent@fake-external-activitypub" + When an authenticated "get" request is made to "/.ghost/activitypub/account/@nonexistent@fake-external-activitypub.test" Then the request is rejected with a 500 Scenario: Get account without authentication diff --git a/features/step_definitions/stepdefs.js b/features/step_definitions/stepdefs.js index be9d8c1f9..2bb6b67c3 100644 --- a/features/step_definitions/stepdefs.js +++ b/features/step_definitions/stepdefs.js @@ -24,8 +24,8 @@ import { WireMock } from 'wiremock-captain'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); -const URL_EXTERNAL_ACTIVITY_PUB = 'http://fake-external-activitypub'; -const URL_GHOST_ACTIVITY_PUB = 'http://fake-ghost-activitypub'; +const URL_EXTERNAL_ACTIVITY_PUB = 'http://fake-external-activitypub.test'; +const URL_GHOST_ACTIVITY_PUB = 'http://fake-ghost-activitypub.test'; async function createActivity(type, object, actor) { let activity; @@ -152,29 +152,29 @@ async function createActor(name, { remote = true, type = 'Person' } = {}) { 'https://www.w3.org/ns/activitystreams', 'https://w3id.org/security/data-integrity/v1', ], - id: 'http://fake-ghost-activitypub/.ghost/activitypub/users/index', - url: 'http://fake-ghost-activitypub/.ghost/activitypub/users/index', + id: 'http://fake-ghost-activitypub.test/.ghost/activitypub/users/index', + url: 'http://fake-ghost-activitypub.test/.ghost/activitypub/users/index', type, - handle: '@index@fake-ghost-activitypub', + handle: '@index@fake-ghost-activitypub.test', preferredUsername: 'index', name, summary: 'A test actor for testing', - inbox: 'http://fake-ghost-activitypub/.ghost/activitypub/inbox/index', - outbox: 'http://fake-ghost-activitypub/.ghost/activitypub/outbox/index', + inbox: 'http://fake-ghost-activitypub.test/.ghost/activitypub/inbox/index', + outbox: 'http://fake-ghost-activitypub.test/.ghost/activitypub/outbox/index', followers: - 'http://fake-ghost-activitypub/.ghost/activitypub/followers/index', + 'http://fake-ghost-activitypub.test/.ghost/activitypub/followers/index', following: - 'http://fake-ghost-activitypub/.ghost/activitypub/following/index', - liked: 'http://fake-ghost-activitypub/.ghost/activitypub/liked/index', + 'http://fake-ghost-activitypub.test/.ghost/activitypub/following/index', + liked: 'http://fake-ghost-activitypub.test/.ghost/activitypub/liked/index', 'https://w3id.org/security#publicKey': { - id: 'http://fake-ghost-activitypub/.ghost/activitypub/users/index#main-key', + id: 'http://fake-ghost-activitypub.test/.ghost/activitypub/users/index#main-key', type: 'https://w3id.org/security#Key', 'https://w3id.org/security#owner': { - id: 'http://fake-ghost-activitypub/.ghost/activitypub/users/index', + id: 'http://fake-ghost-activitypub.test/.ghost/activitypub/users/index', }, 'https://w3id.org/security#publicKeyPem': '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtSc3IqGjRaO3vcFdQ15D\nF90WVJC6tb2QwYBh9kQYVlQ1VhBiF6E4GK2okvyvukIL5PHLCgfQrfJmSiopk9Xo\n46Qri6rJbcPoWoZz/jWN0pfmU20hNuTQx6ebSoSkg6rHv1MKuy5LmDGLFC2ze3kU\nsY8u7X6TOBrifs/N+goLaH3+SkT2hZDKWJrmDyHzj043KLvXs/eiyu50M+ERoSlg\n70uO7QAXQFuLMILdy0UNJFM4xjlK6q4Jfbm4MC8QRG+i31AkmNvpY9JqCLqu0mGD\nBrdfJeN8PN+7DHW/Pzspf5RlJtlvBx1dS8Bxo2xteUyLGIaTZ9HZFhHc3IrmmKeW\naQIDAQAB\n-----END PUBLIC KEY-----\n', @@ -187,27 +187,27 @@ async function createActor(name, { remote = true, type = 'Person' } = {}) { 'https://www.w3.org/ns/activitystreams', 'https://w3id.org/security/data-integrity/v1', ], - id: `http://fake-external-activitypub/user/${name}`, - url: `http://fake-external-activitypub/user/${name}`, + id: `http://fake-external-activitypub.test/user/${name}`, + url: `http://fake-external-activitypub.test/user/${name}`, type, - handle: `@${name}@fake-external-activitypub`, + handle: `@${name}@fake-external-activitypub.test`, preferredUsername: name, name, summary: 'A test actor for testing', - inbox: `http://fake-external-activitypub/inbox/${name}`, - outbox: `http://fake-external-activitypub/inbox/${name}`, - followers: `http://fake-external-activitypub/followers/${name}`, - following: `http://fake-external-activitypub/following/${name}`, - liked: `http://fake-external-activitypub/liked/${name}`, + inbox: `http://fake-external-activitypub.test/inbox/${name}`, + outbox: `http://fake-external-activitypub.test/inbox/${name}`, + followers: `http://fake-external-activitypub.test/followers/${name}`, + following: `http://fake-external-activitypub.test/following/${name}`, + liked: `http://fake-external-activitypub.test/liked/${name}`, 'https://w3id.org/security#publicKey': { - id: 'http://fake-external-activitypub/user#main-key', + id: 'http://fake-external-activitypub.test/user#main-key', type: 'https://w3id.org/security#Key', 'https://w3id.org/security#owner': { - id: 'http://fake-external-activitypub/user', + id: 'http://fake-external-activitypub.test/user', }, 'https://w3id.org/security#publicKeyPem': '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtSc3IqGjRaO3vcFdQ15D\nF90WVJC6tb2QwYBh9kQYVlQ1VhBiF6E4GK2okvyvukIL5PHLCgfQrfJmSiopk9Xo\n46Qri6rJbcPoWoZz/jWN0pfmU20hNuTQx6ebSoSkg6rHv1MKuy5LmDGLFC2ze3kU\nsY8u7X6TOBrifs/N+goLaH3+SkT2hZDKWJrmDyHzj043KLvXs/eiyu50M+ERoSlg\n70uO7QAXQFuLMILdy0UNJFM4xjlK6q4Jfbm4MC8QRG+i31AkmNvpY9JqCLqu0mGD\nBrdfJeN8PN+7DHW/Pzspf5RlJtlvBx1dS8Bxo2xteUyLGIaTZ9HZFhHc3IrmmKeW\naQIDAQAB\n-----END PUBLIC KEY-----\n', @@ -279,17 +279,17 @@ async function createActor(name, { remote = true, type = 'Person' } = {}) { externalActivityPub.register( { method: 'GET', - endpoint: `/.well-known/webfinger?resource=${encodeURIComponent(`acct:${name}@fake-external-activitypub`)}`, + endpoint: `/.well-known/webfinger?resource=${encodeURIComponent(`acct:${name}@fake-external-activitypub.test`)}`, }, { status: 200, body: { - subject: `acct:${name}@fake-external-activitypub`, - aliases: [`http://fake-external-activitypub/user/${name}`], + subject: `acct:${name}@fake-external-activitypub.test`, + aliases: [`http://fake-external-activitypub.test/user/${name}`], links: [ { rel: 'self', - href: `http://fake-external-activitypub/user/${name}`, + href: `http://fake-external-activitypub.test/user/${name}`, type: 'application/activity+json', }, { @@ -317,13 +317,13 @@ function generateObject(type, content) { 'https://w3id.org/security/data-integrity/v1', ], type: 'Article', - id: `http://fake-external-activitypub/article/${uuid}`, - url: `http://fake-external-activitypub/article/${uuid}`, + id: `http://fake-external-activitypub.test/article/${uuid}`, + url: `http://fake-external-activitypub.test/article/${uuid}`, to: 'as:Public', - cc: 'http://fake-external-activitypub/followers', + cc: 'http://fake-external-activitypub.test/followers', content: content ?? '

This is a test article

', published: new Date(), - attributedTo: 'http://fake-external-activitypub/user', + attributedTo: 'http://fake-external-activitypub.test/user', }; } @@ -335,13 +335,13 @@ function generateObject(type, content) { 'https://w3id.org/security/data-integrity/v1', ], type: 'Note', - id: `http://fake-external-activitypub/note/${uuid}`, - url: `http://fake-external-activitypub/note/${uuid}`, + id: `http://fake-external-activitypub.test/note/${uuid}`, + url: `http://fake-external-activitypub.test/note/${uuid}`, to: 'as:Public', - cc: 'http://fake-external-activitypub/followers', + cc: 'http://fake-external-activitypub.test/followers', content: content ?? '

This is a test note

', published: new Date(), - attributedTo: 'http://fake-external-activitypub/user', + attributedTo: 'http://fake-external-activitypub.test/user', }; } @@ -353,8 +353,8 @@ function generateObject(type, content) { 'https://w3id.org/security/data-integrity/v1', ], type: 'Accept', - id: `http://fake-external-activitypub/accept/${uuid}`, - url: `http://fake-external-activitypub/accept/${uuid}`, + id: `http://fake-external-activitypub.test/accept/${uuid}`, + url: `http://fake-external-activitypub.test/accept/${uuid}`, }; } } @@ -400,7 +400,7 @@ function createWebhookPost() { custom_excerpt: null, feature_image: null, published_at: new Date().toISOString(), - url: `http://fake-external-activitypub/post/${uuid}`, + url: `http://fake-external-activitypub.test/post/${uuid}`, visibility: 'public', authors: [], }, @@ -635,7 +635,7 @@ Given('there is no entry in the sites table', async function () { When('we request the outbox', async function () { this.response = await fetchActivityPub( - 'http://fake-ghost-activitypub/.ghost/activitypub/outbox/index', + 'http://fake-ghost-activitypub.test/.ghost/activitypub/outbox/index', { headers: { Accept: 'application/ld+json', @@ -671,7 +671,7 @@ When( } this.response = await fetchActivityPub( - `http://fake-ghost-activitypub${requestPath}`, + `http://fake-ghost-activitypub.test${requestPath}`, { method: requestMethod, headers: { @@ -686,7 +686,7 @@ When( /^an authenticated (\"(post|put)\"\s)?request is made to "(.*)" with data:$/, async function (method, path, data) { this.response = await fetchActivityPub( - `http://fake-ghost-activitypub${path}`, + `http://fake-ghost-activitypub.test${path}`, { method: method, headers: { @@ -701,7 +701,7 @@ When( When('an unauthenticated request is made to {string}', async function (path) { this.response = await fetchActivityPub( - `http://fake-ghost-activitypub${path}`, + `http://fake-ghost-activitypub.test${path}`, { headers: { Accept: 'application/ld+json', @@ -713,7 +713,7 @@ When('an unauthenticated request is made to {string}', async function (path) { When('we request the site endpoint', async function () { this.response = await fetchActivityPub( - 'http://fake-ghost-activitypub/.ghost/activitypub/site', + 'http://fake-ghost-activitypub.test/.ghost/activitypub/site', { headers: { Accept: 'application/ld+json', @@ -762,7 +762,7 @@ Given('we are following {string}', async function (input) { const { actor } = await getActor.call(this, input); const followResponse = await fetchActivityPub( - `http://fake-ghost-activitypub/.ghost/activitypub/actions/follow/${actor.handle}`, + `http://fake-ghost-activitypub.test/.ghost/activitypub/actions/follow/${actor.handle}`, { method: 'POST', }, @@ -777,7 +777,7 @@ Given('we are following {string}', async function (input) { const accept = await createActivity('Accept', follow, actor); const acceptResponse = await fetchActivityPub( - 'http://fake-ghost-activitypub/.ghost/activitypub/inbox/index', + 'http://fake-ghost-activitypub.test/.ghost/activitypub/inbox/index', { method: 'POST', headers: { @@ -797,7 +797,7 @@ Given('we are following {string}', async function (input) { Given('we follow {string}', async function (name) { const handle = this.actors[name].handle; this.response = await fetchActivityPub( - `http://fake-ghost-activitypub/.ghost/activitypub/actions/follow/${handle}`, + `http://fake-ghost-activitypub.test/.ghost/activitypub/actions/follow/${handle}`, { method: 'POST', }, @@ -814,7 +814,7 @@ Given('we follow {string}', async function (name) { Given('we unfollow {string}', async function (name) { const handle = this.actors[name].handle; this.response = await fetchActivityPub( - `http://fake-ghost-activitypub/.ghost/activitypub/actions/unfollow/${handle}`, + `http://fake-ghost-activitypub.test/.ghost/activitypub/actions/unfollow/${handle}`, { method: 'POST', }, @@ -832,7 +832,7 @@ async function weAreFollowedBy(actor) { // Send the follow activity to the inbox const response = await fetchActivityPub( - 'http://fake-ghost-activitypub/.ghost/activitypub/inbox/index', + 'http://fake-ghost-activitypub.test/.ghost/activitypub/inbox/index', { method: 'POST', body: JSON.stringify(activity), @@ -863,7 +863,7 @@ Given('we are followed by:', async function (actors) { When('we like the object {string}', async function (name) { const id = this.objects[name].id; this.response = await fetchActivityPub( - `http://fake-ghost-activitypub/.ghost/activitypub/actions/like/${encodeURIComponent(id)}`, + `http://fake-ghost-activitypub.test/.ghost/activitypub/actions/like/${encodeURIComponent(id)}`, { method: 'POST', }, @@ -873,7 +873,7 @@ When('we like the object {string}', async function (name) { When('we unlike the object {string}', async function (name) { const id = this.objects[name].id; this.response = await fetchActivityPub( - `http://fake-ghost-activitypub/.ghost/activitypub/actions/unlike/${encodeURIComponent(id)}`, + `http://fake-ghost-activitypub.test/.ghost/activitypub/actions/unlike/${encodeURIComponent(id)}`, { method: 'POST', }, @@ -882,7 +882,7 @@ When('we unlike the object {string}', async function (name) { Then('the object {string} should be liked', async function (name) { const response = await fetchActivityPub( - 'http://fake-ghost-activitypub/.ghost/activitypub/inbox/index', + 'http://fake-ghost-activitypub.test/.ghost/activitypub/inbox/index', { headers: { Accept: 'application/ld+json', @@ -899,7 +899,7 @@ Then('the object {string} should be liked', async function (name) { Then('the object {string} should not be liked', async function (name) { const response = await fetchActivityPub( - 'http://fake-ghost-activitypub/.ghost/activitypub/inbox/index', + 'http://fake-ghost-activitypub.test/.ghost/activitypub/inbox/index', { headers: { Accept: 'application/ld+json', @@ -917,7 +917,7 @@ Then('the object {string} should not be liked', async function (name) { When('we repost the object {string}', async function (name) { const id = this.objects[name].id; this.response = await fetchActivityPub( - `http://fake-ghost-activitypub/.ghost/activitypub/actions/repost/${encodeURIComponent(id)}`, + `http://fake-ghost-activitypub.test/.ghost/activitypub/actions/repost/${encodeURIComponent(id)}`, { method: 'POST', }, @@ -926,7 +926,7 @@ When('we repost the object {string}', async function (name) { Then('the object {string} should be reposted', async function (name) { const response = await fetchActivityPub( - 'http://fake-ghost-activitypub/.ghost/activitypub/inbox/index', + 'http://fake-ghost-activitypub.test/.ghost/activitypub/inbox/index', { headers: { Accept: 'application/ld+json', @@ -945,7 +945,7 @@ Then( 'the object {string} should have a repost count of {int}', async function (name, repostCount) { const response = await fetchActivityPub( - 'http://fake-ghost-activitypub/.ghost/activitypub/inbox/index', + 'http://fake-ghost-activitypub.test/.ghost/activitypub/inbox/index', { headers: { Accept: 'application/ld+json', @@ -964,7 +964,7 @@ Then( When('we undo the repost of the object {string}', async function (name) { const id = this.objects[name].id; this.response = await fetchActivityPub( - `http://fake-ghost-activitypub/.ghost/activitypub/actions/derepost/${encodeURIComponent(id)}`, + `http://fake-ghost-activitypub.test/.ghost/activitypub/actions/derepost/${encodeURIComponent(id)}`, { method: 'POST', }, @@ -973,7 +973,7 @@ When('we undo the repost of the object {string}', async function (name) { Then('the object {string} should not be reposted', async function (name) { const response = await fetchActivityPub( - 'http://fake-ghost-activitypub/.ghost/activitypub/inbox/index', + 'http://fake-ghost-activitypub.test/.ghost/activitypub/inbox/index', { headers: { Accept: 'application/ld+json', @@ -989,7 +989,7 @@ Then('the object {string} should not be reposted', async function (name) { async function getObjectInCollection(objectName, collectionType) { const initialResponse = await fetchActivityPub( - `http://fake-ghost-activitypub/.ghost/activitypub/${collectionType}/index`, + `http://fake-ghost-activitypub.test/.ghost/activitypub/${collectionType}/index`, { headers: { Accept: 'application/ld+json', @@ -1151,7 +1151,7 @@ When( const activity = this.activities[activityName]; this.response = await fetchActivityPub( - 'http://fake-ghost-activitypub/.ghost/activitypub/inbox/index', + 'http://fake-ghost-activitypub.test/.ghost/activitypub/inbox/index', { method: 'POST', headers: { @@ -1200,7 +1200,7 @@ async function waitForInboxActivity( const MAX_RETRIES = 5; const response = await fetchActivityPub( - 'http://fake-ghost-activitypub/.ghost/activitypub/inbox/index', + 'http://fake-ghost-activitypub.test/.ghost/activitypub/inbox/index', { headers: { Accept: 'application/ld+json', @@ -1241,7 +1241,7 @@ async function waitForInboxActivity( async function findInOutbox(activity) { const initialResponse = await fetchActivityPub( - 'http://fake-ghost-activitypub/.ghost/activitypub/outbox/index', + 'http://fake-ghost-activitypub.test/.ghost/activitypub/outbox/index', { headers: { Accept: 'application/ld+json', @@ -1314,7 +1314,7 @@ async function waitForOutboxActivityType( const MAX_RETRIES = 5; const initialResponse = await fetchActivityPub( - 'http://fake-ghost-activitypub/.ghost/activitypub/outbox/index', + 'http://fake-ghost-activitypub.test/.ghost/activitypub/outbox/index', { headers: { Accept: 'application/ld+json', @@ -1376,7 +1376,7 @@ Then( 'Activity {string} is sent to all followers', async function (activityName) { const followersResponse = await fetchActivityPub( - 'http://fake-ghost-activitypub/.ghost/activitypub/followers/index', + 'http://fake-ghost-activitypub.test/.ghost/activitypub/followers/index', ); const followersResponseJson = await followersResponse.json(); @@ -1411,7 +1411,7 @@ Then( const endpoints = { 'post.published': - 'http://fake-ghost-activitypub/.ghost/activitypub/webhooks/post/published', + 'http://fake-ghost-activitypub.test/.ghost/activitypub/webhooks/post/published', }; Given('a {string} webhook', function (string) { @@ -1584,7 +1584,7 @@ Then( Then('{string} is not in our Inbox', async function (activityName) { const response = await fetchActivityPub( - 'http://fake-ghost-activitypub/.ghost/activitypub/inbox/index', + 'http://fake-ghost-activitypub.test/.ghost/activitypub/inbox/index', { headers: { Accept: 'application/ld+json', @@ -1601,7 +1601,7 @@ Then('{string} is not in our Inbox', async function (activityName) { Then('{string} is in our Followers', async function (actorName) { const initialResponse = await fetchActivityPub( - 'http://fake-ghost-activitypub/.ghost/activitypub/followers/index', + 'http://fake-ghost-activitypub.test/.ghost/activitypub/followers/index', { headers: { Accept: 'application/ld+json', @@ -1621,7 +1621,7 @@ Then('{string} is in our Followers', async function (actorName) { Then('{string} is in our Followers once only', async function (actorName) { const initialResponse = await fetchActivityPub( - 'http://fake-ghost-activitypub/.ghost/activitypub/followers/index', + 'http://fake-ghost-activitypub.test/.ghost/activitypub/followers/index', { headers: { Accept: 'application/ld+json', @@ -1680,7 +1680,7 @@ Then( When('we attempt to create a note with no content', async function () { this.response = await fetchActivityPub( - 'http://fake-ghost-activitypub/.ghost/activitypub/actions/note', + 'http://fake-ghost-activitypub.test/.ghost/activitypub/actions/note', { method: 'POST', headers: { @@ -1693,7 +1693,7 @@ When('we attempt to create a note with no content', async function () { When('we attempt to create a note with invalid content', async function () { this.response = await fetchActivityPub( - 'http://fake-ghost-activitypub/.ghost/activitypub/actions/note', + 'http://fake-ghost-activitypub.test/.ghost/activitypub/actions/note', { method: 'POST', headers: { @@ -1710,7 +1710,7 @@ When( 'we create a note {string} with the content', async function (noteName, noteContent) { this.response = await fetchActivityPub( - 'http://fake-ghost-activitypub/.ghost/activitypub/actions/note', + 'http://fake-ghost-activitypub.test/.ghost/activitypub/actions/note', { method: 'POST', headers: { @@ -1737,7 +1737,7 @@ When( const object = this.objects[objectName]; this.response = await fetchActivityPub( - `http://fake-ghost-activitypub/.ghost/activitypub/actions/reply/${encodeURIComponent(object.id)}`, + `http://fake-ghost-activitypub.test/.ghost/activitypub/actions/reply/${encodeURIComponent(object.id)}`, { method: 'POST', headers: { @@ -1755,7 +1755,7 @@ When( const object = this.objects[objectName]; this.response = await fetchActivityPub( - `http://fake-ghost-activitypub/.ghost/activitypub/actions/reply/${encodeURIComponent(object.id)}`, + `http://fake-ghost-activitypub.test/.ghost/activitypub/actions/reply/${encodeURIComponent(object.id)}`, { method: 'POST', headers: { @@ -1770,10 +1770,10 @@ When( ); When('we attempt to reply to an unknown object', async function () { - const id = 'http://fake-external-activitypub/note/123'; + const id = 'http://fake-external-activitypub.test/note/123'; this.response = await fetchActivityPub( - `http://fake-ghost-activitypub/.ghost/activitypub/actions/reply/${encodeURIComponent(id)}`, + `http://fake-ghost-activitypub.test/.ghost/activitypub/actions/reply/${encodeURIComponent(id)}`, { method: 'POST', headers: { @@ -1792,7 +1792,7 @@ When( const object = this.objects[objectName]; this.response = await fetchActivityPub( - `http://fake-ghost-activitypub/.ghost/activitypub/actions/reply/${encodeURIComponent(object.id)}`, + `http://fake-ghost-activitypub.test/.ghost/activitypub/actions/reply/${encodeURIComponent(object.id)}`, { method: 'POST', headers: { @@ -1831,7 +1831,7 @@ When('we request the feed with the next cursor', async function () { const nextCursor = responseJson.next; this.response = await fetchActivityPub( - `http://fake-ghost-activitypub/.ghost/activitypub/feed/index?next=${encodeURIComponent(nextCursor)}`, + `http://fake-ghost-activitypub.test/.ghost/activitypub/feed/index?next=${encodeURIComponent(nextCursor)}`, { headers: { Accept: 'application/json', diff --git a/src/helpers/activitypub/actor.ts b/src/helpers/activitypub/actor.ts index cc7277481..e671babc6 100644 --- a/src/helpers/activitypub/actor.ts +++ b/src/helpers/activitypub/actor.ts @@ -90,14 +90,6 @@ export async function isFollowedByDefaultSiteAccount( } export function isHandle(handle: string): boolean { - // In test environments, we have handles that don't match the regex. Ex: @Alice@fake-external-activitypub - if ( - process.env.NODE_ENV === 'testing' && - handle.endsWith('@fake-external-activitypub') - ) { - return true; - } - return /^@([\w.-]+)@([\w-]+\.[\w.-]+[^.])$/.test(handle); }