diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb
index 87fef27a627189c0677ba56bb67a070b6ecf8c16..e95b0f48d35545e5aa52409a496d56e43fea63b8 100644
--- a/app/controllers/posts_controller.rb
+++ b/app/controllers/posts_controller.rb
@@ -3,8 +3,6 @@
 #   the COPYRIGHT file.
 
 class PostsController < ApplicationController
-  include PostsHelper
-
   before_action :authenticate_user!, only: :destroy
   before_action :set_format_if_malformed_from_status_net, only: :show
 
@@ -26,38 +24,36 @@ class PostsController < ApplicationController
   end
 
   def show
-    post_service = PostService.new(id: params[:id], user: current_user)
-    post_service.mark_user_notifications
-    @post = post_service.post
+    post = post_service.find(params[:id])
+    post_service.mark_user_notifications(post.id)
     respond_to do |format|
-      format.html { gon.post = post_service.present_json }
-      format.xml { render xml: @post.to_diaspora_xml }
-      format.json { render json: post_service.present_json }
+      format.html {
+        gon.post = PostPresenter.new(post, current_user)
+        render locals: {post: post}
+      }
+      format.mobile { render locals: {post: post} }
+      format.xml { render xml: post.to_diaspora_xml }
+      format.json { render json: PostPresenter.new(post, current_user) }
     end
   end
 
-  def iframe
-    render text: post_iframe_url(params[:id]), layout: false
-  end
-
   def oembed
     post_id = OEmbedPresenter.id_from_url(params.delete(:url))
-    post_service = PostService.new(id: post_id, user: current_user,
-                                    oembed: params.slice(:format, :maxheight, :minheight))
-    render json: post_service.present_oembed
+    post = post_service.find(post_id)
+    oembed = params.slice(:format, :maxheight, :minheight)
+    render json: OEmbedPresenter.new(post, oembed)
+  rescue
+    render nothing: true, status: 404
   end
 
   def interactions
-    post_service = PostService.new(id: params[:id], user: current_user)
-    respond_with post_service.present_interactions_json
+    post = post_service.find(params[:id])
+    respond_with PostInteractionPresenter.new(post, current_user)
   end
 
   def destroy
-    post_service = PostService.new(id: params[:id], user: current_user)
-    post_service.retract_post
-    @post = post_service.post
+    post_service.destroy(params[:id])
     respond_to do |format|
-      format.js { render "destroy", layout: false, format: :js }
       format.json { render nothing: true, status: 204 }
       format.any { redirect_to stream_path }
     end
@@ -65,6 +61,10 @@ class PostsController < ApplicationController
 
   private
 
+  def post_service
+    @post_service ||= PostService.new(current_user)
+  end
+
   def set_format_if_malformed_from_status_net
     request.format = :html if request.format == "application/html+xml"
   end
diff --git a/app/models/post.rb b/app/models/post.rb
index 70dcea5834b2f64e7f97b9de235e2e353262eb37..77681c070cb2837aca467ebd14c341312da16f7f 100644
--- a/app/models/post.rb
+++ b/app/models/post.rb
@@ -155,21 +155,4 @@ class Post < ActiveRecord::Base
   def nsfw
     self.author.profile.nsfw?
   end
-
-  def self.find_public(id)
-    where(post_key(id) => id).includes(:author, comments: :author).first.tap do |post|
-      raise ActiveRecord::RecordNotFound.new("could not find a post with id #{id}") unless post
-      raise Diaspora::NonPublic unless post.public?
-    end
-  end
-
-  def self.find_non_public_by_guid_or_id_with_user(id, user)
-    user.find_visible_shareable_by_id(Post, id, key: post_key(id)).tap do |post|
-      raise ActiveRecord::RecordNotFound.new("could not find a post with id #{id}") unless post
-    end
-  end
-
-  def self.post_key(id)
-    id.to_s.length <= 8 ? :id : :guid
-  end
 end
