From 5ea3ef99e1edd609912b2176ad059227be496d2c Mon Sep 17 00:00:00 2001 From: Armin Date: Wed, 13 Mar 2019 00:25:32 +0100 Subject: [PATCH] Fixed follow feature + clean database after tests run + wait for user to be created before proceed --- package.json | 2 +- src/activitypub/ActivityPub.js | 10 ++-- src/activitypub/routes/verify.js | 2 +- .../security/httpSignature.spec.js | 2 +- test/features/activity-delete.feature | 4 +- test/features/activity-follow.feature | 33 +++++++------ test/features/object-article.feature | 2 +- test/features/support/steps.js | 48 +++++++++++++------ test/features/world.js | 4 +- 9 files changed, 63 insertions(+), 44 deletions(-) diff --git a/package.json b/package.json index fc0d5a751..db42c1135 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "test:cucumber:cmd": "wait-on tcp:4001 tcp:4123 && cucumber-js --require-module @babel/register --exit test/", "test:jest:cmd:debug": "wait-on tcp:4001 tcp:4123 && node --inspect-brk ./node_modules/.bin/jest -i --forceExit --detectOpenHandles --runInBand", "test:jest": "run-p --race test:before:* 'test:jest:cmd {@}' --", - "test:cucumber": "ACTIVITYPUB_PORT=4123 run-p --race test:before:* 'test:cucumber:cmd {@}' --", + "test:cucumber": "run-p --race test:before:* 'test:cucumber:cmd {@}' --", "test:jest:debug": "run-p --race test:before:* 'test:jest:cmd:debug {@}' --", "test:coverage": "nyc report --reporter=text-lcov > coverage.lcov", "db:script:seed": "wait-on tcp:4001 && babel-node src/seed/seed-db.js", diff --git a/src/activitypub/ActivityPub.js b/src/activitypub/ActivityPub.js index ed64816b9..bcebf4d49 100644 --- a/src/activitypub/ActivityPub.js +++ b/src/activitypub/ActivityPub.js @@ -35,12 +35,13 @@ export default class ActivityPub { const url = new URL(process.env.GRAPHQL_URI) activityPub = new ActivityPub(url.hostname || 'localhost', url.port || 4000, url.origin) - // integrated into "server's" express framework + // integrate into running graphql express server server.express.set('ap', activityPub) + server.express.set('port', url.port) server.express.use(router) - debug('ActivityPub middleware added to the express service') + console.log('-> ActivityPub middleware added to the graphql express server') } else { - debug('ActivityPub middleware already added to the express service') + console.log('-> ActivityPub middleware already added to the graphql express server') } } @@ -60,6 +61,7 @@ export default class ActivityPub { if (err) return reject(err) debug(`name = ${toActorName}@${this.domain}`) // save shared inbox + toActorObject = JSON.parse(toActorObject) await this.dataSource.addSharedInboxEndpoint(toActorObject.endpoints.sharedInbox) let followersCollectionPage = await this.dataSource.getFollowersCollectionPage(activity.object) @@ -159,7 +161,7 @@ export default class ActivityPub { switch (activity.object.type) { case 'Follow': const followObject = activity.object - const followingCollectionPage = await this.getFollowingCollectionPage(followObject.actor) + const followingCollectionPage = await this.collections.getFollowingCollectionPage(followObject.actor) followingCollectionPage.orderedItems.push(followObject.object) await this.dataSource.saveFollowingCollectionPage(followingCollectionPage) } diff --git a/src/activitypub/routes/verify.js b/src/activitypub/routes/verify.js index 34676b44f..bb5850b3e 100644 --- a/src/activitypub/routes/verify.js +++ b/src/activitypub/routes/verify.js @@ -4,7 +4,7 @@ const debug = require('debug')('ea:verify') export default async (req, res, next) => { debug(`actorId = ${req.body.actor}`) // TODO stop if signature validation fails - if (await verifySignature(`${req.protocol}://${req.hostname}:${req.port}${req.originalUrl}`, req.headers)) { + if (await verifySignature(`${req.protocol}://${req.hostname}:${req.app.get('port')}${req.originalUrl}`, req.headers)) { debug('verify = true') next() } else { diff --git a/src/activitypub/security/httpSignature.spec.js b/src/activitypub/security/httpSignature.spec.js index bf1162219..fe09eda8a 100644 --- a/src/activitypub/security/httpSignature.spec.js +++ b/src/activitypub/security/httpSignature.spec.js @@ -60,7 +60,7 @@ describe('Signature creation and verification', () => { httpSignature = createSignature(user.privateKey, 'http://localhost:4001/activitypub/users/test-user#main-key', 'https://democracy-app.de/activitypub/users/max/inbox', headers) }) - it('verifies a Signature by ', async () => { + it('verifies a Signature correct', async () => { headers['Signature'] = httpSignature const isVerified = await verifySignature('https://democracy-app.de/activitypub/users/max/inbox', headers) expect(isVerified).to.equal(true) diff --git a/test/features/activity-delete.feature b/test/features/activity-delete.feature index b5ef7158a..f5e269cce 100644 --- a/test/features/activity-delete.feature +++ b/test/features/activity-delete.feature @@ -37,7 +37,7 @@ Feature: Delete an object "published": "2019-02-07T19:37:55.002Z", "attributedTo": "https://aronda.org/activitypub/users/bernd-das-brot", "content": "Hi Max, how are you?", - "to": "https://localhost:4123/activitypub/users/moritz" + "to": "https://www.w3.org/ns/activitystreams#Public" } } """ @@ -50,6 +50,6 @@ Feature: Delete an object "published": "2019-02-07T19:37:55.002Z", "attributedTo": "https://aronda.org/activitypub/users/bernd-das-brot", "content": "Hi Max, how are you?", - "to": "https://localhost:4123/activitypub/users/moritz" + "to": "https://www.w3.org/ns/activitystreams#Public" } """ diff --git a/test/features/activity-follow.feature b/test/features/activity-follow.feature index a6974309c..6634a342b 100644 --- a/test/features/activity-follow.feature +++ b/test/features/activity-follow.feature @@ -7,45 +7,44 @@ Feature: Follow a user Given our own server runs at "http://localhost:4123" And we have the following users in our database: | Slug | - | peter-lustiger | - | bob-der-baumeister | - | karl-heinz | + | stuart-little | + | tero-vota | Scenario: Send a follow to a user inbox and make sure it's added to the right followers collection - When I send a POST request with the following activity to "/activitypub/users/peter-lustiger/inbox": + When I send a POST request with the following activity to "/activitypub/users/tero-vota/inbox": """ { "@context": "https://www.w3.org/ns/activitystreams", - "id": "https://localhost:4123/activitypub/users/bob-der-baumeister/status/83J23549sda1k72fsa4567na42312455kad83", + "id": "https://localhost:4123/activitypub/users/stuart-little/status/83J23549sda1k72fsa4567na42312455kad83", "type": "Follow", - "actor": "http://localhost:4123/activitypub/users/bob-der-baumeister", - "object": "http://localhost:4123/activitypub/users/peter-lustiger" + "actor": "http://localhost:4123/activitypub/users/stuart-little", + "object": "http://localhost:4123/activitypub/users/tero-vota" } """ Then I expect the status code to be 200 - And the follower is added to the followers collection of "peter-lustiger" + And the follower is added to the followers collection of "tero-vota" """ - https://localhost:4123/activitypub/users/bob-der-baumeister + http://localhost:4123/activitypub/users/stuart-little """ Scenario: Send an undo activity to revert the previous follow activity - When I send a POST request with the following activity to "/activitypub/users/bob-der-baumeister/inbox": + When I send a POST request with the following activity to "/activitypub/users/stuart-little/inbox": """ { "@context": "https://www.w3.org/ns/activitystreams", - "id": "https://localhost:4123/activitypub/users/peter-lustiger/status/a4DJ2afdg323v32641vna42lkj685kasd2", + "id": "https://localhost:4123/activitypub/users/tero-vota/status/a4DJ2afdg323v32641vna42lkj685kasd2", "type": "Undo", - "actor": "http://localhost:4123/activitypub/users/peter-lustiger", + "actor": "http://localhost:4123/activitypub/users/tero-vota", "object": { - "id": "https://localhost:4123/activitypub/users/bob-der-baumeister/status/83J23549sda1k72fsa4567na42312455kad83", + "id": "https://localhost:4123/activitypub/users/stuart-little/status/83J23549sda1k72fsa4567na42312455kad83", "type": "Follow", - "actor": "http://localhost:4123/activitypub/users/bob-der-baumeister", - "object": "http://localhost:4123/activitypub/users/peter-lustiger" + "actor": "http://localhost:4123/activitypub/users/stuart-little", + "object": "http://localhost:4123/activitypub/users/tero-vota" } } """ Then I expect the status code to be 200 - And the follower is removed from the followers collection of "peter-lustiger" + And the follower is removed from the followers collection of "tero-vota" """ - https://localhost:4123/activitypub/users/bob-der-baumeister + http://localhost:4123/activitypub/users/stuart-little """ diff --git a/test/features/object-article.feature b/test/features/object-article.feature index 5358f2925..030e408e9 100644 --- a/test/features/object-article.feature +++ b/test/features/object-article.feature @@ -22,7 +22,7 @@ Feature: Send and receive Articles "published": "2019-02-07T19:37:55.002Z", "attributedTo": "https://aronda.org/users/marvin", "content": "Hi Max, how are you?", - "to": "https://localhost:4123/activitypub/users/max" + "to": "as:Public" } } """ diff --git a/test/features/support/steps.js b/test/features/support/steps.js index d7581f549..a535a523e 100644 --- a/test/features/support/steps.js +++ b/test/features/support/steps.js @@ -22,14 +22,15 @@ function createUser (slug) { AfterAll('Clean up the test data', function () { debug('All the tests are done! Deleting test data') + return factory.cleanDatabase() }) Given('our own server runs at {string}', function (string) { // just documenation }) -Given('we have the following users in our database:', async function (dataTable) { - await Promise.all(dataTable.hashes().map((user) => { +Given('we have the following users in our database:', function (dataTable) { + return Promise.all(dataTable.hashes().map((user) => { return createUser(user.Slug) })) }) @@ -45,6 +46,20 @@ When('I send a GET request to {string}', async function (pathname) { When('I send a POST request with the following activity to {string}:', async function (inboxUrl, activity) { debug(`inboxUrl = ${inboxUrl}`) debug(`activity = ${activity}`) + const splitted = inboxUrl.split('/') + const slug = splitted[splitted.indexOf('users') + 1] + let result + do { + result = await client.request(` + query { + User(slug: "${slug}") { + id + slug + actorId + } + } + `) + } while (result.User.length === 0) this.lastInboxUrl = inboxUrl this.lastActivity = activity const response = await this.post(inboxUrl, activity) @@ -100,22 +115,19 @@ Then('the follower is removed from the followers collection of {string}', async expect(responseObject.orderedItems).to.not.include(follower) }) -Then('the activity is added to the users inbox collection', async function () { - -}) - Then('the post with id {string} to be created', async function (id) { - setTimeout(async () => { - const result = await client.request(` + let result + do { + result = await client.request(` query { Post(id: "${id}") { title } } `) + } while (result.Post.length === 0) - expect(result.data.Post).to.be.an('array').that.is.not.empty // eslint-disable-line - }, 2000) + expect(result.Post).to.be.an('array').that.is.not.empty // eslint-disable-line }) Then('the object is removed from the outbox collection of {string}', async function (name, object) { @@ -128,9 +140,14 @@ Then('I send a GET request to {string} and expect a ordered collection', () => { }) +Then('the activity is added to the users inbox collection', async function () { + +}) + Then('the post with id {string} has been liked by {string}', async function (id, slug) { - setTimeout(async () => { - const result = await client.request(` + let result + do { + result = await client.request(` query { Post(id: "${id}") { shoutedBy { @@ -139,7 +156,8 @@ Then('the post with id {string} has been liked by {string}', async function (id, } } `) - expect(result.data.Post[0].shoutedBy).to.be.an('array').that.is.not.empty // eslint-disable-line - expect(result.data.Post[0].shoutedBy[0].slug).to.equal(slug) - }, 2000) + } while (result.Post.length === 0) + + expect(result.Post[0].shoutedBy).to.be.an('array').that.is.not.empty // eslint-disable-line + expect(result.Post[0].shoutedBy[0].slug).to.equal(slug) }) diff --git a/test/features/world.js b/test/features/world.js index 1b96e0761..be436b536 100644 --- a/test/features/world.js +++ b/test/features/world.js @@ -20,8 +20,8 @@ class CustomWorld { 'Accept': 'application/activity+json' }}, function (error, response, body) { if (!error) { - debug(`get response = ${response.headers['content-type']}`) - debug(`body = ${body}`) + debug(`get content-type = ${response.headers['content-type']}`) + debug(`get body = ${JSON.stringify(typeof body === 'string' ? JSON.parse(body) : body, null, 2)}`) resolve({ lastResponse: body, lastContentType: response.headers['content-type'], statusCode: response.statusCode }) } else { reject(error)