aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/controllers/admin_spam_addresses_controller.rb27
-rw-r--r--app/controllers/track_controller.rb19
-rwxr-xr-xapp/helpers/link_to_helper.rb12
-rw-r--r--app/helpers/track_helper.rb122
-rw-r--r--app/mailers/request_mailer.rb2
-rw-r--r--app/models/spam_address.rb11
-rw-r--r--app/models/track_thing.rb137
-rw-r--r--app/views/admin_request/_incoming_message_actions.html.erb7
-rw-r--r--app/views/admin_spam_addresses/index.html.erb51
-rw-r--r--app/views/layouts/admin.html.erb2
-rw-r--r--app/views/layouts/default.html.erb2
-rw-r--r--app/views/layouts/no_chrome.html.erb2
-rw-r--r--app/views/track/_track_set.erb6
-rw-r--r--app/views/user/show.html.erb2
-rw-r--r--config/crontab-example2
-rw-r--r--config/routes.rb8
-rw-r--r--db/migrate/20140325120619_create_spam_addresses.rb9
-rw-r--r--spec/controllers/admin_spam_addresses_controller_spec.rb91
-rw-r--r--spec/controllers/track_controller_spec.rb6
-rw-r--r--spec/factories.rb6
-rw-r--r--spec/factories/spam_addresses.rb5
-rw-r--r--spec/factories/track_things.rb26
-rw-r--r--spec/helpers/track_helper_spec.rb204
-rw-r--r--spec/mailers/request_mailer_spec.rb10
-rw-r--r--spec/models/spam_address_spec.rb49
-rw-r--r--spec/models/track_thing_spec.rb9
26 files changed, 706 insertions, 121 deletions
diff --git a/app/controllers/admin_spam_addresses_controller.rb b/app/controllers/admin_spam_addresses_controller.rb
new file mode 100644
index 000000000..f5c7e93da
--- /dev/null
+++ b/app/controllers/admin_spam_addresses_controller.rb
@@ -0,0 +1,27 @@
+class AdminSpamAddressesController < AdminController
+
+ def index
+ @spam_addresses = SpamAddress.all
+ @spam_address = SpamAddress.new
+ end
+
+ def create
+ @spam_address = SpamAddress.new(params[:spam_address])
+
+ if @spam_address.save
+ notice = "#{ @spam_address.email } has been added to the spam addresses list"
+ redirect_to spam_addresses_path, :notice => notice
+ else
+ @spam_addresses = SpamAddress.all
+ render :index
+ end
+ end
+
+ def destroy
+ @spam_address = SpamAddress.find(params[:id])
+ @spam_address.destroy
+ notice = "#{ @spam_address.email } has been removed from the spam addresses list"
+ redirect_to spam_addresses_path, :notice => notice
+ end
+
+end
diff --git a/app/controllers/track_controller.rb b/app/controllers/track_controller.rb
index 83e05ebbc..dccc52efc 100644
--- a/app/controllers/track_controller.rb
+++ b/app/controllers/track_controller.rb
@@ -118,7 +118,7 @@ class TrackController < ApplicationController
if @user
@existing_track = TrackThing.find_existing(@user, @track_thing)
if @existing_track
- flash[:notice] = _("You are already following updates about {{track_description}}", :track_description => @track_thing.params[:list_description])
+ flash[:notice] = view_context.already_subscribed_notice(@track_thing)
return true
end
end
@@ -130,11 +130,7 @@ class TrackController < ApplicationController
@track_thing.track_medium = 'email_daily'
@track_thing.tracking_user_id = @user.id
@track_thing.save!
- if @user.receive_email_alerts
- flash[:notice] = _('You will now be emailed updates about {{track_description}}. <a href="{{change_email_alerts_url}}">Prefer not to receive emails?</a>', :track_description => @track_thing.params[:list_description], :change_email_alerts_url => url_for(:controller => "user", :action => "wall", :url_name => @user.url_name))
- else
- flash[:notice] = _('You are now <a href="{{wall_url_user}}">following</a> updates about {{track_description}}', :track_description => @track_thing.params[:list_description], :wall_url_user => url_for(:controller => "user", :action => "wall", :url_name => @user.url_name))
- end
+ flash[:notice] = render_to_string(:partial => 'track_set').html_safe
return true
end
@@ -183,16 +179,8 @@ class TrackController < ApplicationController
new_medium = params[:track_medium]
if new_medium == 'delete'
track_thing.destroy
- flash[:notice] = _("You are no longer following {{track_description}}.", :track_description => track_thing.params[:list_description])
+ flash[:notice] = view_context.unsubscribe_notice(track_thing)
redirect_to URI.parse(params[:r]).path
-
- # Reuse code like this if we let medium change again.
- #elsif new_medium == 'email_daily'
- # track_thing.track_medium = new_medium
- # track_thing.created_at = Time.now() # as created_at is used to limit the alerts to start with
- # track_thing.save!
- # flash[:notice] = "You are now tracking " + track_thing.params[:list_description] + " by email daily"
- # redirect_to user_url(track_thing.tracking_user)
else
raise "new medium not handled " + new_medium
end
@@ -217,7 +205,6 @@ class TrackController < ApplicationController
for track_thing in TrackThing.find(:all, :conditions => [ "track_type = ? and tracking_user_id = ?", track_type, user_id ])
track_thing.destroy
end
- flash[:notice] += "</ul>"
redirect_to params[:r]
end
diff --git a/app/helpers/link_to_helper.rb b/app/helpers/link_to_helper.rb
index 594296e77..dd6ffa805 100755
--- a/app/helpers/link_to_helper.rb
+++ b/app/helpers/link_to_helper.rb
@@ -18,8 +18,8 @@ module LinkToHelper
request_url(info_request, {:only_path => true}.merge(options))
end
- def request_link(info_request, cls=nil )
- link_to h(info_request.title), request_path(info_request), :class => cls
+ def request_link(info_request, cls=nil)
+ link_to info_request.title, request_path(info_request), :class => cls
end
def request_details_path(info_request)
@@ -96,19 +96,19 @@ module LinkToHelper
end
def user_link(user, cls=nil)
- link_to h(user.name), user_path(user), :class => cls
+ link_to user.name, user_path(user), :class => cls
end
def user_link_for_request(request, cls=nil)
if request.is_external?
user_name = request.external_user_name || _("Anonymous user")
if !request.external_url.nil?
- link_to h(user_name), request.external_url
+ link_to user_name, request.external_url
else
user_name
end
else
- link_to h(request.user.name), user_path(request.user), :class => cls
+ link_to request.user.name, user_path(request.user), :class => cls
end
end
@@ -116,7 +116,7 @@ module LinkToHelper
if request.is_external?
external_text || (request.external_user_name || _("Anonymous user")) + " (external)"
else
- link_to(h(internal_text || request.user.name), admin_user_show_url(request.user))
+ link_to(internal_text || request.user.name, admin_user_show_url(request.user))
end
end
diff --git a/app/helpers/track_helper.rb b/app/helpers/track_helper.rb
new file mode 100644
index 000000000..7bd0fa55d
--- /dev/null
+++ b/app/helpers/track_helper.rb
@@ -0,0 +1,122 @@
+module TrackHelper
+
+ def already_subscribed_notice(track_thing)
+ case track_thing.track_type
+ when 'request_updates'
+ _("You are already subscribed to '{{link_to_request}}', a request",
+ :link_to_request => request_link(track_thing.info_request))
+ when 'all_new_requests'
+ _('You are already subscribed to any <a href="{{new_requests_url}}">new requests</a>',
+ :new_requests_url => request_list_path)
+ when 'all_successful_requests'
+ _('You are already subscribed to any <a href="{{successful_requests_url}}">successful requests</a>',
+ :successful_requests_url => request_list_successful_path )
+ when 'public_body_updates'
+ _("You are already subscribed to '{{link_to_authority}}', a public authority",
+ :link_to_authority => public_body_link(track_thing.public_body))
+ when 'user_updates'
+ _("You are already subscribed to '{{link_to_user}}', a person",
+ :link_to_user => user_link(track_thing.tracked_user))
+ when 'search_query'
+ _('You are already subscribed to <a href="{{search_url}}">this search</a>',
+ :search_url => search_path([track_thing.track_query, 'newest', 'advanced']))
+ end
+ end
+
+ def subscribe_email_notice(track_thing)
+ case track_thing.track_type
+ when 'request_updates'
+ _("You will now be emailed updates about '{{link_to_request}}', a request",
+ :link_to_request => request_link(track_thing.info_request))
+ when 'all_new_requests'
+ _('You will now be emailed updates about any <a href="{{new_requests_url}}">new requests</a>',
+ :new_requests_url => request_list_path)
+ when 'all_successful_requests'
+ _('You will now be emailed updates about <a href="{{successful_requests_url}}">successful requests</a>',
+ :successful_requests_url => request_list_successful_path )
+ when 'public_body_updates'
+ _("You will now be emailed updates about '{{link_to_authority}}', a public authority",
+ :link_to_authority => public_body_link(track_thing.public_body))
+ when 'user_updates'
+ _("You will now be emailed updates about '{{link_to_user}}', a person",
+ :link_to_user => user_link(track_thing.tracked_user))
+ when 'search_query'
+ _("You will now be emailed updates about <a href=\"{{search_url}}\">this search</a>",
+ :search_url => search_path([track_thing.track_query, 'newest', 'advanced']))
+ end
+ end
+
+ def subscribe_follow_notice(track_thing)
+ wall_url_user = show_user_wall_path(:url_name => track_thing.tracking_user.url_name)
+ case track_thing.track_type
+ when 'request_updates'
+ _('You are now <a href="{{wall_url_user}}">following</a> updates about \'{{link_to_request}}\', a request',
+ :link_to_request => request_link(track_thing.info_request),
+ :wall_url_user => wall_url_user)
+ when 'all_new_requests'
+ _('You are now <a href="{{wall_url_user}}">following</a> updates about <a href="{{new_requests_url}}">new requests</a>',
+ :new_requests_url => request_list_path,
+ :wall_url_user => wall_url_user)
+ when 'all_successful_requests'
+ _('You are now <a href="{{wall_url_user}}">following</a> updates about <a href="{{successful_requests_url}}">successful requests</a>',
+ :successful_requests_url => request_list_successful_path,
+ :wall_url_user => wall_url_user)
+ when 'public_body_updates'
+ _('You are now <a href="{{wall_url_user}}">following</a> updates about \'{{link_to_authority}}\', a public authority',
+ :wall_url_user => wall_url_user,
+ :link_to_authority => public_body_link(track_thing.public_body))
+ when 'user_updates'
+ _('You are now <a href="{{wall_url_user}}">following</a> updates about \'{{link_to_user}}\', a person',
+ :wall_url_user => wall_url_user,
+ :link_to_user => user_link(track_thing.tracked_user))
+ when 'search_query'
+ _('You are now <a href="{{wall_url_user}}">following</a> updates about <a href="{{search_url}}">this search</a>',
+ :wall_url_user => wall_url_user,
+ :search_url => search_path([track_thing.track_query, 'newest', 'advanced']))
+ end
+ end
+
+ def unsubscribe_notice(track_thing)
+ case track_thing.track_type
+ when 'request_updates'
+ _("You are no longer following '{{link_to_request}}', a request",
+ :link_to_request => request_link(track_thing.info_request))
+ when 'all_new_requests'
+ _('You are no longer following <a href="{{new_requests_url}}">new requests</a>',
+ :new_requests_url => request_list_path)
+ when 'all_successful_requests'
+ _('You are no longer following <a href="{{successful_requests_url}}">successful requests</a>',
+ :successful_requests_url => request_list_successful_path )
+ when 'public_body_updates'
+ _("You are no longer following '{{link_to_authority}}', a public authority",
+ :link_to_authority => public_body_link(track_thing.public_body))
+ when 'user_updates'
+ _("You are no longer following '{{link_to_user}}', a person",
+ :link_to_user => user_link(track_thing.tracked_user))
+ when 'search_query'
+ _('You are no longer following <a href="{{search_url}}">this search</a>',
+ :search_url => search_path([track_thing.track_query, 'newest', 'advanced']))
+ end
+ end
+
+ def track_description(track_thing)
+ case track_thing.track_type
+ when 'request_updates'
+ _("'{{link_to_request}}', a request",
+ :link_to_request => request_link(track_thing.info_request))
+ when 'all_new_requests'
+ link_to(_('new requests'), request_list_path)
+ when 'all_successful_requests'
+ link_to(_('successful requests'), request_list_successful_path)
+ when 'public_body_updates'
+ _("'{{link_to_authority}}', a public authority",
+ :link_to_authority => public_body_link(track_thing.public_body))
+ when 'user_updates'
+ _("'{{link_to_user}}', a person",
+ :link_to_user => user_link(track_thing.tracked_user))
+ when 'search_query'
+ link_to(track_thing.track_query_description,
+ search_path([track_thing.track_query, 'newest', 'advanced']))
+ end
+ end
+end
diff --git a/app/mailers/request_mailer.rb b/app/mailers/request_mailer.rb
index af1a75df9..1fd5b9ba7 100644
--- a/app/mailers/request_mailer.rb
+++ b/app/mailers/request_mailer.rb
@@ -250,7 +250,7 @@ class RequestMailer < ApplicationMailer
if reply_info_requests.size == 0
reason = _("Could not identify the request from the email address")
request = InfoRequest.holding_pen_request
- request.receive(email, raw_email, false, reason)
+ request.receive(email, raw_email, false, reason) unless SpamAddress.spam?(email.to)
return
end
diff --git a/app/models/spam_address.rb b/app/models/spam_address.rb
new file mode 100644
index 000000000..15c9d1ab8
--- /dev/null
+++ b/app/models/spam_address.rb
@@ -0,0 +1,11 @@
+class SpamAddress < ActiveRecord::Base
+ attr_accessible :email
+
+ validates_presence_of :email, :message => _('Please enter the email address to mark as spam')
+ validates_uniqueness_of :email, :message => _('This address is already marked as spam')
+
+ def self.spam?(email_address)
+ exists?(:email => email_address)
+ end
+
+end
diff --git a/app/models/track_thing.rb b/app/models/track_thing.rb
index d5dda7bb5..13b6f78dd 100644
--- a/app/models/track_thing.rb
+++ b/app/models/track_thing.rb
@@ -69,66 +69,30 @@ class TrackThing < ActiveRecord::Base
end
def track_query_description
- # XXX this is very brittle... we should probably ask users
- # simply to name their tracks when they make them?
- original_text = parsed_text = self.track_query.gsub(/([()]|OR)/, "")
- filters = parsed_text.scan /\b\S+:\S+\b/
- varieties = Set.new
- date = ""
- statuses = Set.new
- for filter in filters
- parsed_text = parsed_text.sub(filter, "")
- if filter =~ /variety:user/
- varieties << _("users")
- end
- if filter =~ /variety:comment/
- varieties << _("comments")
- end
- if filter =~ /variety:authority/
- varieties << _("authorities")
- end
- if filter =~ /(variety:(sent|followup_sent|response)|latest_status)/
- varieties << _("requests")
- end
- if filter =~ /[0-9\/]+\.\.[0-9\/]+/
- date = _("between two dates")
- end
- if filter =~ /(rejected|not_held)/
- statuses << _("unsuccessful")
- end
- if filter =~ /(:successful|:partially_successful)/
- statuses << _("successful")
- end
- if filter =~ /waiting/
- statuses << _("awaiting a response")
- end
- end
- if filters.empty?
- parsed_text = original_text
- end
- descriptions = []
- if varieties.include? _("requests")
- if statuses.empty?
- # HACK: Relies on the 'descriptions.sort' below to luckily put this first
- descriptions << _("all requests")
+ filter_description = query_filter_description('(variety:sent OR variety:followup_sent OR variety:response OR variety:comment)',
+ :no_query => N_("all requests or comments"),
+ :query => N_("all requests or comments matching text '{{query}}'"))
+ return filter_description if filter_description
+ filter_description = query_filter_description('(latest_status:successful OR latest_status:partially_successful)',
+ :no_query => N_("requests which are successful"),
+ :query => N_("requests which are successful matching text '{{query}}'"))
+ return filter_description if filter_description
+ return _("anything matching text '{{query}}'", :query => track_query)
+ end
+
+ # Return a readable query description for queries involving commonly used filter clauses
+ def query_filter_description(string, options)
+ parsed_query = track_query.gsub(string, '')
+ if parsed_query != track_query
+ parsed_query.strip!
+ if parsed_query.empty?
+ _(options[:no_query])
else
- descriptions << _("requests which are {{list_of_statuses}}", :list_of_statuses => Array(statuses).sort.join(_(' or ')))
+ _(options[:query], :query => parsed_query)
end
- varieties -= [_("requests")]
end
- if descriptions.empty? and varieties.empty?
- varieties << _("anything")
- end
- descriptions += Array(varieties)
- parsed_text = parsed_text.strip
- descriptions = descriptions.sort.join(_(" or "))
- if !parsed_text.empty?
- descriptions += _("{{list_of_things}} matching text '{{search_query}}'", :list_of_things => "", :search_query => parsed_text)
- end
- return descriptions
end
-
def TrackThing.create_track_for_request(info_request)
track_thing = TrackThing.new
track_thing.track_type = 'request_updates'
@@ -194,30 +158,32 @@ class TrackThing < ActiveRecord::Base
end
# Return hash of text parameters describing the request etc.
- include LinkToHelper
def params
if @params.nil?
if self.track_type == 'request_updates'
@params = {
# Website
- :list_description => _("'{{link_to_request}}', a request",
- :link_to_request => ("<a href=\"/request/" + CGI.escapeHTML(self.info_request.url_title) + "\">" + CGI.escapeHTML(self.info_request.title) + "</a>").html_safe), # XXX yeuch, sometimes I just want to call view helpers from the model, sorry! can't work out how
+
:verb_on_page => _("Follow this request"),
:verb_on_page_already => _("You are already following this request"),
# Email
- :title_in_email => _("New updates for the request '{{request_title}}'", :request_title => self.info_request.title.html_safe),
- :title_in_rss => _("New updates for the request '{{request_title}}'", :request_title => self.info_request.title),
+ :title_in_email => _("New updates for the request '{{request_title}}'",
+ :request_title => self.info_request.title.html_safe),
+ :title_in_rss => _("New updates for the request '{{request_title}}'",
+ :request_title => self.info_request.title),
# Authentication
- :web => _("To follow the request '{{request_title}}'", :request_title => CGI.escapeHTML(self.info_request.title)),
- :email => _("Then you will be updated whenever the request '{{request_title}}' is updated.", :request_title => CGI.escapeHTML(self.info_request.title)),
- :email_subject => _("Confirm you want to follow the request '{{request_title}}'", :request_title => self.info_request.title),
+ :web => _("To follow the request '{{request_title}}'",
+ :request_title => self.info_request.title),
+ :email => _("Then you will be updated whenever the request '{{request_title}}' is updated.",
+ :request_title => self.info_request.title),
+ :email_subject => _("Confirm you want to follow the request '{{request_title}}'",
+ :request_title => self.info_request.title),
# RSS sorting
:feed_sortby => 'newest'
}
elsif self.track_type == 'all_new_requests'
@params = {
# Website
- :list_description => _("any <a href=\"/list\">new requests</a>"),
:verb_on_page => _("Follow all new requests"),
:verb_on_page_already => _("You are already following new requests"),
# Email
@@ -233,7 +199,6 @@ class TrackThing < ActiveRecord::Base
elsif self.track_type == 'all_successful_requests'
@params = {
# Website
- :list_description => _("any <a href=\"/list/successful\">successful requests</a>"),
:verb_on_page => _("Follow new successful responses"),
:verb_on_page_already => _("You are following all new successful responses"),
# Email
@@ -252,39 +217,51 @@ class TrackThing < ActiveRecord::Base
elsif self.track_type == 'public_body_updates'
@params = {
# Website
- :list_description => _("'{{link_to_authority}}', a public authority", :link_to_authority => ("<a href=\"/body/" + CGI.escapeHTML(self.public_body.url_name) + "\">" + CGI.escapeHTML(self.public_body.name) + "</a>").html_safe), # XXX yeuch, sometimes I just want to call view helpers from the model, sorry! can't work out how
- :verb_on_page => _("Follow requests to {{public_body_name}}",:public_body_name=>CGI.escapeHTML(self.public_body.name)),
- :verb_on_page_already => _("You are already following requests to {{public_body_name}}", :public_body_name=>CGI.escapeHTML(self.public_body.name)),
+ :verb_on_page => _("Follow requests to {{public_body_name}}",
+ :public_body_name => self.public_body.name),
+ :verb_on_page_already => _("You are already following requests to {{public_body_name}}",
+ :public_body_name => self.public_body.name),
# Email
- :title_in_email => self.public_body.law_only_short + " requests to '" + self.public_body.name + "'",
- :title_in_rss => self.public_body.law_only_short + " requests to '" + self.public_body.name + "'",
+ :title_in_email => _("{{foi_law}} requests to '{{public_body_name}}'",
+ :foi_law => self.public_body.law_only_short,
+ :public_body_name => self.public_body.name),
+ :title_in_rss => _("{{foi_law}} requests to '{{public_body_name}}'",
+ :foi_law => self.public_body.law_only_short,
+ :public_body_name => self.public_body.name),
# Authentication
- :web => _("To follow requests made using {{site_name}} to the public authority '{{public_body_name}}'", :site_name=>AlaveteliConfiguration::site_name, :public_body_name=>CGI.escapeHTML(self.public_body.name)),
- :email => _("Then you will be notified whenever someone requests something or gets a response from '{{public_body_name}}'.", :public_body_name=>CGI.escapeHTML(self.public_body.name)),
- :email_subject => _("Confirm you want to follow requests to '{{public_body_name}}'", :public_body_name=>self.public_body.name),
+ :web => _("To follow requests made using {{site_name}} to the public authority '{{public_body_name}}'",
+ :site_name => AlaveteliConfiguration::site_name,
+ :public_body_name => self.public_body.name),
+ :email => _("Then you will be notified whenever someone requests something or gets a response from '{{public_body_name}}'.",
+ :public_body_name => self.public_body.name),
+ :email_subject => _("Confirm you want to follow requests to '{{public_body_name}}'",
+ :public_body_name => self.public_body.name),
# RSS sorting
:feed_sortby => 'newest'
}
elsif self.track_type == 'user_updates'
@params = {
# Website
- :list_description => _("'{{link_to_user}}', a person", :link_to_user => ("<a href=\"/user/" + CGI.escapeHTML(self.tracked_user.url_name) + "\">" + CGI.escapeHTML(self.tracked_user.name) + "</a>").html_safe), # XXX yeuch, sometimes I just want to call view helpers from the model, sorry! can't work out how
:verb_on_page => _("Follow this person"),
:verb_on_page_already => _("You are already following this person"),
# Email
- :title_in_email => _("FOI requests by '{{user_name}}'", :user_name=>self.tracked_user.name.html_safe),
- :title_in_rss => _("FOI requests by '{{user_name}}'", :user_name=>self.tracked_user.name),
+ :title_in_email => _("FOI requests by '{{user_name}}'",
+ :user_name => self.tracked_user.name.html_safe),
+ :title_in_rss => _("FOI requests by '{{user_name}}'",
+ :user_name => self.tracked_user.name),
# Authentication
- :web => _("To follow requests by '{{user_name}}'", :user_name=>CGI.escapeHTML(self.tracked_user.name)),
- :email => _("Then you will be notified whenever '{{user_name}}' requests something or gets a response.", :user_name=>CGI.escapeHTML(self.tracked_user.name)),
- :email_subject => _("Confirm you want to follow requests by '{{user_name}}'", :user_name=>self.tracked_user.name),
+ :web => _("To follow requests by '{{user_name}}'",
+ :user_name=> self.tracked_user.name),
+ :email => _("Then you will be notified whenever '{{user_name}}' requests something or gets a response.",
+ :user_name => self.tracked_user.name),
+ :email_subject => _("Confirm you want to follow requests by '{{user_name}}'",
+ :user_name => self.tracked_user.name),
# RSS sorting
:feed_sortby => 'newest'
}
elsif self.track_type == 'search_query'
@params = {
# Website
- :list_description => ("<a href=\"/search/" + CGI.escapeHTML(self.track_query) + "/newest/advanced\">" + CGI.escapeHTML(self.track_query_description) + "</a>").html_safe, # XXX yeuch, sometimes I just want to call view helpers from the model, sorry! can't work out how
:verb_on_page => _("Follow things matching this search"),
:verb_on_page_already => _("You are already following things matching this search"),
# Email
diff --git a/app/views/admin_request/_incoming_message_actions.html.erb b/app/views/admin_request/_incoming_message_actions.html.erb
index 4cf099b53..dd50eb047 100644
--- a/app/views/admin_request/_incoming_message_actions.html.erb
+++ b/app/views/admin_request/_incoming_message_actions.html.erb
@@ -22,6 +22,13 @@
</div>
</div>
+ <div class="control-group">
+ <label class="control-label">Mark <code>To:</code> address as spam</label>
+ <div class="controls">
+ <%= link_to 'Spam Addresses', spam_addresses_path %>
+ </div>
+ </div>
+
<%= form_tag admin_incoming_destroy_path, :class => "form form-inline" do %>
<div class="control-group">
<label class="control-label" for="destroy_message_<%= incoming_message.id %>">Destroy message</label>
diff --git a/app/views/admin_spam_addresses/index.html.erb b/app/views/admin_spam_addresses/index.html.erb
new file mode 100644
index 000000000..9846bc017
--- /dev/null
+++ b/app/views/admin_spam_addresses/index.html.erb
@@ -0,0 +1,51 @@
+<% @title = 'Spam Addresses' %>
+
+<h1><%= @title %></h1>
+
+<div class="row">
+ <div class="span12">
+ <p>
+ Incoming mail that gets redirected to the holding pen will be
+ rejected if it is sent <code>To:</code> an address on this
+ list.
+ </p>
+ </div>
+</div>
+
+<hr />
+
+<div class="row">
+ <div class="span12">
+ <%= form_for(@spam_address, :html => { :class => 'form-inline' }) do |f| -%>
+ <%= error_messages_for @spam_address %>
+ <%= f.text_field :email, :class => 'input-xxlarge', :placeholder => 'Enter email' %>
+ <%= f.submit 'Add Spam Address', :class => 'btn btn-warning' %>
+ <% end -%>
+ </div>
+</div>
+
+<hr />
+
+<% if @spam_addresses.any? %>
+ <div class="row">
+ <table class="table table-hover span12">
+ <thead>
+ <tr>
+ <th>Email</th>
+ <th></th>
+ </tr>
+ </thead>
+ <tbody>
+ <% @spam_addresses.each do |spam| %>
+ <tr>
+ <td><%= spam.email %></td>
+ <td><%= link_to 'Remove', spam,
+ :method => :delete,
+ :confirm => 'This is permanent! Are you sure?',
+ :class => 'btn btn-mini btn-danger' %></td>
+ </tr>
+ <% end %>
+ </tbody>
+ </table>
+ </div>
+<% end %>
diff --git a/app/views/layouts/admin.html.erb b/app/views/layouts/admin.html.erb
index c1f9335b1..2147f22e1 100644
--- a/app/views/layouts/admin.html.erb
+++ b/app/views/layouts/admin.html.erb
@@ -2,6 +2,8 @@
<html lang="en-gb">
<head>
<meta http-equiv="content-type" content="text/html;charset=UTF-8" >
+ <%= csrf_meta_tags %>
+
<title><%= site_name %> admin<%= @title ? ":" : "" %> <%=@title%></title>
<%= javascript_include_tag "admin" %>
diff --git a/app/views/layouts/default.html.erb b/app/views/layouts/default.html.erb
index 79d7b9c93..93b3c3698 100644
--- a/app/views/layouts/default.html.erb
+++ b/app/views/layouts/default.html.erb
@@ -2,6 +2,8 @@
<html lang="<%= I18n.locale %>">
<head>
<meta charset="utf-8">
+ <%= csrf_meta_tags %>
+
<title>
<% if @title %>
<%=@title%> - <%= site_name %>
diff --git a/app/views/layouts/no_chrome.html.erb b/app/views/layouts/no_chrome.html.erb
index e613b8ca2..a4278ab24 100644
--- a/app/views/layouts/no_chrome.html.erb
+++ b/app/views/layouts/no_chrome.html.erb
@@ -2,6 +2,8 @@
<html lang="<%= I18n.locale %>">
<head>
<meta charset="utf-8">
+ <%= csrf_meta_tags %>
+
<title>
<% if @title %>
<%=@title%> - <%= site_name %>
diff --git a/app/views/track/_track_set.erb b/app/views/track/_track_set.erb
new file mode 100644
index 000000000..c7665312d
--- /dev/null
+++ b/app/views/track/_track_set.erb
@@ -0,0 +1,6 @@
+<% if @user.receive_email_alerts %>
+ <%= subscribe_email_notice(@track_thing) %>
+ <%= link_to(_('Prefer not to receive emails?'), show_user_wall_path(:url_name => @user.url_name)) %>
+<% else %>
+ <%= subscribe_follow_notice(@track_thing) %>
+<% end %>
diff --git a/app/views/user/show.html.erb b/app/views/user/show.html.erb
index 1ccb1d649..8dd8c6b88 100644
--- a/app/views/user/show.html.erb
+++ b/app/views/user/show.html.erb
@@ -224,7 +224,7 @@
<li>
<%= form_tag({:controller => 'track', :action => 'update', :track_id => track_thing.id}, :class => "feed_form") do %>
<div>
- <%= track_thing.params[:list_description] %>
+ <%= track_description(track_thing) %>
<%= hidden_field_tag 'track_medium', "delete", { :id => 'track_medium_' + track_thing.id.to_s } %>
<%= hidden_field_tag 'r', request.fullpath, { :id => 'r_' + track_thing.id.to_s } %>
<%= submit_tag _('unsubscribe') %>
diff --git a/config/crontab-example b/config/crontab-example
index 64d0c45c9..8fe13151b 100644
--- a/config/crontab-example
+++ b/config/crontab-example
@@ -12,7 +12,7 @@ MAILTO=cron-!!(*= $site *)!!@mysociety.org
# Every 10 minutes
5,15,25,35,45,55 * * * * !!(*= $user *)!! /etc/init.d/foi-alert-tracks check
5,15,25,35,45,55 * * * * !!(*= $user *)!! /etc/init.d/foi-purge-varnish check
-0,10,20,30,40,50 * * * * !!(*= $user *)!! run-with-lockfile -n /data/vhost/!!(*= $vhost *)!!/send-batch-requests.lock /data/vhost/!!(*= $vhost *)!!/!!(*= $vcspath *)!!/script/send-batch-requests || echo "stalled?"
+0,10,20,30,40,50 * * * * !!(*= $user *)!! run-with-lockfile -n !!(*= $vhost_dir *)!!/send-batch-requests.lock !!(*= $vhost_dir *)!!/!!(*= $vcspath *)!!/script/send-batch-requests || echo "stalled?"
# Once an hour
09 * * * * !!(*= $user *)!! run-with-lockfile -n !!(*= $vhost_dir *)!!/alert-comment-on-request.lock !!(*= $vhost_dir *)!!/!!(*= $vcspath *)!!/script/alert-comment-on-request || echo "stalled?"
diff --git a/config/routes.rb b/config/routes.rb
index 1079fbe14..d9d21f0bd 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -248,6 +248,14 @@ Alaveteli::Application.routes.draw do
match '/admin/censor/destroy/:censor_rule_id' => 'admin_censor_rule#destroy', :as => :admin_rule_destroy
####
+ #### AdminSpamAddresses controller
+ scope '/admin' do
+ resources :spam_addresses,
+ :controller => 'admin_spam_addresses',
+ :only => [:index, :create, :destroy]
+ end
+ ####
+
#### Api controller
match '/api/v2/request.json' => 'api#create_request', :as => :api_create_request, :via => :post
diff --git a/db/migrate/20140325120619_create_spam_addresses.rb b/db/migrate/20140325120619_create_spam_addresses.rb
new file mode 100644
index 000000000..7c730a5c7
--- /dev/null
+++ b/db/migrate/20140325120619_create_spam_addresses.rb
@@ -0,0 +1,9 @@
+class CreateSpamAddresses < ActiveRecord::Migration
+ def change
+ create_table :spam_addresses do |t|
+ t.string :email, :null => false
+
+ t.timestamps
+ end
+ end
+end
diff --git a/spec/controllers/admin_spam_addresses_controller_spec.rb b/spec/controllers/admin_spam_addresses_controller_spec.rb
new file mode 100644
index 000000000..da1e9bb5a
--- /dev/null
+++ b/spec/controllers/admin_spam_addresses_controller_spec.rb
@@ -0,0 +1,91 @@
+require 'spec_helper'
+
+describe AdminSpamAddressesController do
+ render_views
+ before { basic_auth_login @request }
+
+ describe :index do
+
+ it 'lists the spam addresses' do
+ 3.times { FactoryGirl.create(:spam_address) }
+ get :index
+ assigns(:spam_addresses).should == SpamAddress.all
+ end
+
+ it 'creates a new spam address for the form' do
+ get :index
+ expect(assigns(:spam_address)).to be_a_new(SpamAddress)
+ end
+
+ it 'renders the index template' do
+ get :index
+ expect(response).to render_template('index')
+ end
+
+ end
+
+ describe :create do
+
+ let(:spam_params) { FactoryGirl.attributes_for(:spam_address) }
+
+ it 'creates a new spam address with the given parameters' do
+ post :create, :spam_address => spam_params
+ assigns(:spam_address).email.should == spam_params[:email]
+ assigns(:spam_address).should be_persisted
+ end
+
+ it 'redirects to the index action if successful' do
+ SpamAddress.any_instance.stub(:save).and_return(true)
+ post :create, :spam_address => spam_params
+ expect(response).to redirect_to(spam_addresses_path)
+ end
+
+ it 'notifies the admin the spam address has been created' do
+ SpamAddress.any_instance.stub(:save).and_return(true)
+ post :create, :spam_address => spam_params
+ msg = "#{ spam_params[:email] } has been added to the spam addresses list"
+ flash[:notice].should == msg
+ end
+
+ it 'renders the index action if the address could not be saved' do
+ SpamAddress.any_instance.stub(:save).and_return(false)
+ post :create, :spam_address => spam_params
+ expect(response).to render_template('index')
+ end
+
+ it 'collects the spam addresses if the address could not be saved' do
+ 3.times { FactoryGirl.create(:spam_address) }
+ SpamAddress.any_instance.stub(:save).and_return(false)
+ post :create, :spam_address => spam_params
+ assigns(:spam_addresses).should == SpamAddress.all
+ end
+
+ end
+
+ describe :delete do
+
+ before(:each) do
+ @spam = FactoryGirl.create(:spam_address)
+ delete :destroy, :id => @spam.id
+ end
+
+ it 'finds the spam address to delete' do
+ assigns(:spam_address).should == @spam
+ end
+
+ it 'destroys the spam address' do
+ assigns(:spam_address).should be_destroyed
+ end
+
+ it 'tells the admin the spam address has been deleted' do
+ msg = "#{ @spam.email } has been removed from the spam addresses list"
+ flash[:notice].should == msg
+ end
+
+ it 'redirects to the index action' do
+ expect(response).to redirect_to(spam_addresses_path)
+ end
+
+ end
+
+end
diff --git a/spec/controllers/track_controller_spec.rb b/spec/controllers/track_controller_spec.rb
index 40865d2b9..d2b45b6bf 100644
--- a/spec/controllers/track_controller_spec.rb
+++ b/spec/controllers/track_controller_spec.rb
@@ -5,7 +5,7 @@ describe TrackController, "when making a new track on a request" do
@ir = mock_model(InfoRequest, :url_title => 'myrequest',
:title => 'My request')
@track_thing = mock_model(TrackThing, :save! => true,
- :params => {:list_description => 'list description'},
+ :params => {},
:track_medium= => nil,
:tracking_user_id= => nil)
TrackThing.stub!(:create_track_for_request).and_return(@track_thing)
@@ -58,7 +58,7 @@ end
describe TrackController, "when unsubscribing from a track" do
before do
- @track_thing = FactoryGirl.create(:track_thing)
+ @track_thing = FactoryGirl.create(:search_track)
end
it 'should destroy the track thing' do
@@ -78,7 +78,7 @@ describe TrackController, "when unsubscribing from a track" do
end
it 'should not redirect to a url on another site' do
- track_thing = FactoryGirl.create(:track_thing)
+ track_thing = FactoryGirl.create(:search_track)
get :update, {:track_id => @track_thing.id,
:track_medium => 'delete',
:r => 'http://example.com/'},
diff --git a/spec/factories.rb b/spec/factories.rb
deleted file mode 100644
index 7dec41aaf..000000000
--- a/spec/factories.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-# Factories are defined in spec/factories/*.rb
-#
-# You can use this file to define shared sequences
-FactoryGirl.define do
-
-end
diff --git a/spec/factories/spam_addresses.rb b/spec/factories/spam_addresses.rb
new file mode 100644
index 000000000..bafb7cd50
--- /dev/null
+++ b/spec/factories/spam_addresses.rb
@@ -0,0 +1,5 @@
+FactoryGirl.define do
+ factory :spam_address do
+ sequence(:email) { |n| "spam-#{ n }@example.org" }
+ end
+end
diff --git a/spec/factories/track_things.rb b/spec/factories/track_things.rb
index d1a937c02..cf76b00b3 100644
--- a/spec/factories/track_things.rb
+++ b/spec/factories/track_things.rb
@@ -2,9 +2,29 @@ FactoryGirl.define do
factory :track_thing do
association :tracking_user, :factory => :user
- track_medium 'email_daily'
- track_type 'search_query'
- track_query 'Example Query'
+ factory :search_track do
+ track_medium 'email_daily'
+ track_type 'search_query'
+ track_query 'Example Query'
+ end
+ factory :user_track do
+ association :tracked_user, :factory => :user
+ track_type 'user_updates'
+ end
+ factory :public_body_track do
+ association :public_body, :factory => :public_body
+ track_type 'public_body_updates'
+ end
+ factory :request_update_track do
+ association :info_request, :factory => :info_request
+ track_type 'request_updates'
+ end
+ factory :successful_request_track do
+ track_type 'all_successful_requests'
+ end
+ factory :new_request_track do
+ track_type 'all_new_requests'
+ end
end
end
diff --git a/spec/helpers/track_helper_spec.rb b/spec/helpers/track_helper_spec.rb
new file mode 100644
index 000000000..80857067b
--- /dev/null
+++ b/spec/helpers/track_helper_spec.rb
@@ -0,0 +1,204 @@
+require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
+
+describe TrackHelper do
+
+ include TrackHelper
+ include LinkToHelper
+
+ describe 'when displaying notices for a search track' do
+
+ before do
+ @track_thing = FactoryGirl.build(:search_track)
+ end
+
+ it 'should create an already subscribed_notice' do
+ expected = %Q(You are already subscribed to <a href="/search/Example%20Query/newest/advanced">this search</a>)
+ already_subscribed_notice(@track_thing).should == expected
+ end
+
+ it 'should create an email subscription notice' do
+ expected = %Q(You will now be emailed updates about <a href="/search/Example%20Query/newest/advanced">this search</a>)
+ subscribe_email_notice(@track_thing).should == expected
+ end
+
+ it 'should create a following subscription notice' do
+ expected = %Q(You are now <a href="#{show_user_wall_path(:url_name => @track_thing.tracking_user.url_name)}">following</a> updates about <a href="/search/Example%20Query/newest/advanced">this search</a>)
+ subscribe_follow_notice(@track_thing).should == expected
+ end
+
+ it 'should create an unsubscribe notice' do
+ expected = %Q(You are no longer following <a href="/search/Example%20Query/newest/advanced">this search</a>)
+ unsubscribe_notice(@track_thing).should == expected
+ end
+
+ it 'should create a description of the track' do
+ expected = %Q(<a href="/search/Example%20Query/newest/advanced">anything matching text 'Example Query'</a>)
+ track_description(@track_thing).should == expected
+ end
+
+ end
+
+ describe 'when displaying notices for a user track' do
+
+ before do
+ @track_thing = FactoryGirl.build(:user_track)
+ end
+
+ it 'should create an already subscribed_notice' do
+ expected = %Q(You are already subscribed to '#{user_link(@track_thing.tracked_user)}', a person)
+ already_subscribed_notice(@track_thing).should == expected
+ end
+
+ it 'should create an email subscription notice' do
+ expected = %Q(You will now be emailed updates about '#{user_link(@track_thing.tracked_user)}', a person)
+ subscribe_email_notice(@track_thing).should == expected
+ end
+
+ it 'should create a following subscription notice' do
+ expected = %Q(You are now <a href="#{show_user_wall_path(:url_name => @track_thing.tracking_user.url_name)}">following</a> updates about '#{user_link(@track_thing.tracked_user)}', a person)
+ subscribe_follow_notice(@track_thing).should == expected
+ end
+
+ it 'should create an unsubscribe notice' do
+ expected = %Q(You are no longer following '#{user_link(@track_thing.tracked_user)}', a person)
+ unsubscribe_notice(@track_thing).should == expected
+ end
+
+ it 'should create a description of the track' do
+ expected = %Q('#{user_link(@track_thing.tracked_user)}', a person)
+ track_description(@track_thing).should == expected
+ end
+
+ end
+
+ describe 'when displaying notices for a public body track' do
+
+ before do
+ @track_thing = FactoryGirl.build(:public_body_track)
+ end
+
+ it 'should create an already subscribed_notice' do
+ expected = %Q(You are already subscribed to '#{public_body_link(@track_thing.public_body)}', a public authority)
+ already_subscribed_notice(@track_thing).should == expected
+ end
+
+ it 'should create an email subscription notice' do
+ expected = %Q(You will now be emailed updates about '#{public_body_link(@track_thing.public_body)}', a public authority)
+ subscribe_email_notice(@track_thing).should == expected
+ end
+
+ it 'should create a following subscription notice' do
+ expected = %Q(You are now <a href="#{show_user_wall_path(:url_name => @track_thing.tracking_user.url_name)}">following</a> updates about '#{public_body_link(@track_thing.public_body)}', a public authority)
+ subscribe_follow_notice(@track_thing).should == expected
+ end
+
+ it 'should create an unsubscribe notice' do
+ expected = %Q(You are no longer following '#{public_body_link(@track_thing.public_body)}', a public authority)
+ unsubscribe_notice(@track_thing).should == expected
+ end
+
+ it 'should create a description of the track' do
+ expected = %Q('#{public_body_link(@track_thing.public_body)}', a public authority)
+ track_description(@track_thing).should == expected
+ end
+ end
+
+ describe 'when displaying notices for a successful request track' do
+
+ before do
+ @track_thing = FactoryGirl.build(:successful_request_track)
+ end
+
+ it 'should create an already subscribed_notice' do
+ expected = %Q(You are already subscribed to any <a href="/list/successful">successful requests</a>)
+ already_subscribed_notice(@track_thing).should == expected
+ end
+
+ it 'should create an email subscription notice' do
+ expected = %Q(You will now be emailed updates about <a href="/list/successful">successful requests</a>)
+ subscribe_email_notice(@track_thing).should == expected
+ end
+
+ it 'should create a following subscription notice' do
+ expected = %Q(You are now <a href="#{show_user_wall_path(:url_name => @track_thing.tracking_user.url_name)}">following</a> updates about <a href="/list/successful">successful requests</a>)
+ subscribe_follow_notice(@track_thing).should == expected
+ end
+
+ it 'should create an unsubscribe notice' do
+ expected = %Q(You are no longer following <a href="/list/successful">successful requests</a>)
+ unsubscribe_notice(@track_thing).should == expected
+ end
+
+ it 'should create a description of the track' do
+ expected = %Q(<a href="/list/successful">successful requests</a>)
+ track_description(@track_thing).should == expected
+ end
+ end
+
+ describe 'when displaying notices for a new request track' do
+
+ before do
+ @track_thing = FactoryGirl.build(:new_request_track)
+ end
+
+ it 'should create an already subscribed_notice' do
+ expected = %Q(You are already subscribed to any <a href="/list">new requests</a>)
+ already_subscribed_notice(@track_thing).should == expected
+ end
+
+ it 'should create an email subscription notice' do
+ expected = %Q(You will now be emailed updates about any <a href="/list">new requests</a>)
+ subscribe_email_notice(@track_thing).should == expected
+ end
+
+ it 'should create a following subscription notice' do
+ expected = %Q(You are now <a href="#{show_user_wall_path(:url_name => @track_thing.tracking_user.url_name)}">following</a> updates about <a href="/list">new requests</a>)
+ subscribe_follow_notice(@track_thing).should == expected
+ end
+
+ it 'should create an unsubscribe notice' do
+ expected = %Q(You are no longer following <a href="/list">new requests</a>)
+ unsubscribe_notice(@track_thing).should == expected
+ end
+
+ it 'should create a description of the track' do
+ expected = %Q(<a href="/list">new requests</a>)
+ track_description(@track_thing).should == expected
+ end
+
+ end
+
+ describe 'when displaying notices for a request update track' do
+
+ before do
+ @track_thing = FactoryGirl.build(:request_update_track)
+ end
+
+ it 'should create an already subscribed_notice' do
+ expected = %Q(You are already subscribed to '#{request_link(@track_thing.info_request)}', a request)
+ already_subscribed_notice(@track_thing).should == expected
+ end
+
+ it 'should create an email subscription notice' do
+ expected = %Q(You will now be emailed updates about '#{request_link(@track_thing.info_request)}', a request)
+ subscribe_email_notice(@track_thing).should == expected
+ end
+
+ it 'should create a following subscription notice' do
+ expected = %Q(You are now <a href="#{show_user_wall_path(:url_name => @track_thing.tracking_user.url_name)}">following</a> updates about '#{request_link(@track_thing.info_request)}', a request)
+ subscribe_follow_notice(@track_thing).should == expected
+ end
+
+ it 'should create an unsubscribe notice' do
+ expected = %Q(You are no longer following '#{request_link(@track_thing.info_request)}', a request)
+ unsubscribe_notice(@track_thing).should == expected
+ end
+
+ it 'should create a description of the track' do
+ expected = %Q('#{request_link(@track_thing.info_request)}', a request)
+ track_description(@track_thing).should == expected
+ end
+
+ end
+
+end
diff --git a/spec/mailers/request_mailer_spec.rb b/spec/mailers/request_mailer_spec.rb
index 516d13127..2c5d6e6a9 100644
--- a/spec/mailers/request_mailer_spec.rb
+++ b/spec/mailers/request_mailer_spec.rb
@@ -78,6 +78,16 @@ describe RequestMailer, " when receiving incoming mail" do
deliveries.clear
end
+ it "should ignore mail sent to known spam addresses" do
+ @spam_address = FactoryGirl.create(:spam_address)
+
+ receive_incoming_mail('incoming-request-plain.email', @spam_address.email)
+
+ deliveries = ActionMailer::Base.deliveries
+ deliveries.size.should == 0
+ deliveries.clear
+ end
+
it "should return incoming mail to sender when a request is stopped fully for spam" do
# mark request as anti-spam
ir = info_requests(:fancy_dog_request)
diff --git a/spec/models/spam_address_spec.rb b/spec/models/spam_address_spec.rb
new file mode 100644
index 000000000..79a1afd11
--- /dev/null
+++ b/spec/models/spam_address_spec.rb
@@ -0,0 +1,49 @@
+require 'spec_helper'
+
+describe SpamAddress do
+
+ describe :new do
+
+ it 'requres an email address' do
+ SpamAddress.new().should_not be_valid
+ SpamAddress.new(:email => 'spam@example.org').should be_valid
+ end
+
+ it 'must have a unique email address' do
+ existing = FactoryGirl.create(:spam_address)
+ SpamAddress.new(:email => existing.email).should_not be_valid
+ end
+
+ end
+
+ describe '.spam?' do
+
+ before(:each) do
+ @spam_address = FactoryGirl.create(:spam_address)
+ end
+
+ it 'is a spam address if the address is stored' do
+ SpamAddress.spam?(@spam_address.email).should be_true
+ end
+
+ it 'is not a spam address if the adress is not stored' do
+ SpamAddress.spam?('genuine-email@example.com').should be_false
+ end
+
+ describe 'when accepting an array of emails' do
+
+ it 'is spam if any of the emails are stored' do
+ emails = ['genuine-email@example.com', @spam_address.email]
+ SpamAddress.spam?(emails).should be_true
+ end
+
+ it 'is not spam if none of the emails are stored' do
+ emails = ['genuine-email@example.com', 'genuine-email@example.org']
+ SpamAddress.spam?(emails).should be_false
+ end
+
+ end
+
+ end
+
+end
diff --git a/spec/models/track_thing_spec.rb b/spec/models/track_thing_spec.rb
index 1c582564b..3edf2d1ad 100644
--- a/spec/models/track_thing_spec.rb
+++ b/spec/models/track_thing_spec.rb
@@ -51,10 +51,11 @@ describe TrackThing, "when tracking changes" do
end
it "will make some sane descriptions of search-based tracks" do
- tests = { 'bob variety:user' => "users matching text 'bob'",
- 'bob (variety:sent OR variety:followup_sent OR variety:response OR variety:comment) (latest_status:successful OR latest_status:partially_successful OR latest_status:rejected OR latest_status:not_held)' => "comments or requests which are successful or unsuccessful matching text 'bob'",
- '(latest_status:waiting_response OR latest_status:waiting_clarification OR waiting_classification:true)' => 'requests which are awaiting a response',
- ' (variety:sent OR variety:followup_sent OR variety:response OR variety:comment)' => 'all requests or comments' }
+ tests = { ' (variety:sent OR variety:followup_sent OR variety:response OR variety:comment)' => 'all requests or comments',
+ 'bob (variety:sent OR variety:followup_sent OR variety:response OR variety:comment)' => "all requests or comments matching text 'bob'",
+ 'bob (latest_status:successful OR latest_status:partially_successful)' => "requests which are successful matching text 'bob'",
+ '(latest_status:successful OR latest_status:partially_successful)' => 'requests which are successful',
+ 'bob' => "anything matching text 'bob'" }
tests.each do |query, description|
track_thing = TrackThing.create_track_for_search_query(query)
track_thing.track_query_description.should == description