diff --git a/app/services/comment_service.rb b/app/services/comment_service.rb
index b417933a90d447a64b00f8e531f66205a455183e..3f11208cc8fee2b4b797e89703373e12ee248160 100644
--- a/app/services/comment_service.rb
+++ b/app/services/comment_service.rb
@@ -4,7 +4,7 @@ class CommentService
   end
 
   def create(post_id, text)
-    post = find_post!(post_id)
+    post = post_service.find(post_id)
     user.comment!(post, text)
   end
 
@@ -19,24 +19,14 @@ class CommentService
   end
 
   def find_for_post(post_id)
-    find_post!(post_id).comments.for_a_stream
+    post_service.find(post_id).comments.for_a_stream
   end
 
   private
 
   attr_reader :user
 
-  def find_post!(post_id)
-    find_post(post_id).tap do |post|
-      raise ActiveRecord::RecordNotFound unless post
-    end
-  end
-
-  def find_post(post_id)
-    if user
-      user.find_visible_shareable_by_id(Post, post_id)
-    else
-      Post.find_by_id_and_public(post_id, true)
-    end
+  def post_service
+    @post_service ||= PostService.new(user)
   end
 end
diff --git a/app/services/post_service.rb b/app/services/post_service.rb
index 1408d064297cb471770aa34a8c647fac728f9823..928375e29b40fd6e9919757fe1d02cc16d0a1221 100644
--- a/app/services/post_service.rb
+++ b/app/services/post_service.rb
@@ -1,64 +1,59 @@
 class PostService
-  attr_reader :post
-
-  def initialize(params)
-    @id = params[:id]
-    @user = params[:user]
-    @oembed = params[:oembed] || {}
-    assign_post
+  def initialize(user=nil)
+    @user = user
   end
 
-  def assign_post
+  def find(id_or_guid)
     if user
-      @post = Post.find_non_public_by_guid_or_id_with_user(id, user)
+      find_non_public_by_guid_or_id_with_user(id_or_guid)
     else
-      @post = Post.find_public(id)
+      find_public(id_or_guid)
     end
   end
 
-  def present_json
-    PostPresenter.new(post, user)
+  def mark_user_notifications(post_id)
+    return unless user
+    mark_comment_reshare_like_notifications_read(post_id)
+    mark_mention_notifications_read(post_id)
   end
 
-  def present_interactions_json
-    PostInteractionPresenter.new(post, user)
+  def destroy(post_id)
+    post = find(post_id)
+    raise Diaspora::NotMine unless post.author == user.person
+    user.retract(post)
   end
 
-  def present_oembed
-    OEmbedPresenter.new(post, oembed)
-  end
+  private
 
-  def mark_user_notifications
-    mark_corresponding_notifications_read if user
-  end
+  attr_reader :user
 
-  def retract_post
-    raise Diaspora::NotMine unless user_owns_post?
-    user.retract(@post)
+  def find_public(id_or_guid)
+    Post.where(post_key(id_or_guid) => id_or_guid).first.tap do |post|
+      raise ActiveRecord::RecordNotFound, "could not find a post with id #{id_or_guid}" unless post
+      raise Diaspora::NonPublic unless post.public?
+    end
   end
 
-  private
-
-  attr_reader :user, :id, :oembed
-
-  def user_owns_post?
-    post.author == user.person
+  def find_non_public_by_guid_or_id_with_user(id_or_guid)
+    user.find_visible_shareable_by_id(Post, id_or_guid, key: post_key(id_or_guid)).tap do |post|
+      raise ActiveRecord::RecordNotFound, "could not find a post with id #{id_or_guid} for user #{user.id}" unless post
+    end
   end
 
-  def mark_corresponding_notifications_read
-    mark_comment_reshare_like_notifications_read
-    mark_mention_notifications_read
+  # We can assume a guid is at least 16 characters long as we have guids set to hex(8) since we started using them.
+  def post_key(id_or_guid)
+    id_or_guid.to_s.length < 16 ? :id : :guid
   end
 
