auctify 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (115) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +229 -0
  4. data/Rakefile +34 -0
  5. data/app/assets/config/auctify_manifest.js +1 -0
  6. data/app/assets/javascripts/folio/console/main_app.coffee +1 -0
  7. data/app/assets/stylesheets/auctify/application.css +15 -0
  8. data/app/assets/stylesheets/auctify/bidder_registrations.css +4 -0
  9. data/app/assets/stylesheets/auctify/bids.css +4 -0
  10. data/app/assets/stylesheets/auctify/sales.css +4 -0
  11. data/app/assets/stylesheets/auctify/sales_packs.css +4 -0
  12. data/app/assets/stylesheets/folio/console/_main_app.sass +1 -0
  13. data/app/assets/stylesheets/scaffold.css +80 -0
  14. data/app/cells/folio/console/atoms/previews/main_app.coffee +1 -0
  15. data/app/concerns/auctify/behavior/base.rb +20 -0
  16. data/app/concerns/auctify/behavior/buyer.rb +16 -0
  17. data/app/concerns/auctify/behavior/item.rb +27 -0
  18. data/app/concerns/auctify/behavior/seller.rb +36 -0
  19. data/app/concerns/auctify/sale/auction_callbacks.rb +44 -0
  20. data/app/controllers/auctify/api/v1/auctions_controller.rb +61 -0
  21. data/app/controllers/auctify/api/v1/base_controller.rb +22 -0
  22. data/app/controllers/auctify/api/v1/console/bids_controller.rb +37 -0
  23. data/app/controllers/auctify/application_controller.rb +8 -0
  24. data/app/controllers/auctify/bidder_registrations_controller.rb +65 -0
  25. data/app/controllers/auctify/bids_controller.rb +64 -0
  26. data/app/controllers/auctify/sales_controller.rb +75 -0
  27. data/app/controllers/auctify/sales_packs_controller.rb +75 -0
  28. data/app/helpers/auctify/application_helper.rb +10 -0
  29. data/app/helpers/auctify/bidder_registrations_helper.rb +6 -0
  30. data/app/helpers/auctify/bids_helper.rb +6 -0
  31. data/app/helpers/auctify/sales_helper.rb +15 -0
  32. data/app/helpers/auctify/sales_packs_helper.rb +6 -0
  33. data/app/jobs/auctify/application_job.rb +6 -0
  34. data/app/jobs/auctify/bidding_closer_job.rb +23 -0
  35. data/app/jobs/auctify/bidding_is_close_to_end_notifier_job.rb +29 -0
  36. data/app/mailers/auctify/application_mailer.rb +8 -0
  37. data/app/models/auctify/application_record.rb +14 -0
  38. data/app/models/auctify/behaviors.rb +27 -0
  39. data/app/models/auctify/bid.rb +72 -0
  40. data/app/models/auctify/bidder_registration.rb +84 -0
  41. data/app/models/auctify/sale/auction.rb +404 -0
  42. data/app/models/auctify/sale/base.rb +210 -0
  43. data/app/models/auctify/sale/retail.rb +97 -0
  44. data/app/models/auctify/sales_pack.rb +101 -0
  45. data/app/serializers/auctify/sale/auction_serializer.rb +46 -0
  46. data/app/services/auctify/bids_appender.rb +241 -0
  47. data/app/services/auctify/service_base.rb +78 -0
  48. data/app/types/auctify/minimal_bids_ladder_type.rb +77 -0
  49. data/app/views/auctify/api/v1/console/bids/index.html.erb +1 -0
  50. data/app/views/auctify/api/v1/console/bids/show.html.erb +1 -0
  51. data/app/views/auctify/bidder_registrations/_form.html.erb +27 -0
  52. data/app/views/auctify/bidder_registrations/edit.html.erb +6 -0
  53. data/app/views/auctify/bidder_registrations/index.html.erb +33 -0
  54. data/app/views/auctify/bidder_registrations/new.html.erb +5 -0
  55. data/app/views/auctify/bidder_registrations/show.html.erb +24 -0
  56. data/app/views/auctify/bids/_form.html.erb +32 -0
  57. data/app/views/auctify/bids/edit.html.erb +6 -0
  58. data/app/views/auctify/bids/index.html.erb +31 -0
  59. data/app/views/auctify/bids/new.html.erb +5 -0
  60. data/app/views/auctify/bids/show.html.erb +19 -0
  61. data/app/views/auctify/sales/_form.html.erb +32 -0
  62. data/app/views/auctify/sales/edit.html.erb +6 -0
  63. data/app/views/auctify/sales/index.html.erb +36 -0
  64. data/app/views/auctify/sales/new.html.erb +5 -0
  65. data/app/views/auctify/sales/show.html.erb +19 -0
  66. data/app/views/auctify/sales_packs/_form.html.erb +57 -0
  67. data/app/views/auctify/sales_packs/edit.html.erb +6 -0
  68. data/app/views/auctify/sales_packs/index.html.erb +40 -0
  69. data/app/views/auctify/sales_packs/new.html.erb +5 -0
  70. data/app/views/auctify/sales_packs/show.html.erb +44 -0
  71. data/app/views/layouts/auctify/application.html.erb +15 -0
  72. data/config/locales/auctify.cs.yml +121 -0
  73. data/config/locales/default.cs.yml +220 -0
  74. data/config/locales/default.en.yml +215 -0
  75. data/config/routes.rb +23 -0
  76. data/db/migrate/20210212163000_create_auctify_sales.rb +16 -0
  77. data/db/migrate/20210216151350_add_type_to_auctify_sales.rb +7 -0
  78. data/db/migrate/20210217101246_add_state_to_auctify_sales.rb +7 -0
  79. data/db/migrate/20210217110819_add_prices_to_auctify_sales.rb +9 -0
  80. data/db/migrate/20210222103031_add_published_at_to_auctify_sale.rb +7 -0
  81. data/db/migrate/20210223090240_create_auctify_bidder_registrations.rb +15 -0
  82. data/db/migrate/20210223152139_create_auctify_bids.rb +13 -0
  83. data/db/migrate/20210225103227_add_bid_steps_ladder_to_auctify_sales.rb +7 -0
  84. data/db/migrate/20210412114319_add_reserve_price_to_auctify_sales.rb +7 -0
  85. data/db/migrate/20210416140603_create_auctify_sales_packs.rb +17 -0
  86. data/db/migrate/20210416141111_add_pack_reference_to_auctify_sales.rb +7 -0
  87. data/db/migrate/20210419075003_add_ends_at_to_auctify_sales.rb +7 -0
  88. data/db/migrate/20210419082800_add_position_to_auctify_sales.rb +8 -0
  89. data/db/migrate/20210419083321_add_indexes.rb +12 -0
  90. data/db/migrate/20210421093652_add_number_to_auctify_sales.rb +7 -0
  91. data/db/migrate/20210423071326_removing_polymorphic_assoc_sale_to_item.rb +7 -0
  92. data/db/migrate/20210423071534_add_currently_ends_at_to_auctify_sales.rb +7 -0
  93. data/db/migrate/20210427121353_change_column_published_on_auctify_sale.rb +15 -0
  94. data/db/migrate/20210427122315_add_featured_to_auctify_sales.rb +7 -0
  95. data/db/migrate/20210428045651_add_sales_bool_indices.rb +9 -0
  96. data/db/migrate/20210428064615_allow_seller_to_be_nil.rb +13 -0
  97. data/db/migrate/20210429051508_add_sales_pack_start_and_end.rb +15 -0
  98. data/db/migrate/20210430080419_add_sales_slug.rb +11 -0
  99. data/db/migrate/20210503095704_add_cancelled_to_auctify_bids.rb +7 -0
  100. data/db/migrate/20210504072041_add_commission_and_contract_to_auctify_sales.rb +8 -0
  101. data/db/migrate/20210506064100_add_winner_to_auctify_sales.rb +7 -0
  102. data/db/migrate/20210506072438_add_bids_count_to_auctify_sales.rb +7 -0
  103. data/db/migrate/20210507085845_rename_bids_count_to_applied_bids_count.rb +7 -0
  104. data/db/migrate/20210510063146_add_dont_confirm_bids_to_registrations.rb +7 -0
  105. data/db/migrate/20210511081556_add_index_on_cancelled_on.rb +7 -0
  106. data/db/migrate/20210512162942_add_sold_at_to_auctify_sales.rb +7 -0
  107. data/db/migrate/20210607113440_add_commission_in_percent_to_sales_packs.rb +7 -0
  108. data/db/migrate/20210617062509_add_index_to_auctify_sales_currently_ends_at.rb +7 -0
  109. data/db/migrate/20210625125732_add_current_winner_to_auctify_sales.rb +7 -0
  110. data/lib/auctify.rb +7 -0
  111. data/lib/auctify/configuration.rb +43 -0
  112. data/lib/auctify/engine.rb +25 -0
  113. data/lib/auctify/version.rb +5 -0
  114. data/lib/tasks/auctify_tasks.rake +23 -0
  115. metadata +442 -0
