FIX: Support ember app routing to topics with only slugs

This commit is contained in:
Robin Ward 2014-09-17 11:18:41 -04:00
parent 943ad8d1d5
commit c16b8364ab
8 changed files with 54 additions and 6 deletions

View File

@ -458,9 +458,10 @@ Discourse.Topic.reopenClass({
resetNew: function() {
return Discourse.ajax("/topics/reset-new", {type: 'PUT'});
},
idForSlug: function(slug) {
return Discourse.ajax("/t/id_for/" + slug);
}
});

View File

@ -17,6 +17,7 @@ Discourse.Route.buildRoutes(function() {
this.route('fromParams', { path: '/' });
this.route('fromParamsNear', { path: '/:nearPost' });
});
this.resource('topicBySlug', { path: '/t/:slug' });
this.resource('discovery', { path: '/' }, function() {
router = this;

View File

@ -0,0 +1,9 @@
export default Ember.Route.extend({
model: function(params) {
return Discourse.Topic.idForSlug(params.slug);
},
afterModel: function(result) {
Discourse.URL.routeTo(result.url);
}
});

View File

@ -30,6 +30,13 @@ class TopicsController < ApplicationController
skip_before_filter :check_xhr, only: [:show, :feed]
def id_for_slug
topic = Topic.find_by(slug: params[:slug].downcase)
guardian.ensure_can_see!(topic)
raise Discourse::NotFound unless topic
render json: {slug: topic.slug, topic_id: topic.id, url: topic.url}
end
def show
flash["referer"] ||= request.referer

View File

@ -356,6 +356,7 @@ Discourse::Application.routes.draw do
get 'embed/count' => 'embed#count'
# Topic routes
get "t/id_for/:slug" => "topics#id_for_slug"
get "t/:slug/:topic_id/wordpress" => "topics#wordpress", constraints: {topic_id: /\d+/}
get "t/:slug/:topic_id/moderator-liked" => "topics#moderator_liked", constraints: {topic_id: /\d+/}
get "t/:topic_id/wordpress" => "topics#wordpress", constraints: {topic_id: /\d+/}

View File

@ -542,6 +542,26 @@ describe TopicsController do
end
end
describe 'id_for_slug' do
let(:topic) { Fabricate(:post).topic }
it "returns JSON for the slug" do
xhr :get, :id_for_slug, slug: topic.slug
response.should be_success
json = ::JSON.parse(response.body)
json.should be_present
json['topic_id'].should == topic.id
json['url'].should == topic.url
json['slug'].should == topic.slug
end
it "returns invalid access if the user can't see the topic" do
Guardian.any_instance.expects(:can_see?).with(topic).returns(false)
xhr :get, :id_for_slug, slug: topic.slug
response.should_not be_success
end
end
describe 'show' do
let(:topic) { Fabricate(:post).topic }

View File

@ -34,6 +34,10 @@ export default function() {
}
});
this.get("/t/id_for/:slug", function() {
return response({id: 280, slug: "internationalization-localization", url: "/t/internationalization-localization/280"});
});
this.get("/404-body", function() {
return [200, {"Content-Type": "text/html"}, "<div class='page-not-found'>not found</div>"];
});

View File

@ -1,11 +1,16 @@
integration("View Topic");
test("Enter a Topic", function() {
expect(2);
visit("/t/internationalization-localization/280");
andThen(function() {
ok(exists("#topic"), "The was rendered");
ok(exists("#topic"), "The topic was rendered");
ok(exists("#topic .post-cloak"), "The topic has cloaked posts");
});
});
test("Enter without an id", function() {
visit("/t/internationalization-localization");
andThen(function() {
ok(exists("#topic"), "The topic was rendered");
});
});