billing 0.0.4d → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/billing/accounts.js +2 -0
  3. data/app/assets/javascripts/billing/application.js +13 -0
  4. data/app/assets/javascripts/billing/charges.js +2 -0
  5. data/app/assets/javascripts/billing/modifiers.js +2 -0
  6. data/app/assets/stylesheets/billing/accounts.css +4 -0
  7. data/app/assets/stylesheets/billing/application.css +15 -0
  8. data/app/assets/stylesheets/billing/charges.css +4 -0
  9. data/app/assets/stylesheets/billing/modifiers.css +4 -0
  10. data/app/assets/stylesheets/billing/payments.css +4 -0
  11. data/app/controllers/billing/accounts_controller.rb +29 -0
  12. data/app/controllers/billing/application_controller.rb +22 -0
  13. data/app/controllers/billing/charges_controller.rb +29 -0
  14. data/app/controllers/billing/modifiers_controller.rb +29 -0
  15. data/app/controllers/billing/payments_controller.rb +29 -0
  16. data/app/helpers/billing/accounts_helper.rb +4 -0
  17. data/app/helpers/billing/application_helper.rb +4 -0
  18. data/app/helpers/billing/charges_helper.rb +4 -0
  19. data/app/helpers/billing/modifiers_helper.rb +4 -0
  20. data/app/helpers/billing/payments_helper.rb +4 -0
  21. data/app/models/billing/{bill.rb → account.rb} +30 -37
  22. data/app/models/billing/charge.rb +11 -25
  23. data/app/models/billing/modifier.rb +5 -5
  24. data/app/models/billing/origin.rb +2 -7
  25. data/app/models/billing/payment.rb +11 -8
  26. data/app/models/billing/payment_with_type.rb +1 -1
  27. data/app/models/billing/report.rb +12 -23
  28. data/app/models/concerns/billing/{bill_item.rb → account_item.rb} +6 -5
  29. data/app/views/billing/accounts/index.html.erb +7 -0
  30. data/app/views/billing/accounts/new.html.erb +8 -0
  31. data/app/views/billing/accounts/show.html.erb +29 -0
  32. data/app/views/billing/application/index.html.erb +3 -0
  33. data/app/views/billing/charges/new.html.erb +12 -0
  34. data/app/views/billing/modifiers/new.html.erb +18 -0
  35. data/app/views/billing/payments/new.html.erb +11 -0
  36. data/app/views/layouts/billing/application.html.erb +14 -0
  37. data/config/routes.rb +6 -1
  38. data/lib/billing.rb +2 -0
  39. data/lib/billing/billable.rb +3 -3
  40. data/lib/billing/engine.rb +0 -3
  41. data/lib/billing/mapping.rb +32 -0
  42. data/lib/billing/routes.rb +16 -0
  43. data/lib/billing/version.rb +1 -1
  44. data/test/controllers/billing/accounts_controller_test.rb +19 -0
  45. data/test/controllers/billing/charges_controller_test.rb +16 -0
  46. data/test/controllers/billing/modifiers_controller_test.rb +16 -0
  47. data/test/controllers/billing/payments_controller_test.rb +16 -0
  48. data/test/dummy/config/routes.rb +3 -1
  49. data/test/dummy/db/development.sqlite3 +0 -0
  50. data/test/dummy/db/schema.rb +17 -23
  51. data/test/dummy/db/test.sqlite3 +0 -0
  52. data/test/dummy/log/development.log +0 -8144
  53. data/test/dummy/log/test.log +0 -64325
  54. data/test/fixtures/billing/{bills.yml → accounts.yml} +0 -0
  55. data/test/fixtures/billing/charges.yml +2 -2
  56. data/test/fixtures/billing/modifiers.yml +2 -2
  57. data/test/fixtures/billing/payments.yml +2 -2
  58. data/test/helpers/billing/accounts_helper_test.rb +6 -0
  59. data/test/helpers/billing/charges_helper_test.rb +6 -0
  60. data/test/helpers/billing/modifiers_helper_test.rb +6 -0
  61. data/test/helpers/billing/payments_helper_test.rb +6 -0
  62. data/test/integration/navigation_test.rb +10 -0
  63. data/test/models/billing/account_test.rb +56 -0
  64. data/test/models/billing/charge_test.rb +6 -13
  65. data/test/models/billing/modifier_test.rb +2 -2
  66. data/test/models/billing/payment_test.rb +12 -12
  67. metadata +58 -20
  68. data/app/models/billing/room_transfer.rb +0 -4
  69. data/app/models/concerns/billing/bill_text_parser.rb +0 -18
  70. data/config/initializers/money.rb +0 -67
  71. data/db/migrate/20140803073707_rename_billing_account_to_bill.rb +0 -8
  72. data/db/migrate/20140804065726_add_qty_to_billing_charge.rb +0 -5
  73. data/db/migrate/20140804070517_add_tax_ratio_to_billing_charge.rb +0 -5
  74. data/db/migrate/20141001185321_add_transfer_device_to_billing_origin.rb +0 -5
  75. data/db/migrate/20141027235427_add_f_amount_to_billing_report.rb +0 -7
  76. data/lib/collection_proxy_wild.rb +0 -9
  77. data/test/models/billing/bill_test.rb +0 -76