@@ -0,0 +1,210 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Auctify
4
+ module Sale
5
+ class Base < ApplicationRecord
6
+ include Folio::FriendlyId
7
+ include Folio::Positionable
8
+ include Folio::Featurable::Basic
9
+ include Folio::Publishable::Basic
10
+
11
+ self.table_name = "auctify_sales"
12
+
13
+ attribute :bid_steps_ladder, MinimalBidsLadderType.new
14
+
15
+ include Auctify::Behavior::Base
16
+
17
+ belongs_to :seller, polymorphic: true, optional: true
18
+ belongs_to :buyer, polymorphic: true, optional: true
19
+ # added on usage of `auctify_as :item` => belongs_to :item, class_name: ???
20
+ belongs_to :pack, class_name: "Auctify::SalesPack", inverse_of: :sales, optional: true, counter_cache: :sales_count
21
+
22
+ validate :valid_seller
23
+ validate :valid_item
24
+ validate :valid_buyer
25
+
26
+ validates :offered_price,
27
+ :current_price,
28
+ :sold_price,
29
+ :reserve_price,
30
+ numericality: { greater_than_or_equal_to: 0 },
31
+ allow_nil: true
32
+
33
+ validate :validate_offered_price_when_published
34
+
35
+ scope :not_sold, -> { where(sold_price: nil) }
36
+
37
+ # need auction scopes here because of has_many :sales, class_name: "Auctify::Sale::Base"
38
+ scope :auctions_open_for_bids, -> do
39
+ where(aasm_state: "in_sale").where("currently_ends_at > ?", Time.current)
40
+ end
41
+
42
+ scope :auctions_finished, -> do
43
+ where.not(aasm_state: %w[offered accepted refused]).where("currently_ends_at < ?", Time.current)
44
+ end
45
+
46
+ scope :latest_published_by_item, -> { joins(latest_published_sales_by_item_subtable.join_sources) }
47
+
48
+ delegate :to_label,
49
+ to: :item
50
+
51
+ def self.latest_published_sales_by_item_subtable
52
+ # see https://www.salsify.com/blog/engineering/most-recent-by-group-in-rails
53
+ sales_table = self.arel_table
54
+
55
+ latest_sales_query = sales_table.project(sales_table[:item_id],
56
+ sales_table[:id].maximum.as("latest_sale_id"))
57
+ .where(sales_table[:published].eq(true))
58
+ .group(sales_table[:item_id])
59
+
60
+ latest_sales_table = Arel::Table.new(latest_sales_query).alias(:latest_sales) # need to perform join
61
+
62
+ sales_table.join(latest_sales_query.as(latest_sales_table.name.to_s), Arel::Nodes::InnerJoin)
63
+ .on(sales_table[:id].eq(latest_sales_table[:latest_sale_id]))
64
+ end
65
+
66
+ def initialize(*args)
67
+ super
68
+
69
+ self.bid_steps_ladder = configuration.default_bid_steps_ladder if bid_steps_ladder.blank?
70
+ end
71
+
72
+ # need to cover wrong class of item before assigning
73
+ def item=(item)
74
+ @item = item
75
+ valid_item
76
+
77
+ super if errors.blank?
78
+ end
79
+
80
+ [:seller, :buyer, :item].each do |behavior|
81
+ define_method("#{behavior}_auctify_id=") do |auctify_id|
82
+ self.send("#{behavior}=", object_from_auctify_id(auctify_id))
83
+ end
84
+
85
+ define_method("#{behavior}_auctify_id") do
86
+ self.send("#{behavior}")&.auctify_id
87
+ end
88
+ end
89
+
90
+ def publish!
91
+ self.published = true
92
+ save
93
+ end
94
+
95
+ def auctioneer_commission
96
+ return nil if sold_price.nil?
97
+
98
+ percent = commission_in_percent \
99
+ || (pack&.commission_in_percent) \
100
+ || Auctify.configuration.auctioneer_commission_in_percent
101
+
102
+ sold_price * percent * 0.01
103
+ end
104
+
105
+ private
106
+ def valid_seller
107
+ return true if seller_id.blank?
108
+
109
+ db_seller = db_presence_of(seller)
110
+
111
+ errors.add(:seller, :required) unless db_seller.present?
112
+ end
113
+
114
+ def valid_item
115
+ item = @item || self.item
116
+ errors.delete(:item)
117
+
118
+ db_item = db_presence_of(item)
119
+ if db_item.present?
120
+ errors.add(:item, :already_on_sale_in_sales_pack, sale_pack_title: pack.title) if pack && pack.sales
121
+ .where(item: db_item)
122
+ .where.not(id: self.id)
123
+ .exists?
124
+ else
125
+ # Rails will add "required" on item.nil? automagically (and after this validation) but not for non-persisted item
126
+ # we do not allow creating sale along with item, so this trying to cover that
127
+ errors.add(:item, :required) unless item.blank? || errors.details[:item].include?({ error: :blank })
128
+ end
129
+ end
130
+
131
+ def valid_buyer
132
+ db_buyer = db_presence_of(buyer)
133
+ errors.add(:buyer, :required) if buyer.present? && db_buyer.blank?
134
+ end
135
+
136
+ def db_presence_of(record)
137
+ return nil if record.blank?
138
+
139
+ record.reload
140
+ rescue ActiveRecord::RecordNotFound
141
+ nil
142
+ end
143
+
144
+ def configuration
145
+ Auctify.configuration
146
+ end
147
+
148
+ def validate_offered_price_when_published
149
+ if published? && offered_price.blank?
150
+ errors.add(:offered_price, :required_for_published)
151
+ end
152
+ end
153
+
154
+ def slug_candidates
155
+ base = try(:item).try(:title).presence || self.class.model_name.human
156
+ year = Time.zone.now.year
157
+ [base, "#{base}-#{year}"] + 9.times.map { |i| "#{base}-#{year}-#{i + 2}" }
158
+ end
159
+ end
160
+ end
161
+ end
162
+
163
+ # == Schema Information
164
+ #
165
+ # Table name: auctify_sales
166
+ #
167
+ # id :bigint(8) not null, primary key
168
+ # seller_type :string
169
+ # seller_id :integer
170
+ # buyer_type :string
171
+ # buyer_id :integer
172
+ # item_id :integer not null
173
+ # created_at :datetime not null
174
+ # updated_at :datetime not null
175
+ # type :string default("Auctify::Sale::Base")
176
+ # aasm_state :string default("offered"), not null
177
+ # offered_price :decimal(, )
178
+ # current_price :decimal(, )
179
+ # sold_price :decimal(, )
180
+ # bid_steps_ladder :json
181
+ # reserve_price :decimal(, )
182
+ # pack_id :bigint(8)
183
+ # ends_at :datetime
184
+ # position :integer
185
+ # number :string
186
+ # currently_ends_at :datetime
187
+ # published :boolean default(FALSE)
188
+ # featured :boolean default(FALSE)
189
+ # slug :string
190
+ # contract_number :string
191
+ # commission_in_percent :integer
192
+ # winner_type :string
193
+ # winner_id :bigint(8)
194
+ # applied_bids_count :integer default(0)
195
+ # sold_at :datetime
196
+ # current_winner_type :string
197
+ # current_winner_id :bigint(8)
198
+ #
199
+ # Indexes
200
+ #
201
+ # index_auctify_sales_on_buyer_type_and_buyer_id (buyer_type,buyer_id)
202
+ # index_auctify_sales_on_currently_ends_at (currently_ends_at)
203
+ # index_auctify_sales_on_featured (featured)
204
+ # index_auctify_sales_on_pack_id (pack_id)
205
+ # index_auctify_sales_on_position (position)
206
+ # index_auctify_sales_on_published (published)
207
+ # index_auctify_sales_on_seller_type_and_seller_id (seller_type,seller_id)
208
+ # index_auctify_sales_on_slug (slug) UNIQUE
209
+ # index_auctify_sales_on_winner_type_and_winner_id (winner_type,winner_id)
210
+ #
@@ -0,0 +1,97 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Auctify
4
+ module Sale
5
+ class Retail < Auctify::Sale::Base
6
+ include AASM
7
+
8
+ aasm do
9
+ state :offered, initial: true, color: "red"
10
+ state :accepted, color: "red"
11
+ state :refused, color: "dark"
12
+ state :in_sale, color: "yellow"
13
+ state :sold, color: "green"
14
+ state :not_sold, color: "dark"
15
+ state :cancelled, color: "red"
16
+
17
+ event :accept_offer do
18
+ transitions from: :offered, to: :accepted
19
+ end
20
+
21
+ event :refuse_offer do
22
+ transitions from: :offered, to: :refused
23
+ end
24
+
25
+ event :start_sale do
26
+ transitions from: :accepted, to: :in_sale
27
+ end
28
+
29
+ event :sell do
30
+ transitions from: :in_sale, to: :sold
31
+ after do |*args| # TODO: sold_at
32
+ params = args.first # expecting keys :buyer, :price
33
+ self.buyer = params[:buyer]
34
+ self.sold_price = params[:price]
35
+ end
36
+ end
37
+
38
+ event :end_sale do
39
+ transitions from: :in_sale, to: :not_sold
40
+ end
41
+
42
+ event :cancel do
43
+ transitions from: [:offered, :accepted], to: :cancelled
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+
50
+ # == Schema Information
51
+ #
52
+ # Table name: auctify_sales
53
+ #
54
+ # id :bigint(8) not null, primary key
55
+ # seller_type :string
56
+ # seller_id :integer
57
+ # buyer_type :string
58
+ # buyer_id :integer
59
+ # item_id :integer not null
60
+ # created_at :datetime not null
61
+ # updated_at :datetime not null
62
+ # type :string default("Auctify::Sale::Base")
63
+ # aasm_state :string default("offered"), not null
64
+ # offered_price :decimal(, )
65
+ # current_price :decimal(, )
66
+ # sold_price :decimal(, )
67
+ # bid_steps_ladder :json
68
+ # reserve_price :decimal(, )
69
+ # pack_id :bigint(8)
70
+ # ends_at :datetime
71
+ # position :integer
72
+ # number :string
73
+ # currently_ends_at :datetime
74
+ # published :boolean default(FALSE)
75
+ # featured :boolean default(FALSE)
76
+ # slug :string
77
+ # contract_number :string
78
+ # commission_in_percent :integer
79
+ # winner_type :string
80
+ # winner_id :bigint(8)
81
+ # applied_bids_count :integer default(0)
82
+ # sold_at :datetime
83
+ # current_winner_type :string
84
+ # current_winner_id :bigint(8)
85
+ #
86
+ # Indexes
87
+ #
88
+ # index_auctify_sales_on_buyer_type_and_buyer_id (buyer_type,buyer_id)
89
+ # index_auctify_sales_on_currently_ends_at (currently_ends_at)
90
+ # index_auctify_sales_on_featured (featured)
91
+ # index_auctify_sales_on_pack_id (pack_id)
92
+ # index_auctify_sales_on_position (position)
93
+ # index_auctify_sales_on_published (published)
94
+ # index_auctify_sales_on_seller_type_and_seller_id (seller_type,seller_id)
95
+ # index_auctify_sales_on_slug (slug) UNIQUE
96
+ # index_auctify_sales_on_winner_type_and_winner_id (winner_type,winner_id)
97
+ #
@@ -0,0 +1,101 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Auctify
4
+ class SalesPack < ApplicationRecord
5
+ include Folio::FriendlyId
6
+ include Folio::HasAttachments
7
+ include Folio::Positionable
8
+ include Folio::Publishable::Basic
9
+ include Folio::Sitemap::Base
10
+
11
+ has_many :sales, class_name: "Auctify::Sale::Base", foreign_key: :pack_id, inverse_of: :pack, dependent: :restrict_with_error
12
+ has_many :items, through: :sales
13
+
14
+ validates :title,
15
+ presence: true,
16
+ uniqueness: true
17
+
18
+ validates :start_date,
19
+ :end_date,
20
+ presence: true
21
+
22
+ validates :sales_interval,
23
+ numericality: { greater_than: 0, less_than: 240 }
24
+
25
+ validates :sales_beginning_hour,
26
+ numericality: { greater_than_or_equal: 0, less_than: 24 }
27
+
28
+ validates :sales_beginning_minutes,
29
+ numericality: { greater_than_or_equal: 0, less_than: 60 }
30
+
31
+ validate :validate_start_and_end_dates
32
+
33
+ scope :ordered, -> { order(start_date: :desc, id: :desc) }
34
+
35
+ pg_search_scope :by_query,
36
+ against: %i[title],
37
+ ignoring: :accents,
38
+ using: { tsearch: { prefix: true } }
39
+
40
+ after_initialize :set_commission
41
+
42
+ def to_label
43
+ title
44
+ end
45
+
46
+ def dates_to_label
47
+ if start_date && end_date
48
+ if start_date.year == end_date.year
49
+ if start_date.month == end_date.month
50
+ "#{start_date.strftime('%-d.')}–#{end_date.strftime('%-d. %-m. %y')}"
51
+ else
52
+ "#{start_date.strftime('%-d. %-m.')} – #{end_date.strftime('%-d. %-m. %y')}"
53
+ end
54
+ else
55
+ "#{start_date.strftime('%-d. %-m. %y')} – #{end_date.strftime('%-d. %-m. %y')}"
56
+ end
57
+ end
58
+ end
59
+
60
+ private
61
+ def validate_start_and_end_dates
62
+ if start_date.present? && end_date.present? && start_date > end_date
63
+ errors.add(:end_date, :smaller_than_start_date)
64
+ end
65
+ end
66
+
67
+ def set_commission
68
+ return if self.commission_in_percent.present?
69
+
70
+ self.commission_in_percent = Auctify.configuration.auctioneer_commission_in_percent
71
+ end
72
+ end
73
+ end
74
+
75
+ # == Schema Information
76
+ #
77
+ # Table name: auctify_sales_packs
78
+ #
79
+ # id :bigint(8) not null, primary key
80
+ # title :string
81
+ # description :text
82
+ # position :integer default(0)
83
+ # slug :string
84
+ # place :string
85
+ # published :boolean default(FALSE)
86
+ # created_at :datetime not null
87
+ # updated_at :datetime not null
88
+ # sales_count :integer default(0)
89
+ # start_date :date
90
+ # end_date :date
91
+ # sales_interval :integer default(3)
92
+ # sales_beginning_hour :integer default(20)
93
+ # sales_beginning_minutes :integer default(0)
94
+ # commission_in_percent :integer
95
+ #
96
+ # Indexes
97
+ #
98
+ # index_auctify_sales_packs_on_position (position)
99
+ # index_auctify_sales_packs_on_published (published)
100
+ # index_auctify_sales_packs_on_slug (slug) UNIQUE
101
+ #
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Auctify::Sale::AuctionSerializer
4
+ include FastJsonapi::ObjectSerializer
5
+
6
+ attributes :id,
7
+ :current_price,
8
+ :current_minimal_bid,
9
+ :currently_ends_at,
10
+ :ends_at,
11
+ :open_for_bids?
12
+
13
+ attribute :current_winner do |auction|
14
+ winner = auction.current_winner
15
+ {
16
+ id: winner.id,
17
+ auctify_id: winner.auctify_id,
18
+ to_label: winner.to_label
19
+ }
20
+ end
21
+
22
+
23
+
24
+
25
+
26
+ # assert_equal auction.current_winner.id, json_attributes["current_winner"]["id"]
27
+ # assert_equal auction.current_winner.auctify_id, json_attributes["current_winner"]["auctify_id"]
28
+ # assert_equal auction.current_winner.to_label, json_attributes["current_winner"]["to_label"]
29
+ # assert_equal auction.current_price, json_attributes["current_price"]
30
+ # assert_equal auction.current_minimal_bid, json_attributes["current_minimal_bid"]
31
+ # assert_equal auction.ends_at, json_attributes["ends_at"]
32
+ # assert_equal auction.currently_ends_at, json_attributes["currently_ends_at"]
33
+ # assert_equal auction.open_for_bids?, json_attributes["open_for_bids?"]
34
+
35
+
36
+ # attributes :name, :year
37
+ # has_many :actors
38
+ # belongs_to :owner, record_type: :user
39
+ # belongs_to :movie_ty
40
+ # # link :url do |object|
41
+ # # Rails.application
42
+ # # .routes
43
+ # # .url_helpers
44
+ # # .url_for([object, only_path: true])
45
+ # # end
46
+ end