-  def mark_comment_reshare_like_notifications_read
-    notification = Notification.where(recipient_id: user.id, target_type: "Post", target_id: post.id, unread: true)
-    notification.each do |notification|
+  def mark_comment_reshare_like_notifications_read(post_id)
+    notifications = Notification.where(recipient_id: user.id, target_type: "Post", target_id: post_id, unread: true)
+    notifications.each do |notification|
       notification.set_read_state(true)
     end
   end
 
-  def mark_mention_notifications_read
-    mention = post.mentions.where(person_id: user.person_id).first
+  def mark_mention_notifications_read(post_id)
+    mention = find(post_id).mentions.where(person_id: user.person_id).first
     Notification.where(recipient_id: user.id, target_type: "Mention", target_id: mention.id, unread: true)
       .first.try(:set_read_state, true) if mention
   end
diff --git a/app/views/posts/destroy.js.erb b/app/views/posts/destroy.js.erb
deleted file mode 100644
index 5a0c3dd8320e7cd5d111721a26c7fd7cbb415879..0000000000000000000000000000000000000000
--- a/app/views/posts/destroy.js.erb
+++ /dev/null
@@ -1,2 +0,0 @@
-var target = $("#<%= @post.guid %>")
-target.hide('blind', { direction: 'vertical' }, 300, function(){ target.remove() });
diff --git a/app/views/posts/show.html.haml b/app/views/posts/show.html.haml
index 6b09af4df97b2decaf688237c55572fc77b8682f..6798f31cecfe574ff806c449f2048b963f9b532c 100644
--- a/app/views/posts/show.html.haml
+++ b/app/views/posts/show.html.haml
@@ -3,7 +3,7 @@
 -#   the COPYRIGHT file.
 
 - content_for :page_title do
-  = post_page_title @post
+  = post_page_title post
 
 - content_for :content do
   #container.container-fluid
diff --git a/app/views/posts/show.mobile.haml b/app/views/posts/show.mobile.haml
index 63bf093765e1b3aea25a0307cdf774e546a90e65..61d8556e811ebee79d089869ccb8f6590d5d3aad 100644
--- a/app/views/posts/show.mobile.haml
+++ b/app/views/posts/show.mobile.haml
@@ -3,6 +3,6 @@
 -#   the COPYRIGHT file.
 
 .stream
-  = render :partial => 'shared/stream_element',
-    :locals => {:post => @post, :commenting_disabled => commenting_disabled?(@post), :expanded_info => true}
+  = render partial: "shared/stream_element",
+    locals: {post: post, commenting_disabled: commenting_disabled?(post), expanded_info: true}
 
diff --git a/app/views/shared/_stream_element.mobile.haml b/app/views/shared/_stream_element.mobile.haml
index bb6869503a497b22387d17ac19f284d393f91371..237a36af6fb8fea559508aa01d7e5c66d46baff6 100644
--- a/app/views/shared/_stream_element.mobile.haml
+++ b/app/views/shared/_stream_element.mobile.haml
@@ -26,7 +26,7 @@
       != reactions_link(post, "active")
       .comment-container
         %ul.comments
-          = render partial: "comments/comment", collection: @post.comments.for_a_stream, locals: {post: @post}
+          = render partial: "comments/comment", collection: post.comments.for_a_stream, locals: {post: post}
 
     - else
       != reactions_link(post)
diff --git a/config/routes.rb b/config/routes.rb
index e06d98c84288ea8f56ecb2216daf643e58fa39ff..292cc1fb8ab15a3a87e2ea93f13790080a82ec79 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -40,10 +40,7 @@ Diaspora::Application.routes.draw do
     resources :comments, only: %i(new create destroy index)
   end
 
-
-
   get 'p/:id' => 'posts#show', :as => 'short_post'
-  get 'posts/:id/iframe' => 'posts#iframe', :as => 'iframe'
 
   # roll up likes into a nested resource above
   resources :comments, :only => [:create, :destroy] do