@@ -1,13 +1,13 @@
1
1
  module Billing
2
2
  class Modifier < ActiveRecord::Base
3
- include BillItem
4
- belongs_to :bill, inverse_of: :modifiers, validate: true
3
+ include AccountItem
4
+ belongs_to :account, inverse_of: :modifiers, validate: true
5
5
  belongs_to :charge, inverse_of: :modifier
6
6
  monetize :fixed_value_cents
7
7
 
8
8
  validate :percent_or_value
9
- validates_uniqueness_of :charge, scope: :bill_id, allow_nil: true
10
- validates_uniqueness_of :bill, scope: :charge_id
9
+ validates_uniqueness_of :charge, scope: :account_id, allow_nil: true
10
+ validates_uniqueness_of :account, scope: :charge_id
11
11
 
12
12
  private
13
13
  def percent_or_value
@@ -16,7 +16,7 @@ module Billing
16
16
  end
17
17
 
18
18
  class << self
19
- def wild_args(*args)
19
+ def args(*args)
20
20
  case when args.blank? || args.first.kind_of?(Hash) then
21
21
  {}.merge(*args)
22
22
  when args.first.kind_of?(String) then
@@ -1,11 +1,10 @@
1
1
  module Billing
2
2
  class Origin < ActiveRecord::Base
3
- has_many :bills, inverse_of: :origin
3
+ has_many :accounts, inverse_of: :origin
4
4
  has_many :charges, inverse_of: :origin
5
- has_many :payments, through: :bills
5
+ has_many :payments, through: :accounts
6
6
  if defined? Extface
7
7
  belongs_to :fiscal_device, ->(o) { where( extfaceable_id: o.master_id ) }, class_name: 'Extface::Device'
8
- belongs_to :transfer_device, ->(o) { where( extfaceable_id: o.master_id ) }, class_name: 'Extface::Device'
9
8
  end
10
9
 
11
10
  validates_presence_of :name
@@ -14,9 +13,5 @@ module Billing
14
13
  def external_payment?
15
14
  payment_model != Payment::PAYMENT_WITH_TYPE
16
15
  end
17
-
18
- def room_transfer?
19
- payment_model == Payment::ROOM_TRANSFER
20
- end
21
16
  end
22
17
  end
@@ -3,31 +3,34 @@ module Billing
3
3
  PAYMENT_WITH_TYPE = 'Billing::PaymentWithType'.freeze
4
4
  PAYMENT_EXTERNAL = 'Billing::PaymentExternal'.freeze
5
5
  PAYPAL_EXPRESS = 'Billing::PaypalExpress'.freeze
6
- ROOM_TRANSFER = 'Billing::RoomTransfer'.freeze
7
- PAYMENT_MODELS = [PAYMENT_WITH_TYPE, PAYMENT_EXTERNAL, PAYPAL_EXPRESS, ROOM_TRANSFER].freeze
6
+ PAYMENT_MODELS = [PAYMENT_WITH_TYPE, PAYMENT_EXTERNAL, PAYPAL_EXPRESS].freeze
8
7
 
9
- include BillItem
8
+ include AccountItem
10
9
 
11
10
  attr_writer :origin
12
11
  attr_accessor :origin_id
