From f40f74b20d736b72152ffdf3823026b9bce6f920 Mon Sep 17 00:00:00 2001
From: Dessalines <tyhou13@gmx.com>
Date: Wed, 3 Jun 2020 17:55:32 -0400
Subject: [PATCH] Adding additional 3-instance integration test for community
 announce.

---
 docker/federation-test/run-tests.sh  |   1 +
 docker/federation/docker-compose.yml |  41 +++++++-
 docker/federation/nginx.conf         |  35 +++++++
 server/src/apub/shared_inbox.rs      |   1 -
 ui/src/api_tests/api.spec.ts         | 142 ++++++++++++++++++++++++++-
 5 files changed, 215 insertions(+), 5 deletions(-)

diff --git a/docker/federation-test/run-tests.sh b/docker/federation-test/run-tests.sh
index 9d8a7e58fb1..b2d319dddf0 100755
--- a/docker/federation-test/run-tests.sh
+++ b/docker/federation-test/run-tests.sh
@@ -14,6 +14,7 @@ yarn
 echo "Waiting for Lemmy to start..."
 while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8540/api/v1/site')" != "200" ]]; do sleep 1; done
 while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8550/api/v1/site')" != "200" ]]; do sleep 1; done
+while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8560/api/v1/site')" != "200" ]]; do sleep 1; done
 yarn api-test || true
 popd
 
diff --git a/docker/federation/docker-compose.yml b/docker/federation/docker-compose.yml
index 496e7fa60ea..3f986a8149d 100644
--- a/docker/federation/docker-compose.yml
+++ b/docker/federation/docker-compose.yml
@@ -6,6 +6,7 @@ services:
     ports:
       - "8540:8540"
       - "8550:8550"
+      - "8560:8560"
     volumes:
       # Hack to make this work from both docker/federation/ and docker/federation-test/
       - ../federation/nginx.conf:/etc/nginx/nginx.conf
@@ -14,6 +15,8 @@ services:
       - pictshare_alpha
       - lemmy_beta
       - pictshare_beta
+      - lemmy_gamma
+      - pictshare_gamma
       - iframely
     restart: "always"
 
@@ -26,7 +29,7 @@ services:
       - LEMMY_FRONT_END_DIR=/app/dist
       - LEMMY_FEDERATION__ENABLED=true
       - LEMMY_FEDERATION__TLS_ENABLED=false
-      - LEMMY_FEDERATION__INSTANCE_WHITELIST=lemmy_beta
+      - LEMMY_FEDERATION__INSTANCE_WHITELIST=lemmy_beta,lemmy_gamma
       - LEMMY_PORT=8540
       - LEMMY_SETUP__ADMIN_USERNAME=lemmy_alpha
       - LEMMY_SETUP__ADMIN_PASSWORD=lemmy
@@ -60,7 +63,7 @@ services:
       - LEMMY_FRONT_END_DIR=/app/dist
       - LEMMY_FEDERATION__ENABLED=true
       - LEMMY_FEDERATION__TLS_ENABLED=false
-      - LEMMY_FEDERATION__INSTANCE_WHITELIST=lemmy_alpha
+      - LEMMY_FEDERATION__INSTANCE_WHITELIST=lemmy_alpha,lemmy_gamma
       - LEMMY_PORT=8550
       - LEMMY_SETUP__ADMIN_USERNAME=lemmy_beta
       - LEMMY_SETUP__ADMIN_PASSWORD=lemmy
@@ -85,6 +88,40 @@ services:
       - ./volumes/pictshare_beta:/usr/share/nginx/html/data
     restart: always
 
+  lemmy_gamma:
+    image: lemmy-federation:latest
+    environment:
+      - LEMMY_HOSTNAME=lemmy_gamma:8560
+      - LEMMY_DATABASE_URL=postgres://lemmy:password@postgres_gamma:5432/lemmy
+      - LEMMY_JWT_SECRET=changeme
+      - LEMMY_FRONT_END_DIR=/app/dist
+      - LEMMY_FEDERATION__ENABLED=true
+      - LEMMY_FEDERATION__TLS_ENABLED=false
+      - LEMMY_FEDERATION__INSTANCE_WHITELIST=lemmy_alpha,lemmy_beta
+      - LEMMY_PORT=8560
+      - LEMMY_SETUP__ADMIN_USERNAME=lemmy_gamma
+      - LEMMY_SETUP__ADMIN_PASSWORD=lemmy
+      - LEMMY_SETUP__SITE_NAME=lemmy_gamma
+      - RUST_BACKTRACE=1
+      - RUST_LOG=debug
+    restart: always
+    depends_on:
+      - postgres_gamma
+  postgres_gamma:
+    image: postgres:12-alpine
+    environment:
+      - POSTGRES_USER=lemmy
+      - POSTGRES_PASSWORD=password
+      - POSTGRES_DB=lemmy
+    volumes:
+      - ./volumes/postgres_gamma:/var/lib/postgresql/data
+    restart: always
+  pictshare_gamma:
+    image: shtripok/pictshare:latest
+    volumes:
+      - ./volumes/pictshare_gamma:/usr/share/nginx/html/data
+    restart: always
+
   iframely:
     image: dogbin/iframely:latest
     volumes:
