summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/controllers/v1/sessions_controller.rb2
-rw-r--r--app/models/anonymous_user.rb4
-rw-r--r--app/models/identity.rb6
-rw-r--r--app/models/service_level.rb8
-rw-r--r--app/models/token.rb4
-rw-r--r--app/models/user.rb9
-rw-r--r--config/defaults.yml5
-rw-r--r--config/routes.rb3
-rw-r--r--engines/support/app/controllers/tickets_controller.rb6
-rw-r--r--engines/support/app/models/ticket.rb25
-rw-r--r--engines/support/app/views/tickets/_edit_form.html.haml2
-rw-r--r--engines/support/app/views/tickets/new.html.haml4
-rw-r--r--engines/support/test/functional/tickets_controller_test.rb4
-rw-r--r--engines/support/test/integration/create_ticket_test.rb36
-rw-r--r--engines/support/test/unit/ticket_test.rb4
-rw-r--r--test/factories.rb5
-rw-r--r--test/functional/v1/services_controller_test.rb6
-rw-r--r--test/integration/browser/account_test.rb27
-rw-r--r--test/integration/browser/session_test.rb20
-rw-r--r--test/support/browser_integration_test.rb15
-rw-r--r--test/unit/account_test.rb2
21 files changed, 143 insertions, 54 deletions
diff --git a/app/controllers/v1/sessions_controller.rb b/app/controllers/v1/sessions_controller.rb
index eae3a1e..d88fcdc 100644
--- a/app/controllers/v1/sessions_controller.rb
+++ b/app/controllers/v1/sessions_controller.rb
@@ -38,7 +38,7 @@ module V1
def login_response
handshake = session.delete(:handshake) || {}
- handshake.to_hash.merge(:id => current_user.id, :token => @token.id)
+ handshake.to_hash.merge(:id => current_user.id, :token => @token.to_s)
end
end
diff --git a/app/models/anonymous_user.rb b/app/models/anonymous_user.rb
index 360a577..87239eb 100644
--- a/app/models/anonymous_user.rb
+++ b/app/models/anonymous_user.rb
@@ -13,6 +13,10 @@ class AnonymousUser < Object
nil
end
+ def email
+ nil
+ end
+
def email_address
nil
end
diff --git a/app/models/identity.rb b/app/models/identity.rb
index 9b97b51..ad8c01e 100644
--- a/app/models/identity.rb
+++ b/app/models/identity.rb
@@ -70,6 +70,12 @@ class Identity < CouchRest::Model::Base
end
end
+ def self.destroy_all_for(user)
+ Identity.by_user_id.key(user.id).each do |identity|
+ identity.destroy
+ end
+ end
+
def self.destroy_all_disabled
Identity.disabled.each do |identity|
identity.destroy
diff --git a/app/models/service_level.rb b/app/models/service_level.rb
index 5dd8838..a8df55b 100644
--- a/app/models/service_level.rb
+++ b/app/models/service_level.rb
@@ -24,6 +24,14 @@ class ServiceLevel
end
end
+ def provides?(service)
+ services.include? service
+ end
+
+ def services
+ config_hash[:services] || []
+ end
+
protected
def limited_cert?
diff --git a/app/models/token.rb b/app/models/token.rb
index 4856c31..e759ee3 100644
--- a/app/models/token.rb
+++ b/app/models/token.rb
@@ -30,6 +30,10 @@ class Token < CouchRest::Model::Base
end
end
+ def to_s
+ id
+ end
+
def authenticate
if expired?
destroy
diff --git a/app/models/user.rb b/app/models/user.rb
index c297ac8..6678de6 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -61,6 +61,15 @@ class User < CouchRest::Model::Base
login
end
+ # use this if you want to get a working email address only.
+ def email
+ if effective_service_level.provides?('email')
+ email_address
+ end
+ end
+
+ # use this if you want the email address associated with a
+ # user no matter if the user actually has a local email account
def email_address
LocalEmail.new(login)
end
diff --git a/config/defaults.yml b/config/defaults.yml
index 47cb641..1c7e694 100644
--- a/config/defaults.yml
+++ b/config/defaults.yml
@@ -54,12 +54,17 @@ service_levels: &service_levels
description: "free account, with rate limited VPN"
eip_rate_limit: true
storage: 100
+ services:
+ - eip
2:
name: premium
description: "premium account, with unlimited vpn"
rate:
USD: 10
EUR: 10
+ services:
+ - eip
+ - email
default_service_level: 1
development:
diff --git a/config/routes.rb b/config/routes.rb
index f612b47..745b97d 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -20,7 +20,8 @@ LeapWeb::Application.routes.draw do
namespace "api", { module: "v1",
path: "/1/",
defaults: {format: 'json'} } do
- resources :sessions, :only => [:new, :create, :update]
+ resources :sessions, :only => [:new, :create, :update],
+ :constraints => { :id => /[^\/]+(?=\.json\z)|[^\/]+/ }
delete "logout" => "sessions#destroy", :as => "logout"
resources :users, :only => [:create, :update, :destroy, :index]
resources :messages, :only => [:index, :update]
diff --git a/engines/support/app/controllers/tickets_controller.rb b/engines/support/app/controllers/tickets_controller.rb
index d552209..99357ab 100644
--- a/engines/support/app/controllers/tickets_controller.rb
+++ b/engines/support/app/controllers/tickets_controller.rb
@@ -12,6 +12,7 @@ class TicketsController < ApplicationController
def new
@ticket = Ticket.new
+ @ticket.created_by = current_user.id
@ticket.comments.build
end
@@ -22,12 +23,9 @@ class TicketsController < ApplicationController
@ticket.comments.last.posted_by = current_user.id
@ticket.comments.last.private = false unless admin?
@ticket.created_by = current_user.id
- @ticket.email = current_user.email_address if current_user.email_address
if @ticket.save
flash[:notice] = t(:thing_was_successfully_created, :thing => t(:ticket))
-
- # cannot set this until ticket has been saved, as @ticket.id will not be set
- if !logged_in? and flash[:notice]
+ if !logged_in?
flash[:notice] += " " + t(:access_ticket_text, :full_url => ticket_url(@ticket.id))
end
end
diff --git a/engines/support/app/models/ticket.rb b/engines/support/app/models/ticket.rb
index cd22758..bf5df53 100644
--- a/engines/support/app/models/ticket.rb
+++ b/engines/support/app/models/ticket.rb
@@ -19,8 +19,6 @@ class Ticket < CouchRest::Model::Base
timestamps!
- before_validation :set_email, :set_regarding_user, :on => :create
-
design do
view :by_updated_at
view :by_created_at
@@ -34,7 +32,12 @@ class Ticket < CouchRest::Model::Base
end
validates :subject, :presence => true
- validates :email, :allow_blank => true, :format => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/
+
+ # email can have three states:
+ # * nil - prefilled with created_by's email
+ # * "" - cleared
+ # * valid email address
+ validates :email, :allow_blank => true, :format => /\A(([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,}))?\Z/
def self.search(options = {})
@selection = TicketSelection.new(options)
@@ -48,15 +51,15 @@ class Ticket < CouchRest::Model::Base
end
def is_creator_validated?
- !!created_by
+ created_by_user.is_a? User
end
- def set_email
- self.email = nil if self.email == ""
+ def email
+ read_attribute(:email) || created_by_user.email
end
- def set_regarding_user
- self.regarding_user = nil if self.regarding_user == ""
+ def regarding_user
+ read_attribute(:regarding_user) || created_by_user.login
end
def close
@@ -95,7 +98,11 @@ class Ticket < CouchRest::Model::Base
end
def created_by_user
- User.find(self.created_by)
+ if self.created_by
+ User.find(self.created_by) || AnonymousUser.new
+ else
+ AnonymousUser.new
+ end
end
def regarding_user_actual_user
diff --git a/engines/support/app/views/tickets/_edit_form.html.haml b/engines/support/app/views/tickets/_edit_form.html.haml
index bf175fe..fb279fb 100644
--- a/engines/support/app/views/tickets/_edit_form.html.haml
+++ b/engines/support/app/views/tickets/_edit_form.html.haml
@@ -1,6 +1,6 @@
:ruby
# created by user link
- if @ticket.created_by_user
+ if @ticket.is_creator_validated?
created_by = link_to @ticket.created_by_user.login, @ticket.created_by_user
else
created_by = t(:anonymous)
diff --git a/engines/support/app/views/tickets/new.html.haml b/engines/support/app/views/tickets/new.html.haml
index ab008d2..3de5fe9 100644
--- a/engines/support/app/views/tickets/new.html.haml
+++ b/engines/support/app/views/tickets/new.html.haml
@@ -8,8 +8,8 @@
= simple_form_for @ticket, :validate => true, :html => {:class => 'form-horizontal'} do |f|
= hidden_ticket_fields
= f.input :subject
- = f.input :email, input_html: {value: user.email_address}
- = f.input :regarding_user, input_html: {value: user.login}
+ = f.input :email
+ = f.input :regarding_user
= f.simple_fields_for :comments, @comment do |c|
= c.input :body, :label => t(:description), :as => :text, :input_html => {:class => "full-width", :rows=> 5}
- if admin?
diff --git a/engines/support/test/functional/tickets_controller_test.rb b/engines/support/test/functional/tickets_controller_test.rb
index d746b59..fc4a6f8 100644
--- a/engines/support/test/functional/tickets_controller_test.rb
+++ b/engines/support/test/functional/tickets_controller_test.rb
@@ -85,7 +85,7 @@ class TicketsControllerTest < ActionController::TestCase
test "should create authenticated ticket" do
- params = {:subject => "auth ticket test subject", :comments_attributes => {"0" => {"body" =>"body of test ticket"}}}
+ params = {:subject => "auth ticket test subject",:email => "", :comments_attributes => {"0" => {"body" =>"body of test ticket"}}}
login
@@ -97,7 +97,7 @@ class TicketsControllerTest < ActionController::TestCase
assert_not_nil assigns(:ticket).created_by
assert_equal assigns(:ticket).created_by, @current_user.id
- assert_equal assigns(:ticket).email, @current_user.email_address
+ assert_equal "", assigns(:ticket).email
assert_equal 1, assigns(:ticket).comments.count
assert_not_nil assigns(:ticket).comments.first.posted_by
diff --git a/engines/support/test/integration/create_ticket_test.rb b/engines/support/test/integration/create_ticket_test.rb
index 2583fc7..0f8453c 100644
--- a/engines/support/test/integration/create_ticket_test.rb
+++ b/engines/support/test/integration/create_ticket_test.rb
@@ -20,9 +20,45 @@ class CreateTicketTest < BrowserIntegrationTest
click_on 'Get Help'
fill_in 'Subject', with: 'test ticket'
fill_in 'Email', with: 'invalid data'
+ fill_in 'Regarding user', with: 'some user'
fill_in 'Description', with: 'description of the problem goes here'
click_on 'Create Ticket'
assert page.has_content?("is invalid")
+ assert_equal 'invalid data', find_field('Email').value
+ assert_equal 'some user', find_field('Regarding user').value
+ end
+
+ test "prefills fields" do
+ login FactoryGirl.create(:premium_user)
+ visit '/'
+ click_on "Support Tickets"
+ click_on "New Ticket"
+ email = "#{@user.login}@#{APP_CONFIG[:domain]}"
+ assert_equal email, find_field('Email').value
+ assert_equal @user.login, find_field('Regarding user').value
+ end
+
+ test "no prefill of email without email service" do
+ login
+ visit '/'
+ click_on "Support Tickets"
+ click_on "New Ticket"
+ assert_equal "", find_field('Email').value
+ assert_equal @user.login, find_field('Regarding user').value
+ end
+
+ test "cleared email field should remain clear" do
+ login FactoryGirl.create(:premium_user)
+ visit '/'
+ click_on "Support Tickets"
+ click_on "New Ticket"
+ fill_in 'Subject', with: 'test ticket'
+ fill_in 'Email', with: ''
+ fill_in 'Description', with: 'description of the problem goes here'
+ click_on 'Create Ticket'
+ ticket = Ticket.last
+ assert_equal "", ticket.email
+ ticket.destroy
end
end
diff --git a/engines/support/test/unit/ticket_test.rb b/engines/support/test/unit/ticket_test.rb
index f5e6ea7..678d8dc 100644
--- a/engines/support/test/unit/ticket_test.rb
+++ b/engines/support/test/unit/ticket_test.rb
@@ -27,10 +27,10 @@ class TicketTest < ActiveSupport::TestCase
end
test "creation validated" do
+ user = FactoryGirl.create :user
@sample = Ticket.new
assert !@sample.is_creator_validated?
- #p current_user
- @sample.created_by = 22 #current_user
+ @sample.created_by = user.id
assert @sample.is_creator_validated?
end
diff --git a/test/factories.rb b/test/factories.rb
index ac9333c..bebda5c 100644
--- a/test/factories.rb
+++ b/test/factories.rb
@@ -22,6 +22,11 @@ FactoryGirl.define do
admin.stubs(:is_admin?).returns(true)
end
end
+
+ factory :premium_user do
+ effective_service_level_code 2
+ end
+
end
factory :token do
diff --git a/test/functional/v1/services_controller_test.rb b/test/functional/v1/services_controller_test.rb
index e4058c0..cde7d9f 100644
--- a/test/functional/v1/services_controller_test.rb
+++ b/test/functional/v1/services_controller_test.rb
@@ -21,10 +21,8 @@ class V1::ServicesControllerTest < ActionController::TestCase
test "user can see their service info" do
login
get :show, format: :json
- assert_json_response name: 'free',
- eip_rate_limit: true,
- description: 'free account, with rate limited VPN',
- storage: 100
+ default_level = APP_CONFIG[:default_service_level]
+ assert_json_response APP_CONFIG[:service_levels][default_level]
end
end
diff --git a/test/integration/browser/account_test.rb b/test/integration/browser/account_test.rb
index 4e11520..491a9e1 100644
--- a/test/integration/browser/account_test.rb
+++ b/test/integration/browser/account_test.rb
@@ -6,7 +6,7 @@ class AccountTest < BrowserIntegrationTest
Identity.destroy_all_disabled
end
- test "normal account workflow" do
+ test "signup successfully" do
username, password = submit_signup
assert page.has_content?("Welcome #{username}")
click_on 'Logout'
@@ -16,6 +16,12 @@ class AccountTest < BrowserIntegrationTest
user.account.destroy
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 "successful login" do
username, password = submit_signup
click_on 'Logout'
@@ -51,7 +57,7 @@ class AccountTest < BrowserIntegrationTest
end
test "default user actions" do
- username, password = submit_signup
+ login
click_on "Account Settings"
assert page.has_content? I18n.t('destroy_my_account')
assert page.has_no_css? '#update_login_and_password'
@@ -59,8 +65,8 @@ class AccountTest < BrowserIntegrationTest
end
test "default admin actions" do
- username, password = submit_signup
- with_config admins: [username] 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'
@@ -70,7 +76,7 @@ class AccountTest < BrowserIntegrationTest
test "change password" do
with_config user_actions: ['change_password'] do
- username, password = submit_signup
+ login
click_on "Account Settings"
within('#update_login_and_password') do
fill_in 'Password', with: "other password"
@@ -78,16 +84,15 @@ class AccountTest < BrowserIntegrationTest
click_on 'Save'
end
click_on 'Logout'
- attempt_login(username, "other password")
- assert page.has_content?("Welcome #{username}")
- User.find_by_login(username).account.destroy
+ attempt_login(@user.login, "other password")
+ assert page.has_content?("Welcome #{@user.login}")
end
end
test "change pgp key" do
with_config user_actions: ['change_pgp_key'] do
pgp_key = FactoryGirl.build :pgp_key
- username, password = submit_signup
+ login
click_on "Account Settings"
within('#update_pgp_key') do
fill_in 'Public key', with: pgp_key
@@ -97,9 +102,7 @@ class AccountTest < BrowserIntegrationTest
# 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 = User.find_by_login(username)
- assert_equal pgp_key, user.public_key
- user.account.destroy
+ assert_equal pgp_key, @user.reload.public_key
end
end
diff --git a/test/integration/browser/session_test.rb b/test/integration/browser/session_test.rb
index 3a41b3a..fb20847 100644
--- a/test/integration/browser/session_test.rb
+++ b/test/integration/browser/session_test.rb
@@ -2,26 +2,16 @@ require 'test_helper'
class SessionTest < BrowserIntegrationTest
- setup do
- @username, password = submit_signup
- end
-
- teardown do
- user = User.find_by_login(@username)
- id = user.identity
- id.destroy
- user.destroy
- end
-
test "valid session" do
- assert page.has_content?("Welcome #{@username}")
+ login
+ assert page.has_content?("Logout")
end
test "expired session" do
- assert page.has_content?("Welcome #{@username}")
- pretend_now_is(Time.now + 40.minutes) do
+ login
+ pretend_now_is(Time.now + 80.minutes) do
visit '/'
- assert page.has_no_content?("Welcome #{@username}")
+ assert page.has_content?("Log In")
end
end
end
diff --git a/test/support/browser_integration_test.rb b/test/support/browser_integration_test.rb
index 9cae8cb..1c872ff 100644
--- a/test/support/browser_integration_test.rb
+++ b/test/support/browser_integration_test.rb
@@ -53,6 +53,21 @@ class BrowserIntegrationTest < ActionDispatch::IntegrationTest
return username, password
end
+ # currently this only works for tests with poltergeist.
+ def login(user = nil)
+ @user ||= user ||= FactoryGirl.create(:user)
+ token = Token.create user_id: user.id
+ page.driver.add_header "Authorization", %Q(Token token="#{token}")
+ visit '/'
+ end
+
+ teardown do
+ if @user && @user.reload
+ Identity.destroy_all_for @user
+ @user.destroy
+ end
+ end
+
add_teardown_hook do |testcase|
unless testcase.passed?
testcase.save_state
diff --git a/test/unit/account_test.rb b/test/unit/account_test.rb
index 4fb3c3d..b2bfe27 100644
--- a/test/unit/account_test.rb
+++ b/test/unit/account_test.rb
@@ -8,7 +8,7 @@ class AccountTest < ActiveSupport::TestCase
test "create a new account" do
user = Account.create(FactoryGirl.attributes_for(:user))
- assert user.valid?
+ assert user.valid?, "unexpected errors: #{user.errors.inspect}"
assert user.persisted?
assert id = user.identity
assert_equal user.email_address, id.address