13
12
  monetize :value_cents
14
13
 
15
- belongs_to :bill, inverse_of: :payments, validate: true
14
+ belongs_to :account, inverse_of: :payments, validate: true
16
15
 
17
16
  scope :in_period, lambda {|from, to| where(created_at: from..to) }
18
- scope :for_report, -> { joins(:bill).where(billing_bills: { balance_cents: 0 ,report_id: nil }) }
17
+ scope :for_report, -> { joins(:account).where(billing_accounts: { balance_cents: 0 ,report_id: nil }) }
19
18
 
20
19
  if defined? Extface
21
20
  belongs_to :extface_job, class_name: 'Extface::Job'
22
21
  end
23
22
 
24
- delegate :billable, to: :bill
23
+ delegate :billable, to: :account
25
24
 
26
25
  validates_numericality_of :value, greater_than_or_equal_to: 0
27
26
  validates :type, inclusion: { in: PAYMENT_MODELS }
28
27
 
29
28
  after_initialize on: :create do
30
- self.value = -bill.try(:balance) if value.zero?
29
+ self.value = -account.try(:balance) if value.zero?
30
+ end
31
+
32
+ before_validation do
33
+ account.origin = origin unless account.origin and account.payments.many?
31
34
  end
32
35
 
33
36
  def fiscal?; false; end
@@ -40,7 +43,7 @@ module Billing
40
43
 
41
44
  private
42
45
  class << self
43
- def wild_args(*args)
46
+ def args(*args)
44
47
  h = {}
45
48
  case when args.blank? || args.first.kind_of?(Hash) then
46
49
  args.blank? ? h : h.merge(*args)
@@ -22,7 +22,7 @@ module Billing
22
22
  if pt = billable.try(:default_payment_type)
23
23
  pt
24
24
  else
25
- bill.payment_types.try(:first) unless bill.payment_types.many?
25
+ account.payment_types.try(:first) unless account.payment_types.many?
26
26
  end
27
27
  end
28
28
 
@@ -3,31 +3,26 @@ module Billing
3
3
  FISCAL_X_REPORT = 'x_report'.freeze
4
4
  FISCAL_Z_REPORT = 'z_report'.freeze
5
5
  FISCAL_PERIOD_REPORT = 'period_report'.freeze
6
- FISCAL_PAYED_RECVD = 'payed_recvd'.freeze
7
- F_OPERATIONS = [FISCAL_X_REPORT, FISCAL_Z_REPORT, FISCAL_PERIOD_REPORT, FISCAL_PAYED_RECVD].freeze
6
+ F_OPERATIONS = [FISCAL_X_REPORT, FISCAL_Z_REPORT, FISCAL_PERIOD_REPORT].freeze
8
7
 
9
8
  has_paper_trail class_name: 'Billing::Version'
10
9
  belongs_to :origin, inverse_of: :reports
11
- has_many :bills, inverse_of: :report, autosave: true
10
+ has_many :accounts, inverse_of: :report, autosave: true
12
11
  belongs_to :extface_job, class_name: 'Extface::Job'
13
- has_many :payments, through: :bills
12
+ has_many :payments, through: :accounts
14
13
 
15
14
  monetize :payments_sum_cents
16
15
  monetize :payments_cash_cents
17
16
  monetize :payments_fiscal_cents
18
- monetize :f_amount_cents
19
17
 
20
18
  validates_presence_of :origin
21
- validates_absence_of :partially_paid_bills?
19
+ validates_absence_of :partially_paid_accounts?
22
20
  validates :f_operation, inclusion: { in: F_OPERATIONS }, allow_nil: true
23
21
  validates_presence_of :f_period_from, :f_period_to, if: :fiscal_period_report?
24
- validates_presence_of :f_amount, if: :fiscal_payed_recvd?
25
22
 
26
- before_validation :set_report_to_bills
23
+ before_validation :set_report_to_accounts
27
24
  before_create :update_summary
28
25
 
29
- scope :in_period, lambda {|from, to| where(created_at: from..to) }
30
-
31
26
 
32
27
  def fiscalization
33
28
  if origin.fiscal_device.present?
@@ -42,18 +37,14 @@ module Billing
42
37
  f_operation == FISCAL_PERIOD_REPORT