diff --git a/docker/federation/nginx.conf b/docker/federation/nginx.conf
index c0633ea4242..a73b0954e24 100644
--- a/docker/federation/nginx.conf
+++ b/docker/federation/nginx.conf
@@ -72,4 +72,39 @@ http {
             proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
         }
     }
+
+    server {
+        listen 8560;
+        server_name 127.0.0.1;
+        access_log off;
+
+        # Upload limit for pictshare
+        client_max_body_size 50M;
+
+        location / {
+            proxy_pass http://lemmy_gamma:8560;
+            proxy_set_header X-Real-IP $remote_addr;
+            proxy_set_header Host $host;
+            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+
+            # WebSocket support
+            proxy_http_version 1.1;
+            proxy_set_header Upgrade $http_upgrade;
+            proxy_set_header Connection "upgrade";
+        }
+
+        location /pictshare/ {
+            proxy_pass http://pictshare_gamma:80/;
+            proxy_set_header X-Real-IP $remote_addr;
+            proxy_set_header Host $host;
+            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+        }
+
+        location /iframely/ {
+            proxy_pass http://iframely:80/;
+            proxy_set_header X-Real-IP $remote_addr;
+            proxy_set_header Host $host;
+            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+        }
+    }
 }
diff --git a/server/src/apub/shared_inbox.rs b/server/src/apub/shared_inbox.rs
index 81dd14c3998..3ecc873e532 100644
--- a/server/src/apub/shared_inbox.rs
+++ b/server/src/apub/shared_inbox.rs
@@ -218,7 +218,6 @@ where
   let community = Community::read_from_actor_id(conn, &community_uri)?;
   if community.local {
     let sending_user = get_or_fetch_and_upsert_remote_user(&sender.to_string(), &conn)?;
-    insert_activity(&conn, sending_user.id, &activity, false)?;
     Community::do_announce(activity, &community, &sending_user, conn)
   } else {
     Ok(HttpResponse::NotFound().finish())
diff --git a/ui/src/api_tests/api.spec.ts b/ui/src/api_tests/api.spec.ts
index d5da17c7f0a..4e38cfee4c4 100644
--- a/ui/src/api_tests/api.spec.ts
+++ b/ui/src/api_tests/api.spec.ts
@@ -26,12 +26,17 @@ import {
 } from '../interfaces';
 
 let lemmyAlphaUrl = 'http://localhost:8540';
-let lemmyBetaUrl = 'http://localhost:8550';
 let lemmyAlphaApiUrl = `${lemmyAlphaUrl}/api/v1`;
-let lemmyBetaApiUrl = `${lemmyBetaUrl}/api/v1`;
 let lemmyAlphaAuth: string;
+
+let lemmyBetaUrl = 'http://localhost:8550';
+let lemmyBetaApiUrl = `${lemmyBetaUrl}/api/v1`;
 let lemmyBetaAuth: string;
 
+let lemmyGammaUrl = 'http://localhost:8560';
+let lemmyGammaApiUrl = `${lemmyGammaUrl}/api/v1`;
+let lemmyGammaAuth: string;
+
 // Workaround for tests being run before beforeAll() is finished
 // https://github.com/facebook/jest/issues/9527#issuecomment-592406108
 describe('main', () => {
@@ -67,6 +72,22 @@ describe('main', () => {
     }).then(d => d.json());
 
     lemmyBetaAuth = resB.jwt;
+
+    console.log('Logging in as lemmy_gamma');
+    let formC = {
+      username_or_email: 'lemmy_gamma',
+      password: 'lemmy',
+    };
+
+    let resG: LoginResponse = await fetch(`${lemmyGammaApiUrl}/user/login`, {
+      method: 'POST',
+      headers: {
+        'Content-Type': 'application/json',
+      },
+      body: wrapper(formC),
+    }).then(d => d.json());
+
+    lemmyGammaAuth = resG.jwt;
   });
 
   describe('post_search', () => {
@@ -190,6 +211,51 @@ describe('main', () => {
       // Make sure the follow response went through
       expect(followResAgain.community.local).toBe(false);
       expect(followResAgain.community.name).toBe('main');
+
+      // Also make G follow B
+
+      // Use short-hand search url
+      let searchUrlG = `${lemmyGammaApiUrl}/search?q=!main@lemmy_beta:8550&type_=All&sort=TopAll`;
+
+      let searchResponseG: SearchResponse = await fetch(searchUrlG, {
+        method: 'GET',
+      }).then(d => d.json());
+
+      expect(searchResponseG.communities[0].name).toBe('main');
+
+      let followFormG: FollowCommunityForm = {
+        community_id: searchResponseG.communities[0].id,
+        follow: true,
+        auth: lemmyGammaAuth,
+      };
+
+      let followResG: CommunityResponse = await fetch(
+        `${lemmyGammaApiUrl}/community/follow`,
+        {
+          method: 'POST',
+          headers: {
+            'Content-Type': 'application/json',
+          },
+          body: wrapper(followFormG),
+        }
+      ).then(d => d.json());
+
+      // Make sure the follow response went through
+      expect(followResG.community.local).toBe(false);
+      expect(followResG.community.name).toBe('main');
+
+      // Check that you are subscribed to it locally
+      let followedCommunitiesUrlG = `${lemmyGammaApiUrl}/user/followed_communities?&auth=${lemmyGammaAuth}`;
+      let followedCommunitiesResG: GetFollowedCommunitiesResponse = await fetch(
+        followedCommunitiesUrlG,
+        {
+          method: 'GET',
+        }
+      ).then(d => d.json());
+
+      expect(followedCommunitiesResG.communities[1].community_local).toBe(
+        false
+      );
     });
   });
 
@@ -1176,6 +1242,78 @@ describe('main', () => {
       expect(searchResponse.comments[0].content).toBe(content);
     });
   });