diff --git a/spec/controllers/posts_controller_spec.rb b/spec/controllers/posts_controller_spec.rb
index 8da4502f3dcda0d456f58d4820500648b8f57aab..c8d2d215dd320b5c9ff518585ddccffe8eb64d1a 100644
--- a/spec/controllers/posts_controller_spec.rb
+++ b/spec/controllers/posts_controller_spec.rb
@@ -5,104 +5,86 @@
 require "spec_helper"
 
 describe PostsController, type: :controller do
-  let!(:post_service_double) { double("post_service") }
-
-  before do
-    aspect = alice.aspects.first
-    @message = alice.build_post :status_message, text: "ohai", to: aspect.id
-    @message.save!
-
-    alice.add_to_streams(@message, [aspect])
-    alice.dispatch_post @message, to: aspect.id
-
-    allow(PostService).to receive(:new).and_return(post_service_double)
-  end
+  let(:post) { alice.post(:status_message, text: "ohai", to: alice.aspects.first) }
 
   describe "#show" do
-    before do
-      expect(post_service_double).to receive(:mark_user_notifications)
-      allow(post_service_double).to receive(:present_json)
-    end
-
     context "user signed in" do
       context "given a post that the user is allowed to see" do
         before do
           sign_in :user, alice
-          expect(post_service_double).to receive(:post).and_return(@message)
         end
 
         it "succeeds" do
-          get :show, id: @message.id
+          expect_any_instance_of(PostService).to receive(:mark_user_notifications).with(post.id)
+
+          get :show, id: post.id
           expect(response).to be_success
         end
 
-        it 'succeeds after removing a mention when closing the mentioned user\'s account' do
+        it "succeeds after removing a mention when closing the mentioned user's account" do
           user = FactoryGirl.create(:user, username: "user")
           alice.share_with(user.person, alice.aspects.first)
-          msg = alice.build_post :status_message,
-                                 text: "Mention @{User ; #{user.diaspora_handle}}", public: true, to: "all"
-          msg.save!
+
+          msg = alice.post(:status_message, text: "Mention @{User ; #{user.diaspora_handle}}", public: true)
+
           expect(msg.mentioned_people.count).to eq(1)
           user.destroy
+
           get :show, id: msg.id
           expect(response).to be_success
         end
 
         it "renders the application layout on mobile" do
-          get :show, id: @message.id, format: :mobile
+          get :show, id: post.id, format: :mobile
           expect(response).to render_template("layouts/application")
         end
 
         it "succeeds on mobile with a reshare" do
-          get :show, id: FactoryGirl.create(:reshare, author: alice.person).id, format: :mobile
+          reshare_id = FactoryGirl.create(:reshare, author: alice.person).id
+          expect_any_instance_of(PostService).to receive(:mark_user_notifications).with(reshare_id)
+
+          get :show, id: reshare_id, format: :mobile
           expect(response).to be_success
         end
       end
 
       context "given a post that the user is not allowed to see" do
         before do
-          sign_in :user, alice
-          expect(post_service_double).to receive(:post).and_raise(Diaspora::NonPublic)
+          sign_in :user, eve
         end
 
         it "returns a 404" do
-          get :show, id: @message.id
-          expect(response.code).to eq("404")
+          expect {
+            get :show, id: post.id
+          }.to raise_error ActiveRecord::RecordNotFound
         end
       end
     end
 
     context "user not signed in" do
       context "given a public post" do
-        before :each do
-          @status = alice.post(:status_message, text: "hello", public: true, to: "all")
-          expect(post_service_double).to receive(:post).and_return(@status)
-        end
+        let(:public) { alice.post(:status_message, text: "hello", public: true) }
 
         it "shows a public post" do
-          get :show, id: @status.id
+          get :show, id: public.id
           expect(response.body).to match "hello"
         end
 
         it "succeeds for statusnet" do
           @request.env["HTTP_ACCEPT"] = "application/html+xml,text/html"
-          get :show, id: @status.id
+          get :show, id: public.id
           expect(response.body).to match "hello"
         end
 
         it "responds with diaspora xml if format is xml" do