43
38
  end
44
39
 
45
- def fiscal_payed_recvd?
46
- f_operation == FISCAL_PAYED_RECVD
47
- end
48
-
49
- def set_report_to_bills
50
- self.bills << origin.bills.for_report if zeroing?
40
+ def set_report_to_accounts
41
+ self.accounts << origin.accounts.select(&:paid?) if zeroing?
51
42
  end
52
43
 
53
44
  def update_summary
54
- self.payments_sum = bills.to_a.sum(Money.new(0, 'USD'), &:payments_sum)
55
- self.payments_cash = bills.collect(&:payments).flatten.select{ |p| p.try(:cash?) }.sum(Money.new(0, 'USD'), &:value)
56
- self.payments_fiscal = bills.collect(&:payments).flatten.select{ |p| p.try(:fiscal?) }.sum(Money.new(0, 'USD'), &:value)
45
+ self.payments_sum = accounts.to_a.sum(Money.new(0, 'USD'), &:payments_sum)
46
+ self.payments_cash = payments.select{ |p| p.try(:cash?) }.sum(Money.new(0, 'USD'), &:value)
47
+ self.payments_fiscal = payments.select{ |p| p.try(:fiscal?) }.sum(Money.new(0, 'USD'), &:value)
57
48
  perform_fiscal_job
58
49
  end
59
50
 
@@ -65,13 +56,11 @@ module Billing
65
56
  self.extface_job = origin.fiscal_device.driver.x_report_session
66
57
  when FISCAL_PERIOD_REPORT then
67
58
  p "period"
68
- when FISCAL_PAYED_RECVD then
69
- self.extface_job = origin.fiscal_device.driver.payed_recv_account(f_amount.to_f)
70
59
  end
71
60
  end
72
61
 
73
- def partially_paid_bills?
74
- bills.partially_paid.any?
62
+ def partially_paid_accounts?
63
+ accounts.partially_paid.any?
75
64
  end
76
65
  end
77
66
  end
@@ -1,16 +1,17 @@
1
1
  module Billing
2
- module BillItem
2
+ module AccountItem
3
3
  extend ActiveSupport::Concern
4
4
 
5
5
  included do
6
6
  acts_as_paranoid if respond_to?(:acts_as_paranoid)
7
7
  has_paper_trail class_name: 'Billing::Version' if respond_to?(:has_paper_trail)
8
8
 
9
- delegate :save, to: :bill, prefix: :bill
10
- delegate :origins, :payment_types, to: :bill
9
+ delegate :save, to: :account, prefix: :account
10
+ delegate :origins, :payment_types, to: :account
11
11
 
12
- after_save :bill_save
13
- after_destroy :bill_save
12
+ after_save :account_save
13
+
14
+ validates_presence_of :account
14
15
  end
15
16
 
16
17
  end