+
+  describe('announce', () => {
+    test('A and G subscribe to B (center) A does action, it gets announced to G', async () => {
+      // A and G are already subscribed to B earlier.
+      //
+      let postName = 'A jest test post for announce';
+      let createPostForm: PostForm = {
+        name: postName,
+        auth: lemmyAlphaAuth,
+        community_id: 2,
+        creator_id: 2,
+        nsfw: false,
+      };
+
+      let createPostRes: PostResponse = await fetch(
+        `${lemmyAlphaApiUrl}/post`,
+        {
+          method: 'POST',
+          headers: {
+            'Content-Type': 'application/json',
+          },
+          body: wrapper(createPostForm),
+        }
+      ).then(d => d.json());
+      expect(createPostRes.post.name).toBe(postName);
+
+      // Make sure that post got announced to Gamma
+      let searchUrl = `${lemmyGammaApiUrl}/search?q=${createPostRes.post.ap_id}&type_=All&sort=TopAll`;
+      let searchResponse: SearchResponse = await fetch(searchUrl, {
+        method: 'GET',
+      }).then(d => d.json());
+      let postId = searchResponse.posts[0].id;
+      expect(searchResponse.posts[0].name).toBe(postName);
+
+      // Create a test comment on Gamma, make sure it gets announced to alpha
+      let commentContent =
+        'A jest test federated comment announce, lets mention @lemmy_beta@lemmy_beta:8550';
+
+      let commentForm: CommentForm = {
+        content: commentContent,
+        post_id: postId,
+        auth: lemmyGammaAuth,
+      };
+
+      let createCommentRes: CommentResponse = await fetch(
+        `${lemmyGammaApiUrl}/comment`,
+        {
+          method: 'POST',
+          headers: {
+            'Content-Type': 'application/json',
+          },
+          body: wrapper(commentForm),
+        }
+      ).then(d => d.json());
+
+      expect(createCommentRes.comment.content).toBe(commentContent);
+      expect(createCommentRes.comment.community_local).toBe(false);
+      expect(createCommentRes.comment.creator_local).toBe(true);
+      expect(createCommentRes.comment.score).toBe(1);
+
+      // Get the post from alpha, make sure it has gamma's comment
+      let getPostUrl = `${lemmyAlphaApiUrl}/post?id=5`;
+      let getPostRes: GetPostResponse = await fetch(getPostUrl, {
+        method: 'GET',
+      }).then(d => d.json());
+
+      expect(getPostRes.comments[0].content).toBe(commentContent);
+      expect(getPostRes.comments[0].community_local).toBe(true);
+      expect(getPostRes.comments[0].creator_local).toBe(false);
+      expect(getPostRes.comments[0].score).toBe(1);
+    });
+  });
 });
 
 function wrapper(form: any): string {