-          get :show, id: @status.guid, format: :xml
-          expect(response.body).to eq(@status.to_diaspora_xml)
+          get :show, id: public.guid, format: :xml
+          expect(response.body).to eq(public.to_diaspora_xml)
         end
       end
 
       context "given a limited post" do
-        before do
-          expect(post_service_double).to receive(:post).and_raise(Diaspora::NonPublic)
-        end
-
         it "forces the user to sign" do
-          get :show, id: @message.id
+          get :show, id: post.id
           expect(response).to be_redirect
           expect(response).to redirect_to new_user_session_path
         end
@@ -110,40 +92,55 @@ describe PostsController, type: :controller do
     end
   end
 
-  describe "iframe" do
-    it "contains an iframe" do
-      get :iframe, id: @message.id
+  describe "oembed" do
+    it "works when you can see it" do
+      sign_in alice
+      get :oembed, url: "/posts/#{post.id}"
       expect(response.body).to match /iframe/
     end
-  end
 
-  describe "oembed" do
-    it "receives a present oembed" do
-      expect(post_service_double).to receive(:present_oembed)
-      get :oembed, url: "/posts/#{@message.id}"
+    it "returns a 404 response when the post is not found" do
+      get :oembed, url: "/posts/#{post.id}"
+      expect(response.status).to eq(404)
     end
   end
 
   describe "#destroy" do
-    before do
-      sign_in alice
-    end
+    context "own post" do
+      before do
+        sign_in alice
+      end
+
+      it "works when it is your post" do
+        expect_any_instance_of(PostService).to receive(:destroy).with(post.id.to_s)
 
-    it "will receive a retract post" do
-      expect(post_service_double).to receive(:retract_post)
-      expect(post_service_double).to receive(:post).and_return(@message)
-      message = alice.post(:status_message, text: "hey", to: alice.aspects.first.id)
-      delete :destroy, format: :js, id: message.id
+        delete :destroy, format: :json, id: post.id
+        expect(response.status).to eq(204)
+      end
+
+      it "redirects to stream on mobile" do
+        delete :destroy, format: :mobile, id: post.id
+        expect(response).to be_redirect
+        expect(response).to redirect_to stream_path
+      end
     end
 
-    context "when Diaspora::NotMine is raised by retract post" do
+    context "post of another user" do
       it "will respond with a 403" do
-        expect(post_service_double).to receive(:retract_post).and_raise(Diaspora::NotMine)
-        message = alice.post(:status_message, text: "hey", to: alice.aspects.first.id)
-        delete :destroy, format: :js, id: message.id
+        sign_in :user, bob
+
+        delete :destroy, format: :json, id: post.id
         expect(response.body).to eq("You are not allowed to do that")
         expect(response.status).to eq(403)
       end
+
+      it "will respond with a 404 if the post is not visible" do
+        sign_in :user, eve
+
+        expect {
+          delete :destroy, format: :json, id: post.id
+        }.to raise_error ActiveRecord::RecordNotFound
+      end
     end
   end
 end
diff --git a/spec/models/post_spec.rb b/spec/models/post_spec.rb
index 3a988f2a273f1fc18beef4a1805ea6a8125082fb..c6f33d6c10f6fa4b4743be81f9dff94fb75230cb 100644
--- a/spec/models/post_spec.rb
+++ b/spec/models/post_spec.rb
@@ -415,56 +415,4 @@ describe Post, :type => :model do
       expect(post.interacted_at).not_to be_blank
     end
   end
