headword 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.textile +3 -0
- data/LICENSE +20 -0
- data/README.textile +63 -0
- data/Rakefile +93 -0
- data/TODO.textile +1 -0
- data/TUTORIAL.textile +80 -0
- data/VERSION +1 -0
- data/app/controllers/headword/users_controller.rb +10 -0
- data/config/headword_routes.rb +3 -0
- data/generators/headword/USAGE +1 -0
- data/generators/headword/headword_generator.rb +57 -0
- data/generators/headword/templates/README +6 -0
- data/generators/headword/templates/factories.rb +13 -0
- data/generators/headword/templates/migrations/create_users.rb +14 -0
- data/generators/headword/templates/migrations/update_users.rb +35 -0
- data/generators/headword/templates/show.html.erb +1 -0
- data/generators/headword/templates/user.rb +3 -0
- data/lib/headword.rb +3 -0
- data/lib/headword/extensions/routes.rb +14 -0
- data/lib/headword/user.rb +63 -0
- data/rails/init.rb +1 -0
- data/test/controllers/users_controller_test.rb +70 -0
- data/test/models/user_test.rb +15 -0
- data/test/test_helper.rb +18 -0
- metadata +90 -0
data/CHANGELOG.textile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Jeff Rafter, SocialRange, Inc.
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.textile
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
h1. Headword
|
2
|
+
|
3
|
+
Rails user name routes for vain users.
|
4
|
+
|
5
|
+
h2. Installation
|
6
|
+
|
7
|
+
Headword is a Rails engine. It works with versions of Rails greater than 2.3.
|
8
|
+
|
9
|
+
In config/environment.rb:
|
10
|
+
|
11
|
+
<pre>
|
12
|
+
config.gem "jeffrafter-headword",
|
13
|
+
:lib => 'headword',
|
14
|
+
:source => 'http://gems.github.com'
|
15
|
+
</pre>
|
16
|
+
|
17
|
+
We recommend you don't vendor the gem:
|
18
|
+
|
19
|
+
Make sure the development database exists and run the generator:
|
20
|
+
|
21
|
+
<pre>
|
22
|
+
script/generate headword
|
23
|
+
</pre>
|
24
|
+
|
25
|
+
A number of files will be created and instructions will be printed.
|
26
|
+
|
27
|
+
You may already have some of these files. Don't worry. You'll be asked if you want to overwrite them.
|
28
|
+
|
29
|
+
Run the migration:
|
30
|
+
|
31
|
+
<pre>
|
32
|
+
rake db:migrate
|
33
|
+
</pre>
|
34
|
+
|
35
|
+
h2. Routes
|
36
|
+
|
37
|
+
Headword installs a default catch-all route for single words (e.g., /jeffrafter). These are given the lowest priority in your application. If your application is already catching these routes then you may not be able to access your headword based user pages.
|
38
|
+
|
39
|
+
h2. Tutorial
|
40
|
+
|
41
|
+
Checkout the "tutorial":http://wiki.github.com/jeffrafter/headword/tutorial.
|
42
|
+
|
43
|
+
h2. Authors
|
44
|
+
|
45
|
+
Headword is based on Spreadhead.
|
46
|
+
|
47
|
+
The engine implementation and gem was patterned after the Clearance gem by Thoughtbot.
|
48
|
+
|
49
|
+
h2. Suggestions, Bugs, Refactoring?
|
50
|
+
|
51
|
+
Fork away and create a "Github Issue":http://github.com/jeffrafter/headword/issues. Please send pull requests.
|
52
|
+
|
53
|
+
When you do:
|
54
|
+
|
55
|
+
* Fork the project.
|
56
|
+
* Make your feature addition or bug fix.
|
57
|
+
* Add tests for it. This is important so I don't break it in a future version unintentionally.
|
58
|
+
* Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
59
|
+
* Send me a pull request. Bonus points for topic branches.
|
60
|
+
|
61
|
+
h2. Documentation
|
62
|
+
|
63
|
+
Documentation is available at "http://rdoc.info/projects/jeffrafter/headword":http://rdoc.info/jeffrafter/headword
|
data/Rakefile
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "headword"
|
8
|
+
gem.summary = %Q{When your users are that vain.}
|
9
|
+
gem.description = %Q{Simplify adding usernames to your application.}
|
10
|
+
gem.email = "jeff@socialrange.org"
|
11
|
+
gem.homepage = "http://github.com/jeffrafter/headword"
|
12
|
+
gem.authors = ["Jeff Rafter"]
|
13
|
+
gem.add_dependency "rsl-stringex", ">= 1.0.2"
|
14
|
+
gem.files = FileList["[A-Z]*", "{app,config,generators,lib,rails}/**/*", "test/{controllers,models}/**/*", "test/test_helper.rb"]
|
15
|
+
gem.test_files = FileList["test/{controllers,models}/**/*", "test/test_helper.rb"]
|
16
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
17
|
+
end
|
18
|
+
|
19
|
+
rescue LoadError
|
20
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
21
|
+
end
|
22
|
+
|
23
|
+
require 'rake/testtask'
|
24
|
+
Rake::TestTask.new(:test => ["generator:cleanup", "generator:headword"]) do |task|
|
25
|
+
task.libs << "lib" << "test"
|
26
|
+
task.pattern = "test/**/*_test.rb"
|
27
|
+
task.verbose = true
|
28
|
+
end
|
29
|
+
|
30
|
+
namespace :test do
|
31
|
+
Rake::TestTask.new(:clearance => ["generator:cleanup", "generator:clearance", "generator:headword"]) do |task|
|
32
|
+
task.libs << "lib" << "test"
|
33
|
+
task.pattern = "test/**/*_test.rb"
|
34
|
+
task.verbose = true
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
generators = %w(headword)
|
39
|
+
|
40
|
+
namespace :generator do
|
41
|
+
desc "Cleans up the test app before running the generator"
|
42
|
+
task :cleanup do
|
43
|
+
FileUtils.rm_rf("test/rails")
|
44
|
+
system "cd test && rails rails"
|
45
|
+
|
46
|
+
# I don't like testing performance!
|
47
|
+
FileUtils.rm_rf("test/rails/test/performance")
|
48
|
+
|
49
|
+
system "echo \"\" >> test/rails/config/environments/test.rb"
|
50
|
+
system "echo \"config.gem 'thoughtbot-shoulda', :lib => 'shoulda'\" >> test/rails/config/environments/test.rb"
|
51
|
+
system "echo \"config.gem 'thoughtbot-factory_girl', :lib => 'factory_girl'\" >> test/rails/config/environments/test.rb"
|
52
|
+
|
53
|
+
# Make a thing
|
54
|
+
system "cd test/rails && ./script/generate scaffold thing name:string mood:string"
|
55
|
+
|
56
|
+
FileUtils.mkdir_p("test/rails/vendor/plugins")
|
57
|
+
headword_root = File.expand_path(File.dirname(__FILE__))
|
58
|
+
system("ln -s #{headword_root} test/rails/vendor/plugins/headword")
|
59
|
+
end
|
60
|
+
|
61
|
+
desc "Prepares the application with clearance"
|
62
|
+
task :clearance do
|
63
|
+
system "echo \"config.gem 'thoughtbot-clearance', :lib => 'clearance'\" >> test/rails/config/environments/test.rb"
|
64
|
+
system "echo \"HOST = 'headword'\" >> test/rails/config/environments/test.rb"
|
65
|
+
system "echo \"DO_NOT_REPLY = 'donotreply'\" >> test/rails/config/environments/test.rb"
|
66
|
+
system "cd test/rails && ./script/generate clearance && rake db:migrate db:test:prepare"
|
67
|
+
end
|
68
|
+
|
69
|
+
desc "Run the headword generator"
|
70
|
+
task :headword do
|
71
|
+
system "cd test/rails && ./script/generate headword && rake db:migrate db:test:prepare"
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
task :default => :test
|
77
|
+
|
78
|
+
require 'rake/rdoctask'
|
79
|
+
Rake::RDocTask.new do |rdoc|
|
80
|
+
if File.exist?('VERSION.yml')
|
81
|
+
config = YAML.load(File.read('VERSION.yml'))
|
82
|
+
version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
|
83
|
+
else
|
84
|
+
version = ""
|
85
|
+
end
|
86
|
+
|
87
|
+
rdoc.rdoc_dir = 'rdoc'
|
88
|
+
rdoc.title = "headword #{version}"
|
89
|
+
rdoc.rdoc_files.include('README*')
|
90
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
91
|
+
rdoc.rdoc_files.include('app/**/*.rb')
|
92
|
+
rdoc.rdoc_files.include('generators/**/*.rb')
|
93
|
+
end
|
data/TODO.textile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
h1. To-do
|
data/TUTORIAL.textile
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
Before you can use Headword you are going to need a few things, most importantly the headword gem:
|
2
|
+
|
3
|
+
<pre>
|
4
|
+
<code>
|
5
|
+
sudo gem install jeffrafter-headword --source=http://gems.github.com
|
6
|
+
</code>
|
7
|
+
</pre>
|
8
|
+
|
9
|
+
By default this should install the rsl-stringex gem which handles the url formatting. If you want to run the spreadhead-specific tests, you will need Thoughtbot's shoulda and factory_girl. Once you have all of the requisite gems, you need to configure your Rails application to use the gem. You can do this by adding a config.gem statement to your environment.rb (or to a specific environment). For example:
|
10
|
+
|
11
|
+
<pre>
|
12
|
+
<code>
|
13
|
+
Rails::Initializer.run do |config|
|
14
|
+
# Specify gems that this application depends on and have them installed with
|
15
|
+
# rake gems:install
|
16
|
+
config.gem "jeffrafter-headword",
|
17
|
+
:lib => 'headword',
|
18
|
+
:source => 'http://gems.github.com'
|
19
|
+
|
20
|
+
# Skip frameworks you're not going to use. To use Rails without a database,
|
21
|
+
# you must remove the Active Record framework.
|
22
|
+
config.frameworks -= [ :active_resource ]
|
23
|
+
|
24
|
+
# Set Time.zone default to the specified zone and make Active Record
|
25
|
+
# auto-convert to this zone. Run "rake -D time" for a list of tasks for
|
26
|
+
# finding time zone names.
|
27
|
+
config.time_zone = 'UTC'
|
28
|
+
end
|
29
|
+
</code>
|
30
|
+
</pre>
|
31
|
+
|
32
|
+
After you have done this, you can use the headword generator from the console (while in the rails root).
|
33
|
+
|
34
|
+
<pre>
|
35
|
+
<code>
|
36
|
+
script/generate headword
|
37
|
+
</code>
|
38
|
+
</pre>
|
39
|
+
|
40
|
+
This will create (or update) a migration for the users table for the url attribute. Additionally, it will create a User model in your app/models folder (if it does not exist). The model must have include statement to bring in all of the base functionality. This is all you need to get started, you should be able to run the migration and restart your application.
|
41
|
+
|
42
|
+
h2. What do I get?
|
43
|
+
|
44
|
+
By default you will have a "/:username" route. Additionally any time a user name is changed headword will automatically generate a new url. If there is a conflict it will add "-1" to the end (or "-2" and so on).
|
45
|
+
|
46
|
+
You don't get any editing. You will want to add a username field to your user editing form:
|
47
|
+
|
48
|
+
<pre>
|
49
|
+
<code>
|
50
|
+
<div class="text_field">
|
51
|
+
<%= form.label :username %>
|
52
|
+
<%= form.text_field :username %>
|
53
|
+
</div>
|
54
|
+
</code>
|
55
|
+
</pre>
|
56
|
+
|
57
|
+
h2. Wait a second, I am using a Clearance, this works with Clearance right?
|
58
|
+
|
59
|
+
Yup. In fact, that's the point. But, there are a couple more things you need to do. In order to modify the views that come with clearance, you need to override the UserController. To do this you need to add add the following to @app/controllers/user_controller.rb@:
|
60
|
+
|
61
|
+
<pre>
|
62
|
+
<code>
|
63
|
+
class UsersController < Clearance::UsersController
|
64
|
+
end
|
65
|
+
</code>
|
66
|
+
</pre>
|
67
|
+
|
68
|
+
And you need to modify your routes:
|
69
|
+
|
70
|
+
<pre>
|
71
|
+
<code>
|
72
|
+
# Add this to the top
|
73
|
+
map.resources :users
|
74
|
+
</code>
|
75
|
+
</pre>
|
76
|
+
|
77
|
+
h2. Hey my routes aren't working
|
78
|
+
|
79
|
+
Maybe you have some fancy routes already, maybe something using a glob? Maybe you are using another engine? The only way to really manage these things are to carefully specify the order that the engines are included.
|
80
|
+
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
@@ -0,0 +1 @@
|
|
1
|
+
script/generate headword
|
@@ -0,0 +1,57 @@
|
|
1
|
+
|
2
|
+
# Mostly pinched from http://github.com/ryanb/nifty-generators/tree/master
|
3
|
+
Rails::Generator::Commands::Create.class_eval do
|
4
|
+
def insert_into(file, line)
|
5
|
+
logger.insert "#{line} into #{file}"
|
6
|
+
unless options[:pretend] || File.read(destination_path(file)).include?(line)
|
7
|
+
gsub_file file, /^(class|module) .+$/ do |match|
|
8
|
+
"#{match}\n #{line}"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
Rails::Generator::Commands::Destroy.class_eval do
|
15
|
+
def insert_into(file, line)
|
16
|
+
logger.remove "#{line} from #{file}"
|
17
|
+
unless options[:pretend]
|
18
|
+
gsub_file file, "\n #{line}", ''
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class HeadwordGenerator < Rails::Generator::Base
|
24
|
+
def manifest
|
25
|
+
record do |m|
|
26
|
+
model = "app/models/user.rb"
|
27
|
+
|
28
|
+
if File.exists?(model)
|
29
|
+
m.insert_into model, "include Headword::User"
|
30
|
+
else
|
31
|
+
m.directory File.join("app", "models")
|
32
|
+
m.file "user.rb", model
|
33
|
+
end
|
34
|
+
|
35
|
+
m.directory File.join("app", "views", "users")
|
36
|
+
m.file "show.html.erb", "app/views/users/show.html.erb"
|
37
|
+
|
38
|
+
m.directory File.join("test", "factories")
|
39
|
+
m.file "factories.rb", "test/factories/headword.rb"
|
40
|
+
|
41
|
+
m.migration_template "migrations/#{migration_name}.rb", 'db/migrate',
|
42
|
+
:migration_file_name => "headword_#{migration_name}"
|
43
|
+
|
44
|
+
m.readme "README"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def migration_name
|
51
|
+
if ActiveRecord::Base.connection.table_exists?(:users)
|
52
|
+
'update_users'
|
53
|
+
else
|
54
|
+
'create_users'
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
Factory.sequence :username do |n|
|
2
|
+
"user#{n}"
|
3
|
+
end
|
4
|
+
|
5
|
+
# We need a stub if none exists
|
6
|
+
unless Factory.factories.include?(:user)
|
7
|
+
Factory.define :user do |user|
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
Factory.define :user_with_username, :parent => :user do |user|
|
12
|
+
user.username { Factory.next :username }
|
13
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class HeadwordCreateUsers < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table(:users) do |t|
|
4
|
+
t.string :username, :null => false
|
5
|
+
t.string :url, :null => false
|
6
|
+
t.timestamps
|
7
|
+
end
|
8
|
+
add_index :users, [:url, :id]
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.down
|
12
|
+
drop_table :users
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
class HeadwordUpdateUsers < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
<%
|
4
|
+
existing_columns = ActiveRecord::Base.connection.columns(:users).collect { |each| each.name }
|
5
|
+
columns = [
|
6
|
+
[:url, 't.string :url, :null => false'],
|
7
|
+
[:username, 't.string :username, :null => false']
|
8
|
+
].delete_if {|c| existing_columns.include?(c.first.to_s)}
|
9
|
+
-%>
|
10
|
+
change_table(:users) do |t|
|
11
|
+
<% columns.each do |c| -%>
|
12
|
+
<%= c.last %>
|
13
|
+
<% end -%>
|
14
|
+
end
|
15
|
+
|
16
|
+
<%
|
17
|
+
existing_indexes = ActiveRecord::Base.connection.indexes(:users)
|
18
|
+
index_names = existing_indexes.collect { |each| each.name }
|
19
|
+
new_indexes = [
|
20
|
+
[:index_users_on_id_and_url, 'add_index :users, [:url, :id]']
|
21
|
+
].delete_if { |each| index_names.include?(each.first.to_s) }
|
22
|
+
-%>
|
23
|
+
<% new_indexes.each do |each| -%>
|
24
|
+
<%= each.last %>
|
25
|
+
<% end -%>
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.down
|
29
|
+
change_table(:pages) do |t|
|
30
|
+
<% unless columns.empty? -%>
|
31
|
+
t.remove <%= columns.collect { |each| ":#{each.first}" }.join(',') %>
|
32
|
+
<% end -%>
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
<h2><%= @user.username -%></h2>
|
data/lib/headword.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
if defined?(ActionController::Routing::RouteSet)
|
2
|
+
class ActionController::Routing::RouteSet
|
3
|
+
def load_routes_with_headword!
|
4
|
+
lib_path = File.dirname(__FILE__)
|
5
|
+
routes = File.join(lib_path, *%w[.. .. .. config headword_routes.rb])
|
6
|
+
unless configuration_files.include?(routes)
|
7
|
+
add_configuration_file(routes)
|
8
|
+
end
|
9
|
+
load_routes_without_headword!
|
10
|
+
end
|
11
|
+
|
12
|
+
alias_method_chain :load_routes!, :headword
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module Headword
|
2
|
+
module User
|
3
|
+
|
4
|
+
# Hook for all Headword::User modules.
|
5
|
+
#
|
6
|
+
# If you need to override parts of Headword::User
|
7
|
+
# extend and include à la carte.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# extend ClassMethods
|
11
|
+
# include InstanceMethods
|
12
|
+
# include AttrAccessor
|
13
|
+
# include Callbacks
|
14
|
+
#
|
15
|
+
# @see ClassMethods
|
16
|
+
# @see InstanceMethods
|
17
|
+
# @see Validations
|
18
|
+
# @see Scopes
|
19
|
+
# @see Callbacks
|
20
|
+
def self.included(model)
|
21
|
+
model.extend(ClassMethods)
|
22
|
+
model.send(:include, InstanceMethods)
|
23
|
+
model.send(:include, Validations)
|
24
|
+
model.send(:include, Callbacks)
|
25
|
+
end
|
26
|
+
|
27
|
+
module Validations
|
28
|
+
# Hook for validations.
|
29
|
+
#
|
30
|
+
# :username must be present and unique
|
31
|
+
# :url must be unique
|
32
|
+
def self.included(model)
|
33
|
+
model.class_eval do
|
34
|
+
validates_presence_of :username
|
35
|
+
validates_uniqueness_of :username
|
36
|
+
validates_uniqueness_of :url
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
module Callbacks
|
42
|
+
# Hook for callbacks.
|
43
|
+
#
|
44
|
+
# :title should act like a url.
|
45
|
+
def self.included(model)
|
46
|
+
model.class_eval do
|
47
|
+
acts_as_url :username, :sync_url => true
|
48
|
+
attr_accessible :username
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
module InstanceMethods
|
54
|
+
# We want to use username urls instead of ids in our routes
|
55
|
+
def to_param
|
56
|
+
url
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
module ClassMethods
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
data/rails/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'headword'
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + "/../rails/test/factories/headword")
|
3
|
+
|
4
|
+
class UsersControllerTest < ActionController::TestCase
|
5
|
+
|
6
|
+
tests Headword::UsersController
|
7
|
+
|
8
|
+
context "default setup" do
|
9
|
+
context "on show existing user" do
|
10
|
+
setup do
|
11
|
+
user = Factory(:user_with_username)
|
12
|
+
get :show, :username => user.url
|
13
|
+
end
|
14
|
+
|
15
|
+
should_respond_with :success
|
16
|
+
should_render_template :show
|
17
|
+
should_not_set_the_flash
|
18
|
+
end
|
19
|
+
|
20
|
+
context "on show unknown user" do
|
21
|
+
setup do
|
22
|
+
user = Factory(:user_with_username)
|
23
|
+
end
|
24
|
+
|
25
|
+
should "not find an unknown user" do
|
26
|
+
begin
|
27
|
+
get :show, :username => 'turnbuckle-turnbuckle'
|
28
|
+
flunk "Should raise ActiveRecord::RecordNotFound"
|
29
|
+
rescue ActiveRecord::RecordNotFound
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context "routes" do
|
36
|
+
|
37
|
+
should "recognize usernames" do
|
38
|
+
assert_recognizes({:controller => 'headword/users', :action => 'show', :username => 'marymary'}, {:path => '/marymary', :method => :get})
|
39
|
+
end
|
40
|
+
|
41
|
+
should "not recognize things that are not usernames" do
|
42
|
+
assert_does_not_recognize('/mary/jane', :method => :get)
|
43
|
+
end
|
44
|
+
|
45
|
+
should "recognize the root path" do
|
46
|
+
assert_recognizes({:controller => 'things', :action => 'index'}, {:path => '/', :method => :get})
|
47
|
+
end
|
48
|
+
|
49
|
+
should "not override the things" do
|
50
|
+
assert_recognizes({:controller => 'things', :action => 'index'}, {:path => '/things', :method => :get})
|
51
|
+
assert_recognizes({:controller => 'things', :action => 'new'}, {:path => '/things/new', :method => :get})
|
52
|
+
assert_recognizes({:controller => 'things', :action => 'create'}, {:path => '/things', :method => :post})
|
53
|
+
assert_recognizes({:controller => 'things', :id => '1', :action => 'destroy'}, {:path => '/things/1', :method => :delete})
|
54
|
+
assert_recognizes({:controller => 'things', :id => '1', :action => 'update'}, {:path => '/things/1', :method => :put})
|
55
|
+
assert_recognizes({:controller => 'things', :id => '1', :action => 'edit'}, {:path => '/things/1/edit', :method => :get})
|
56
|
+
end
|
57
|
+
|
58
|
+
if defined?(Clearance)
|
59
|
+
should "not override clearance paths" do
|
60
|
+
assert_recognizes({:controller => 'sessions', :action => 'new'}, {:path => '/session/new', :method => :get})
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def assert_does_not_recognize(path, options)
|
66
|
+
assert_raises(ActionController::RoutingError) do
|
67
|
+
ActionController::Routing::Routes.recognize_path(path, options)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + "/../rails/test/factories/headword")
|
3
|
+
|
4
|
+
class UserTest < ActiveSupport::TestCase
|
5
|
+
should_allow_mass_assignment_of :username
|
6
|
+
|
7
|
+
context "When signing up" do
|
8
|
+
should_validate_presence_of :username
|
9
|
+
end
|
10
|
+
|
11
|
+
context "When multiple users have signed up" do
|
12
|
+
setup { @user = Factory(:user_with_username) }
|
13
|
+
should_validate_uniqueness_of :username
|
14
|
+
end
|
15
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
ENV["RAILS_ENV"] = "test"
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + "/rails/config/environment")
|
3
|
+
require 'test_help'
|
4
|
+
require 'factory_girl'
|
5
|
+
require 'shoulda'
|
6
|
+
|
7
|
+
if defined?(Clearance)
|
8
|
+
require 'clearance/../../shoulda_macros/clearance'
|
9
|
+
end
|
10
|
+
|
11
|
+
# Name the root_url for testing
|
12
|
+
ActionController::Routing::Routes.add_named_route('root', '/', :controller => 'things', :action => 'index')
|
13
|
+
|
14
|
+
class ActiveSupport::TestCase
|
15
|
+
self.use_transactional_fixtures = true
|
16
|
+
self.use_instantiated_fixtures = false
|
17
|
+
fixtures :all
|
18
|
+
end
|
metadata
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: headword
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jeff Rafter
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-09-08 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rsl-stringex
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 1.0.2
|
24
|
+
version:
|
25
|
+
description: Simplify adding usernames to your application.
|
26
|
+
email: jeff@socialrange.org
|
27
|
+
executables: []
|
28
|
+
|
29
|
+
extensions: []
|
30
|
+
|
31
|
+
extra_rdoc_files:
|
32
|
+
- LICENSE
|
33
|
+
- README.textile
|
34
|
+
files:
|
35
|
+
- CHANGELOG.textile
|
36
|
+
- LICENSE
|
37
|
+
- README.textile
|
38
|
+
- Rakefile
|
39
|
+
- TODO.textile
|
40
|
+
- TUTORIAL.textile
|
41
|
+
- VERSION
|
42
|
+
- app/controllers/headword/users_controller.rb
|
43
|
+
- config/headword_routes.rb
|
44
|
+
- generators/headword/USAGE
|
45
|
+
- generators/headword/headword_generator.rb
|
46
|
+
- generators/headword/templates/README
|
47
|
+
- generators/headword/templates/factories.rb
|
48
|
+
- generators/headword/templates/migrations/create_users.rb
|
49
|
+
- generators/headword/templates/migrations/update_users.rb
|
50
|
+
- generators/headword/templates/show.html.erb
|
51
|
+
- generators/headword/templates/user.rb
|
52
|
+
- lib/headword.rb
|
53
|
+
- lib/headword/extensions/routes.rb
|
54
|
+
- lib/headword/user.rb
|
55
|
+
- rails/init.rb
|
56
|
+
- test/controllers/users_controller_test.rb
|
57
|
+
- test/models/user_test.rb
|
58
|
+
- test/test_helper.rb
|
59
|
+
has_rdoc: true
|
60
|
+
homepage: http://github.com/jeffrafter/headword
|
61
|
+
licenses: []
|
62
|
+
|
63
|
+
post_install_message:
|
64
|
+
rdoc_options:
|
65
|
+
- --charset=UTF-8
|
66
|
+
require_paths:
|
67
|
+
- lib
|
68
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: "0"
|
73
|
+
version:
|
74
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: "0"
|
79
|
+
version:
|
80
|
+
requirements: []
|
81
|
+
|
82
|
+
rubyforge_project:
|
83
|
+
rubygems_version: 1.3.4
|
84
|
+
signing_key:
|
85
|
+
specification_version: 3
|
86
|
+
summary: When your users are that vain.
|
87
|
+
test_files:
|
88
|
+
- test/controllers/users_controller_test.rb
|
89
|
+
- test/models/user_test.rb
|
90
|
+
- test/test_helper.rb
|