Matt W. wrote:
If you think you know the URL you want, why not try hard-coding it for
a while in the step until you get the desired effect on the
controller? Then you can add a spec for your routing which proves that
the call to users_url() with the parameters you’re trying gives you
the same hard-coded value. Then you’ll have discovered for yourself
exactly the right parameters to use to send the right PUT request all
the way to the controller.
I took your advice and, after a very long session of trial and error
(mostly error), I derived this formulation:
post account_url, { :user=> { “administrator” => true }, :action =>
“update”, :commit => “Update”, :_method => “put” }
Now, this has the following effect in the tests:
Processing UsersController#update (for 127.0.0.1 at 2009-01-17 22:58:54)
[PUT]
Parameters: {“commit”=>“Update”, “_method”=>“put”, “action”=>“update”,
“controller”=>“users”, “user”=>{“administrator”=>“true”}}
That seems to be what I was trying to pass.
The stuff that follows next is authlogic updating the last_request_at
field in the users table:
User Load (0.0ms) SELECT * FROM “users” WHERE (“users”.“id” = 3) LIMIT 1
User Update (0.0ms) UPDATE “users” SET “updated_at” = ‘2009-01-18 03:58:54’,
“last_request_at” = ‘2009-01-17 22:58:54’ WHERE “id” = 3
User Exists (0.0ms) SELECT “users”.id FROM “users” WHERE (
“users”.“perishable_token” = ‘TuHra3ozvoDVJLEtFQIX’ AND “users”.id <> 3)
LIMIT 1
User Exists (0.0ms) SELECT “users”.id FROM “users” WHERE (
“users”.“username” = ‘myuser’ AND “users”.id <> 3) LIMIT 1
User Exists (0.0ms) SELECT “users”.id FROM “users” WHERE (
“users”.“email” = ‘[email protected]’ AND “users”.id <> 3) LIMIT 1
This is the magic SQL statement I was trying to produce:
User Update (0.0ms) UPDATE “users” SET “perishable_token” =
‘TuHra3ozvoDVJLEtFQIX’, “administrator” = ‘t’ WHERE “id” = 3
This next bit seems to be right too:
Redirected to http://www.example.com/account
Completed in 0ms (DB: 0) | 302 Found [http://www.example.com/account]
User Load (0.0ms) SELECT * FROM “users” WHERE (“users”.“username” =
‘myuser’
) LIMIT 1
AND… The next feature step fails as desired:
When /user named “(.*)” should not be an administrator/ do |name|
my_user = User.find_by_username!(name)
fail if my_user.administrator
end
Then the user named "myuser" should not be an administrator #
features/
app/models/users/step_definitions/user_steps.rb:41
(RuntimeError)
./features/app/models/users/step_definitions/user_steps.rb:43:in
Then /us er named "(.*)" should not be an administrator/' features/app/models/users/user.feature:45:in
Then the user named
“myuser”
should not be an administrator’
So, I now have my failing test and can write (uncomment) the code needed
to protect against it.
Thanks for the help. It was extremely valuable in leading me to the
right answer.