Added build_completed_partially status for ProductBuildList
This commit is contained in:
parent
264ea371f6
commit
41d72ce87a
|
@ -82,7 +82,9 @@ class Platforms::ProductBuildListsController < Platforms::BaseController
|
||||||
scoped_to_product_name(@product_build_list.product_name).
|
scoped_to_product_name(@product_build_list.product_name).
|
||||||
for_status(@product_build_list.status)
|
for_status(@product_build_list.status)
|
||||||
end
|
end
|
||||||
@product_build_lists = @product_build_lists.recent.paginate page: params[:page]
|
@product_build_lists = @product_build_lists.
|
||||||
|
includes(:project, product: :platform).
|
||||||
|
recent.paginate(page: params[:page])
|
||||||
@build_server_status = AbfWorkerStatusPresenter.new.products_status
|
@build_server_status = AbfWorkerStatusPresenter.new.products_status
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,14 @@ module AbfWorker
|
||||||
when COMPLETED
|
when COMPLETED
|
||||||
subject.build_success
|
subject.build_success
|
||||||
when FAILED
|
when FAILED
|
||||||
subject.build_error
|
|
||||||
|
case options['exit_status'].to_i
|
||||||
|
when ProductBuildList::BUILD_COMPLETED_PARTIALLY
|
||||||
|
subject.build_success_partially
|
||||||
|
else
|
||||||
|
subject.build_error
|
||||||
|
end
|
||||||
|
|
||||||
when STARTED
|
when STARTED
|
||||||
subject.start_build
|
subject.start_build
|
||||||
when CANCELED
|
when CANCELED
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
# Internal: various definitions and instance methods related to AbfWorker.
|
||||||
|
#
|
||||||
|
# This module gets mixed in into ProductBuildList class.
|
||||||
|
module ProductBuildList::AbfWorkerable
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
CACHED_CHROOT_TOKEN_DESCRIPTION = 'cached-chroot'
|
||||||
|
|
||||||
|
include AbfWorkerMethods
|
||||||
|
|
||||||
|
included do
|
||||||
|
delegate :url_helpers, to: 'Rails.application.routes'
|
||||||
|
|
||||||
|
after_create :add_job_to_abf_worker_queue
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
######################################
|
||||||
|
# Instance methods #
|
||||||
|
######################################
|
||||||
|
|
||||||
|
def sha1_of_file_store_files
|
||||||
|
(results || []).map{ |r| r['sha1'] }.compact
|
||||||
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
def abf_worker_priority
|
||||||
|
''
|
||||||
|
end
|
||||||
|
|
||||||
|
def abf_worker_base_queue
|
||||||
|
'iso_worker'
|
||||||
|
end
|
||||||
|
|
||||||
|
def abf_worker_args
|
||||||
|
file_name = "#{project.name}-#{commit_hash}"
|
||||||
|
opts = default_url_options
|
||||||
|
opts.merge!({user: user.authentication_token, password: ''}) if user.present?
|
||||||
|
srcpath = url_helpers.archive_url(
|
||||||
|
project.name_with_owner,
|
||||||
|
file_name,
|
||||||
|
'tar.gz',
|
||||||
|
opts
|
||||||
|
)
|
||||||
|
|
||||||
|
cmd_params = "BUILD_ID=#{id} "
|
||||||
|
if product.platform.hidden?
|
||||||
|
token = product.platform.tokens.by_active.where(description: CACHED_CHROOT_TOKEN_DESCRIPTION).first
|
||||||
|
cmd_params << "TOKEN=#{token.authentication_token} " if token
|
||||||
|
end
|
||||||
|
cmd_params << params.to_s
|
||||||
|
|
||||||
|
{
|
||||||
|
id: id,
|
||||||
|
srcpath: srcpath,
|
||||||
|
params: cmd_params,
|
||||||
|
time_living: time_living,
|
||||||
|
main_script: main_script,
|
||||||
|
platform: {
|
||||||
|
type: product.platform.distrib_type,
|
||||||
|
name: product.platform.name,
|
||||||
|
arch: arch.name
|
||||||
|
},
|
||||||
|
user: {uname: user.try(:uname), email: user.try(:email)}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,117 @@
|
||||||
|
# Internal: various definitions and instance methods related to status.
|
||||||
|
#
|
||||||
|
# This module gets mixed in into ProductBuildList class.
|
||||||
|
module ProductBuildList::Statusable
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
BUILD_COMPLETED = 0
|
||||||
|
BUILD_FAILED = 1
|
||||||
|
BUILD_PENDING = 2
|
||||||
|
BUILD_STARTED = 3
|
||||||
|
BUILD_CANCELED = 4
|
||||||
|
BUILD_CANCELING = 5
|
||||||
|
BUILD_COMPLETED_PARTIALLY = 6
|
||||||
|
|
||||||
|
STATUSES = [
|
||||||
|
BUILD_STARTED,
|
||||||
|
BUILD_COMPLETED,
|
||||||
|
BUILD_COMPLETED_PARTIALLY,
|
||||||
|
BUILD_FAILED,
|
||||||
|
BUILD_PENDING,
|
||||||
|
BUILD_CANCELED,
|
||||||
|
BUILD_CANCELING
|
||||||
|
].freeze
|
||||||
|
|
||||||
|
HUMAN_STATUSES = {
|
||||||
|
BUILD_STARTED => :build_started,
|
||||||
|
BUILD_COMPLETED => :build_completed,
|
||||||
|
BUILD_COMPLETED_PARTIALLY => :build_completed_partially,
|
||||||
|
BUILD_FAILED => :build_failed,
|
||||||
|
BUILD_PENDING => :build_pending,
|
||||||
|
BUILD_CANCELED => :build_canceled,
|
||||||
|
BUILD_CANCELING => :build_canceling
|
||||||
|
}.freeze
|
||||||
|
|
||||||
|
|
||||||
|
included do
|
||||||
|
|
||||||
|
scope :for_status, -> (status) { where(status: status) if status.present? }
|
||||||
|
|
||||||
|
validates :status,
|
||||||
|
presence: true,
|
||||||
|
inclusion: { in: STATUSES }
|
||||||
|
|
||||||
|
attr_accessible :status
|
||||||
|
|
||||||
|
before_destroy :can_destroy?
|
||||||
|
|
||||||
|
state_machine :status, initial: :build_pending do
|
||||||
|
|
||||||
|
event :start_build do
|
||||||
|
transition build_pending: :build_started
|
||||||
|
end
|
||||||
|
|
||||||
|
event :cancel do
|
||||||
|
transition [:build_pending, :build_started] => :build_canceling
|
||||||
|
end
|
||||||
|
after_transition on: :cancel, do: :cancel_job
|
||||||
|
|
||||||
|
# build_canceling: :build_canceled - canceling from UI
|
||||||
|
# build_started: :build_canceled - canceling from worker by time-out (time_living has been expired)
|
||||||
|
event :build_canceled do
|
||||||
|
transition [:build_canceling, :build_started] => :build_canceled
|
||||||
|
end
|
||||||
|
|
||||||
|
# build_canceling: :build_completed - Worker hasn't time to cancel building because build had been already completed
|
||||||
|
event :build_success do
|
||||||
|
transition [:build_started, :build_canceling] => :build_completed
|
||||||
|
end
|
||||||
|
|
||||||
|
# build_canceling: :build_completed - Worker hasn't time to cancel building because build had been already completed
|
||||||
|
event :build_success_partially do
|
||||||
|
transition [:build_started, :build_canceling] => :build_completed_partially
|
||||||
|
end
|
||||||
|
|
||||||
|
# build_canceling: :build_failed - Worker hasn't time to cancel building because build had been already failed
|
||||||
|
event :build_error do
|
||||||
|
transition [:build_started, :build_canceling] => :build_failed
|
||||||
|
end
|
||||||
|
|
||||||
|
HUMAN_STATUSES.each do |code,name|
|
||||||
|
state name, value: code
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
module ClassMethods
|
||||||
|
def human_status(status)
|
||||||
|
I18n.t("layout.product_build_lists.statuses.#{HUMAN_STATUSES[status]}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
######################################
|
||||||
|
# Instance methods #
|
||||||
|
######################################
|
||||||
|
|
||||||
|
def build_started?
|
||||||
|
status == BUILD_STARTED
|
||||||
|
end
|
||||||
|
|
||||||
|
def build_canceling?
|
||||||
|
status == BUILD_CANCELING
|
||||||
|
end
|
||||||
|
|
||||||
|
def can_destroy?
|
||||||
|
[BUILD_STARTED, BUILD_PENDING, BUILD_CANCELING].exclude?(status)
|
||||||
|
end
|
||||||
|
|
||||||
|
def can_cancel?
|
||||||
|
[BUILD_STARTED, BUILD_PENDING].include?(status)
|
||||||
|
end
|
||||||
|
|
||||||
|
def human_status
|
||||||
|
self.class.human_status(status)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -3,39 +3,13 @@ class ProductBuildList < ActiveRecord::Base
|
||||||
include TimeLiving
|
include TimeLiving
|
||||||
include FileStoreClean
|
include FileStoreClean
|
||||||
include UrlHelper
|
include UrlHelper
|
||||||
include AbfWorkerMethods
|
|
||||||
include EventLoggable
|
include EventLoggable
|
||||||
|
include ProductBuildList::Statusable
|
||||||
delegate :url_helpers, to: 'Rails.application.routes'
|
include ProductBuildList::AbfWorkerable
|
||||||
|
|
||||||
LIVE_TIME = 2.week # for autostart
|
LIVE_TIME = 2.week # for autostart
|
||||||
MAX_LIVE_TIME = 3.month # for manual start;
|
MAX_LIVE_TIME = 3.month # for manual start;
|
||||||
|
|
||||||
BUILD_COMPLETED = 0
|
|
||||||
BUILD_FAILED = 1
|
|
||||||
BUILD_PENDING = 2
|
|
||||||
BUILD_STARTED = 3
|
|
||||||
BUILD_CANCELED = 4
|
|
||||||
BUILD_CANCELING = 5
|
|
||||||
|
|
||||||
STATUSES = [ BUILD_STARTED,
|
|
||||||
BUILD_COMPLETED,
|
|
||||||
BUILD_FAILED,
|
|
||||||
BUILD_PENDING,
|
|
||||||
BUILD_CANCELED,
|
|
||||||
BUILD_CANCELING
|
|
||||||
].freeze
|
|
||||||
|
|
||||||
HUMAN_STATUSES = { BUILD_STARTED => :build_started,
|
|
||||||
BUILD_COMPLETED => :build_completed,
|
|
||||||
BUILD_FAILED => :build_failed,
|
|
||||||
BUILD_PENDING => :build_pending,
|
|
||||||
BUILD_CANCELED => :build_canceled,
|
|
||||||
BUILD_CANCELING => :build_canceling
|
|
||||||
}.freeze
|
|
||||||
|
|
||||||
CACHED_CHROOT_TOKEN_DESCRIPTION = 'cached-chroot'
|
|
||||||
|
|
||||||
belongs_to :product
|
belongs_to :product
|
||||||
belongs_to :project
|
belongs_to :project
|
||||||
belongs_to :arch
|
belongs_to :arch
|
||||||
|
@ -47,17 +21,14 @@ class ProductBuildList < ActiveRecord::Base
|
||||||
before_validation -> { self.not_delete = false unless build_completed?; true }
|
before_validation -> { self.not_delete = false unless build_completed?; true }
|
||||||
|
|
||||||
validates :product, :product_id,
|
validates :product, :product_id,
|
||||||
:status,
|
|
||||||
:project, :project_id,
|
:project, :project_id,
|
||||||
:main_script,
|
:main_script,
|
||||||
:arch, :arch_id,
|
:arch, :arch_id,
|
||||||
presence: true
|
presence: true
|
||||||
validates :status, inclusion: { in: STATUSES }
|
|
||||||
validates :main_script, :params, length: { maximum: 255 }
|
validates :main_script, :params, length: { maximum: 255 }
|
||||||
|
|
||||||
attr_accessor :base_url, :product_name
|
attr_accessor :base_url, :product_name
|
||||||
attr_accessible :status,
|
attr_accessible :base_url,
|
||||||
:base_url,
|
|
||||||
:branch,
|
:branch,
|
||||||
:project_id,
|
:project_id,
|
||||||
:main_script,
|
:main_script,
|
||||||
|
@ -73,7 +44,6 @@ class ProductBuildList < ActiveRecord::Base
|
||||||
|
|
||||||
|
|
||||||
scope :default_order, -> { order(updated_at: :desc) }
|
scope :default_order, -> { order(updated_at: :desc) }
|
||||||
scope :for_status, -> (status) { where(status: status) if status.present? }
|
|
||||||
scope :for_user, -> (user) { where(user_id: user.id) }
|
scope :for_user, -> (user) { where(user_id: user.id) }
|
||||||
scope :scoped_to_product_name, -> (product_name) {
|
scope :scoped_to_product_name, -> (product_name) {
|
||||||
joins(:product).where('products.name LIKE ?', "%#{product_name}%") if product_name.present?
|
joins(:product).where('products.name LIKE ?', "%#{product_name}%") if product_name.present?
|
||||||
|
@ -87,123 +57,14 @@ class ProductBuildList < ActiveRecord::Base
|
||||||
|
|
||||||
after_initialize :init_project, if: :new_record?
|
after_initialize :init_project, if: :new_record?
|
||||||
|
|
||||||
after_create :add_job_to_abf_worker_queue
|
|
||||||
before_destroy :can_destroy?
|
|
||||||
|
|
||||||
state_machine :status, initial: :build_pending do
|
|
||||||
|
|
||||||
event :start_build do
|
|
||||||
transition build_pending: :build_started
|
|
||||||
end
|
|
||||||
|
|
||||||
event :cancel do
|
|
||||||
transition [:build_pending, :build_started] => :build_canceling
|
|
||||||
end
|
|
||||||
after_transition on: :cancel, do: :cancel_job
|
|
||||||
|
|
||||||
# build_canceling: :build_canceled - canceling from UI
|
|
||||||
# build_started: :build_canceled - canceling from worker by time-out (time_living has been expired)
|
|
||||||
event :build_canceled do
|
|
||||||
transition [:build_canceling, :build_started] => :build_canceled
|
|
||||||
end
|
|
||||||
|
|
||||||
# build_canceling: :build_completed - Worker hasn't time to cancel building because build had been already completed
|
|
||||||
event :build_success do
|
|
||||||
transition [:build_started, :build_canceling] => :build_completed
|
|
||||||
end
|
|
||||||
|
|
||||||
# build_canceling: :build_failed - Worker hasn't time to cancel building because build had been already failed
|
|
||||||
event :build_error do
|
|
||||||
transition [:build_started, :build_canceling] => :build_failed
|
|
||||||
end
|
|
||||||
|
|
||||||
HUMAN_STATUSES.each do |code,name|
|
|
||||||
state name, value: code
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def build_started?
|
|
||||||
status == BUILD_STARTED
|
|
||||||
end
|
|
||||||
|
|
||||||
def build_canceling?
|
|
||||||
status == BUILD_CANCELING
|
|
||||||
end
|
|
||||||
|
|
||||||
def can_destroy?
|
|
||||||
![BUILD_STARTED, BUILD_PENDING, BUILD_CANCELING].include?(status)
|
|
||||||
end
|
|
||||||
|
|
||||||
def can_cancel?
|
|
||||||
[BUILD_STARTED, BUILD_PENDING].include?(status)
|
|
||||||
end
|
|
||||||
|
|
||||||
def event_log_message
|
def event_log_message
|
||||||
{product: product.name}.inspect
|
{product: product.name}.inspect
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.human_status(status)
|
|
||||||
I18n.t("layout.product_build_lists.statuses.#{HUMAN_STATUSES[status]}")
|
|
||||||
end
|
|
||||||
|
|
||||||
def human_status
|
|
||||||
self.class.human_status(status)
|
|
||||||
end
|
|
||||||
|
|
||||||
def can_destroy?
|
|
||||||
[BUILD_COMPLETED, BUILD_FAILED, BUILD_CANCELED].include? status
|
|
||||||
end
|
|
||||||
|
|
||||||
def sha1_of_file_store_files
|
|
||||||
(results || []).map{ |r| r['sha1'] }.compact
|
|
||||||
end
|
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def init_project
|
def init_project
|
||||||
self.project ||= product.try(:project)
|
self.project ||= product.try(:project)
|
||||||
end
|
end
|
||||||
|
|
||||||
def abf_worker_priority
|
|
||||||
''
|
|
||||||
end
|
|
||||||
|
|
||||||
def abf_worker_base_queue
|
|
||||||
'iso_worker'
|
|
||||||
end
|
|
||||||
|
|
||||||
def abf_worker_args
|
|
||||||
file_name = "#{project.name}-#{commit_hash}"
|
|
||||||
opts = default_url_options
|
|
||||||
opts.merge!({user: user.authentication_token, password: ''}) if user.present?
|
|
||||||
srcpath = url_helpers.archive_url(
|
|
||||||
project.name_with_owner,
|
|
||||||
file_name,
|
|
||||||
'tar.gz',
|
|
||||||
opts
|
|
||||||
)
|
|
||||||
|
|
||||||
cmd_params = "BUILD_ID=#{id} "
|
|
||||||
if product.platform.hidden?
|
|
||||||
token = product.platform.tokens.by_active.where(description: CACHED_CHROOT_TOKEN_DESCRIPTION).first
|
|
||||||
cmd_params << "TOKEN=#{token.authentication_token} " if token
|
|
||||||
end
|
|
||||||
cmd_params << params.to_s
|
|
||||||
|
|
||||||
{
|
|
||||||
id: id,
|
|
||||||
# TODO: remove comment
|
|
||||||
# srcpath: 'http://dl.dropbox.com/u/945501/avokhmin-test-iso-script-5d9b463d4e9c06ea8e7c89e1b7ff5cb37e99e27f.tar.gz',
|
|
||||||
srcpath: srcpath,
|
|
||||||
params: cmd_params,
|
|
||||||
time_living: time_living,
|
|
||||||
main_script: main_script,
|
|
||||||
platform: {
|
|
||||||
type: product.platform.distrib_type,
|
|
||||||
name: product.platform.name,
|
|
||||||
arch: arch.name
|
|
||||||
},
|
|
||||||
user: {uname: user.try(:uname), email: user.try(:email)}
|
|
||||||
}
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,14 +9,11 @@ tr
|
||||||
- else
|
- else
|
||||||
td= pbl.id
|
td= pbl.id
|
||||||
td= pbl.human_status
|
td= pbl.human_status
|
||||||
td
|
|
||||||
- unless pbl.project
|
|
||||||
= link_to(nil, pbl.container_path)
|
|
||||||
td
|
td
|
||||||
a href=platform_product_path(platform, product)
|
a href=platform_product_path(platform, product)
|
||||||
= pbl.product.name
|
= pbl.product.name
|
||||||
td.text-center
|
td.text-center
|
||||||
- if can?(:destroy, pbl) && pbl.can_destroy? && !pbl.project
|
- if can?(:destroy, pbl) && pbl.can_destroy?
|
||||||
= link_to platform_product_product_build_list_path(platform, product, pbl), method: :delete, data: { confirm: t('layout.confirm') } do
|
= link_to platform_product_product_build_list_path(platform, product, pbl), method: :delete, data: { confirm: t('layout.confirm') } do
|
||||||
span.glyphicon.glyphicon-remove
|
span.glyphicon.glyphicon-remove
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
tr
|
tr
|
||||||
th= t("activerecord.attributes.product_build_list.id")
|
th= t("activerecord.attributes.product_build_list.id")
|
||||||
th= t("activerecord.attributes.product_build_list.status")
|
th= t("activerecord.attributes.product_build_list.status")
|
||||||
th= t("activerecord.attributes.product_build_list.container_path")
|
|
||||||
th= t("activerecord.attributes.product_build_list.product")
|
th= t("activerecord.attributes.product_build_list.product")
|
||||||
th= t("layout.product_build_lists.action")
|
th= t("layout.product_build_lists.action")
|
||||||
th= t("activerecord.attributes.product_build_list.notified_at")
|
th= t("activerecord.attributes.product_build_list.notified_at")
|
||||||
|
|
|
@ -40,7 +40,6 @@
|
||||||
tr
|
tr
|
||||||
th= t("activerecord.attributes.product_build_list.id")
|
th= t("activerecord.attributes.product_build_list.id")
|
||||||
th= t("activerecord.attributes.product_build_list.status")
|
th= t("activerecord.attributes.product_build_list.status")
|
||||||
th= t("activerecord.attributes.product_build_list.container_path")
|
|
||||||
th= t("activerecord.attributes.product_build_list.product")
|
th= t("activerecord.attributes.product_build_list.product")
|
||||||
th= t("layout.product_build_lists.action")
|
th= t("layout.product_build_lists.action")
|
||||||
th= t("activerecord.attributes.product_build_list.notified_at")
|
th= t("activerecord.attributes.product_build_list.notified_at")
|
||||||
|
|
|
@ -21,6 +21,7 @@ en:
|
||||||
build_started: Build started
|
build_started: Build started
|
||||||
build_canceled: Build canceled
|
build_canceled: Build canceled
|
||||||
build_canceling: Build is canceling
|
build_canceling: Build is canceling
|
||||||
|
build_completed_partially: Build complete (partially)
|
||||||
|
|
||||||
ownership:
|
ownership:
|
||||||
header: Build list ownership
|
header: Build list ownership
|
||||||
|
@ -36,7 +37,6 @@ en:
|
||||||
id: Id
|
id: Id
|
||||||
user: User
|
user: User
|
||||||
product: Product
|
product: Product
|
||||||
container_path: Container
|
|
||||||
status: Status
|
status: Status
|
||||||
user: User
|
user: User
|
||||||
notified_at: Notified at
|
notified_at: Notified at
|
||||||
|
|
|
@ -21,6 +21,7 @@ ru:
|
||||||
build_started: Собирается
|
build_started: Собирается
|
||||||
build_canceled: Сборка отменена
|
build_canceled: Сборка отменена
|
||||||
build_canceling: Сборка отменяется
|
build_canceling: Сборка отменяется
|
||||||
|
build_completed_partially: Собран (частично)
|
||||||
|
|
||||||
ownership:
|
ownership:
|
||||||
header: Принадлежность заданий
|
header: Принадлежность заданий
|
||||||
|
@ -36,7 +37,6 @@ ru:
|
||||||
id: Id
|
id: Id
|
||||||
user: Пользователь
|
user: Пользователь
|
||||||
product: Продукт
|
product: Продукт
|
||||||
container_path: Контейнер
|
|
||||||
status: Статус
|
status: Статус
|
||||||
user: Пользователь
|
user: Пользователь
|
||||||
notified_at: Информация получена
|
notified_at: Информация получена
|
||||||
|
|
|
@ -12,28 +12,28 @@ describe ProductBuildList do
|
||||||
it 'is valid given valid attributes' do
|
it 'is valid given valid attributes' do
|
||||||
arch = FactoryGirl.create(:arch, name: 'x86_64')
|
arch = FactoryGirl.create(:arch, name: 'x86_64')
|
||||||
allow(Arch).to receive(:find_by).with(name: 'x86_64').and_return(arch)
|
allow(Arch).to receive(:find_by).with(name: 'x86_64').and_return(arch)
|
||||||
FactoryGirl.create(:product_build_list).should be_truthy
|
expect(FactoryGirl.create(:product_build_list)).to be_truthy
|
||||||
end
|
end
|
||||||
|
|
||||||
it { should belong_to(:product) }
|
it { is_expected.to belong_to(:product) }
|
||||||
|
|
||||||
it { should ensure_length_of(:main_script).is_at_most(255) }
|
it { is_expected.to validate_length_of(:main_script).is_at_most(255) }
|
||||||
it { should ensure_length_of(:params).is_at_most(255) }
|
it { is_expected.to validate_length_of(:params).is_at_most(255) }
|
||||||
|
|
||||||
it { should validate_presence_of(:product_id) }
|
it { is_expected.to validate_presence_of(:product_id) }
|
||||||
it { should validate_presence_of(:status) }
|
it { is_expected.to validate_presence_of(:status) }
|
||||||
|
|
||||||
ProductBuildList::STATUSES.each do |value|
|
ProductBuildList::STATUSES.each do |value|
|
||||||
it { should allow_value(value).for(:status) }
|
it { is_expected.to allow_value(value).for(:status) }
|
||||||
end
|
end
|
||||||
|
|
||||||
it { should_not allow_value(555).for(:status) }
|
it { is_expected.to_not allow_value(555).for(:status) }
|
||||||
|
|
||||||
it { should have_readonly_attribute(:product_id) }
|
it { is_expected.to have_readonly_attribute(:product_id) }
|
||||||
#it { should_not allow_mass_assignment_of(:product_id) }
|
#it { should_not allow_mass_assignment_of(:product_id) }
|
||||||
|
|
||||||
it { should allow_mass_assignment_of(:status) }
|
it { is_expected.to allow_mass_assignment_of(:status) }
|
||||||
it { should allow_mass_assignment_of(:base_url) }
|
it { is_expected.to allow_mass_assignment_of(:base_url) }
|
||||||
end
|
end
|
||||||
|
|
||||||
# see app/ability.rb
|
# see app/ability.rb
|
||||||
|
@ -43,6 +43,6 @@ describe ProductBuildList do
|
||||||
FactoryGirl.create(:product_build_list)
|
FactoryGirl.create(:product_build_list)
|
||||||
user = FactoryGirl.create(:user)
|
user = FactoryGirl.create(:user)
|
||||||
ability = Ability.new user
|
ability = Ability.new user
|
||||||
ProductBuildList.accessible_by(ability).count.should == 1
|
expect(ProductBuildList.accessible_by(ability).count).to eq 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue