port tagFollowings to BackBone
This commit is contained in:
parent
7517c29ed0
commit
97664cb880
25 changed files with 353 additions and 98 deletions
17
app/assets/javascripts/app/collections/tag_followings.js
Normal file
17
app/assets/javascripts/app/collections/tag_followings.js
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
app.collections.TagFollowings = Backbone.Collection.extend({
|
||||
|
||||
model: app.models.TagFollowing,
|
||||
|
||||
url : "/tag_followings",
|
||||
|
||||
create : function(model) {
|
||||
var name = model.name || model.get("name");
|
||||
if(!this.any(
|
||||
function(tagFollowing){
|
||||
return tagFollowing.get("name") === name;
|
||||
})) {
|
||||
Backbone.Collection.prototype.create.apply(this, arguments);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
3
app/assets/javascripts/app/models/tag_following.js
Normal file
3
app/assets/javascripts/app/models/tag_following.js
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
app.models.TagFollowing = Backbone.Model.extend({
|
||||
urlRoot: "/tag_followings"
|
||||
});
|
||||
|
|
@ -16,8 +16,8 @@ app.Router = Backbone.Router.extend({
|
|||
"commented": "stream",
|
||||
"liked": "stream",
|
||||
"mentions": "stream",
|
||||
"followed_tags": "stream",
|
||||
"tags/:name": "stream",
|
||||
"followed_tags": "followed_tags",
|
||||
"tags/:name": "followed_tags",
|
||||
"people/:id/photos": "photos",
|
||||
|
||||
"people/:id": "stream",
|
||||
|
|
@ -63,6 +63,24 @@ app.Router = Backbone.Router.extend({
|
|||
app.photos = new app.models.Stream([], {collection: app.collections.Photos});
|
||||
app.page = new app.views.Photos({model : app.photos});
|
||||
$("#main_stream").html(app.page.render().el);
|
||||
},
|
||||
|
||||
followed_tags : function(name) {
|
||||
this.stream();
|
||||
|
||||
app.tagFollowings = new app.collections.TagFollowings();
|
||||
var followedTagsView = new app.views.TagFollowingList({collection: app.tagFollowings});
|
||||
$("#tags_list").replaceWith(followedTagsView.render().el);
|
||||
followedTagsView.setupAutoSuggest();
|
||||
|
||||
app.tagFollowings.add(preloads.tagFollowings);
|
||||
|
||||
if(name) {
|
||||
var followedTagsAction = new app.views.TagFollowingAction(
|
||||
{tagText: name}
|
||||
);
|
||||
$("#author_info").prepend(followedTagsAction.render().el)
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,62 @@
|
|||
app.views.TagFollowingAction = app.views.Base.extend({
|
||||
|
||||
templateName: "tag_following_action",
|
||||
|
||||
events : {
|
||||
"mouseenter .button.red_on_hover": "mouseIn",
|
||||
"mouseleave .button.red_on_hover": "mouseOut",
|
||||
"click .button": "tagAction"
|
||||
},
|
||||
|
||||
initialize : function(options){
|
||||
this.tagText = options.tagText;
|
||||
this.getTagFollowing();
|
||||
app.tagFollowings.bind("remove add", this.getTagFollowing, this);
|
||||
},
|
||||
|
||||
presenter : function() {
|
||||
return _.extend(this.defaultPresenter(), {
|
||||
tag_is_followed : this.tag_is_followed(),
|
||||
followString : this.followString()
|
||||
})
|
||||
},
|
||||
|
||||
followString : function() {
|
||||
if(this.tag_is_followed()) {
|
||||
return Diaspora.I18n.t("stream.tags.following", {"tag" : this.model.attributes.name});
|
||||
} else {
|
||||
return Diaspora.I18n.t("stream.tags.follow", {"tag" : this.model.attributes.name});
|
||||
}
|
||||
},
|
||||
|
||||
tag_is_followed : function() {
|
||||
return !this.model.isNew();
|
||||
},
|
||||
|
||||
getTagFollowing : function(tagFollowing) {
|
||||
this.model = app.tagFollowings.where({"name":this.tagText})[0] ||
|
||||
new app.models.TagFollowing({"name":this.tagText});
|
||||
this.model.bind("change", this.render, this);
|
||||
this.render();
|
||||
},
|
||||
|
||||
mouseIn : function(){
|
||||
this.$("input").removeClass("in_aspects");
|
||||
this.$("input").val( Diaspora.I18n.t('stream.tags.stop_following', {tag: this.model.attributes.name} ) );
|
||||
},
|
||||
|
||||
mouseOut : function() {
|
||||
this.$("input").addClass("in_aspects");
|
||||
this.$("input").val( Diaspora.I18n.t('stream.tags.following', {"tag" : this.model.attributes.name} ) );
|
||||
},
|
||||
|
||||
tagAction : function(evt){
|
||||
if(evt){ evt.preventDefault(); }
|
||||
|
||||
if(this.tag_is_followed()) {
|
||||
this.model.destroy();
|
||||
} else {
|
||||
app.tagFollowings.create(this.model);
|
||||
}
|
||||
}
|
||||
});
|
||||
75
app/assets/javascripts/app/views/tag_following_list_view.js
Normal file
75
app/assets/javascripts/app/views/tag_following_list_view.js
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
//= require jquery.autoSuggest.custom
|
||||
app.views.TagFollowingList = app.views.Base.extend({
|
||||
|
||||
templateName: "tag_following_list",
|
||||
|
||||
className : "sub_nav",
|
||||
|
||||
id : "tags_list",
|
||||
|
||||
tagName : "ul",
|
||||
|
||||
events: {
|
||||
"submit form": "createTagFollowing"
|
||||
},
|
||||
|
||||
initialize : function(){
|
||||
this.collection.bind("add", this.appendTagFollowing, this);
|
||||
},
|
||||
|
||||
postRenderTemplate : function() {
|
||||
this.collection.each(this.appendTagFollowing, this);
|
||||
},
|
||||
|
||||
setupAutoSuggest : function() {
|
||||
this.$("input").autoSuggest("/tags", {
|
||||
selectedItemProp: "name",
|
||||
selectedValuesProp: "name",
|
||||
searchObjProps: "name",
|
||||
asHtmlID: "tags",
|
||||
neverSubmit: true,
|
||||
retrieveLimit: 10,
|
||||
selectionLimit: false,
|
||||
minChars: 2,
|
||||
keyDelay: 200,
|
||||
startText: "",
|
||||
emptyText: "no_results",
|
||||
selectionAdded: _.bind(this.suggestSelection, this)
|
||||
});
|
||||
|
||||
this.$("input").bind('keydown', function(evt){
|
||||
if(evt.keyCode == 13 || evt.keyCode == 9 || evt.keyCode == 32){
|
||||
evt.preventDefault();
|
||||
if( $('li.as-result-item.active').length == 0 ){
|
||||
$('li.as-result-item').first().click();
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
presenter : function() {
|
||||
return this.defaultPresenter();
|
||||
},
|
||||
|
||||
suggestSelection : function(elem) {
|
||||
this.$(".tag_input").val($(elem[0]).text().substring(2));
|
||||
elem.remove();
|
||||
this.createTagFollowing();
|
||||
},
|
||||
|
||||
createTagFollowing: function(evt) {
|
||||
if(evt){ evt.preventDefault(); }
|
||||
var name = this.$(".tag_input").val();
|
||||
|
||||
this.collection.create({"name":this.$(".tag_input").val()});
|
||||
this.$(".tag_input").val("");
|
||||
return this;
|
||||
},
|
||||
|
||||
appendTagFollowing: function(tag) {
|
||||
this.$el.prepend(new app.views.TagFollowing({
|
||||
model: tag
|
||||
}).render().el);
|
||||
}
|
||||
|
||||
});
|
||||
33
app/assets/javascripts/app/views/tag_following_view.js
Normal file
33
app/assets/javascripts/app/views/tag_following_view.js
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
app.views.TagFollowing = app.views.Base.extend({
|
||||
|
||||
templateName: "tag_following",
|
||||
|
||||
className : "unfollow",
|
||||
|
||||
tagName: "li",
|
||||
|
||||
events : {
|
||||
"click .tag_following_delete": "destroyModel"
|
||||
},
|
||||
|
||||
initialize : function(){
|
||||
this.el.id = "tag-following-" + this.model.get("name");
|
||||
this.model.bind("destroy", this.hide, this);
|
||||
},
|
||||
|
||||
hide : function() {
|
||||
this.$el.slideUp();
|
||||
},
|
||||
|
||||
postRenderTemplate : function() {
|
||||
this.$el.hide();
|
||||
this.$el.slideDown();
|
||||
},
|
||||
|
||||
presenter : function() {
|
||||
return _.extend(this.defaultPresenter(), {
|
||||
tag : this.model
|
||||
})
|
||||
}
|
||||
|
||||
});
|
||||
|
|
@ -36,12 +36,10 @@ Diaspora.Pages.UsersGettingStarted = function() {
|
|||
});
|
||||
|
||||
$("#awesome_button").bind("click", function(evt){
|
||||
evt.preventDefault();
|
||||
|
||||
var confirmMessage = Diaspora.I18n.t("getting_started.no_tags");
|
||||
|
||||
if(($("#as-selections-tags").find(".as-selection-item").length > 0) || confirm(confirmMessage)) {
|
||||
$('.tag_input').submit();
|
||||
|
||||
/* flash message prompt */
|
||||
var message = Diaspora.I18n.t("getting_started.preparing_your_stream");
|
||||
|
|
@ -55,18 +53,25 @@ Diaspora.Pages.UsersGettingStarted = function() {
|
|||
|
||||
/* ------ */
|
||||
var autocompleteInput = $("#follow_tags");
|
||||
var tagFollowings = new app.collections.TagFollowings();
|
||||
|
||||
autocompleteInput.autoSuggest("/tags", {
|
||||
selectedItemProp: "name",
|
||||
selectedValuesProp: "name",
|
||||
searchObjProps: "name",
|
||||
asHtmlID: "tags",
|
||||
neverSubmit: true,
|
||||
retriveLimit: 10,
|
||||
retrieveLimit: 10,
|
||||
selectionLimit: false,
|
||||
minChars: 2,
|
||||
keyDelay: 200,
|
||||
startText: "",
|
||||
emptyText: "no_results"
|
||||
emptyText: "no_results",
|
||||
selectionAdded: function(elem){tagFollowings.create({"name":$(elem[0]).text().substring(2)})},
|
||||
selectionRemoved: function(elem){
|
||||
tagFollowings.where({"name":$(elem[0]).text().substring(2)})[0].destroy();
|
||||
elem.remove();
|
||||
}
|
||||
});
|
||||
|
||||
autocompleteInput.bind('keydown', function(evt){
|
||||
|
|
|
|||
|
|
@ -2778,6 +2778,7 @@ a.toggle_selector
|
|||
:left 24px
|
||||
|
||||
input[type='text']
|
||||
:width 100%
|
||||
:font
|
||||
:size 13px
|
||||
|
||||
|
|
|
|||
10
app/assets/templates/tag_following_action_tpl.jst.hbs
Normal file
10
app/assets/templates/tag_following_action_tpl.jst.hbs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<div class="right">
|
||||
<form accept-charset="UTF-8" action="/tag_followings" method="post">
|
||||
<input type="submit" class="button take_action
|
||||
{{#if tag_is_followed }}
|
||||
red_on_hover in_aspects
|
||||
{{/if}}
|
||||
" type="submit" value="{{followString}}"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
5
app/assets/templates/tag_following_list_tpl.jst.hbs
Normal file
5
app/assets/templates/tag_following_list_tpl.jst.hbs
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<li>
|
||||
<form accept-charset="UTF-8" action="/tag_followings" id="new_tag_following" method="post">
|
||||
<input class="tag_input" type="text" name="name" placeholder="{{t "stream.followed_tag.add_a_tag"}}" />
|
||||
</form>
|
||||
</li>
|
||||
9
app/assets/templates/tag_following_tpl.jst.hbs
Normal file
9
app/assets/templates/tag_following_tpl.jst.hbs
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<div class="unfollow_icon hidden">
|
||||
<a href="#" id="unfollow_{{name}}" rel="nofollow" class="delete tag_following_delete" title="{{t "delete"}}">
|
||||
<img alt="Deletelabel" src="{{imageUrl "deletelabel.png"}}" />
|
||||
<a/>
|
||||
</div>
|
||||
|
||||
<a class="tag_selector" href="/tags/{{name}}">
|
||||
#{{ name }}
|
||||
</a>
|
||||
|
|
@ -165,7 +165,8 @@ class PeopleController < ApplicationController
|
|||
def redirect_if_tag_search
|
||||
if search_query.starts_with?('#')
|
||||
if search_query.length > 1
|
||||
redirect_to tag_path(:name => search_query.delete('#.'), :q => search_query)
|
||||
|
||||
redirect_to tag_path(:name => search_query.delete('#.'))
|
||||
else
|
||||
flash[:error] = I18n.t('tags.show.none', :name => search_query)
|
||||
redirect_to :back
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ class StreamsController < ApplicationController
|
|||
end
|
||||
|
||||
def followed_tags
|
||||
gon.tagFollowings = tags
|
||||
stream_responder(Stream::FollowedTag)
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
class TagFollowingsController < ApplicationController
|
||||
before_filter :authenticate_user!
|
||||
|
||||
respond_to :html, :json
|
||||
respond_to :json
|
||||
|
||||
# POST /tag_followings
|
||||
# POST /tag_followings.xml
|
||||
|
|
@ -14,52 +14,38 @@ class TagFollowingsController < ApplicationController
|
|||
name_normalized = ActsAsTaggableOn::Tag.normalize(params['name'])
|
||||
|
||||
if name_normalized.nil? || name_normalized.empty?
|
||||
flash[:error] = I18n.t('tag_followings.create.none')
|
||||
render :nothing => true, :status => 403
|
||||
else
|
||||
@tag = ActsAsTaggableOn::Tag.find_or_create_by_name(name_normalized)
|
||||
@tag_following = current_user.tag_followings.new(:tag_id => @tag.id)
|
||||
|
||||
if @tag_following.save
|
||||
flash[:notice] = I18n.t('tag_followings.create.success', :name => name_normalized)
|
||||
render :json => @tag.to_json, :status => 201
|
||||
else
|
||||
flash[:error] = I18n.t('tag_followings.create.failure', :name => name_normalized)
|
||||
render :nothing => true, :status => 403
|
||||
end
|
||||
end
|
||||
redirect_to :back
|
||||
end
|
||||
|
||||
# DELETE /tag_followings/1
|
||||
# DELETE /tag_followings/1.xml
|
||||
def destroy
|
||||
@tag = ActsAsTaggableOn::Tag.find_by_name(params[:name])
|
||||
tag_following = current_user.tag_followings.find_by_tag_id( @tag.id )
|
||||
tag_following = current_user.tag_followings.find_by_tag_id( params['id'] )
|
||||
|
||||
if tag_following && tag_following.destroy
|
||||
tag_unfollowed = true
|
||||
respond_to do |format|
|
||||
format.any(:js, :json) { render :nothing => true, :status => 204 }
|
||||
end
|
||||
else
|
||||
tag_unfollowed = false
|
||||
end
|
||||
|
||||
respond_to do |format|
|
||||
format.js { render 'tags/update' }
|
||||
format.any {
|
||||
if tag_unfollowed
|
||||
flash[:notice] = I18n.t('tag_followings.destroy.success', :name => params[:name])
|
||||
else
|
||||
flash[:error] = I18n.t('tag_followings.destroy.failure', :name => params[:name])
|
||||
end
|
||||
redirect_to tag_path(:name => params[:name])
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def create_multiple
|
||||
if params[:tags].present?
|
||||
params[:tags].split(",").each do |name|
|
||||
name_normalized = ActsAsTaggableOn::Tag.normalize(name)
|
||||
@tag = ActsAsTaggableOn::Tag.find_or_create_by_name(name_normalized)
|
||||
@tag_following = current_user.tag_followings.create(:tag_id => @tag.id)
|
||||
respond_to do |format|
|
||||
format.any(:js, :json) {render :nothing => true, :status => 403}
|
||||
end
|
||||
end
|
||||
redirect_to stream_path
|
||||
end
|
||||
|
||||
def index
|
||||
respond_to do |format|
|
||||
format.json{ render(:json => tags.to_json, :status => 200) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -32,8 +32,10 @@ class TagsController < ApplicationController
|
|||
end
|
||||
|
||||
def show
|
||||
if user_signed_in?
|
||||
gon.tagFollowings = tags
|
||||
end
|
||||
@stream = Stream::Tag.new(current_user, params[:name], :max_time => max_time, :page => params[:page])
|
||||
|
||||
respond_with do |format|
|
||||
format.json { render :json => @stream.stream_posts.map { |p| LastThreeCommentsDecorator.new(PostPresenter.new(p, current_user)) }}
|
||||
end
|
||||
|
|
@ -47,18 +49,10 @@ class TagsController < ApplicationController
|
|||
|
||||
def prep_tags_for_javascript
|
||||
@tags.map! do |tag|
|
||||
{
|
||||
:name => ("#" + tag.name),
|
||||
:value => ("#" + tag.name),
|
||||
:url => tag_path(tag.name)
|
||||
}
|
||||
{ :name => ("#" + tag.name) }
|
||||
end
|
||||
|
||||
@tags << {
|
||||
:name => ('#' + params[:q]),
|
||||
:value => ("#" + params[:q]),
|
||||
:url => tag_path(params[:q].downcase)
|
||||
}
|
||||
@tags << { :name => ('#' + params[:q]) }
|
||||
@tags.uniq!
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
class ActsAsTaggableOn::Tag
|
||||
|
||||
self.include_root_in_json = false
|
||||
|
||||
def followed_count
|
||||
@followed_count ||= TagFollowing.where(:tag_id => self.id).count
|
||||
end
|
||||
|
|
|
|||
|
|
@ -46,6 +46,8 @@
|
|||
= yield(:head)
|
||||
= csrf_meta_tag
|
||||
|
||||
= include_gon(:camel_case => true, :namespace => :preloads)
|
||||
|
||||
%body
|
||||
= flash_messages
|
||||
|
||||
|
|
|
|||
|
|
@ -7,15 +7,4 @@
|
|||
%li
|
||||
%b=link_to t('streams.followed_tag.title'), followed_tags_stream_path, :class => 'home_selector'
|
||||
|
||||
- if @stream.is_a?(Stream::FollowedTag)
|
||||
%ul.sub_nav
|
||||
- if tags.size > 0
|
||||
- for tg in tags
|
||||
%li.unfollow{:id => "tag-following-#{tg.name}"}
|
||||
.unfollow_icon.hidden
|
||||
= link_to image_tag("icons/monotone_close_exit_delete.png", :height => 16, :title => t('aspects.index.unfollow_tag', :tag => tg.name)), tag_tag_followings_path(:name => tg.name, :remote => true), :data => { :confirm => t('are_you_sure') }, :method => :delete, :remote => true, :id => "unfollow_" + tg.name
|
||||
= link_to "##{tg.name}", tag_path(:name => tg.name), :class => "tag_selector"
|
||||
%li
|
||||
= form_for TagFollowing.new do |tg|
|
||||
= text_field_tag :name, "", :class => "tag_input", :placeholder => t('streams.followed_tag.add_a_tag')
|
||||
= tg.submit t('streams.followed_tag.follow'), :class => "button"
|
||||
%ul.sub_nav#tags_list
|
||||
|
|
|
|||
|
|
@ -9,27 +9,6 @@
|
|||
- else
|
||||
= t('.whatup', :pod => @pod_url)
|
||||
|
||||
- content_for :head do
|
||||
= javascript_include_tag :home
|
||||
:javascript
|
||||
$(document).ready(function(){
|
||||
// Change the text and color of the "follow this tag" button on hover.
|
||||
$(".button.tag_following").hover(function(){
|
||||
$this = $(this);
|
||||
$this.removeClass("in_aspects");
|
||||
$this.val("#{t('.stop_following', :tag => @stream.tag_name)}");
|
||||
},
|
||||
function(){
|
||||
$this = $(this);
|
||||
$this.addClass("in_aspects");
|
||||
$this.val("#{t('.following', :tag => @stream.tag_name)}");
|
||||
});
|
||||
});
|
||||
$(".people_stream .pagination a").live("click", function() {
|
||||
$.getScript(this.href);
|
||||
return false;
|
||||
});
|
||||
|
||||
|
||||
- content_for :body_class do
|
||||
= "tags_show"
|
||||
|
|
@ -49,12 +28,6 @@
|
|||
.span-15.last
|
||||
.stream_container
|
||||
#author_info
|
||||
- if user_signed_in?
|
||||
.right
|
||||
- unless tag_followed?
|
||||
= button_to t('.follow', :tag => @stream.tag_name), tag_tag_followings_path(:name => @stream.tag_name), :method => :post, :class => 'button take_action'
|
||||
- else
|
||||
= button_to t('.following', :tag => @stream.tag_name), tag_tag_followings_path(:name => @stream.tag_name), :method => :delete, :class => 'button red_on_hover tag_following in_aspects take_action'
|
||||
%h2
|
||||
= @stream.display_tag_name
|
||||
%small
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@
|
|||
|
||||
.row
|
||||
.span13
|
||||
= form_tag(multiple_tag_followings_path, :method => 'post', :class => "tag_input search_form") do
|
||||
= form_tag(tag_followings_path, :method => 'get', :class => "tag_input search_form") do
|
||||
%fieldset
|
||||
.clearfix
|
||||
= label_tag 'follow_tags', t('.hashtag_suggestions'), :class => "bootstrapped"
|
||||
|
|
@ -77,5 +77,5 @@
|
|||
%br
|
||||
%br
|
||||
.input
|
||||
= link_to "#{t('.awesome_take_me_to_diaspora')} »", "#", :id => "awesome_button", :class => "btn primary"
|
||||
= link_to "#{t('.awesome_take_me_to_diaspora')} »", stream_path, :id => "awesome_button", :class => "btn primary"
|
||||
|
||||
|
|
|
|||
|
|
@ -106,6 +106,17 @@ en:
|
|||
one: "Show <%= count %> more comment"
|
||||
other: "Show <%= count %> more comments"
|
||||
|
||||
followed_tag:
|
||||
title: "#Followed Tags"
|
||||
contacts_title: "People who dig these tags"
|
||||
add_a_tag: "Add a tag"
|
||||
follow: "Follow"
|
||||
|
||||
tags:
|
||||
follow: "Follow #<%= tag %>"
|
||||
following: "Following #<%= tag %>"
|
||||
stop_following: "Stop Following #<%= tag %>"
|
||||
|
||||
header:
|
||||
home: "Home"
|
||||
profile: "Profile"
|
||||
|
|
|
|||
|
|
@ -74,13 +74,8 @@ Diaspora::Application.routes.draw do
|
|||
end
|
||||
|
||||
resources :tags, :only => [:index]
|
||||
scope "tags/:name" do
|
||||
post "tag_followings" => "tag_followings#create", :as => 'tag_tag_followings'
|
||||
delete "tag_followings" => "tag_followings#destroy", :as => 'tag_tag_followings'
|
||||
end
|
||||
|
||||
post "multiple_tag_followings" => "tag_followings#create_multiple", :as => 'multiple_tag_followings'
|
||||
resources "tag_followings", :only => [:create]
|
||||
resources "tag_followings", :only => [:create, :destroy, :index]
|
||||
|
||||
get 'tags/:name' => 'tags#show', :as => 'tag'
|
||||
|
||||
|
|
|
|||
|
|
@ -67,12 +67,12 @@ describe PeopleController do
|
|||
context 'query is a tag' do
|
||||
it 'goes to a tag page' do
|
||||
get :index, :q => '#babies'
|
||||
response.should redirect_to(tag_path('babies', :q => '#babies'))
|
||||
response.should redirect_to(tag_path('babies'))
|
||||
end
|
||||
|
||||
it 'removes dots from the query' do
|
||||
get :index, :q => '#babi.es'
|
||||
response.should redirect_to(tag_path('babies', :q => '#babi.es'))
|
||||
response.should redirect_to(tag_path('babies'))
|
||||
end
|
||||
|
||||
it 'stay on the page if you search for the empty hash' do
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
describe("app.collections.TagFollowings", function(){
|
||||
beforeEach(function(){
|
||||
this.collection = new app.collections.TagFollowings();
|
||||
})
|
||||
|
||||
describe("create", function(){
|
||||
it("should not allow duplicates", function(){
|
||||
this.collection.create({"name":"name"})
|
||||
this.collection.create({"name":"name"})
|
||||
expect(this.collection.length).toBe(1)
|
||||
})
|
||||
})
|
||||
})
|
||||
50
spec/javascripts/app/views/tag_following_action_view_spec.js
Normal file
50
spec/javascripts/app/views/tag_following_action_view_spec.js
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
describe("app.views.TagFollowingAction", function(){
|
||||
beforeEach(function(){
|
||||
app.tagFollowings = new app.collections.TagFollowings();
|
||||
this.tagName = "test_tag";
|
||||
this.view = new app.views.TagFollowingAction({tagName : this.tagName})
|
||||
})
|
||||
|
||||
describe("render", function(){
|
||||
it("shows the output of followString", function(){
|
||||
spyOn(this.view, "tag_is_followed").andReturn(false)
|
||||
spyOn(this.view, "followString").andReturn("a_follow_string")
|
||||
expect(this.view.render().$('input').val()).toMatch(/^a_follow_string$/)
|
||||
})
|
||||
|
||||
it("should have the extra classes if the tag is followed", function(){
|
||||
spyOn(this.view, "tag_is_followed").andReturn(true)
|
||||
expect(this.view.render().$('input').hasClass("red_on_hover")).toBe(true)
|
||||
expect(this.view.render().$('input').hasClass("in_aspects")).toBe(true)
|
||||
})
|
||||
})
|
||||
|
||||
describe("tagAction", function(){
|
||||
it("toggles the tagFollowed from followed to unfollowed", function(){
|
||||
// first set the tag to followed
|
||||
var origModel = this.view.model;
|
||||
this.view.model.set("id", 3);
|
||||
|
||||
expect(this.view.tag_is_followed()).toBe(true);
|
||||
spyOn(this.view.model, "destroy").andCallFake(_.bind(function(){
|
||||
// model.destroy leads to collection.remove, which is bound to getTagFollowing
|
||||
this.view.getTagFollowing();
|
||||
}, this) )
|
||||
this.view.tagAction();
|
||||
expect(origModel.destroy).toHaveBeenCalled()
|
||||
|
||||
expect(this.view.tag_is_followed()).toBe(false);
|
||||
})
|
||||
|
||||
|
||||
it("toggles the tagFollowed from unfollowed to followed", function(){
|
||||
expect(this.view.tag_is_followed()).toBe(false);
|
||||
spyOn(app.tagFollowings, "create").andCallFake(function(model){
|
||||
// 'save' the model by giving it an id
|
||||
model.set("id", 3)
|
||||
})
|
||||
this.view.tagAction();
|
||||
expect(this.view.tag_is_followed()).toBe(true);
|
||||
})
|
||||
})
|
||||
})
|
||||
Loading…
Reference in a new issue