-
-  describe "#find_public" do
-    it "succeeds with an id" do
-      post = FactoryGirl.create :status_message, public: true
-      expect(Post.find_public post.id).to eq(post)
-    end
-
-    it "succeeds with an guid" do
-      post = FactoryGirl.create :status_message, public: true
-      expect(Post.find_public post.guid).to eq(post)
-    end
-
-    it "raises ActiveRecord::RecordNotFound for a non-existing id without a user" do
-      allow(Post).to receive_messages where: double(includes: double(first: nil))
-      expect {
-        Post.find_public 123
-      }.to raise_error ActiveRecord::RecordNotFound
-    end
-
-    it "raises Diaspora::NonPublic for a private post without a user" do
-      post = FactoryGirl.create :status_message
-      expect {
-        Post.find_public post.id
-      }.to raise_error Diaspora::NonPublic
-    end
-  end
-
-  describe "#find_non_public_by_guid_or_id_with_user" do
-    it "succeeds with an id" do
-      post = FactoryGirl.create :status_message_in_aspect
-      expect(Post.find_non_public_by_guid_or_id_with_user(post.id, post.author.owner)).to eq(post)
-    end
-
-    it "succeeds with an guid" do
-      post = FactoryGirl.create :status_message_in_aspect
-      expect(Post.find_non_public_by_guid_or_id_with_user(post.guid, post.author.owner)).to eq(post)
-    end
-
-    it "looks up on the passed user object if it's non-nil" do
-      post = FactoryGirl.create :status_message
-      user = double
-      expect(user).to receive(:find_visible_shareable_by_id).with(Post, post.id, key: :id).and_return(post)
-      Post.find_non_public_by_guid_or_id_with_user(post.id, user)
-    end
-
-    it "raises ActiveRecord::RecordNotFound with a non-existing id and a user" do
-      user = double(find_visible_shareable_by_id: nil)
-      expect {
-        Post.find_non_public_by_guid_or_id_with_user(123, user)
-      }.to raise_error ActiveRecord::RecordNotFound
-    end
-  end
 end
diff --git a/spec/services/comment_service_spec.rb b/spec/services/comment_service_spec.rb
index 947fa89e5c12afa0946e1c44a59231795048bc81..d6b24cfb746376b44da2d5433130cf115744e013 100644
--- a/spec/services/comment_service_spec.rb
+++ b/spec/services/comment_service_spec.rb
@@ -88,7 +88,7 @@ describe CommentService do
       it "does not return comments for private post" do
         expect {
           CommentService.new.find_for_post(post.id)
-        }.to raise_error ActiveRecord::RecordNotFound
+        }.to raise_error Diaspora::NonPublic
       end
     end
 
diff --git a/spec/services/post_service_spec.rb b/spec/services/post_service_spec.rb
index 47f57d750c0734a3f510c18f80b7bdb81480cb77..660e7add4386bb517bccaaab5fee8f85a76ba129 100644
--- a/spec/services/post_service_spec.rb
+++ b/spec/services/post_service_spec.rb
@@ -1,127 +1,128 @@
 require "spec_helper"
 
 describe PostService do
-  before do
-    aspect = alice.aspects.first
-    @message = alice.build_post :status_message, text: "ohai", to: aspect.id
-    @message.save!
+  let(:post) { alice.post(:status_message, text: "ohai", to: alice.aspects.first) }
+  let(:public) { alice.post(:status_message, text: "hey", public: true) }
 
-    alice.add_to_streams(@message, [aspect])
-    alice.dispatch_post @message, to: aspect.id
-  end
+  describe "#find" do
+    context "with user" do
+      it "returns the post, if it is the users post" do
+        expect(PostService.new(alice).find(post.id)).to eq(post)
+      end
 
-  describe "#assign_post" do
-    context "when the post is private" do
-      it "RecordNotFound if the post cannot be found" do
-        expect { PostService.new(id: 1_234_567, user: alice) }.to raise_error(ActiveRecord::RecordNotFound)
+      it "works with guid" do
+        expect(PostService.new(alice).find(post.guid)).to eq(post)
       end
-      it "NonPublic if there is no user" do
-        expect { PostService.new(id: @message.id) }.to raise_error(Diaspora::NonPublic)
+
+      it "returns the post, if the user can see the it" do
+        expect(PostService.new(bob).find(post.id)).to eq(post)
       end
