After thinking over the test refactoring I did yesterday, I thought it would be useful to do a few more refactorings to the Redmine API test suite. Today I refactored how HTTP Basic authentication is used with a username and password by creating a new shoulda macro.
Before
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | require "#{File.dirname(__FILE__)}/../../test_helper" class ApiTest::HttpBasicLoginTest 'my_password', :password_confirmation => 'my_password') @authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@user.login, 'my_password') get "/news.xml", nil, :authorization => @authorization end should_respond_with :success should_respond_with_content_type :xml should "login as the user" do assert_equal @user, User.current end end context "with an invalid HTTP authentication" do setup do @user = User.generate_with_protected! @authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@user.login, 'wrong_password') get "/news.xml", nil, :authorization => @authorization end should_respond_with :unauthorized should_respond_with_content_type :xml should "not login as the user" do assert_equal User.anonymous, User.current end end context "without credentials" do setup do get "/projects/onlinestore/news.xml" end should_respond_with :unauthorized should_respond_with_content_type :xml should "include_www_authenticate_header" do assert @controller.response.headers.has_key?('WWW-Authenticate') end end end context "in :json format" do context "with a valid HTTP authentication" do setup do @user = User.generate_with_protected!(:password => 'my_password', :password_confirmation => 'my_password') @authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@user.login, 'my_password') get "/news.json", nil, :authorization => @authorization end should_respond_with :success should_respond_with_content_type :json should "login as the user" do assert_equal @user, User.current end end context "with an invalid HTTP authentication" do setup do @user = User.generate_with_protected! @authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@user.login, 'wrong_password') get "/news.json", nil, :authorization => @authorization end should_respond_with :unauthorized should_respond_with_content_type :json should "not login as the user" do assert_equal User.anonymous, User.current end end end context "without credentials" do setup do get "/projects/onlinestore/news.json" end should_respond_with :unauthorized should_respond_with_content_type :json should "include_www_authenticate_header" do assert @controller.response.headers.has_key?('WWW-Authenticate') end end end end |
After
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | require "#{File.dirname(__FILE__)}/../../test_helper" class ApiTest::HttpBasicLoginTest project, :name => 'news') end context "in :xml format" do should_allow_http_basic_auth_with_username_and_password(:get, "/projects/onlinestore/news.xml") end context "in :json format" do should_allow_http_basic_auth_with_username_and_password(:get, "/projects/onlinestore/news.json") end end end |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | # test_helper.rb # Test that a request allows the username and password for HTTP BASIC # # @param [Symbol] http_method the HTTP method for request (:get, :post, :put, :delete) # @param [String] url the request url # @param [optional, Hash] parameters additional request parameters def self.should_allow_http_basic_auth_with_username_and_password(http_method, url, parameters={}) context "should allow http basic auth using a username and password for #{http_method} #{url}" do context "with a valid HTTP authentication" do setup do @user = User.generate_with_protected!(:password => 'my_password', :password_confirmation => 'my_password', :admin => true) # Admin so they can access the project @authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@user.login, 'my_password') send(http_method, url, parameters, {:authorization => @authorization}) end should_respond_with :success should_respond_with_content_type_based_on_url(url) should "login as the user" do assert_equal @user, User.current end end context "with an invalid HTTP authentication" do setup do @user = User.generate_with_protected! @authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@user.login, 'wrong_password') send(http_method, url, parameters, {:authorization => @authorization}) end should_respond_with :unauthorized should_respond_with_content_type_based_on_url(url) should "not login as the user" do assert_equal User.anonymous, User.current end end context "without credentials" do setup do send(http_method, url, parameters, {:authorization => ''}) end should_respond_with :unauthorized should_respond_with_content_type_based_on_url(url) should "include_www_authenticate_header" do assert @controller.response.headers.has_key?('WWW-Authenticate') end end end end |
Just like the yesterday’s refactoring, this removes a lot of duplication in the tests themselves. It also will let me to use the should_allow_http_basic_auth_with_username_and_password macro in all of the API tests to make sure that they are working.
Share
Related posts:
