Custom Wordpress Serializer and Path, with Specs

This commit is contained in:
Robin Ward 2013-06-28 13:55:34 -04:00
parent 2d6118297d
commit 2deaf8ef98
8 changed files with 137 additions and 42 deletions

View File

@ -25,7 +25,12 @@ class TopicsController < ApplicationController
caches_action :avatar, cache_path: Proc.new {|c| "#{c.params[:post_number]}-#{c.params[:topic_id]}" }
def show
opts = params.slice(:username_filters, :best_of, :page, :post_number, :posts_before, :posts_after, :best)
# We'd like to migrate the wordpress feed to another url. This keeps up backwards compatibility with
# existing installs.
return wordpress if params[:best].present?
opts = params.slice(:username_filters, :best_of, :page, :post_number, :posts_before, :posts_after)
begin
@topic_view = TopicView.new(params[:id] || params[:topic_id], current_user, opts)
rescue Discourse::NotFound
@ -34,8 +39,6 @@ class TopicsController < ApplicationController
return redirect_to(topic.relative_url)
end
raise Discourse::NotFound if @topic_view.posts.blank? && !(opts[:best].to_i > 0)
anonymous_etag(@topic_view.topic) do
redirect_to_correct_topic && return if slugs_do_not_match
View.create_for(@topic_view.topic, request.remote_ip, current_user)
@ -46,6 +49,21 @@ class TopicsController < ApplicationController
canonical_url @topic_view.canonical_path
end
def wordpress
params.require(:best)
params.require(:topic_id)
@topic_view = TopicView.new(params[:topic_id], current_user, best: params[:best].to_i)
raise Discourse::NotFound if @topic_view.posts.blank?
anonymous_etag(@topic_view.topic) do
wordpress_serializer = TopicViewWordpressSerializer.new(@topic_view, scope: guardian, root: false)
render_json_dump(wordpress_serializer)
end
end
def destroy_timings
PostTiming.destroy_for(current_user.id, params[:topic_id].to_i)
render nothing: true
@ -257,6 +275,7 @@ class TopicsController < ApplicationController
def perform_show_response
topic_view_serializer = TopicViewSerializer.new(@topic_view, scope: guardian, root: false)
respond_to do |format|
format.html do
store_preloaded("topic_#{@topic_view.topic.id}", MultiJson.dump(topic_view_serializer))

View File

@ -0,0 +1,34 @@
# The most basic attributes of a topic that we need to create a link for it.
class BasicPostSerializer < ApplicationSerializer
attributes :id,
:name,
:username,
:avatar_template,
:created_at,
:cooked
def name
object.user.name
end
def username
object.user.username
end
def avatar_template
object.user.avatar_template
end
def cooked
if object.hidden && !scope.is_staff?
if scope.current_user && object.user_id == scope.current_user.id
I18n.t('flagging.you_must_edit')
else
I18n.t('flagging.user_must_edit')
end
else
object.filter_quotes(@parent_post)
end
end
end

View File

@ -1,5 +1,3 @@
require_dependency 'age_words'
# The most basic attributes of a topic that we need to create a link for it.
class BasicTopicSerializer < ApplicationSerializer
attributes :id, :fancy_title, :slug, :posts_count

View File

