From fca6121c6a90b26db61aabf36b5d99d724bada9c Mon Sep 17 00:00:00 2001
From: cmrd Senya <senya@riseup.net>
Date: Sun, 2 Apr 2017 19:37:47 +0300
Subject: [PATCH] Exporter::PostsWithActivity class

This class allows to query posts where a person made any activity (submitted comments,
likes, participations or poll participations).
---
 app/models/status_message.rb                  |  1 +
 lib/diaspora/exporter/posts_with_activity.rb  | 54 +++++++++++++++++++
 .../exporter/posts_with_activity_spec.rb      | 23 ++++++++
 3 files changed, 78 insertions(+)
 create mode 100644 lib/diaspora/exporter/posts_with_activity.rb
 create mode 100644 spec/lib/diaspora/exporter/posts_with_activity_spec.rb

diff --git a/app/models/status_message.rb b/app/models/status_message.rb
index 423ea01fce..a0c9d727ba 100644
--- a/app/models/status_message.rb
+++ b/app/models/status_message.rb
@@ -19,6 +19,7 @@ class StatusMessage < Post
 
   has_one :location
   has_one :poll, autosave: true
+  has_many :poll_participations, through: :poll
 
   attr_accessor :oembed_url
   attr_accessor :open_graph_url
diff --git a/lib/diaspora/exporter/posts_with_activity.rb b/lib/diaspora/exporter/posts_with_activity.rb
new file mode 100644
index 0000000000..9cbec03c17
--- /dev/null
+++ b/lib/diaspora/exporter/posts_with_activity.rb
@@ -0,0 +1,54 @@
+module Diaspora
+  class Exporter
+    # This class allows to query posts where a person made any activity (submitted comments,
+    # likes, participations or poll participations).
+    class PostsWithActivity
+      # TODO: docs
+      def initialize(user)
+        @user = user
+      end
+
+      # TODO: docs
+      def query
+        Post.from("(#{sql_union_all_activities}) AS posts")
+      end
+
+      private
+
+      attr_reader :user
+
+      def person
+        user.person
+      end
+
+      def sql_union_all_activities
+        all_activities.map(&:to_sql).join(" UNION ")
+      end
+
+      def all_activities
+        [comments_activity, likes_activity, subscriptions, polls_activity].compact
+      end
+
+      def likes_activity
+        other_people_posts.liked_by(person)
+      end
+
+      def comments_activity
+        other_people_posts.commented_by(person)
+      end
+
+      def subscriptions
+        other_people_posts.subscribed_by(user)
+      end
+
+      def polls_activity
+        StatusMessage.where.not(author_id: person.id).joins(:poll_participations)
+                     .where(poll_participations: {author_id: person.id})
+      end
+
+      def other_people_posts
+        Post.where.not(author_id: person.id)
+      end
+    end
+  end
+end
diff --git a/spec/lib/diaspora/exporter/posts_with_activity_spec.rb b/spec/lib/diaspora/exporter/posts_with_activity_spec.rb
new file mode 100644
index 0000000000..c6335cbb45
--- /dev/null
+++ b/spec/lib/diaspora/exporter/posts_with_activity_spec.rb
@@ -0,0 +1,23 @@
+describe Diaspora::Exporter::PostsWithActivity do
+  let(:user) { FactoryGirl.create(:user) }
+  let(:instance) { Diaspora::Exporter::PostsWithActivity.new(user) }
+
+  describe "#query" do
+    let(:activity) {
+      [
+        user.person.likes.first.target,
+        user.person.comments.first.parent,
+        user.person.poll_participations.first.parent.status_message,
+        user.person.participations.first.target
+      ]
+    }
+
+    before do
+      DataGenerator.create(user, %i[activity participation])
+    end
+
+    it "returns all posts with person's activity" do
+      expect(instance.query).to match_array(activity)
+    end
+  end
+end
-- 
GitLab