@@ -0,0 +1,7 @@
1
+ <h1>Accounts#index</h1>
2
+ <p>Find me in app/views/billing/accounts/index.html.erb</p>
3
+ <%= link_to :new, new_account_path %>
4
+ <hr />
5
+ <% @accounts.each do |account| %>
6
+ <%= link_to account.inspect, account %>
7
+ <% end %>
@@ -0,0 +1,8 @@
1
+ <h1>
2
+ New account
3
+ <small><%= billable %></small>
4
+ </h1>
5
+ <%= form_for @account do |f| %>
6
+ <%= @account.inspect %>
7
+ <%= f.submit %>
8
+ <% end %>
@@ -0,0 +1,29 @@
1
+ <%= @account.inspect %>
2
+ <h2>
3
+ total: <%= @account.total %>
4
+ <br />
5
+ balance: <%= @account.balance %>
6
+ </h2>
7
+ <hr />
8
+ Charges:<br />
9
+ <% @account.charges.each do |charge| %>
10
+ <%= charge.inspect %>
11
+ <% end %>
12
+ <%= link_to :charge, [:new, @account, :charge] %>
13
+ <hr />
14
+ Modifiers:<br />
15
+ <% @account.modifiers.each do |modifier| %>
16
+ <%= modifier.inspect %>
17
+ <% end %>
18
+ <%= link_to :modifier, [:new, @account, :modifier] %>
19
+ <div>
20
+ <% @account.modifier_items.each do |mi| %>
21
+ <%= mi.inspect %><br />
22
+ <% end %>
23
+ </div>
24
+ <hr />
25
+ Payments:<br />
26
+ <% @account.payments.each do |payment| %>
27
+ <%= payment.inspect %>
28
+ <% end %>
29
+ <%= link_to :pay, [:new, @account, :payment] %>
@@ -0,0 +1,3 @@
1
+ <%= link_to :accounts, accounts_path %>
2
+ <br />
3
+ <%= link_to :new_account, new_account_path %>
@@ -0,0 +1,12 @@
1
+ <h1>
2
+ New charge
3
+ <small><%= @account %></small>
4
+ </h1>
5
+ <%= form_for [@account, @charge] do |f| %>
6
+ <%= @charge.inspect %>
7
+ <br />
8
+ <%= f.number_field :price, step: 0.01 %>
9
+ <br />
10
+ <%= f.submit %>
11
+ <% end %>
12
+
@@ -0,0 +1,18 @@
1
+ <h1>
2
+ New Modifier
3
+ <small><%= @account %></small>
4
+ </h1>
5
+ <div>
6
+ <%= @modifier.errors.full_messages.join(', ') %>
7
+ </div>
8
+ <%= form_for [@account, @modifier] do |f| %>
9
+ <%= @modifier.inspect %>
10
+ <br />
11
+ percent ratio <%= f.number_field :percent_ratio, step: 0.001 %>
12
+ <br />
13
+ fixed value <%= f.number_field :fixed_value, step: 0.01 %>
14
+ <br />
15
+ <%= f.select :charge_id, @account.charges.collect(&:id), { include_blank: true } %>
16
+ <br />
17
+ <%= f.submit %>
18
+ <% end %>
@@ -0,0 +1,11 @@
1
+ <h1>
2
+ New payment
3
+ <small><%= @account %></small>
4
+ </h1>
5
+ <%= form_for [@account, @payment] do |f| %>
6
+ <%= @payment.inspect %>
7
+ <br />
8
+ <%= f.number_field :value, step: 0.01 %>
9
+ <br />
10
+ <%= f.submit %>
11
+ <% end %>
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Billing</title>
5
+ <%= stylesheet_link_tag "billing/application", media: "all" %>
6
+ <%= javascript_include_tag "billing/application" %>
7
+ <%= csrf_meta_tags %>
8
+ </head>
9
+ <body>
10
+
11
+ <%= yield %>
12
+
13
+ </body>
14
+ </html>
data/config/routes.rb CHANGED
@@ -1,3 +1,8 @@
1
1
  Billing::Engine.routes.draw do
2
-
2
+ resources :accounts do
3
+ resources :charges
4
+ resources :modifiers
5
+ resources :payments
6
+ end
7
+ root "application#index"
3
8
  end
data/lib/billing.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  require "billing/engine"
2
2
  require "billing/billable"
3
+ require "billing/mapping"
4
+ require "billing/routes"
3
5
 
4
6
  module Billing
5
7
  mattr_reader :mappings
@@ -9,10 +9,10 @@ module Billing
9
9
  module ClassMethods
10
10
  def has_billing(options={})
11
11
  payment_types_scope = options.delete(:payment_types)
12
- has_many :billing_bills, options.merge(as: :billable).reverse_merge(class_name: 'Billing::Bill')
13
- provide_billing_items(:billing_bills)
12
+ has_many :billing_accounts, options.merge(as: :billable).reverse_merge(class_name: 'Billing::Account')
13
+ provide_billing_items(:billing_accounts)
14
14
  if options[:as]
15
- has_many options[:as], options.merge(as: :billable).reverse_merge(class_name: 'Billing::Bill')
15
+ has_many options[:as], options.merge(as: :billable).reverse_merge(class_name: 'Billing::Account')
16
16
  provide_billing_items(options[:as])
17
17
  end
18
18
  if payment_types_scope.present?
@@ -1,8 +1,5 @@
1
1
  require 'money-rails'
2
2
  require 'paper_trail'
3
-
4
- require 'collection_proxy_wild'
5
-
6
3
  module Billing
7
4
  class Engine < ::Rails::Engine
