diff options
Diffstat (limited to 'test')
36 files changed, 405 insertions, 211 deletions
diff --git a/test/functional/account_controller_test.rb b/test/functional/account_controller_test.rb new file mode 100644 index 0000000..f5f1446 --- /dev/null +++ b/test/functional/account_controller_test.rb @@ -0,0 +1,26 @@ +require 'test_helper' + +class AccountControllerTest < ActionController::TestCase + +  test "should get new" do +    get :new +    assert_equal User, assigns(:user).class +    assert_response :success +  end + +  test "new should redirect logged in users" do +    login +    get :new +    assert_response :redirect +    assert_redirected_to home_path +  end + +  test "new redirects if registration is closed" do +    with_config(allow_registration: false) do +      get :new +      assert_response :redirect +      assert_redirected_to home_path +    end +  end +end + diff --git a/test/functional/v1/certs_controller_test.rb b/test/functional/api/certs_controller_test.rb index 04c1c86..f23b4c8 100644 --- a/test/functional/v1/certs_controller_test.rb +++ b/test/functional/api/certs_controller_test.rb @@ -1,11 +1,11 @@ -require_relative '../../test_helper' +require 'test_helper' -class V1::CertsControllerTest < ActionController::TestCase +class Api::CertsControllerTest < ApiControllerTest    test "create unlimited cert without login" do      with_config allow_anonymous_certs: true do        cert = expect_cert('UNLIMITED') -      post :create +      api_post :create        assert_response :success        assert_equal cert.to_s, @response.body      end @@ -15,7 +15,7 @@ class V1::CertsControllerTest < ActionController::TestCase      with_config allow_limited_certs: true do        login        cert = expect_cert('LIMITED') -      post :create +      api_post :create        assert_response :success        assert_equal cert.to_s, @response.body      end @@ -23,14 +23,14 @@ class V1::CertsControllerTest < ActionController::TestCase    test "fail to create cert when disabled" do      login :enabled? => false -    post :create +    api_post :create      assert_access_denied    end    test "create unlimited cert" do      login effective_service_level: ServiceLevel.new(id: 2)      cert = expect_cert('UNLIMITED') -    post :create +    api_post :create      assert_response :success      assert_equal cert.to_s, @response.body    end @@ -38,13 +38,13 @@ class V1::CertsControllerTest < ActionController::TestCase    test "GET still works as an alias" do      login effective_service_level: ServiceLevel.new(id: 2)      cert = expect_cert('UNLIMITED') -    get :show +    api_get :show      assert_response :success      assert_equal cert.to_s, @response.body    end    test "redirect if no eip service offered" do -    post :create +    api_post :create      assert_response :redirect    end diff --git a/test/functional/v1/identities_controller_test.rb b/test/functional/api/identities_controller_test.rb index 6410c44..57345c8 100644 --- a/test/functional/v1/identities_controller_test.rb +++ b/test/functional/api/identities_controller_test.rb @@ -1,15 +1,15 @@  require_relative '../../test_helper' -class V1::IdentitiesControllerTest < ActionController::TestCase +class Api::IdentitiesControllerTest < ApiControllerTest    test "api monitor can fetch identity" do      monitor_auth do        identity = FactoryGirl.create :identity -      get :show, :id => identity.address, :format => 'json' +      api_get :show, :id => identity.address, :format => 'json'        assert_response :success        assert_equal identity, assigns(:identity) -      get :show, :id => "blahblahblah", :format => 'json' +      api_get :show, :id => "blahblahblah", :format => 'json'        assert_response :not_found      end    end @@ -17,7 +17,7 @@ class V1::IdentitiesControllerTest < ActionController::TestCase    test "anonymous cannot fetch identity" do      identity = FactoryGirl.create :identity -    get :show, :id => identity.address, :format => 'json' +    api_get :show, :id => identity.address, :format => 'json'      assert_response :forbidden    end diff --git a/test/functional/v1/messages_controller_test.rb b/test/functional/api/messages_controller_test.rb index 67f34a1..e586980 100644 --- a/test/functional/v1/messages_controller_test.rb +++ b/test/functional/api/messages_controller_test.rb @@ -1,6 +1,6 @@  require 'test_helper' -class V1::MessagesControllerTest < ActionController::TestCase +class Api::MessagesControllerTest < ApiControllerTest    setup do      @user = FactoryGirl.build(:user) @@ -13,9 +13,8 @@ class V1::MessagesControllerTest < ActionController::TestCase    test "get the motd" do      with_config("customization_directory" => Rails.root+'test/files') do        login @user -      get :index, :locale => 'es' +      api_get :index, :locale => 'es'        body = JSON.parse(response.body) -      p body        message1 = "<p>\"This\" is a <strong>very</strong> fine message. <a href=\"https://bitmask.net\">https://bitmask.net</a></p>\n"        assert_equal 2, body.size, 'there should be two messages'        assert_equal message1, body.first["text"], 'first message text should match files/motd/1.en.md' @@ -25,7 +24,7 @@ class V1::MessagesControllerTest < ActionController::TestCase    test "get localized motd" do      with_config("customization_directory" => Rails.root+'test/files') do        login @user -      get :index, :locale => 'de' +      api_get :index, :locale => 'de'        body = JSON.parse(response.body)        message1 = "<p>Dies ist eine sehr feine Nachricht. <a href=\"https://bitmask.net\">https://bitmask.net</a></p>\n"        assert_equal message1, body.first["text"], 'first message text should match files/motd/1.de.md' @@ -34,7 +33,7 @@ class V1::MessagesControllerTest < ActionController::TestCase    test "get empty motd" do      login @user -    get :index +    api_get :index      assert_equal "[]", response.body, "motd response should be empty if no motd directory exists"    end @@ -59,7 +58,7 @@ class V1::MessagesControllerTest < ActionController::TestCase    test "get messages for user" do      login @user -    get :index +    api_get :index      assert response.body.include? @message.text      assert response.body.include? @message.id    end @@ -79,7 +78,7 @@ class V1::MessagesControllerTest < ActionController::TestCase      login @user      put :update, :id => @message.id      @message.reload -    get :index +    api_get :index      assert !(response.body.include? @message.text)      assert !(response.body.include? @message.id)    end @@ -92,7 +91,7 @@ class V1::MessagesControllerTest < ActionController::TestCase   end    test "fails if not authenticated" do -    get :index, :format => :json +    api_get :index, :format => :json      assert_login_required    end  =end diff --git a/test/functional/v1/services_controller_test.rb b/test/functional/api/services_controller_test.rb index 039eb27..cb85edf 100644 --- a/test/functional/v1/services_controller_test.rb +++ b/test/functional/api/services_controller_test.rb @@ -1,16 +1,16 @@  require 'test_helper' -class V1::ServicesControllerTest < ActionController::TestCase +class Api::ServicesControllerTest < ApiControllerTest    test "anonymous user gets login required service info" do -    get :show, format: :json +    api_get :show, format: :json      assert_json_response error: 'not_authorized_login',        message: 'Please log in to perform that action.'    end    test "anonymous user gets vpn service info" do      with_config allow_anonymous_certs: true do -      get :show, format: :json +      api_get :show, format: :json        assert_json_response name: 'anonymous',          eip_rate_limit: false,          description: 'anonymous access to the VPN' @@ -19,7 +19,7 @@ class V1::ServicesControllerTest < ActionController::TestCase    test "user can see their service info" do      login -    get :show, format: :json +    api_get :show, format: :json      default_level = APP_CONFIG[:default_service_level]      assert_json_response APP_CONFIG[:service_levels][default_level]    end diff --git a/test/functional/v1/sessions_controller_test.rb b/test/functional/api/sessions_controller_test.rb index 8bb6acd..03a1ef9 100644 --- a/test/functional/v1/sessions_controller_test.rb +++ b/test/functional/api/sessions_controller_test.rb @@ -3,7 +3,7 @@ require 'test_helper'  # This is a simple controller unit test.  # We're stubbing out both warden and srp.  # There's an integration test testing the full rack stack and srp -class V1::SessionsControllerTest < ActionController::TestCase +class Api::SessionsControllerTest < ApiControllerTest    setup do      @request.env['HTTP_HOST'] = 'api.lvh.me' @@ -12,7 +12,7 @@ class V1::SessionsControllerTest < ActionController::TestCase    end    test "renders json" do -    get :new, :format => :json +    api_get :new, :format => :json      assert_response :success      assert_json_error nil    end @@ -22,7 +22,7 @@ class V1::SessionsControllerTest < ActionController::TestCase      strategy = stub :message => {:field => :translate_me}      request.env['warden'].stubs(:winning_strategy).returns(strategy)      I18n.expects(:t).with(:translate_me).at_least_once.returns("translation stub") -    get :new, :format => :json +    api_get :new, :format => :json      assert_response 422      assert_json_error :field => "translation stub"    end @@ -33,7 +33,7 @@ class V1::SessionsControllerTest < ActionController::TestCase      request.env['warden'].expects(:authenticate!)      # make sure we don't get a template missing error:      @controller.stubs(:render) -    post :create, :login => @user.login, 'A' => @client_hex +    api_post :create, :login => @user.login, 'A' => @client_hex    end    test "should authenticate" do @@ -42,7 +42,7 @@ class V1::SessionsControllerTest < ActionController::TestCase      handshake = stub(:to_hash => {h: "ash"})      session[:handshake] = handshake -    post :update, :id => @user.login, :client_auth => @client_hex +    api_post :update, :id => @user.login, :client_auth => @client_hex      assert_nil session[:handshake]      assert_response :success @@ -55,7 +55,7 @@ class V1::SessionsControllerTest < ActionController::TestCase    test "destroy should logout" do      login      expect_logout -    delete :destroy +    api_delete :destroy      assert_response 204    end diff --git a/test/functional/v1/smtp_certs_controller_test.rb b/test/functional/api/smtp_certs_controller_test.rb index 1b03995..393f090 100644 --- a/test/functional/v1/smtp_certs_controller_test.rb +++ b/test/functional/api/smtp_certs_controller_test.rb @@ -1,17 +1,17 @@  require 'test_helper' -class V1::SmtpCertsControllerTest < ActionController::TestCase +class Api::SmtpCertsControllerTest < ApiControllerTest    test "no smtp cert without login" do      with_config allow_anonymous_certs: true do -      post :create +      api_post :create        assert_login_required      end    end    test "require service level with email" do      login -    post :create +    api_post :create      assert_access_denied    end @@ -19,14 +19,14 @@ class V1::SmtpCertsControllerTest < ActionController::TestCase      login effective_service_level: ServiceLevel.new(id: 2)      cert = expect_cert(@current_user.email_address)      cert.expects(:fingerprint).returns('fingerprint') -    post :create +    api_post :create      assert_response :success      assert_equal cert.to_s, @response.body    end    test "fail to create cert when disabled" do      login :enabled? => false -    post :create +    api_post :create      assert_access_denied    end diff --git a/test/functional/token_auth_test.rb b/test/functional/api/token_auth_test.rb index 53d5fb3..c7f91c7 100644 --- a/test/functional/token_auth_test.rb +++ b/test/functional/api/token_auth_test.rb @@ -3,15 +3,15 @@  # via static configured tokens.  # -require_relative '../test_helper' +require 'test_helper' -class TokenAuthTest < ActionController::TestCase -  tests V1::ConfigsController +class Api::TokenAuthTest < ApiControllerTest +  tests Api::ConfigsController    def test_login_via_api_token      with_config(:allow_anonymous_certs => false) do        monitor_auth do -        get :index +        api_get :index          assert assigns(:token), 'should have authenticated via api token'          assert assigns(:token).is_a? ApiToken          assert @controller.send(:current_user).is_a? ApiMonitorUser @@ -26,10 +26,10 @@ class TokenAuthTest < ActionController::TestCase        with_config(new_config) do          monitor_auth do            request.env['REMOTE_ADDR'] = "1.1.1.1" -          get :index +          api_get :index            assert_nil assigns(:token), "should not be able to auth with api token when ip restriction doesn't allow it"            request.env['REMOTE_ADDR'] = allowed -          get :index +          api_get :index            assert assigns(:token), "should have authenticated via api token"          end        end diff --git a/test/functional/v1/users_controller_test.rb b/test/functional/api/users_controller_test.rb index df59c4d..32afd0a 100644 --- a/test/functional/v1/users_controller_test.rb +++ b/test/functional/api/users_controller_test.rb @@ -1,6 +1,6 @@ -require_relative '../../test_helper' +require 'test_helper' -class V1::UsersControllerTest < ActionController::TestCase +class Api::UsersControllerTest < ApiControllerTest    test "user can change settings" do      user = find_record :user @@ -10,11 +10,11 @@ class V1::UsersControllerTest < ActionController::TestCase      Account.expects(:new).with(user).returns(account_settings)      login user -    put :update, :user => changed_attribs, :id => user.id, :format => :json +    api_put :update, :user => changed_attribs, :id => user.id, :format => :json      assert_equal user, assigns[:user]      assert_response 204 -    assert_equal " ", @response.body +    assert @response.body.blank?, "Response should be blank"    end    test "admin can update user" do @@ -25,7 +25,7 @@ class V1::UsersControllerTest < ActionController::TestCase      Account.expects(:new).with(user).returns(account_settings)      login :is_admin? => true -    put :update, :user => changed_attribs, :id => user.id, :format => :json +    api_put :update, :user => changed_attribs, :id => user.id, :format => :json      assert_equal user, assigns[:user]      assert_response 204 @@ -34,7 +34,7 @@ class V1::UsersControllerTest < ActionController::TestCase    test "user cannot update other user" do      user = find_record :user      login -    put :update, id: user.id, +    api_put :update, id: user.id,        user: record_attributes_for(:user_with_settings),        :format => :json      assert_access_denied @@ -45,7 +45,7 @@ class V1::UsersControllerTest < ActionController::TestCase      user = User.new(user_attribs)      Account.expects(:create).with(user_attribs).returns(user) -    post :create, :user => user_attribs, :format => :json +    api_post :create, :user => user_attribs, :format => :json      assert_nil session[:user_id]      assert_json_response user @@ -59,7 +59,7 @@ class V1::UsersControllerTest < ActionController::TestCase      assert !user.valid?      Account.expects(:create).with(user_attribs).returns(user) -    post :create, :user => user_attribs, :format => :json +    api_post :create, :user => user_attribs, :format => :json      assert_json_error user.errors.messages      assert_response 422 @@ -67,7 +67,7 @@ class V1::UsersControllerTest < ActionController::TestCase    test "admin can autocomplete users" do      login :is_admin? => true -    get :index, :query => 'a', :format => :json +    api_get :index, :query => 'a', :format => :json      assert_response :success      assert assigns(:users) @@ -76,7 +76,7 @@ class V1::UsersControllerTest < ActionController::TestCase    test "create returns forbidden if registration is closed" do      user_attribs = record_attributes_for :user      with_config(allow_registration: false) do -      post :create, :user => user_attribs, :format => :json +      api_post :create, :user => user_attribs, :format => :json        assert_response :forbidden      end    end @@ -84,20 +84,20 @@ class V1::UsersControllerTest < ActionController::TestCase    test "admin can show user" do      user = FactoryGirl.create :user      login :is_admin? => true -    get :show, :id => 0, :login => user.login, :format => :json +    api_get :show, :id => 0, :login => user.login, :format => :json      assert_response :success      assert_json_response user -    get :show, :id => user.id, :format => :json +    api_get :show, :id => user.id, :format => :json      assert_response :success      assert_json_response user -    get :show, :id => "0", :format => :json +    api_get :show, :id => "0", :format => :json      assert_response :not_found    end    test "normal users cannot show user" do      user = find_record :user      login -    get :show, :id => 0, :login => user.login, :format => :json +    api_get :show, :id => 0, :login => user.login, :format => :json      assert_access_denied    end @@ -106,9 +106,9 @@ class V1::UsersControllerTest < ActionController::TestCase      with_config(allow_registration: false, invite_required: true) do        monitor_auth do          user_attribs = record_attributes_for :test_user -        post :create, :user => user_attribs, :format => :json +        api_post :create, :user => user_attribs, :format => :json          assert_response :success -        delete :destroy, :id => assigns(:user).id, :format => :json +        api_delete :destroy, :id => assigns(:user).id, :format => :json          assert_response :success        end      end @@ -117,17 +117,17 @@ class V1::UsersControllerTest < ActionController::TestCase    test "api monitor auth cannot create normal users" do      monitor_auth do        user_attribs = record_attributes_for :user -      post :create, :user => user_attribs, :format => :json +      api_post :create, :user => user_attribs, :format => :json        assert_response :forbidden      end    end -  test "api monitor auth cannot delete normal users" do -    post :create, :user => record_attributes_for(:user), :format => :json +  test "api monitor auth cannot api_delete normal users" do +    api_post :create, :user => record_attributes_for(:user), :format => :json      assert_response :success      normal_user_id = assigns(:user).id      monitor_auth do -      delete :destroy, :id => normal_user_id, :format => :json +      api_delete :destroy, :id => normal_user_id, :format => :json        assert_response :forbidden      end    end diff --git a/test/functional/static_config_controller_test.rb b/test/functional/static_config_controller_test.rb index 9c2cfef..7027bf8 100644 --- a/test/functional/static_config_controller_test.rb +++ b/test/functional/static_config_controller_test.rb @@ -1,7 +1,7 @@  require 'test_helper'  # use minitest for stubbing, rather than bloated mocha -require 'minitest/stub_const' +require 'minitest/mock'  class StaticConfigControllerTest < ActionController::TestCase @@ -9,7 +9,7 @@ class StaticConfigControllerTest < ActionController::TestCase    end    def test_provider_success -    StaticConfigController.stub_const(:PROVIDER_JSON, file_path('provider.json')) do +    @controller.stub(:provider_json, file_path('provider.json')) do        get :provider, format: :json        assert_equal 'application/json', @response.content_type        assert_response :success @@ -17,7 +17,7 @@ class StaticConfigControllerTest < ActionController::TestCase    end    def test_provider_not_modified -    StaticConfigController.stub_const(:PROVIDER_JSON, file_path('provider.json')) do +    @controller.stub(:provider_json, file_path('provider.json')) do        request.env["HTTP_IF_MODIFIED_SINCE"] = File.mtime(file_path('provider.json')).rfc2822()        get :provider, format: :json        assert_response 304 diff --git a/test/functional/users_controller_test.rb b/test/functional/users_controller_test.rb index 7b24098..2794422 100644 --- a/test/functional/users_controller_test.rb +++ b/test/functional/users_controller_test.rb @@ -1,20 +1,7 @@ -require_relative '../test_helper' +require 'test_helper'  class UsersControllerTest < ActionController::TestCase -  test "should get new" do -    get :new -    assert_equal User, assigns(:user).class -    assert_response :success -  end - -  test "new should redirect logged in users" do -    login -    get :new -    assert_response :redirect -    assert_redirected_to home_path -  end -    test "failed show without login" do      user = find_record :user      get :show, :id => user.id @@ -67,8 +54,8 @@ class UsersControllerTest < ActionController::TestCase      nonid = 'thisisnotanexistinguserid'      login :is_admin? => true      get :show, :id => nonid +    assert_error_response :no_such_user      assert_response :redirect -    assert_equal({:alert => "No such user."}, flash.to_hash)      assert_redirected_to users_path    end @@ -163,11 +150,4 @@ class UsersControllerTest < ActionController::TestCase      assert !assigns(:user).enabled?    end -  test "new redirects if registration is closed" do -    with_config(allow_registration: false) do -      get :new -      assert_response :redirect -      assert_redirected_to home_path -    end -  end  end diff --git a/test/integration/api/cert_test.rb b/test/integration/api/cert_test.rb index 772901d..289d3c6 100644 --- a/test/integration/api/cert_test.rb +++ b/test/integration/api/cert_test.rb @@ -5,7 +5,7 @@ class CertTest < ApiIntegrationTest    test "retrieve eip cert" do      login -    get '/1/cert', {}, RACK_ENV +    get cert_url, {}, RACK_ENV      assert_text_response      assert_response_includes "BEGIN RSA PRIVATE KEY"      assert_response_includes "END RSA PRIVATE KEY" @@ -14,13 +14,13 @@ class CertTest < ApiIntegrationTest    end    test "fetching certs requires login by default" do -    get '/1/cert', {}, RACK_ENV +    get cert_url, {}, RACK_ENV      assert_login_required    end    test "retrieve anonymous eip cert" do      with_config allow_anonymous_certs: true do -      get '/1/cert', {}, RACK_ENV +      get cert_url, {}, RACK_ENV        assert_text_response        assert_response_includes "BEGIN RSA PRIVATE KEY"        assert_response_includes "END RSA PRIVATE KEY" @@ -28,4 +28,9 @@ class CertTest < ApiIntegrationTest        assert_response_includes "END CERTIFICATE"      end    end + +  def cert_url +    "/#{api_version}/cert" +  end +  end diff --git a/test/integration/api/signup_test.rb b/test/integration/api/signup_test.rb index 05a0abe..2e515c1 100644 --- a/test/integration/api/signup_test.rb +++ b/test/integration/api/signup_test.rb @@ -1,4 +1,4 @@ -require_relative '../../test_helper' +require 'test_helper'  require_relative 'srp_test'  class SignupTest < SrpTest diff --git a/test/integration/api/smtp_cert_test.rb b/test/integration/api/smtp_cert_test.rb index 681d509..53382c1 100644 --- a/test/integration/api/smtp_cert_test.rb +++ b/test/integration/api/smtp_cert_test.rb @@ -11,7 +11,7 @@ class SmtpCertTest < ApiIntegrationTest    test "retrieve smtp cert" do      @user = FactoryGirl.create :user, effective_service_level_code: 2, :invite_code => @testcode.invite_code      login -    post '/1/smtp_cert', {}, RACK_ENV +    post smtp_cert_url, {}, RACK_ENV      assert_text_response      assert_response_includes "BEGIN RSA PRIVATE KEY"      assert_response_includes "END RSA PRIVATE KEY" @@ -22,7 +22,7 @@ class SmtpCertTest < ApiIntegrationTest    test "cert and key" do      @user = FactoryGirl.create :user, effective_service_level_code: 2, :invite_code => @testcode.invite_code      login -    post '/1/smtp_cert', {}, RACK_ENV +    post smtp_cert_url, {}, RACK_ENV      assert_text_response      cert = OpenSSL::X509::Certificate.new(get_response.body)      key = OpenSSL::PKey::RSA.new(get_response.body) @@ -34,7 +34,7 @@ class SmtpCertTest < ApiIntegrationTest    test "fingerprint is stored with identity" do      @user = FactoryGirl.create :user, effective_service_level_code: 2, :invite_code => @testcode.invite_code      login -    post '/1/smtp_cert', {}, RACK_ENV +    post smtp_cert_url, {}, RACK_ENV      assert_text_response      cert = OpenSSL::X509::Certificate.new(get_response.body)      fingerprint = OpenSSL::Digest::SHA1.hexdigest(cert.to_der).scan(/../).join(':') @@ -48,14 +48,18 @@ class SmtpCertTest < ApiIntegrationTest    test "fetching smtp certs requires email account" do      login -    post '/1/smtp_cert', {}, RACK_ENV +    post smtp_cert_url, {}, RACK_ENV      assert_access_denied    end    test "no anonymous smtp certs" do      with_config allow_anonymous_certs: true do -      post '/1/smtp_cert', {}, RACK_ENV +      post smtp_cert_url, {}, RACK_ENV        assert_login_required      end    end + +  def smtp_cert_url +    "/#{api_version}/smtp_cert" +  end  end diff --git a/test/integration/api/srp_test.rb b/test/integration/api/srp_test.rb index 463abcd..b9605f9 100644 --- a/test/integration/api/srp_test.rb +++ b/test/integration/api/srp_test.rb @@ -14,7 +14,7 @@ class SrpTest < RackTest    # this test wraps the api and implements the interface the ruby-srp client.    def handshake(login, aa) -    post "http://api.lvh.me:3000/1/sessions.json", +    post api_url("sessions.json"),        :login => login,        'A' => aa,        :format => :json @@ -27,7 +27,7 @@ class SrpTest < RackTest    end    def validate(m) -    put "http://api.lvh.me:3000/1/sessions/" + @login + '.json', +    put api_url("sessions/#{@login}.json"),        :client_auth => m,        :format => :json      return JSON.parse(last_response.body) @@ -39,7 +39,7 @@ class SrpTest < RackTest    def register_user(login = "integration_test", password = 'srp, verify me!', invite_code = @testcode.invite_code)      cleanup_user(login) -    post 'http://api.lvh.me:3000/1/users.json', +    post api_url('users.json'),        user_params(login: login, password: password, invite_code: invite_code)      assert(@user = User.find_by_login(login), 'user should have been created: %s' % last_response_errors)      @login = login @@ -47,7 +47,7 @@ class SrpTest < RackTest    end    def update_user(params) -    put "http://api.lvh.me:3000/1/users/" + @user.id + '.json', +    put api_url("users/#{@user.id}.json"),        user_params(params),        auth_headers    end @@ -68,7 +68,7 @@ class SrpTest < RackTest    end    def logout(params=nil, headers=nil) -    delete "http://api.lvh.me:3000/1/logout.json", +    delete api_url("logout.json"),        params || {format: :json},        headers || auth_headers    end @@ -112,4 +112,12 @@ class SrpTest < RackTest    rescue      ""    end + +  def api_url(path) +    "http://api.lvh.me:3000/#{api_version}/#{path}" +  end + +  def api_version +    2 +  end  end diff --git a/test/integration/api/token_test.rb b/test/integration/api/token_auth_test.rb index dafbfb7..7b20b00 100644 --- a/test/integration/api/token_test.rb +++ b/test/integration/api/token_auth_test.rb @@ -1,7 +1,7 @@ -require_relative '../../test_helper' +require 'test_helper'  require_relative 'srp_test' -class TokenTest < SrpTest +class TokenAuthTest < SrpTest    setup do      register_user diff --git a/test/integration/api/update_account_test.rb b/test/integration/api/update_account_test.rb index 16bbb8c..1492006 100644 --- a/test/integration/api/update_account_test.rb +++ b/test/integration/api/update_account_test.rb @@ -14,7 +14,7 @@ class UpdateAccountTest < SrpTest    test "require token" do      authenticate -    put "http://api.lvh.me:3000/1/users/" + @user.id + '.json', +    put "http://api.lvh.me:3000/2/users/" + @user.id + '.json',        user_params(password: "No! Verify me instead.")      assert_login_required    end diff --git a/test/integration/browser/account_livecycle_test.rb b/test/integration/browser/account_livecycle_test.rb new file mode 100644 index 0000000..85dbf13 --- /dev/null +++ b/test/integration/browser/account_livecycle_test.rb @@ -0,0 +1,114 @@ +require 'test_helper' + +class AccountLivecycleTest < BrowserIntegrationTest + +  teardown do +    Identity.destroy_all_orphaned +  end + +  test "signup successfully when invited" do +    username, password = submit_signup +    assert page.has_content?("Welcome #{username}") +    click_on 'Log Out' +    assert page.has_content?("Log In") +    assert_equal '/', current_path +    assert user = User.find_by_login(username) +    user.account.destroy +  end + +  test "signup successfully without invitation" do +    with_config invite_required: false do + +      username ||= "test_#{SecureRandom.urlsafe_base64}".downcase +      password ||= SecureRandom.base64 + +      visit '/signup' +      fill_in 'Username', with: username +      fill_in 'Password', with: password +      fill_in 'Password confirmation', with: password +      click_on 'Sign Up' + +      assert page.has_content?("Welcome #{username}") +    end +  end + +  test "signup with username ending in dot json" do +    username = Faker::Internet.user_name + '.json' +    submit_signup username +    assert page.has_content?("Welcome #{username}") +  end + +  test "signup with reserved username" do +    username = 'certmaster' +    submit_signup username +    assert page.has_content?("is reserved.") +  end + +  test "successful login" do +    username, password = submit_signup +    click_on 'Log Out' +    attempt_login(username, password) +    assert page.has_content?("Welcome #{username}") +    within('.sidenav li.active') do +      assert page.has_content?("Overview") +    end +    User.find_by_login(username).account.destroy +  end + +  test "failed login" do +    visit '/' +    attempt_login("username", "wrong password") +    assert_invalid_login(page) +  end + +  test "account destruction" do +    username, password = submit_signup + +    click_on I18n.t('account_settings') +    click_on I18n.t('destroy_my_account') +    assert page.has_content?(I18n.t('account_destroyed')) +    assert_equal 1, Identity.by_address.key("#{username}@test.me").count +    attempt_login(username, password) +    assert_invalid_login(page) +  end + +  test "handle blocked after account destruction" do +    username, password = submit_signup +    click_on I18n.t('account_settings') +    click_on I18n.t('destroy_my_account') +    submit_signup(username) +    assert page.has_content?('has already been taken') +  end + +  test "change pgp key" do +    with_config user_actions: ['change_pgp_key'] do +      pgp_key = FactoryGirl.build :pgp_key +      login +      click_on "Account Settings" +      within('#update_pgp_key') do +        fill_in 'Public key', with: pgp_key +        click_on 'Save' +      end +      page.assert_selector 'input[value="Saving..."]' +      # at some point we're done: +      page.assert_no_selector 'input[value="Saving..."]' +      assert page.has_field? 'Public key', with: pgp_key.to_s +      @user.reload +      assert_equal pgp_key, @user.public_key +    end +  end + +  def attempt_login(username, password) +    click_on 'Log In' +    fill_in 'Username', with: username +    fill_in 'Password', with: password +    click_on 'Log In' +  end + +  def assert_invalid_login(page) +    assert page.has_selector? '.btn-primary.disabled' +    assert page.has_content? I18n.t(:invalid_user_pass) +    assert page.has_no_selector? '.btn-primary.disabled' +  end + +end diff --git a/test/integration/browser/account_test.rb b/test/integration/browser/account_livecycle_test.rb.orig index 50adb23..d1f800b 100644 --- a/test/integration/browser/account_test.rb +++ b/test/integration/browser/account_livecycle_test.rb.orig @@ -1,6 +1,6 @@  require 'test_helper' -class AccountTest < BrowserIntegrationTest +class AccountLivecycleTest < BrowserIntegrationTest    teardown do      Identity.destroy_all_orphaned @@ -80,24 +80,6 @@ class AccountTest < BrowserIntegrationTest      assert page.has_content?('has already been taken')    end -  test "default user actions" do -    login -    click_on "Account Settings" -    assert page.has_content? I18n.t('destroy_my_account') -    assert page.has_no_css? '#update_login_and_password' -    assert page.has_no_css? '#update_pgp_key' -  end - -  test "default admin actions" do -    login -    with_config admins: [@user.login] do -      click_on "Account Settings" -      assert page.has_content? I18n.t('destroy_my_account') -      assert page.has_no_css? '#update_login_and_password' -      assert page.has_css? '#update_pgp_key' -    end -  end -    test "change pgp key" do      with_config user_actions: ['change_pgp_key'] do        pgp_key = FactoryGirl.build :pgp_key @@ -116,6 +98,8 @@ class AccountTest < BrowserIntegrationTest      end    end +<<<<<<< HEAD:test/integration/browser/account_livecycle_test.rb +=======    # trying to seed an invalid A for srp login    test "detects attempt to circumvent SRP" do @@ -133,7 +117,7 @@ class AccountTest < BrowserIntegrationTest    end    test "reports internal server errors" do -    V1::UsersController.any_instance.stubs(:create).raises +    Api::UsersController.any_instance.stubs(:create).raises      submit_signup      assert page.has_content?("server failed")    end @@ -152,6 +136,7 @@ class AccountTest < BrowserIntegrationTest      assert page.has_no_content?("Password")    end +>>>>>>> api: allow version bumping - bump to 2:test/integration/browser/account_test.rb    def attempt_login(username, password)      click_on 'Log In'      fill_in 'Username', with: username @@ -165,12 +150,4 @@ class AccountTest < BrowserIntegrationTest      assert page.has_no_selector? '.btn-primary.disabled'    end -  def inject_malicious_js -    page.execute_script <<-EOJS -      var calc = new srp.Calculate(); -      calc.A = function(_a) {return "00";}; -      calc.S = calc.A; -      srp.session = new srp.Session(null, calc); -    EOJS -  end  end diff --git a/test/integration/browser/admin_test.rb b/test/integration/browser/admin_test.rb index 902c981..0b43c29 100644 --- a/test/integration/browser/admin_test.rb +++ b/test/integration/browser/admin_test.rb @@ -2,6 +2,24 @@ require 'test_helper'  class AdminTest < BrowserIntegrationTest +  test "default user actions" do +    login +    click_on "Account Settings" +    assert page.has_content? I18n.t('destroy_my_account') +    assert page.has_no_css? '#update_login_and_password' +    assert page.has_no_css? '#update_pgp_key' +  end + +  test "default admin actions" do +    login +    with_config admins: [@user.login] do +      click_on "Account Settings" +      assert page.has_content? I18n.t('destroy_my_account') +      assert page.has_no_css? '#update_login_and_password' +      assert page.has_css? '#update_pgp_key' +    end +  end +    test "clear blocked handle" do      id = FactoryGirl.create :identity      submit_signup(id.login) diff --git a/test/integration/browser/password_validation_test.rb b/test/integration/browser/password_validation_test.rb index 45eb0bf..51fcc5d 100644 --- a/test/integration/browser/password_validation_test.rb +++ b/test/integration/browser/password_validation_test.rb @@ -5,26 +5,26 @@ class PasswordValidationTest < BrowserIntegrationTest    test "password confirmation is validated" do      username ||= "test_#{SecureRandom.urlsafe_base64}".downcase      password ||= SecureRandom.base64 -    visit '/users/new' +    visit '/signup'      fill_in 'Username', with: username      fill_in 'Password', with: password      fill_in 'Password confirmation', with: password + "-typo"      click_on 'Sign Up'      assert page.has_content? "does not match." -    assert_equal '/users/new', current_path +    assert_equal '/signup', current_path      assert page.has_selector? ".error #srp_password_confirmation"    end    test "password needs to be at least 8 chars long" do      username ||= "test_#{SecureRandom.urlsafe_base64}".downcase      password ||= SecureRandom.base64[0,7] -    visit '/users/new' +    visit '/signup'      fill_in 'Username', with: username      fill_in 'Password', with: password      fill_in 'Password confirmation', with: password      click_on 'Sign Up'      assert page.has_content? "needs to be at least 8 characters long" -    assert_equal '/users/new', current_path +    assert_equal '/signup', current_path      assert page.has_selector? ".error #srp_password"    end  end diff --git a/test/integration/browser/security_test.rb b/test/integration/browser/security_test.rb new file mode 100644 index 0000000..825d50b --- /dev/null +++ b/test/integration/browser/security_test.rb @@ -0,0 +1,52 @@ +require 'test_helper' + +class SecurityTest < BrowserIntegrationTest + +  teardown do +    Identity.destroy_all_orphaned +  end + +  # trying to seed an invalid A for srp login +  test "detects attempt to circumvent SRP" do +    InviteCodeValidator.any_instance.stubs(:validate) + +    user = FactoryGirl.create :user +    visit '/login' +    fill_in 'Username', with: user.login +    fill_in 'Password', with: "password" +    inject_malicious_js +    click_on 'Log In' +    assert page.has_content?("Invalid random key") +    assert page.has_no_content?("Welcome") +    user.destroy +  end + +  test "reports internal server errors" do +    Api::UsersController.any_instance.stubs(:create).raises +    submit_signup +    assert page.has_content?("server failed") +  end + +  test "does not render signup form without js" do +    Capybara.current_driver = :rack_test # no js +    visit '/signup' +    assert page.has_no_content?("Username") +    assert page.has_no_content?("Password") +  end + +  test "does not render login form without js" do +    Capybara.current_driver = :rack_test # no js +    visit '/login' +    assert page.has_no_content?("Username") +    assert page.has_no_content?("Password") +  end + +  def inject_malicious_js +    page.execute_script <<-EOJS +      var calc = new srp.Calculate(); +      calc.A = function(_a) {return "00";}; +      calc.S = calc.A; +      srp.session = new srp.Session(null, calc); +    EOJS +  end +end diff --git a/test/integration/locale_path_test.rb b/test/integration/locale_path_test.rb index 738e7f5..22293dc 100644 --- a/test/integration/locale_path_test.rb +++ b/test/integration/locale_path_test.rb @@ -21,6 +21,11 @@ require 'test_helper'  #  class LocalePathTest < ActionDispatch::IntegrationTest + +  teardown do +    I18n.locale = 'en' +  end +    test "redirect if accept-language is not default locale" do      get_via_redirect '/', {}, 'HTTP_ACCEPT_LANGUAGE' => 'de'      assert_equal '/de', path @@ -55,4 +60,4 @@ class LocalePathTest < ActionDispatch::IntegrationTest      @controller.send(:default_url_options)    end -end
\ No newline at end of file +end diff --git a/test/integration/navigation_test.rb b/test/integration/navigation_test.rb deleted file mode 100644 index eec8c0e..0000000 --- a/test/integration/navigation_test.rb +++ /dev/null @@ -1,9 +0,0 @@ -require 'test_helper' - -class NavigationTest < ActionDispatch::IntegrationTest - -  # test "the truth" do -  #   assert true -  # end -end - diff --git a/test/leap_web_users_test.rb b/test/leap_web_users_test.rb deleted file mode 100644 index f142e54..0000000 --- a/test/leap_web_users_test.rb +++ /dev/null @@ -1,7 +0,0 @@ -require 'test_helper' - -class LeapWebUsersTest < ActiveSupport::TestCase -  test "module exists" do -    assert_kind_of Module, LeapWebUsers -  end -end diff --git a/test/performance/browsing_test.rb b/test/performance/browsing_test.rb deleted file mode 100644 index 3fea27b..0000000 --- a/test/performance/browsing_test.rb +++ /dev/null @@ -1,12 +0,0 @@ -require 'test_helper' -require 'rails/performance_test_help' - -class BrowsingTest < ActionDispatch::PerformanceTest -  # Refer to the documentation for all available options -  # self.profile_options = { :runs => 5, :metrics => [:wall_time, :memory] -  #                          :output => 'tmp/performance', :formats => [:flat] } - -  def test_homepage -    get '/' -  end -end diff --git a/test/support/api_controller_test.rb b/test/support/api_controller_test.rb new file mode 100644 index 0000000..06cb46a --- /dev/null +++ b/test/support/api_controller_test.rb @@ -0,0 +1,29 @@ +class ApiControllerTest < ActionController::TestCase + +  def api_get(*args) +    get *add_api_defaults(args) +  end + +  def api_post(*args) +    post *add_api_defaults(args) +  end + +  def api_delete(*args) +    delete *add_api_defaults(args) +  end + +  def api_put(*args) +    put *add_api_defaults(args) +  end + +  def add_api_defaults(args) +    add_defaults args, version: '2' +  end + +  def add_defaults(args, defaults) +    opts = args.extract_options! +    opts.reverse_merge! defaults +    args << opts +    args +  end +end diff --git a/test/support/api_integration_test.rb b/test/support/api_integration_test.rb index 3b3481b..cea480c 100644 --- a/test/support/api_integration_test.rb +++ b/test/support/api_integration_test.rb @@ -3,6 +3,10 @@ class ApiIntegrationTest < ActionDispatch::IntegrationTest    DUMMY_TOKEN = Token.new    RACK_ENV = {'HTTP_AUTHORIZATION' => %Q(Token token="#{DUMMY_TOKEN.to_s}")} +  def api_version +    2 +  end +    setup do      @testcode = InviteCode.new      @testcode.save! diff --git a/test/support/assert_responses.rb b/test/support/assert_responses.rb index 7724fb4..6a22642 100644 --- a/test/support/assert_responses.rb +++ b/test/support/assert_responses.rb @@ -71,21 +71,24 @@ module AssertResponses    end    def assert_login_required -    assert_error_response :not_authorized_login, :unauthorized +    assert_error_response :not_authorized_login, +      status: :unauthorized    end    def assert_access_denied -    assert_error_response :not_authorized, :forbidden +    assert_error_response :not_authorized, +      status: :forbidden    end -  def assert_error_response(key, status=nil) -    message = I18n.t(key) +  def assert_error_response(key, options = {}) +    status=options.delete :status +    message = I18n.t(key, options)      if content_type == 'application/json'        status ||= :unprocessable_entity        assert_json_response('error' => key.to_s, 'message' => message)        assert_response status      else -      assert_equal({:alert => message}, flash.to_hash) +      assert_equal({'alert' => message}, flash.to_hash)      end    end diff --git a/test/support/browser_integration_test.rb b/test/support/browser_integration_test.rb index 1deb8fa..1f5e3d2 100644 --- a/test/support/browser_integration_test.rb +++ b/test/support/browser_integration_test.rb @@ -3,10 +3,11 @@  #  # Use this class for capybara based integration tests for the ui.  # +require 'capybara/rails'  class BrowserIntegrationTest < ActionDispatch::IntegrationTest    # let's use dom_id inorder to identify sections -  include ActionController::RecordIdentifier +  include ActionView::RecordIdentifier    CONFIG_RU = (Rails.root + 'config.ru').to_s    OUTER_APP = Rack::Builder.parse_file(CONFIG_RU).first @@ -28,7 +29,7 @@ class BrowserIntegrationTest < ActionDispatch::IntegrationTest    Capybara.app_host = 'http://lvh.me:3003'    Capybara.server_port = 3003    Capybara.javascript_driver = :poltergeist -  Capybara.default_wait_time = 5 +  Capybara.default_max_wait_time = 5    # Make the Capybara DSL available    include Capybara::DSL @@ -46,32 +47,17 @@ class BrowserIntegrationTest < ActionDispatch::IntegrationTest    end    def submit_signup(username = nil, password = nil) - -    with_config invite_required: true do - -      username ||= "test_#{SecureRandom.urlsafe_base64}".downcase -      password ||= SecureRandom.base64 -      visit '/users/new' -      fill_in 'Username', with: username -      fill_in 'Password', with: password +    username ||= "test_#{SecureRandom.urlsafe_base64}".downcase +    password ||= SecureRandom.base64 +    visit '/signup' +    fill_in 'Username', with: username +    fill_in 'Password', with: password +    if APP_CONFIG[:invite_required]        fill_in 'Invite code', with: @testcode.invite_code -      fill_in 'Password confirmation', with: password -      click_on 'Sign Up' -      return username, password -    end - -    with_config invite_required: false do - -      username ||= "test_#{SecureRandom.urlsafe_base64}".downcase -      password ||= SecureRandom.base64 -      visit '/users/new' -      fill_in 'Username', with: username -      fill_in 'Password', with: password -      fill_in 'Password confirmation', with: password -      click_on 'Sign Up' -      return username, password      end - +    fill_in 'Password confirmation', with: password +    click_on 'Sign Up' +    return username, password    end    # currently this only works for tests with poltergeist. @@ -101,7 +87,7 @@ class BrowserIntegrationTest < ActionDispatch::IntegrationTest      File.open(logfile_path, 'w') do |test_log|        test_log.puts self.class.name        test_log.puts "=========================" -      test_log.puts __name__ +      test_log.puts name        test_log.puts Time.now        test_log.puts current_path        test_log.puts page.status_code diff --git a/test/support/record_assertions.rb b/test/support/record_assertions.rb new file mode 100644 index 0000000..30b947f --- /dev/null +++ b/test/support/record_assertions.rb @@ -0,0 +1,10 @@ +module RecordAssertions + +  def assert_error(record, options) +    options.each do |k, v| +      errors = record.errors[k] +      assert_equal I18n.t("errors.messages.#{v}"), errors.first +    end +  end + +end diff --git a/test/test_helper.rb b/test/test_helper.rb index dfc6627..a06f710 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -1,5 +1,5 @@  ENV["RAILS_ENV"] = "test" -require File.expand_path('../../config/environment', __FILE__) +require_relative '../config/environment'  require 'rails/test_help'  require 'mocha/setup' @@ -16,11 +16,11 @@ class ActiveSupport::TestCase    protected    def logfile_path -    Rails.root + 'tmp' + "#{self.class.name.underscore}.#{__name__}.log" +    Rails.root + 'tmp' + "#{self.class.name.underscore}.#{name}.log"    end    def screenshot_path -    Rails.root + 'tmp' + "#{self.class.name.underscore}.#{__name__}.png" +    Rails.root + 'tmp' + "#{self.class.name.underscore}.#{name}.png"    end    def file_path(name) diff --git a/test/unit/email_test.rb b/test/unit/email_test.rb index e858bd5..739b43e 100644 --- a/test/unit/email_test.rb +++ b/test/unit/email_test.rb @@ -1,4 +1,5 @@  require 'test_helper' +require 'email'  class EmailTest < ActiveSupport::TestCase diff --git a/test/unit/identity_test.rb b/test/unit/identity_test.rb index 9d4bc90..e9173af 100644 --- a/test/unit/identity_test.rb +++ b/test/unit/identity_test.rb @@ -2,6 +2,7 @@ require_relative '../test_helper'  class IdentityTest < ActiveSupport::TestCase    include StubRecordHelper +  include RecordAssertions    setup do      @user = find_record :user @@ -22,7 +23,7 @@ class IdentityTest < ActiveSupport::TestCase    test "enabled identity requires destination" do      @id = Identity.new user: @user, address: @user.email_address      assert !@id.valid? -    assert_equal ["can't be blank"], @id.errors[:destination] +    assert_error @id, destination: :blank    end    test "disabled identity requires no destination" do @@ -62,7 +63,7 @@ class IdentityTest < ActiveSupport::TestCase      @id = Identity.create_for @user, address: alias_name, destination: forward_address      dup = Identity.build_for @user, address: alias_name, destination: forward_address      assert !dup.valid? -    assert_equal ["has already been taken"], dup.errors[:destination] +    assert_error dup, destination: :taken    end    test "validates availability" do @@ -70,7 +71,7 @@ class IdentityTest < ActiveSupport::TestCase      @id = Identity.create_for @user, address: alias_name, destination: forward_address      taken = Identity.build_for other_user, address: alias_name      assert !taken.valid? -    assert_equal ["has already been taken"], taken.errors[:address] +    assert_error taken, address: :taken    end    test "setting and getting pgp key" do @@ -133,7 +134,7 @@ class IdentityTest < ActiveSupport::TestCase      other_user = find_record :user      taken = Identity.build_for other_user, address: @id.address      assert !taken.valid? -    assert_equal ["has already been taken"], taken.errors[:address] +    assert_error taken, address: :taken    end    test "destroy all orphaned identities" do diff --git a/test/unit/invite_code_validator_test.rb b/test/unit/invite_code_validator_test.rb index 62eeae6..934ba2e 100644 --- a/test/unit/invite_code_validator_test.rb +++ b/test/unit/invite_code_validator_test.rb @@ -3,9 +3,9 @@ require 'test_helper'  class InviteCodeValidatorTest < ActiveSupport::TestCase    test "user should not be created with invalid invite code" do      with_config invite_required: true do -    invalid_user = FactoryGirl.build(:user) +      invalid_user = FactoryGirl.build(:user) -    assert !invalid_user.valid? +      assert !invalid_user.valid?      end    end @@ -30,7 +30,7 @@ class InviteCodeValidatorTest < ActiveSupport::TestCase    test "Invite count >= invite max uses is not accepted for new account signup" do -    validator = InviteCodeValidator.new nil +    validator = InviteCodeValidator.new      user_code = InviteCode.new      user_code.invite_count = 1 @@ -46,7 +46,7 @@ class InviteCodeValidatorTest < ActiveSupport::TestCase    end    test "Invite count < invite max uses is accepted for new account signup" do -    validator = InviteCodeValidator.new nil +    validator = InviteCodeValidator.new      user_code = InviteCode.create      user_code.save @@ -60,7 +60,7 @@ class InviteCodeValidatorTest < ActiveSupport::TestCase    end    test "Invite count 0 is accepted for new account signup" do -    validator = InviteCodeValidator.new nil +    validator = InviteCodeValidator.new      user_code = InviteCode.create @@ -73,7 +73,7 @@ class InviteCodeValidatorTest < ActiveSupport::TestCase    end    test "There is an error message if the invite code does not exist" do -    validator = InviteCodeValidator.new nil +    validator = InviteCodeValidator.new      user = FactoryGirl.build :user      user.invite_code = "wrongcode" @@ -83,4 +83,4 @@ class InviteCodeValidatorTest < ActiveSupport::TestCase      assert_equal ["This is not a valid code"], user.errors[:invite_code]    end -end
\ No newline at end of file +end diff --git a/test/unit/tmp_user_test.rb b/test/unit/temporary_user_test.rb index 1dea5f9..38ccd67 100644 --- a/test/unit/tmp_user_test.rb +++ b/test/unit/temporary_user_test.rb @@ -1,6 +1,6 @@  require 'test_helper' -class TmpUserTest < ActiveSupport::TestCase +class TemporaryUserTest < ActiveSupport::TestCase    setup do      InviteCodeValidator.any_instance.stubs(:validate)  | 