-      it "RecordNotFound if user cannot see post" do
-        expect { PostService.new(id: @message.id, user: eve) }.to raise_error(ActiveRecord::RecordNotFound)
+
+      it "returns the post, if it is public" do
+        expect(PostService.new(eve).find(public.id)).to eq(public)
+      end
+
+      it "RecordNotFound if the post cannot be found" do
+        expect {
+          PostService.new(alice).find("unknown")
+        }.to raise_error ActiveRecord::RecordNotFound, "could not find a post with id unknown for user #{alice.id}"
+      end
+
+      it "RecordNotFound if user cannot see the post" do
+        expect {
+          PostService.new(eve).find(post.id)
+        }.to raise_error ActiveRecord::RecordNotFound, "could not find a post with id #{post.id} for user #{eve.id}"
       end
     end
 
-    context "when the post is public" do
+    context "without user" do
+      it "returns the post, if it is public" do
+        expect(PostService.new.find(public.id)).to eq(public)
+      end
+
+      it "works with guid" do
+        expect(PostService.new.find(public.guid)).to eq(public)
+      end
+
+      it "NonPublic if the post is private" do
+        expect {
+          PostService.new.find(post.id)
+        }.to raise_error Diaspora::NonPublic
+      end
+
       it "RecordNotFound if the post cannot be found" do
-        expect { PostService.new(id: 1_234_567) }.to raise_error(ActiveRecord::RecordNotFound)
+        expect {
+          PostService.new.find("unknown")
+        }.to raise_error ActiveRecord::RecordNotFound, "could not find a post with id unknown"
       end
     end
 
-    # We want to be using guids from now on for this post route, but do not want to break
-    # pre-exisiting permalinks.  We can assume a guid is 8 characters long as we have
-    # guids set to hex(8) since we started using them.
     context "id/guid switch" do
-      before do
-        @status = alice.post(:status_message, text: "hello", public: true, to: "all")
-      end
+      let(:public) { alice.post(:status_message, text: "ohai", public: true) }
 
-      it "assumes guids less than 8 chars are ids and not guids" do
-        post = Post.where(id: @status.id.to_s)
-        expect(Post).to receive(:where).with(hash_including(id: @status.id)).and_return(post).at_least(:once)
-        PostService.new(id: @status.id, user: alice)
+      it "assumes ids less than 16 chars are ids and not guids" do
+        post = Post.where(id: public.id)
+        expect(Post).to receive(:where).with(hash_including(id: "123456789012345")).and_return(post).at_least(:once)
+        PostService.new(alice).find("123456789012345")
       end
 
-      it "assumes guids more than (or equal to) 8 chars are actually guids" do
-        post = Post.where(guid: @status.guid)
-        expect(Post).to receive(:where).with(hash_including(guid: @status.guid)).and_return(post).at_least(:once)
-        PostService.new(id: @status.guid, user: alice)
+      it "assumes ids more than (or equal to) 16 chars are actually guids" do
+        post = Post.where(guid: public.guid)
+        expect(Post).to receive(:where).with(hash_including(guid: "1234567890123456")).and_return(post).at_least(:once)
+        PostService.new(alice).find("1234567890123456")
       end
     end
   end
 
   describe "#mark_user_notifications" do
     it "marks a corresponding notifications as read" do
-      FactoryGirl.create(:notification, recipient: alice, target: @message, unread: true)
-      FactoryGirl.create(:notification, recipient: alice, target: @message, unread: true)
-      post_service = PostService.new(id: @message.id, user: alice)
-      expect { post_service.mark_user_notifications }.to change(Notification.where(unread: true), :count).by(-2)
+      FactoryGirl.create(:notification, recipient: alice, target: post, unread: true)
+      FactoryGirl.create(:notification, recipient: alice, target: post, unread: true)
+
+      expect {
+        PostService.new(alice).mark_user_notifications(post.id)
+      }.to change(Notification.where(unread: true), :count).by(-2)
     end
 
     it "marks a corresponding mention notification as read" do
       status_text = "this is a text mentioning @{Mention User ; #{alice.diaspora_handle}} ... have fun testing!"