8
5
  isolate_namespace Billing
@@ -0,0 +1,32 @@
1
+ module Billing
2
+ class Mapping
3
+ attr_reader :name, :i_klass, :i_param, :i_find_key, :i_extra_module
4
+ def initialize(resource, options)
5
+ @name = (options[:as] || resource).to_s
6
+
7
+ @i_klass = (options[:billable_type] || name.to_s.classify).to_s.constantize
8
+
9
+ @i_param = options[:billable_param] || "#{name.singularize}_id" #default #{resource}_id
10
+
11
+ # key to find interfaceable in controller, when
12
+ # :uuid then find_by! :uuid => params[:uuid]
13
+ # :shop_uuid then find_by! :uuid => params[:shop_uuid]
14
+ # :shop_id then find_by! :id => params[:shop_id]
15
+ @i_find_key = @i_param[/^(#{resource}_|)(\w+)/,2]
16
+ # FIXME not before schema load
17
+ #raise "#{@i_klass.name} has no method #{@i_find_key}" unless @i_klass.new.respond_to? @i_find_key
18
+ #raise "Did you forget to add 'has_extface_devices' in #{@i_klass.name} ?" unless @i_klass.new.respond_to? :extface_devices
19
+ @i_extra_module = options[:controller_include].to_s.constantize if options[:controller_include].present?
20
+ end
21
+
22
+ def mount_point
23
+ "#{name}_billing"
24
+ end
25
+
26
+ class << self
27
+ def find(fullpath)
28
+ Billing.mappings[fullpath[%r{/(\w+)_billing\/}, 1]]
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,16 @@
1
+ module ActionDispatch::Routing
2
+ class Mapper
3
+ def billing_for(resource, options = {})
4
+ mapping = Billing.add_mapping(resource, options)
5
+ mount Billing::Engine, at: mapping.mount_point, as: [options[:as],:billing].compact.join('_')
6
+ get "#{mapping.mount_point}/accounts", to: "billing/accounts#index", as: options[:as] ? options[:as].to_s.pluralize.intern : :billing_accounts
7
+ get "#{mapping.mount_point}/accounts/:account_id", to: "billing/accounts#show", as: options[:as] ? options[:as].to_s.singularize.intern : :billing_account
8
+ get "#{mapping.mount_point}/accounts/:account_id/charges", to: "billing/charges#index", as: options[:as] ? "#{options[:as].to_s.singularize.intern}_charges" : :billing_account_charges
9
+ get "#{mapping.mount_point}/accounts/:account_id/charges/new", to: "billing/charges#new", as: options[:as] ? "#{options[:as].to_s.singularize.intern}_new_charge" : :billing_account_new_charge
10
+ get "#{mapping.mount_point}/accounts/:account_id/charges/:charge_id", to: "billing/charges#show", as: options[:as] ? "#{options[:as].to_s.singularize.intern}_charge" : :billing_account_charge
11
+ get "#{mapping.mount_point}/accounts/:account_id/payments", to: "billing/payments#index", as: options[:as] ? "#{options[:as].to_s.singularize.intern}_payments" : :billing_account_payments
12
+ get "#{mapping.mount_point}/accounts/:account_id/payments/new", to: "billing/payments#new", as: options[:as] ? "#{options[:as].to_s.singularize.intern}_new_payment" : :billing_account_new_payment
13
+ get "#{mapping.mount_point}/accounts/:account_id/payments/:payment_id", to: "billing/payments#show", as: options[:as] ? "#{options[:as].to_s.singularize.intern}_payment" : :billing_account_payment
14
+ end
15
+ end
16
+ end
@@ -1,3 +1,3 @@
1
1
  module Billing
2
- VERSION = "0.0.4d"
2
+ VERSION = "0.0.4"
3
3
  end
@@ -0,0 +1,19 @@
1
+ require 'test_helper'
2
+
3
+ module Billing
4
+ class AccountsControllerTest < ActionController::TestCase
5
+ setup do
6
+ @account = billing_accounts(:one)
7
+ end
8
+
9
+ test "should get index" do
10
+ get :index
11
+ assert_response :success
12
+ end
13
+
14
+ test "new" do
15
+ get :new
16
+ assert_response :success
17
+ end
18
+ end
19
+ end