@ -1,4 +1,4 @@
class PostSerializer < ApplicationSerializer
class PostSerializer < BasicPostSerializer
# To pass in additional information we might need
attr_accessor :topic_slug
@ -8,10 +8,8 @@ class PostSerializer < ApplicationSerializer
attr_accessor :single_post_link_counts
attr_accessor :draft_sequence
attributes :id,
:post_number,
attributes :post_number,
:post_type,
:created_at,
:updated_at,
:reply_count,
:reply_to_post_number,
@ -29,10 +27,7 @@ class PostSerializer < ApplicationSerializer
:can_delete,
:can_recover,
:link_counts,
:cooked,
:read,
:username,
:name,
:user_title,
:reply_to_user,
:bookmarked,
@ -40,7 +35,6 @@ class PostSerializer < ApplicationSerializer
:actions_summary,
:moderator?,
:staff?,
:avatar_template,
:user_id,
:draft_sequence,
:hidden,
@ -57,10 +51,6 @@ class PostSerializer < ApplicationSerializer
object.user.staff?
end
def avatar_template
object.user.avatar_template
end
def yours
scope.user == object.user
end
@ -77,6 +67,10 @@ class PostSerializer < ApplicationSerializer
scope.can_recover_post?(object)
end
def display_username
object.user.name
end
def link_counts
return @single_post_link_counts if @single_post_link_counts.present?
@ -93,18 +87,6 @@ class PostSerializer < ApplicationSerializer
end
end
def cooked
if object.hidden && !scope.is_staff?
if scope.current_user && object.user_id == scope.current_user.id
I18n.t('flagging.you_must_edit')
else
I18n.t('flagging.user_must_edit')
end
else
object.filter_quotes(@parent_post)
end
end
def read
@topic_view.read?(object.post_number)
end
@ -113,22 +95,10 @@ class PostSerializer < ApplicationSerializer
object.score || 0
end
def display_username
object.user.name
end
def version
object.cached_version
end
def username
object.user.username
end
def name
object.user.name
end
def user_title
object.user.title
end

View File

@ -0,0 +1,32 @@
class TopicViewWordpressSerializer < ApplicationSerializer
# These attributes will be delegated to the topic
attributes :id,
:posts_count,
:filtered_posts_count,
:posts
has_many :participants, serializer: BasicUserSerializer, embed: :objects
has_many :posts, serializer: BasicPostSerializer, embed: :objects
def id
object.topic.id
end
def posts_count
object.topic.posts_count
end
def filtered_posts_count
object.filtered_posts_count
end
def participants
object.participants.values
end
def posts
object.posts
end
end

View File

@ -197,6 +197,8 @@ Discourse::Application.routes.draw do
get 'threads/:topic_id/:post_number/avatar' => 'topics#avatar', constraints: {topic_id: /\d+/, post_number: /\d+/}
# Topic routes
get 't/:slug/:topic_id/wordpress' => 'topics#wordpress', constraints: {topic_id: /\d+/}
get 't/:topic_id/wordpress' => 'topics#wordpress', constraints: {topic_id: /\d+/}
get 't/:slug/:topic_id/best_of' => 'topics#show', defaults: {best_of: true}, constraints: {topic_id: /\d+/, post_number: /\d+/}
get 't/:topic_id/best_of' => 'topics#show', constraints: {topic_id: /\d+/, post_number: /\d+/}
put 't/:slug/:topic_id' => 'topics#update', constraints: {topic_id: /\d+/}

View File

@ -1,7 +1,7 @@
# encoding: utf-8
require 'spec_helper'
require 'avatar_lookup'
require_dependency 'avatar_lookup'
describe AvatarLookup do
let!(:user){ Fabricate(:user) }

View File

@ -2,6 +2,46 @@ require 'spec_helper'
describe TopicsController do
context 'wordpress' do
let!(:user) { log_in(:moderator) }
let(:p1) { Fabricate(:post, user: user) }
let(:topic) { p1.topic }
let!(:p2) { Fabricate(:post, topic: topic, user:user )}
it "returns the JSON in the format our wordpress plugin needs" do
xhr :get, :wordpress, topic_id: topic.id, best: 3
response.should be_success
json = ::JSON.parse(response.body)
json.should be_present
# The JSON has the data the wordpress plugin needs
json['id'].should == topic.id
json['posts_count'].should == 2
json['filtered_posts_count'].should == 2
# Posts
json['posts'].size.should == 1
post = json['posts'][0]
post['id'].should == p2.id
post['username'].should == user.username
post['avatar_template'].should == user.avatar_template
post['name'].should == user.name
post['created_at'].should be_present
post['cooked'].should == p2.cooked
# Participants
json['participants'].size.should == 1
participant = json['participants'][0]
participant['id'].should == user.id
participant['username'].should == user.username
participant['avatar_template'].should == user.avatar_template
puts json.inspect
end
end
context 'move_posts' do
it 'needs you to be logged in' do
lambda { xhr :post, :move_posts, topic_id: 111, title: 'blah', post_ids: [1,2,3] }.should raise_error(Discourse::NotLoggedIn)