From 532b1f5450fec8c93b2d2124e6e4bbff48fb417f Mon Sep 17 00:00:00 2001 From: Robin Ward Date: Thu, 21 Feb 2013 18:09:56 -0500 Subject: [PATCH] Can edit category descriptions, they show up in a `title` attribute --- .../discourse/components/utilities.js | 22 ++++-- .../javascripts/discourse/models/composer.js | 1 + .../javascripts/discourse/models/post.js | 15 ++-- .../javascripts/discourse/models/site.js | 8 ++ .../modal/edit_category.js.handlebars | 13 +++- .../views/modal/edit_category_view.js | 60 ++++++++------- app/controllers/posts_controller.rb | 33 +++++--- app/models/category.rb | 21 ++---- app/models/site_setting.rb | 2 - app/serializers/category_serializer.rb | 10 ++- config/locales/client.en.yml | 3 + config/locales/nl.yml.working | 1 - config/locales/server.en.yml | 3 +- config/locales/server.fr.yml | 1 - config/locales/server.nl.yml | 1 - ...221215017_add_description_to_categories.rb | 25 +++++++ db/structure.sql | 39 +++++----- lib/post_revisor.rb | 23 ++++++ spec/components/post_revisor_spec.rb | 75 +++++++++++++++++++ spec/controllers/posts_controller_spec.rb | 2 +- spec/models/category_spec.rb | 13 ++-- 21 files changed, 268 insertions(+), 103 deletions(-) create mode 100644 db/migrate/20130221215017_add_description_to_categories.rb diff --git a/app/assets/javascripts/discourse/components/utilities.js b/app/assets/javascripts/discourse/components/utilities.js index 4b33c9ad843..fc6b1040d87 100644 --- a/app/assets/javascripts/discourse/components/utilities.js +++ b/app/assets/javascripts/discourse/components/utilities.js @@ -40,16 +40,22 @@ */ categoryLink: function(category) { - var color, name; - if (!category) { - return ""; - } + var color, name, description, result; + if (!category) return ""; + color = Em.get(category, 'color'); name = Em.get(category, 'name'); - return "" + - name + ""; + description = Em.get(category, 'description'); + + // Build the HTML link + result = "" + name + ""; }, avatarUrl: function(username, size, template) { var rawSize; diff --git a/app/assets/javascripts/discourse/models/composer.js b/app/assets/javascripts/discourse/models/composer.js index 176d5ab2ed2..0fd05e781c1 100644 --- a/app/assets/javascripts/discourse/models/composer.js +++ b/app/assets/javascripts/discourse/models/composer.js @@ -312,6 +312,7 @@ post.set('cooked', jQuery('#wmd-preview').html()); this.set('composeState', CLOSED); post.save(function(savedPost) { + var idx, postNumber, posts; posts = _this.get('topic.posts'); /* perhaps our post came from elsewhere eg. draft diff --git a/app/assets/javascripts/discourse/models/post.js b/app/assets/javascripts/discourse/models/post.js index 8c4a581766c..c05a93606cf 100644 --- a/app/assets/javascripts/discourse/models/post.js +++ b/app/assets/javascripts/discourse/models/post.js @@ -144,22 +144,25 @@ url: "/posts/" + (this.get('id')), type: 'PUT', data: { - post: { - raw: this.get('raw') - }, + post: { raw: this.get('raw') }, image_sizes: this.get('imageSizes') }, success: function(result) { - return typeof complete === "function" ? complete(Discourse.Post.create(result)) : void 0; + + console.log(result) + + // If we received a category update, update it + if (result.category) Discourse.get('site').updateCategory(result.category); + + return typeof complete === "function" ? complete(Discourse.Post.create(result.post)) : void 0; }, error: function(result) { return typeof error === "function" ? error(result) : void 0; } }); } else { - /* We're saving a post - */ + // We're saving a post data = { post: this.getProperties('raw', 'topic_id', 'reply_to_post_number', 'category'), archetype: this.get('archetype'), diff --git a/app/assets/javascripts/discourse/models/site.js b/app/assets/javascripts/discourse/models/site.js index ec5f1cf7d95..8a349c20abe 100644 --- a/app/assets/javascripts/discourse/models/site.js +++ b/app/assets/javascripts/discourse/models/site.js @@ -1,6 +1,7 @@ (function() { window.Discourse.Site = Discourse.Model.extend({ + notificationLookup: (function() { var result; result = []; @@ -9,6 +10,7 @@ }); return result; }).property('notification_types'), + flagTypes: (function() { var postActionTypes; postActionTypes = this.get('post_action_types'); @@ -17,8 +19,14 @@ } return postActionTypes.filterProperty('is_flag', true); }).property('post_action_types.@each'), + postActionTypeById: function(id) { return this.get("postActionByIdLookup.action" + id); + }, + + updateCategory: function(newCategory) { + var existingCategory = this.get('categories').findProperty('id', Em.get(newCategory, 'id')); + if (existingCategory) existingCategory.mergeAttributes(newCategory); } }); diff --git a/app/assets/javascripts/discourse/templates/modal/edit_category.js.handlebars b/app/assets/javascripts/discourse/templates/modal/edit_category.js.handlebars index 9415888ce0c..0db67a2d301 100644 --- a/app/assets/javascripts/discourse/templates/modal/edit_category.js.handlebars +++ b/app/assets/javascripts/discourse/templates/modal/edit_category.js.handlebars @@ -3,10 +3,17 @@ {{view Discourse.TextField valueBinding="view.category.name" placeholderKey="category.name_placeholder"}} - {{#if view.category.excerpt}} +
-

{{view.category.excerpt}} {{i18n category.topic}}

- {{/if}} + + {{#if view.category.description}} + {{view.category.description}} + {{i18n category.change_in_category_topic}} + {{else}} + {{i18n category.no_description}} {{i18n category.change_in_category_topic}} + {{/if}} + +
diff --git a/app/assets/javascripts/discourse/views/modal/edit_category_view.js b/app/assets/javascripts/discourse/views/modal/edit_category_view.js index 3d7e8814788..988e6e2b450 100644 --- a/app/assets/javascripts/discourse/views/modal/edit_category_view.js +++ b/app/assets/javascripts/discourse/views/modal/edit_category_view.js @@ -1,64 +1,72 @@ (function() { - window.Discourse.EditCategoryView = window.Discourse.ModalBodyView.extend({ + /** + A modal view for editing the basic aspects of a category + + @class EditCategoryView + @extends Discourse.ModalBodyView + @namespace Discourse + @module Discourse + **/ + Discourse.EditCategoryView = Discourse.ModalBodyView.extend({ templateName: 'modal/edit_category', appControllerBinding: 'Discourse.appController', + disabled: (function() { - if (this.get('saving')) { - return true; - } - if (!this.get('category.name')) { - return true; - } - if (!this.get('category.color')) { - return true; - } + if (this.get('saving')) return true; + if (!this.get('category.name')) return true; + if (!this.get('category.color')) return true; return false; }).property('category.name', 'category.color'), + colorStyle: (function() { return "background-color: #" + (this.get('category.color')) + ";"; }).property('category.color'), + title: (function() { - if (this.get('category.id')) { - return "Edit Category"; - } else { - return "Create Category"; - } + if (this.get('category.id')) return Em.String.i18n("category.edit_long"); + return "Create Category"; }).property('category.id'), + buttonTitle: (function() { - if (this.get('saving')) { - return "Saving..."; - } else { - return this.get('title'); - } + if (this.get('saving')) return Em.String.i18n("saving"); + return this.get('title'); }).property('title', 'saving'), + didInsertElement: function() { this._super(); if (this.get('category')) { - return this.set('id', this.get('category.slug')); + this.set('id', this.get('category.slug')); } else { - return this.set('category', Discourse.Category.create({ - color: 'AB9364' - })); + this.set('category', Discourse.Category.create({ color: 'AB9364' })); } }, + + showCategoryTopic: function() { + jQuery('#discourse-modal').modal('hide'); + Discourse.routeTo(this.get('category.topic_url')); + return false; + }, + saveSuccess: function(result) { jQuery('#discourse-modal').modal('hide'); window.location = "/category/" + (Discourse.Utilities.categoryUrlId(result.category)); }, + saveCategory: function() { var _this = this; this.set('saving', true); return this.get('category').save({ success: function(result) { - return _this.saveSuccess(result); + _this.saveSuccess(result); }, error: function(errors) { _this.displayErrors(errors); - return _this.set('saving', false); + _this.set('saving', false); } }); } + }); }).call(this); diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index 9607c2ece3c..819aca614d9 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -35,23 +35,32 @@ class PostsController < ApplicationController def update requires_parameter(:post) - @post = Post.where(id: params[:id]).first - @post.image_sizes = params[:image_sizes] if params[:image_sizes].present? - guardian.ensure_can_edit!(@post) - if @post.revise(current_user, params[:post][:raw]) - TopicLink.extract_from(@post) + post = Post.where(id: params[:id]).first + post.image_sizes = params[:image_sizes] if params[:image_sizes].present? + guardian.ensure_can_edit!(post) + + revisor = PostRevisor.new(post) + if revisor.revise!(current_user, params[:post][:raw]) + TopicLink.extract_from(post) end - if @post.errors.present? - render_json_error(@post) + if post.errors.present? + render_json_error(post) return end - post_serializer = PostSerializer.new(@post, scope: guardian, root: false) - post_serializer.draft_sequence = DraftSequence.current(current_user, @post.topic.draft_key) - link_counts = TopicLinkClick.counts_for(@post.topic, [@post]) - post_serializer.single_post_link_counts = link_counts[@post.id] if link_counts.present? - render_json_dump(post_serializer) + post_serializer = PostSerializer.new(post, scope: guardian, root: false) + post_serializer.draft_sequence = DraftSequence.current(current_user, post.topic.draft_key) + link_counts = TopicLinkClick.counts_for(post.topic, [post]) + post_serializer.single_post_link_counts = link_counts[post.id] if link_counts.present? + + + result = {post: post_serializer.as_json} + if revisor.category_changed.present? + result[:category] = CategorySerializer.new(revisor.category_changed, scope: guardian, root: false).as_json + end + + render_json_dump(result) end def by_number diff --git a/app/models/category.rb b/app/models/category.rb index 0088f7aef97..954b059f984 100644 --- a/app/models/category.rb +++ b/app/models/category.rb @@ -44,19 +44,6 @@ class Category < ActiveRecord::Base topics_week = (#{topics_week})") end - # Use the first paragraph of the topic's first post as the excerpt - def excerpt - if topic.present? - first_post = topic.posts.order(:post_number).first - body = first_post.cooked - matches = body.scan(/\(.*)\<\/p\>/) - if matches and matches[0] and matches[0][0] - return matches[0][0] - end - end - nil - end - def topic_url topic.try(:relative_url) end @@ -67,11 +54,17 @@ class Category < ActiveRecord::Base after_create do topic = Topic.create!(title: I18n.t("category.topic_prefix", category: name), user: user, visible: false) - topic.posts.create!(raw: SiteSetting.category_post_template, user: user) + + post_contents = I18n.t("category.post_template", replace_paragraph: I18n.t("category.replace_paragraph")) + topic.posts.create!(raw: post_contents, user: user) update_column(:topic_id, topic.id) topic.update_column(:category_id, self.id) end + def self.post_template + I18n.t("category.post_template", replace_paragraph: I18n.t("category.replace_paragraph")) + end + # We cache the categories in the site json, so we need to invalidate it when they change def invalidate_site_cache Site.invalidate_cache diff --git a/app/models/site_setting.rb b/app/models/site_setting.rb index 82d9011b70b..91af3d223ee 100644 --- a/app/models/site_setting.rb +++ b/app/models/site_setting.rb @@ -100,8 +100,6 @@ class SiteSetting < ActiveRecord::Base setting(:best_of_score_threshold, 15) setting(:best_of_posts_required, 50) setting(:best_of_likes_required, 1) - setting(:category_post_template, - "[Replace this first paragraph with a short description of your new category. Try to keep it below 200 characters.]\n\nUse this space below for a longer description, as well as to establish any rules or discussion!") # we need to think of a way to force users to enter certain settings, this is a minimal config thing setting(:notification_email, 'info@discourse.org') diff --git a/app/serializers/category_serializer.rb b/app/serializers/category_serializer.rb index 40b459406d9..ae33145d4e6 100644 --- a/app/serializers/category_serializer.rb +++ b/app/serializers/category_serializer.rb @@ -1,3 +1,11 @@ class CategorySerializer < ApplicationSerializer - attributes :id, :name, :color, :slug, :topic_count + + attributes :id, + :name, + :color, + :slug, + :topic_count, + :description, + :topic_url + end diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index eb123fa1e6e..ce7e62789b6 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -519,6 +519,7 @@ en: category: none: '(no category)' edit: 'edit' + edit_long: "Edit Category" view: 'View Topics in Category' delete: 'Delete Category' create: 'Create Category' @@ -531,6 +532,8 @@ en: color_placeholder: "Any web color" delete_confirm: "Are you sure you want to delete that category?" list: "List Categories" + no_description: "There is no description for this category." + change_in_category_topic: "visit category topic to edit the description" flagging: title: 'Why are you flagging this post?' diff --git a/config/locales/nl.yml.working b/config/locales/nl.yml.working index 2c0572dc105..6c93abaa651 100644 --- a/config/locales/nl.yml.working +++ b/config/locales/nl.yml.working @@ -228,7 +228,6 @@ nl: exclude_rel_nofollow_domains: "Een commagescheiden lijst van domeinen waar 'nofollow' niet is toegevoegd. (voorbeelddomein.com zal automatisch sub.voorbeelddomein.com toestaan)" post_excerpt_maxlength: "Maximale lengte in karakters van een post-uittreksel." post_onebox_maxlength: "Maximale lengte van een 'oneboxed' discourse post." - category_post_template: "De post-template die verschijnt wanneer je een categorie aanmaakt" new_topics_rollup: "Hoeveel topics er aan een topic-lijst kunnen worden toegevoegd voordat de lijst oprolt." onebox_max_chars: "Het maximaal aantal karakters dat een 'onebox' zal importeren in een lap text." logo_url: "Het logo van je site bijv: http://xyz.com/x.png" diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index c8514304add..dc7f9fd0499 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -62,6 +62,8 @@ en: category: topic_prefix: "Category definition for %{category}" + replace_paragraph: "[Replace this first paragraph with a short description of your new category. Try to keep it below 200 characters.]" + post_template: "%{replace_paragraph}\n\nUse this space below for a longer description, as well as to establish any rules or discussion!" trust_levels: new: @@ -254,7 +256,6 @@ en: exclude_rel_nofollow_domains: "A comma delimited list of domains where nofollow is not added (tld.com will automatically allow sub.tld.com as well)" post_excerpt_maxlength: "Maximum length in chars of a post's excerpt." post_onebox_maxlength: "Maximum length of a oneboxed discourse post." - category_post_template: "The post template that appears once you create a category" new_topics_rollup: "How many topics can be inserted on the topic list before rolling up." onebox_max_chars: "The maximum amount of characters a onebox will import in a text blob." logo_url: "The logo for your site eg: http://xyz.com/x.png" diff --git a/config/locales/server.fr.yml b/config/locales/server.fr.yml index e4b07ad8252..2e0749dc883 100644 --- a/config/locales/server.fr.yml +++ b/config/locales/server.fr.yml @@ -261,7 +261,6 @@ fr: exclude_rel_nofollow_domains: "Une liste séparée par des virgules contenant les noms de domaines de premier niveau pour lesquels il faut ajouter un attribut nofollow (exemple.com va automatiquement fonctionner aussi avec sous.domaine.exemple.com)" post_excerpt_maxlength: "Longueur maximale d'un extrait de message." post_onebox_maxlength: "Longueur maximale d'un message emboîté." - category_post_template: "Le modèle de message qui va apparaitre quand vous créez une catégorie" new_topics_rollup: "Combien de discussions peuvent être insérées dans la liste des discussions avant de remonter." onebox_max_chars: "Nombre maximal de caractères qu'une boîte peut importer en blob de texte." logo_url: "Le logo de votre site, par exemple: http://xyz.com/x.png" diff --git a/config/locales/server.nl.yml b/config/locales/server.nl.yml index fc06cd68a24..ef14d6888b5 100644 --- a/config/locales/server.nl.yml +++ b/config/locales/server.nl.yml @@ -255,7 +255,6 @@ nl: exclude_rel_nofollow_domains: "Een commagescheiden lijst van domeinen waar 'nofollow' niet is toegevoegd. (voorbeelddomein.com zal automatisch sub.voorbeelddomein.com toestaan)" post_excerpt_maxlength: "Maximale lengte in karakters van een post-uittreksel." post_onebox_maxlength: "Maximale lengte van een 'oneboxed' discourse post." - category_post_template: "De post-template die verschijnt wanneer je een categorie aanmaakt" new_topics_rollup: "Hoeveel topics er aan een topic-lijst kunnen worden toegevoegd voordat de lijst oprolt." onebox_max_chars: "Het maximaal aantal karakters dat een 'onebox' zal importeren in een lap tekst." logo_url: "Het logo van je site bijv: http://xyz.com/x.png" diff --git a/db/migrate/20130221215017_add_description_to_categories.rb b/db/migrate/20130221215017_add_description_to_categories.rb new file mode 100644 index 00000000000..715f7bab7ba --- /dev/null +++ b/db/migrate/20130221215017_add_description_to_categories.rb @@ -0,0 +1,25 @@ +class AddDescriptionToCategories < ActiveRecord::Migration + def up + add_column :categories, :description, :text, null: true + + # While we're at it, remove unused columns + remove_column :categories, :top1_topic_id + remove_column :categories, :top2_topic_id + remove_column :categories, :top1_user_id + remove_column :categories, :top2_user_id + + # Migrate excerpts over + Category.all.each do |c| + excerpt = c.excerpt + unless excerpt == I18n.t("category.replace_paragraph") + c.update_column(:description, c.excerpt) + end + end + + end + + def down + remove_column :categories, :description + end + +end diff --git a/db/structure.sql b/db/structure.sql index 2d3e08c02da..c95ef4865a3 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -1222,10 +1222,6 @@ CREATE TABLE categories ( name character varying(50) NOT NULL, color character varying(6) DEFAULT 'AB9364'::character varying NOT NULL, topic_id integer, - top1_topic_id integer, - top2_topic_id integer, - top1_user_id integer, - top2_user_id integer, topic_count integer DEFAULT 0 NOT NULL, created_at timestamp without time zone NOT NULL, updated_at timestamp without time zone NOT NULL, @@ -1233,7 +1229,8 @@ CREATE TABLE categories ( topics_year integer, topics_month integer, topics_week integer, - slug character varying(255) NOT NULL + slug character varying(255) NOT NULL, + description text ); @@ -1242,7 +1239,7 @@ CREATE TABLE categories ( -- CREATE SEQUENCE categories_id_seq - START WITH 5 + START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE @@ -1327,7 +1324,7 @@ CREATE TABLE draft_sequences ( -- CREATE SEQUENCE draft_sequences_id_seq - START WITH 20 + START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE @@ -1361,7 +1358,7 @@ CREATE TABLE drafts ( -- CREATE SEQUENCE drafts_id_seq - START WITH 2 + START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE @@ -1394,7 +1391,7 @@ CREATE TABLE email_logs ( -- CREATE SEQUENCE email_logs_id_seq - START WITH 3 + START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE @@ -1429,7 +1426,7 @@ CREATE TABLE email_tokens ( -- CREATE SEQUENCE email_tokens_id_seq - START WITH 3 + START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE @@ -1642,7 +1639,7 @@ CREATE TABLE onebox_renders ( -- CREATE SEQUENCE onebox_renders_id_seq - START WITH 2 + START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE @@ -1676,7 +1673,7 @@ CREATE TABLE post_action_types ( -- CREATE SEQUENCE post_action_types_id_seq - START WITH 6 + START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE @@ -1807,7 +1804,7 @@ CREATE TABLE posts ( -- CREATE SEQUENCE posts_id_seq - START WITH 16 + START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE @@ -1898,7 +1895,7 @@ CREATE TABLE site_settings ( -- CREATE SEQUENCE site_settings_id_seq - START WITH 4 + START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE @@ -1930,7 +1927,7 @@ CREATE TABLE topic_allowed_users ( -- CREATE SEQUENCE topic_allowed_users_id_seq - START WITH 3 + START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE @@ -2122,7 +2119,7 @@ CREATE TABLE topics ( -- CREATE SEQUENCE topics_id_seq - START WITH 16 + START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE @@ -2228,7 +2225,7 @@ CREATE TABLE user_actions ( -- CREATE SEQUENCE user_actions_id_seq - START WITH 40 + START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE @@ -2292,7 +2289,7 @@ CREATE TABLE user_visits ( -- CREATE SEQUENCE user_visits_id_seq - START WITH 4 + START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE @@ -2359,7 +2356,7 @@ CREATE TABLE users ( -- CREATE SEQUENCE users_id_seq - START WITH 3 + START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE @@ -4578,4 +4575,6 @@ INSERT INTO schema_migrations (version) VALUES ('20130208220635'); INSERT INTO schema_migrations (version) VALUES ('20130213021450'); -INSERT INTO schema_migrations (version) VALUES ('20130213203300'); \ No newline at end of file +INSERT INTO schema_migrations (version) VALUES ('20130213203300'); + +INSERT INTO schema_migrations (version) VALUES ('20130221215017'); \ No newline at end of file diff --git a/lib/post_revisor.rb b/lib/post_revisor.rb index c8ec6449eac..4eb7656fc36 100644 --- a/lib/post_revisor.rb +++ b/lib/post_revisor.rb @@ -1,5 +1,8 @@ require 'edit_rate_limiter' class PostRevisor + + attr_reader :category_changed + def initialize(post) @post = post end @@ -8,6 +11,7 @@ class PostRevisor @user, @new_raw, @opts = user, new_raw, opts return false if not should_revise? revise_post + update_category_description post_process_post true end @@ -76,6 +80,25 @@ class PostRevisor @post.save end + def update_category_description + # If we're revising the first post, we might have to update the category description + return unless @post.post_number == 1 + + # Is there a category with our topic id? + category = Category.where(topic_id: @post.topic_id).first + return unless category.present? + + # If found, update its description + body = @post.cooked + matches = body.scan(/\(.*)\<\/p\>/) + if matches and matches[0] and matches[0][0] + new_description = matches[0][0] + new_description = nil if new_description == I18n.t("category.replace_paragraph") + category.update_column(:description, new_description) + @category_changed = category + end + end + def post_process_post @post.invalidate_oneboxes = true @post.trigger_post_process diff --git a/spec/components/post_revisor_spec.rb b/spec/components/post_revisor_spec.rb index 386211f472a..36662d9cd99 100644 --- a/spec/components/post_revisor_spec.rb +++ b/spec/components/post_revisor_spec.rb @@ -43,6 +43,11 @@ describe PostRevisor do it "doesn't change the last_version_at" do post.last_version_at.should == first_version_at end + + it "doesn't update a category" do + subject.category_changed.should be_blank + end + end describe 'revision much later' do @@ -55,6 +60,10 @@ describe PostRevisor do post.reload end + it "doesn't update a category" do + subject.category_changed.should be_blank + end + it 'updates the cached_version' do post.cached_version.should == 2 end @@ -82,6 +91,10 @@ describe PostRevisor do post.last_version_at.to_i.should == revised_at.to_i end + it "doesn't update a category" do + subject.category_changed.should be_blank + end + context "after second window" do let!(:new_revised_at) {revised_at + 2.minutes} @@ -102,6 +115,68 @@ describe PostRevisor do end end + describe 'category topic' do + + let!(:category) do + category = Fabricate(:category) + category.update_column(:topic_id, topic.id) + category + end + + let(:new_description) { "this is my new description." } + + it "should have to description by default" do + category.description.should be_blank + end + + context "one paragraph description" do + before do + subject.revise!(post.user, new_description) + category.reload + end + + it "returns true for category_changed" do + subject.category_changed.should be_true + end + + it "updates the description of the category" do + category.description.should == new_description + end + end + + context "multiple paragraph description" do + before do + subject.revise!(post.user, "#{new_description}\n\nOther content goes here.") + category.reload + end + + it "returns the changed category info" do + subject.category_changed.should == category + end + + it "updates the description of the category" do + category.description.should == new_description + end + end + + context 'when updating back to the original paragraph' do + before do + category.update_column(:description, 'this is my description') + subject.revise!(post.user, Category.post_template) + category.reload + end + + it "puts the description back to nothing" do + category.description.should be_blank + end + + it "returns true for category_changed" do + subject.category_changed.should == category + end + end + + end + describe 'rate limiter' do let(:changed_by) { Fabricate(:coding_horror) } diff --git a/spec/controllers/posts_controller_spec.rb b/spec/controllers/posts_controller_spec.rb index 73929f8b1a0..88c5d85cef0 100644 --- a/spec/controllers/posts_controller_spec.rb +++ b/spec/controllers/posts_controller_spec.rb @@ -192,7 +192,7 @@ describe PostsController do end it "calls revise with valid parameters" do - Post.any_instance.expects(:revise).with(post.user, 'edited body') + PostRevisor.any_instance.expects(:revise!).with(post.user, 'edited body') xhr :put, :update, update_params end diff --git a/spec/models/category_spec.rb b/spec/models/category_spec.rb index b81b9c757d0..9f1c713e5d6 100644 --- a/spec/models/category_spec.rb +++ b/spec/models/category_spec.rb @@ -83,6 +83,10 @@ describe Category do @category.slug.should == 'amazing-category' end + it 'has a default description' do + @category.description.should be_blank + end + it 'has one topic' do Topic.where(category_id: @category).count.should == 1 end @@ -107,14 +111,12 @@ describe Category do @topic.posts.count.should == 1 end - it 'should have an excerpt' do - @category.excerpt.should be_present - end - it 'should have a topic url' do @category.topic_url.should be_present end + + describe "trying to change the category topic's category" do before do @@ -166,8 +168,7 @@ describe Category do context 'with regular topics' do before do - @category.topics << Fabricate(:topic, - user: @category.user) + @category.topics << Fabricate(:topic, user: @category.user) Category.update_stats @category.reload end