-      status_msg =
-        bob.post(:status_message, text: status_text, public: true, to: "all")
-      mention = status_msg.mentions.where(person_id: alice.person.id).first
-      FactoryGirl.create(:notification, recipient: alice, target_type: "Mention", target_id: mention.id, unread: true)
-      post_service = PostService.new(id: status_msg.id, user: alice)
-      expect { post_service.mark_user_notifications }.to change(Notification.where(unread: true), :count).by(-1)
-    end
-  end
-
-  describe "#present_json" do
-    it "works for a private post" do
-      post_service = PostService.new(id: @message.id, user: alice)
-      expect(post_service.present_json.to_json).to match(/\"text\"\:\"ohai\"/)
-    end
-
-    it "works for a public post " do
-      status = alice.post(:status_message, text: "hello", public: true, to: "all")
-      post_service = PostService.new(id: status.id)
-      expect(post_service.present_json.to_json).to match(/\"text\"\:\"hello\"/)
-    end
-  end
+      mention_post = bob.post(:status_message, text: status_text, public: true)
 
-  describe "#present_oembed" do
-    it "works for a private post" do
-      post_service = PostService.new(id: @message.id, user: alice)
-      expect(post_service.present_oembed.to_json).to match(/iframe/)
+      expect {
+        PostService.new(alice).mark_user_notifications(mention_post.id)
+      }.to change(Notification.where(unread: true), :count).by(-1)
     end
 
-    it "works for a public post" do
-      status = alice.post(:status_message, text: "hello", public: true, to: "all")
-      post_service = PostService.new(id: status.id)
-      expect(post_service.present_oembed.to_json).to match(/iframe/)
+    it "does nothing without a user" do
+      expect_any_instance_of(PostService).not_to receive(:mark_comment_reshare_like_notifications_read).with(post.id)
+      expect_any_instance_of(PostService).not_to receive(:mark_mention_notifications_read).with(post.id)
+      PostService.new.mark_user_notifications(post.id)
     end
   end
 
-  describe "#retract_post" do
+  describe "#destroy" do
     it "let a user delete his message" do
-      message = alice.post(:status_message, text: "hey", to: alice.aspects.first.id)
-      post_service = PostService.new(id: message.id, user: alice)
-      post_service.retract_post
-      expect(StatusMessage.find_by_id(message.id)).to be_nil
+      PostService.new(alice).destroy(post.id)
+      expect(StatusMessage.find_by_id(post.id)).to be_nil
     end
 
     it "sends a retraction on delete" do
-      message = alice.post(:status_message, text: "hey", to: alice.aspects.first.id)
-      post_service = PostService.new(id: message.id, user: alice)
-      expect(alice).to receive(:retract).with(message)
-      post_service.retract_post
+      expect(alice).to receive(:retract).with(post)
+      PostService.new(alice).destroy(post.id)
     end
 
     it "will not let you destroy posts visible to you but that you do not own" do
-      message = bob.post(:status_message, text: "hey", to: bob.aspects.first.id)
-      post_service = PostService.new(id: message.id, user: alice)
-      expect { post_service.retract_post }.to raise_error(Diaspora::NotMine)
-      expect(StatusMessage.exists?(message.id)).to be true
+      expect {
+        PostService.new(bob).destroy(post.id)
+      }.to raise_error Diaspora::NotMine
+      expect(StatusMessage.find_by_id(post.id)).not_to be_nil
     end
 
     it "will not let you destroy posts that are not visible to you" do
-      message = eve.post(:status_message, text: "hey", to: eve.aspects.first.id)
-      expect { PostService.new(id: message.id, user: alice) }.to raise_error(ActiveRecord::RecordNotFound)
-      expect(StatusMessage.exists?(message.id)).to be true
+      expect {
+        PostService.new(eve).destroy(post.id)
+      }.to raise_error(ActiveRecord::RecordNotFound)
+      expect(StatusMessage.find_by_id(post.id)).not_to be_nil
     end
   end
 end