Merge branch 'master' of gitlab.com:gitlab-org/gitlab-ce into bitbucket-oauth2

This commit is contained in:
Valery Sizov 2016-12-14 20:19:43 +02:00
commit 076cdd2044
85 changed files with 1347 additions and 212 deletions

View file

@ -232,6 +232,7 @@
&:hover:not(.active) {
background-color: $gray-lightest;
box-shadow: inset 2px 0 0 0 $border-color;
cursor: pointer;
}
&:first-child {

View file

@ -4,25 +4,7 @@ module CiStatusHelper
builds_namespace_project_commit_path(project.namespace, project, pipeline.sha)
end
def ci_status_with_icon(status, target = nil)
content = ci_icon_for_status(status) + ci_text_for_status(status)
klass = "ci-status ci-#{status}"
if target
link_to content, target, class: klass
else
content_tag :span, content, class: klass
end
end
def ci_text_for_status(status)
if detailed_status?(status)
status.text
else
status
end
end
# Is used by Commit and Merge Request Widget
def ci_label_for_status(status)
if detailed_status?(status)
return status.label

View file

@ -100,6 +100,12 @@ module Ci
end
end
def detailed_status(current_user)
Gitlab::Ci::Status::Build::Factory
.new(self, current_user)
.fabricate!
end
def manual?
self.when == 'manual'
end
@ -123,8 +129,13 @@ module Ci
end
end
def cancelable?
active?
end
def retryable?
project.builds_enabled? && commands.present? && complete?
project.builds_enabled? && commands.present? &&
(success? || failed? || canceled?)
end
def retried?
@ -148,7 +159,7 @@ module Ci
end
def environment_action
self.options.fetch(:environment, {}).fetch(:action, 'start')
self.options.fetch(:environment, {}).fetch(:action, 'start') if self.options
end
def outdated_deployment?

View file

@ -336,8 +336,10 @@ module Ci
.select { |merge_request| merge_request.head_pipeline.try(:id) == self.id }
end
def detailed_status
Gitlab::Ci::Status::Pipeline::Factory.new(self).fabricate!
def detailed_status(current_user)
Gitlab::Ci::Status::Pipeline::Factory
.new(self, current_user)
.fabricate!
end
private

View file

@ -22,8 +22,10 @@ module Ci
@status ||= statuses.latest.status
end
def detailed_status
Gitlab::Ci::Status::Stage::Factory.new(self).fabricate!
def detailed_status(current_user)
Gitlab::Ci::Status::Stage::Factory
.new(self, current_user)
.fabricate!
end
def statuses

View file

@ -131,4 +131,10 @@ class CommitStatus < ActiveRecord::Base
def has_trace?
false
end
def detailed_status(current_user)
Gitlab::Ci::Status::Factory
.new(self, current_user)
.fabricate!
end
end

View file

@ -17,14 +17,13 @@ class Namespace < ActiveRecord::Base
validates :owner, presence: true, unless: ->(n) { n.type == "Group" }
validates :name,
presence: true,
uniqueness: true,
uniqueness: { scope: :parent_id },
length: { maximum: 255 },
namespace_name: true
validates :description, length: { maximum: 255 }
validates :path,
presence: true,
uniqueness: { case_sensitive: false },
length: { maximum: 255 },
namespace: true

View file

@ -8,7 +8,7 @@
%span
Overview
= nav_link(controller: [:admin, :projects]) do
= link_to admin_namespaces_projects_path, title: 'Projects' do
= link_to admin_projects_path, title: 'Projects' do
%span
Projects
= nav_link(controller: :users) do

View file

@ -116,7 +116,7 @@
.light-well.well-centered
%h4 Projects
.data
= link_to admin_namespaces_projects_path do
= link_to admin_projects_path do
%h1= number_with_delimiter(Project.cached_count)
%hr
= link_to('New Project', new_project_path, class: "btn btn-new")

View file

@ -2,7 +2,7 @@
%li.group-row{ class: css_class }
.controls
= link_to 'Edit', edit_admin_group_path(group), id: "edit_#{dom_id(group)}", class: 'btn'
= link_to 'Edit', admin_group_edit_path(group), id: "edit_#{dom_id(group)}", class: 'btn'
= link_to 'Delete', [:admin, group], data: { confirm: "Are you sure you want to remove #{group.name}?" }, method: :delete, class: 'btn btn-remove'
.stats
%span

View file

@ -2,7 +2,7 @@
%h3.page-title
Group: #{@group.name}
= link_to edit_admin_group_path(@group), class: "btn pull-right" do
= link_to admin_group_edit_path(@group), class: "btn pull-right" do
%i.fa.fa-pencil-square-o
Edit
%hr
@ -88,7 +88,7 @@
Read more about project permissions
%strong= link_to "here", help_page_path("user/permissions"), class: "vlink"
= form_tag members_update_admin_group_path(@group), id: "new_project_member", class: "bulk_import", method: :put do
= form_tag admin_group_members_update_path(@group), id: "new_project_member", class: "bulk_import", method: :put do
%div
= users_select_tag(:user_ids, multiple: true, email_user: true, scope: :all)
%div.prepend-top-10

View file

@ -7,7 +7,7 @@
%div{ class: container_class }
.top-area
.prepend-top-default
= form_tag admin_namespaces_projects_path, method: :get do |f|
= form_tag admin_projects_path, method: :get do |f|
.search-holder
.search-field-holder
= search_field_tag :name, params[:name], class: "form-control search-text-input js-search-input", id: "dashboard_search", autofocus: true, spellcheck: false, placeholder: 'Search by name'
@ -41,19 +41,19 @@
= button_tag "Search", class: "btn btn-primary btn-search"
%ul.nav-links
- opts = params[:visibility_level].present? ? {} : { page: admin_namespaces_projects_path }
- opts = params[:visibility_level].present? ? {} : { page: admin_projects_path }
= nav_link(opts) do
= link_to admin_namespaces_projects_path do
= link_to admin_projects_path do
All
= nav_link(html_options: { class: params[:visibility_level] == Gitlab::VisibilityLevel::PRIVATE.to_s ? 'active' : '' }) do
= link_to admin_namespaces_projects_path(visibility_level: Gitlab::VisibilityLevel::PRIVATE) do
= link_to admin_projects_path(visibility_level: Gitlab::VisibilityLevel::PRIVATE) do
Private
= nav_link(html_options: { class: params[:visibility_level] == Gitlab::VisibilityLevel::INTERNAL.to_s ? 'active' : '' }) do
= link_to admin_namespaces_projects_path(visibility_level: Gitlab::VisibilityLevel::INTERNAL) do
= link_to admin_projects_path(visibility_level: Gitlab::VisibilityLevel::INTERNAL) do
Internal
= nav_link(html_options: { class: params[:visibility_level] == Gitlab::VisibilityLevel::PUBLIC.to_s ? 'active' : '' }) do
= link_to admin_namespaces_projects_path(visibility_level: Gitlab::VisibilityLevel::PUBLIC) do
= link_to admin_projects_path(visibility_level: Gitlab::VisibilityLevel::PUBLIC) do
Public
.nav-controls

View file

@ -91,7 +91,7 @@
%strong ##{build.id}
%td.status
= ci_status_with_icon(build.status)
= render 'ci/status/badge', status: build.detailed_status(current_user)
%td.status
- if project

View file

@ -0,0 +1,10 @@
- status = local_assigns.fetch(:status)
- if status.has_details?
= link_to status.details_path, class: "ci-status ci-#{status}" do
= custom_icon(status.icon)
= status.text
- else
%span{ class: "ci-status ci-#{status}" }
= custom_icon(status.icon)
= status.text

View file

@ -1,6 +1,6 @@
.content-block.build-header
.header-content
= ci_status_with_icon(@build.status)
= render 'ci/status/badge', status: @build.detailed_status(current_user)
Build
%strong ##{@build.id}
in pipeline

View file

@ -9,10 +9,7 @@
%tr.build.commit{class: ('retried' if retried)}
%td.status
- if can?(current_user, :read_build, build)
= ci_status_with_icon(build.status, namespace_project_build_url(build.project.namespace, build.project, build))
- else
= ci_status_with_icon(build.status)
= render "ci/status/badge", status: build.detailed_status(current_user)
%td.branch-commit
- if can?(current_user, :read_build, build)

View file

@ -1,13 +1,10 @@
- status = pipeline.status
- detailed_status = pipeline.detailed_status
- show_commit = local_assigns.fetch(:show_commit, true)
- show_branch = local_assigns.fetch(:show_branch, true)
%tr.commit
%td.commit-link
= link_to namespace_project_pipeline_path(pipeline.project.namespace, pipeline.project, pipeline.id), class: "ci-status ci-#{detailed_status}" do
= ci_icon_for_status(detailed_status)
= ci_text_for_status(detailed_status)
= render 'ci/status/badge', status: pipeline.detailed_status(current_user)
%td
= link_to namespace_project_pipeline_path(pipeline.project.namespace, pipeline.project, pipeline.id) do

View file

@ -8,10 +8,7 @@
%tr.generic_commit_status{class: ('retried' if retried)}
%td.status
- if can?(current_user, :read_commit_status, generic_commit_status) && generic_commit_status.target_url
= ci_status_with_icon(generic_commit_status.status, generic_commit_status.target_url)
- else
= ci_status_with_icon(generic_commit_status.status)
= render 'ci/status/badge', status: generic_commit_status.detailed_status(current_user)
%td.generic_commit_status-link
- if can?(current_user, :read_commit_status, generic_commit_status) && generic_commit_status.target_url

View file

@ -1,6 +1,6 @@
.page-content-header
.header-main-content
= ci_status_with_icon(@pipeline.detailed_status)
= render 'ci/status/badge', status: @pipeline.detailed_status(current_user)
%strong Pipeline ##{@commit.pipelines.last.id}
triggered #{time_ago_with_tooltip(@commit.authored_date)} by
= author_avatar(@commit, size: 24)

View file

@ -19,4 +19,4 @@
%li.build
.curve
.dropdown.inline.build-content
= render "projects/stage/in_stage_group", name: group_name, subject: grouped_statuses
= render 'projects/stage/in_stage_group', name: group_name, subject: grouped_statuses

View file

@ -2,7 +2,7 @@
#{@message}.
%p
= link_to "See the affected projects in the GitLab admin panel", admin_namespaces_projects_url(last_repository_check_failed: 1)
= link_to "See the affected projects in the GitLab admin panel", admin_projects_url(last_repository_check_failed: 1)
%p
You are receiving this message because you are a GitLab administrator for #{Gitlab.config.gitlab.url}.

View file

@ -1,6 +1,6 @@
#{@message}.
\
View details: #{admin_namespaces_projects_url(last_repository_check_failed: 1)}
View details: #{admin_projects_url(last_repository_check_failed: 1)}
You are receiving this message because you are a GitLab administrator
for #{Gitlab.config.gitlab.url}.

View file

@ -0,0 +1 @@
<svg width="14" height="14" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg"><g fill-rule="evenodd"><path d="M0 7a7 7 0 1 1 14 0A7 7 0 0 1 0 7z"/><path d="M13 7A6 6 0 1 0 1 7a6 6 0 0 0 12 0z" fill="#FFF"/><path d="M10.5 7.63V6.37l-.787-.13c-.044-.175-.132-.349-.263-.61l.481-.652-.918-.913-.657.478a2.346 2.346 0 0 0-.612-.26L7.656 3.5H6.388l-.132.783c-.219.043-.394.13-.612.26l-.657-.478-.918.913.437.652c-.131.218-.175.392-.262.61l-.744.086v1.261l.787.13c.044.218.132.392.263.61l-.438.651.92.913.655-.434c.175.086.394.173.613.26l.131.783h1.313l.131-.783c.219-.043.394-.13.613-.26l.656.478.918-.913-.48-.652c.13-.218.218-.435.262-.61l.656-.13zM7 8.283a1.285 1.285 0 0 1-1.313-1.305c0-.739.57-1.304 1.313-1.304.744 0 1.313.565 1.313 1.304 0 .74-.57 1.305-1.313 1.305z"/></g></svg>

After

Width:  |  Height:  |  Size: 787 B

View file

@ -0,0 +1,5 @@
---
title: Changed cursor icon to pointer when mousing over stages on the Cycle Analytics
pages
merge_request:
author: Ryan Harris

View file

@ -0,0 +1,4 @@
---
title: Adds tests for custom event polyfill
merge_request: 7996
author:

View file

@ -28,9 +28,19 @@ namespace :admin do
resources :applications
resources :groups, constraints: { id: /[^\/]+/ } do
member do
resources :groups, only: [:index, :new, :create]
scope(path: 'groups/*id',
controller: :groups,
constraints: { id: Gitlab::Regex.namespace_route_regex }) do
scope(as: :group) do
put :members_update
get :edit, action: :edit
get '/', action: :show
patch '/', action: :update
put '/', action: :update
delete '/', action: :destroy
end
end
@ -50,14 +60,13 @@ namespace :admin do
resource :system_info, controller: 'system_info', only: [:show]
resources :requests_profiles, only: [:index, :show], param: :name, constraints: { name: /.+\.html/ }
resources :namespaces, path: '/projects', constraints: { id: /[a-zA-Z.0-9_\-]+/ }, only: [] do
root to: 'projects#index', as: :projects
resources :projects, only: [:index]
scope(path: 'projects/*namespace_id', as: :namespace) do
resources(:projects,
path: '/',
constraints: { id: /[a-zA-Z.0-9_\-]+/ },
only: [:index, :show]) do
root to: 'projects#show'
constraints: { id: Gitlab::Regex.project_route_regex },
only: [:show]) do
member do
put :transfer

View file

@ -0,0 +1,36 @@
# See http://doc.gitlab.com/ce/development/migration_style_guide.html
# for more information on how to write migrations for GitLab.
class RemoveUniqPathIndexFromNamespace < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
disable_ddl_transaction!
DOWNTIME = false
def up
constraint_name = 'namespaces_path_key'
transaction do
if index_exists?(:namespaces, :path)
remove_index(:namespaces, :path)
end
# In some bizarre cases PostgreSQL might have a separate unique constraint
# that we'll need to drop.
if constraint_exists?(constraint_name) && Gitlab::Database.postgresql?
execute("ALTER TABLE namespaces DROP CONSTRAINT IF EXISTS #{constraint_name};")
end
end
end
def down
unless index_exists?(:namespaces, :path)
add_concurrent_index(:namespaces, :path, unique: true)
end
end
def constraint_exists?(name)
indexes(:namespaces).map(&:name).include?(name)
end
end

View file

@ -0,0 +1,20 @@
# See http://doc.gitlab.com/ce/development/migration_style_guide.html
# for more information on how to write migrations for GitLab.
class AddPathIndexToNamespace < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
disable_ddl_transaction!
DOWNTIME = false
def up
add_concurrent_index :namespaces, :path
end
def down
if index_exists?(:namespaces, :path)
remove_index :namespaces, :path
end
end
end

View file

@ -0,0 +1,36 @@
# See http://doc.gitlab.com/ce/development/migration_style_guide.html
# for more information on how to write migrations for GitLab.
class RemoveUniqNameIndexFromNamespace < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
disable_ddl_transaction!
DOWNTIME = false
def up
constraint_name = 'namespaces_name_key'
transaction do
if index_exists?(:namespaces, :name)
remove_index(:namespaces, :name)
end
# In some bizarre cases PostgreSQL might have a separate unique constraint
# that we'll need to drop.
if constraint_exists?(constraint_name) && Gitlab::Database.postgresql?
execute("ALTER TABLE namespaces DROP CONSTRAINT IF EXISTS #{constraint_name};")
end
end
end
def down
unless index_exists?(:namespaces, :name)
add_concurrent_index(:namespaces, :name, unique: true)
end
end
def constraint_exists?(name)
indexes(:namespaces).map(&:name).include?(name)
end
end

View file

@ -0,0 +1,20 @@
# See http://doc.gitlab.com/ce/development/migration_style_guide.html
# for more information on how to write migrations for GitLab.
class AddNameIndexToNamespace < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
disable_ddl_transaction!
DOWNTIME = false
def up
add_concurrent_index(:namespaces, [:name, :parent_id], unique: true)
end
def down
if index_exists?(:namespaces, :name)
remove_index :namespaces, [:name, :parent_id]
end
end
end

View file

@ -744,11 +744,11 @@ ActiveRecord::Schema.define(version: 20161212142807) do
add_index "namespaces", ["created_at"], name: "index_namespaces_on_created_at", using: :btree
add_index "namespaces", ["deleted_at"], name: "index_namespaces_on_deleted_at", using: :btree
add_index "namespaces", ["name"], name: "index_namespaces_on_name", unique: true, using: :btree
add_index "namespaces", ["name", "parent_id"], name: "index_namespaces_on_name_and_parent_id", unique: true, using: :btree
add_index "namespaces", ["name"], name: "index_namespaces_on_name_trigram", using: :gin, opclasses: {"name"=>"gin_trgm_ops"}
add_index "namespaces", ["owner_id"], name: "index_namespaces_on_owner_id", using: :btree
add_index "namespaces", ["parent_id", "id"], name: "index_namespaces_on_parent_id_and_id", unique: true, using: :btree
add_index "namespaces", ["path"], name: "index_namespaces_on_path", unique: true, using: :btree
add_index "namespaces", ["path"], name: "index_namespaces_on_path", using: :btree
add_index "namespaces", ["path"], name: "index_namespaces_on_path_trigram", using: :gin, opclasses: {"path"=>"gin_trgm_ops"}
add_index "namespaces", ["type"], name: "index_namespaces_on_type", using: :btree
@ -1290,4 +1290,4 @@ ActiveRecord::Schema.define(version: 20161212142807) do
add_foreign_key "subscriptions", "projects", on_delete: :cascade
add_foreign_key "trending_projects", "projects", on_delete: :cascade
add_foreign_key "u2f_registrations", "users"
end
end

View file

@ -72,7 +72,7 @@ sudo -u git -H git checkout 8-14-stable-ee
```bash
cd /home/git/gitlab-shell
sudo -u git -H git fetch --all --tags
sudo -u git -H git checkout v4.0.0
sudo -u git -H git checkout v4.0.3
```
### 6. Update gitlab-workhorse

View file

@ -168,7 +168,7 @@ module SharedPaths
end
step 'I visit admin projects page' do
visit admin_namespaces_projects_path
visit admin_projects_path
end
step 'I visit admin users page' do

7
lib/gitlab/allowable.rb Normal file
View file

@ -0,0 +1,7 @@
module Gitlab
module Allowable
def can?(user, action, subject)
Ability.allowed?(user, action, subject)
end
end
end

View file

@ -0,0 +1,37 @@
module Gitlab
module Ci
module Status
module Build
class Cancelable < SimpleDelegator
include Status::Extended
def has_action?
can?(user, :update_build, subject)
end
def action_icon
'ban'
end
def action_path
cancel_namespace_project_build_path(subject.project.namespace,
subject.project,
subject)
end
def action_method
:post
end
def action_title
'Cancel'
end
def self.matches?(build, user)
build.cancelable?
end
end
end
end
end
end

View file

@ -0,0 +1,19 @@
module Gitlab
module Ci
module Status
module Build
module Common
def has_details?
can?(user, :read_build, subject)
end
def details_path
namespace_project_build_path(subject.project.namespace,
subject.project,
subject)
end
end
end
end
end
end

View file

@ -0,0 +1,18 @@
module Gitlab
module Ci
module Status
module Build
class Factory < Status::Factory
def self.extended_statuses
[Status::Build::Stop, Status::Build::Play,
Status::Build::Cancelable, Status::Build::Retryable]
end
def self.common_helpers
Status::Build::Common
end
end
end
end
end
end

View file

@ -0,0 +1,53 @@
module Gitlab
module Ci
module Status
module Build
class Play < SimpleDelegator
include Status::Extended
def text
'manual'
end
def label
'manual play action'
end
def icon
'icon_status_manual'
end
def has_action?
can?(user, :update_build, subject)
end
def action_icon
'play'
end
def action_title
'Play'
end
def action_class
'ci-play-icon'
end
def action_path
play_namespace_project_build_path(subject.project.namespace,
subject.project,
subject)
end
def action_method
:post
end
def self.matches?(build, user)
build.playable? && !build.stops_environment?
end
end
end
end
end
end

View file

@ -0,0 +1,37 @@
module Gitlab
module Ci
module Status
module Build
class Retryable < SimpleDelegator
include Status::Extended
def has_action?
can?(user, :update_build, subject)
end
def action_icon
'refresh'
end
def action_title
'Retry'
end
def action_path
retry_namespace_project_build_path(subject.project.namespace,
subject.project,
subject)
end
def action_method
:post
end
def self.matches?(build, user)
build.retryable?
end
end
end
end
end
end

View file

@ -0,0 +1,49 @@
module Gitlab
module Ci
module Status
module Build
class Stop < SimpleDelegator
include Status::Extended
def text
'manual'
end
def label
'manual stop action'
end
def icon
'icon_status_manual'
end
def has_action?
can?(user, :update_build, subject)
end
def action_icon
'stop'
end
def action_title
'Stop'
end
def action_path
play_namespace_project_build_path(subject.project.namespace,
subject.project,
subject)
end
def action_method
:post
end
def self.matches?(build, user)
build.playable? && build.stops_environment?
end
end
end
end
end
end

View file

@ -4,10 +4,14 @@ module Gitlab
# Base abstract class fore core status
#
class Core
include Gitlab::Routing.url_helpers
include Gitlab::Routing
include Gitlab::Allowable
def initialize(subject)
attr_reader :subject, :user
def initialize(subject, user)
@subject = subject
@user = user
end
def icon
@ -18,10 +22,6 @@ module Gitlab
raise NotImplementedError
end
def title
"#{@subject.class.name.demodulize}: #{label}"
end
# Deprecation warning: this method is here because we need to maintain
# backwards compatibility with legacy statuses. We often do something
# like "ci-status ci-status-#{status}" to set CSS class.
@ -34,7 +34,7 @@ module Gitlab
end
def has_details?
raise NotImplementedError
false
end
def details_path
@ -42,16 +42,27 @@ module Gitlab
end
def has_action?
raise NotImplementedError
false
end
def action_icon
raise NotImplementedError
end
def action_class
end
def action_path
raise NotImplementedError
end
def action_method
raise NotImplementedError
end
def action_title
raise NotImplementedError
end
end
end
end

View file

@ -2,8 +2,12 @@ module Gitlab
module Ci
module Status
module Extended
def matches?(_subject)
raise NotImplementedError
extend ActiveSupport::Concern
class_methods do
def matches?(_subject, _user)
raise NotImplementedError
end
end
end
end

View file

@ -2,10 +2,9 @@ module Gitlab
module Ci
module Status
class Factory
attr_reader :subject
def initialize(subject)
def initialize(subject, user)
@subject = subject
@user = user
end
def fabricate!
@ -16,27 +15,32 @@ module Gitlab
end
end
def self.extended_statuses
[]
end
def self.common_helpers
Module.new
end
private
def subject_status
@subject_status ||= subject.status
def simple_status
@simple_status ||= @subject.status || :created
end
def core_status
Gitlab::Ci::Status
.const_get(subject_status.capitalize)
.new(subject)
.const_get(simple_status.capitalize)
.new(@subject, @user)
.extend(self.class.common_helpers)
end
def extended_status
@extended ||= extended_statuses.find do |status|
status.matches?(subject)
@extended ||= self.class.extended_statuses.find do |status|
status.matches?(@subject, @user)
end
end
def extended_statuses
[]
end
end
end
end

View file

@ -4,13 +4,13 @@ module Gitlab
module Pipeline
module Common
def has_details?
true
can?(user, :read_pipeline, subject)
end
def details_path
namespace_project_pipeline_path(@subject.project.namespace,
@subject.project,
@subject)
namespace_project_pipeline_path(subject.project.namespace,
subject.project,
subject)
end
def has_action?

View file

@ -3,14 +3,12 @@ module Gitlab
module Status
module Pipeline
class Factory < Status::Factory
private
def extended_statuses
def self.extended_statuses
[Pipeline::SuccessWithWarnings]
end
def core_status
super.extend(Status::Pipeline::Common)
def self.common_helpers
Status::Pipeline::Common
end
end
end

View file

@ -3,7 +3,7 @@ module Gitlab
module Status
module Pipeline
class SuccessWithWarnings < SimpleDelegator
extend Status::Extended
include Status::Extended
def text
'passed'
@ -21,7 +21,7 @@ module Gitlab
'success_with_warnings'
end
def self.matches?(pipeline)
def self.matches?(pipeline, user)
pipeline.success? && pipeline.has_warnings?
end
end

View file

@ -4,14 +4,14 @@ module Gitlab
module Stage
module Common
def has_details?
true
can?(user, :read_pipeline, subject.pipeline)
end
def details_path
namespace_project_pipeline_path(@subject.project.namespace,
@subject.project,
@subject.pipeline,
anchor: @subject.name)
namespace_project_pipeline_path(subject.project.namespace,
subject.project,
subject.pipeline,
anchor: subject.name)
end
def has_action?

View file

@ -3,10 +3,8 @@ module Gitlab
module Status
module Stage
class Factory < Status::Factory
private
def core_status
super.extend(Status::Stage::Common)
def self.common_helpers
Status::Stage::Common
end
end
end

View file

@ -1,5 +1,11 @@
module Gitlab
module Routing
extend ActiveSupport::Concern
included do
include Gitlab::Routing.url_helpers
end
# Returns the URL helpers Module.
#
# This method caches the output as Rails' "url_helpers" method creates an

View file

@ -12,12 +12,14 @@ FactoryGirl.define do
started_at 'Di 29. Okt 09:51:28 CET 2013'
finished_at 'Di 29. Okt 09:53:28 CET 2013'
commands 'ls -a'
options do
{
image: "ruby:2.1",
services: ["postgres"]
}
end
yaml_variables do
[
{ key: :DB_NAME, value: 'postgres', public: true }
@ -60,15 +62,20 @@ FactoryGirl.define do
end
trait :teardown_environment do
options do
{ environment: { action: 'stop' } }
end
environment 'staging'
options environment: { name: 'staging',
action: 'stop' }
end
trait :allowed_to_fail do
allow_failure true
end
trait :playable do
skipped
manual
end
after(:build) do |build, evaluator|
build.project = build.pipeline.project
end

View file

@ -21,7 +21,7 @@ feature 'Admin Groups', feature: true do
scenario 'shows the visibility level radio populated with the group visibility_level value' do
group = create(:group, :private)
visit edit_admin_group_path(group)
visit admin_group_edit_path(group)
expect_selected_visibility(group.visibility_level)
end

View file

@ -8,11 +8,11 @@ describe "Admin::Projects", feature: true do
describe "GET /admin/projects" do
before do
visit admin_namespaces_projects_path
visit admin_projects_path
end
it "is ok" do
expect(current_path).to eq(admin_namespaces_projects_path)
expect(current_path).to eq(admin_projects_path)
end
it "has projects list" do
@ -22,7 +22,7 @@ describe "Admin::Projects", feature: true do
describe "GET /admin/projects/:id" do
before do
visit admin_namespaces_projects_path
visit admin_projects_path
click_link "#{@project.name}"
end

View file

@ -4,7 +4,7 @@ describe "Admin::Projects", feature: true do
include AccessMatchers
describe "GET /admin/projects" do
subject { admin_namespaces_projects_path }
subject { admin_projects_path }
it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_denied_for :user }

View file

@ -0,0 +1,43 @@
//= require lib/utils/custom_event_polyfill
describe('Custom Event Polyfill', () => {
it('should be defined', () => {
expect(window.CustomEvent).toBeDefined();
});
it('should create a `CustomEvent` instance', () => {
const e = new window.CustomEvent('foo');
expect(e.type).toEqual('foo');
expect(e.bubbles).toBe(false);
expect(e.cancelable).toBe(false);
expect(e.detail).toBeFalsy();
});
it('should create a `CustomEvent` instance with a `details` object', () => {
const e = new window.CustomEvent('bar', { detail: { foo: 'bar' } });
expect(e.type).toEqual('bar');
expect(e.bubbles).toBe(false);
expect(e.cancelable).toBe(false);
expect(e.detail.foo).toEqual('bar');
});
it('should create a `CustomEvent` instance with a `bubbles` boolean', () => {
const e = new window.CustomEvent('bar', { bubbles: true });
expect(e.type).toEqual('bar');
expect(e.bubbles).toBe(true);
expect(e.cancelable).toBe(false);
expect(e.detail).toBeFalsy();
});
it('should create a `CustomEvent` instance with a `cancelable` boolean', () => {
const e = new window.CustomEvent('bar', { cancelable: true });
expect(e.type).toEqual('bar');
expect(e.bubbles).toBe(false);
expect(e.cancelable).toBe(true);
expect(e.detail).toBeFalsy();
});
});

View file

@ -0,0 +1,27 @@
require 'spec_helper'
describe Gitlab::Allowable do
subject do
Class.new.include(described_class).new
end
describe '#can?' do
let(:user) { create(:user) }
context 'when user is allowed to do something' do
let(:project) { create(:empty_project, :public) }
it 'reports correct ability to perform action' do
expect(subject.can?(user, :read_project, project)).to be true
end
end
context 'when user is not allowed to do something' do
let(:project) { create(:empty_project, :private) }
it 'reports correct ability to perform action' do
expect(subject.can?(user, :read_project, project)).to be false
end
end
end
end

View file

@ -0,0 +1,86 @@
require 'spec_helper'
describe Gitlab::Ci::Status::Build::Cancelable do
let(:status) { double('core status') }
let(:user) { double('user') }
subject do
described_class.new(status)
end
describe '#text' do
it 'does not override status text' do
expect(status).to receive(:text)
subject.text
end
end
describe '#icon' do
it 'does not override status icon' do
expect(status).to receive(:icon)
subject.icon
end
end
describe '#label' do
it 'does not override status label' do
expect(status).to receive(:label)
subject.label
end
end
describe 'action details' do
let(:user) { create(:user) }
let(:build) { create(:ci_build) }
let(:status) { Gitlab::Ci::Status::Core.new(build, user) }
describe '#has_action?' do
context 'when user is allowed to update build' do
before { build.project.team << [user, :developer] }
it { is_expected.to have_action }
end
context 'when user is not allowed to update build' do
it { is_expected.not_to have_action }
end
end
describe '#action_path' do
it { expect(subject.action_path).to include "#{build.id}/cancel" }
end
describe '#action_icon' do
it { expect(subject.action_icon).to eq 'ban' }
end
describe '#action_title' do
it { expect(subject.action_title).to eq 'Cancel' }
end
end
describe '.matches?' do
subject { described_class.matches?(build, user) }
context 'when build is cancelable' do
let(:build) do
create(:ci_build, :running)
end
it 'is a correct match' do
expect(subject).to be true
end
end
context 'when build is not cancelable' do
let(:build) { create(:ci_build, :success) }
it 'does not match' do
expect(subject).to be false
end
end
end
end

View file

@ -0,0 +1,37 @@
require 'spec_helper'
describe Gitlab::Ci::Status::Build::Common do
let(:user) { create(:user) }
let(:build) { create(:ci_build) }
let(:project) { build.project }
subject do
Gitlab::Ci::Status::Core
.new(build, user)
.extend(described_class)
end
describe '#has_action?' do
it { is_expected.not_to have_action }
end
describe '#has_details?' do
context 'when user has access to read build' do
before { project.team << [user, :developer] }
it { is_expected.to have_details }
end
context 'when user does not have access to read build' do
before { project.update(public_builds: false) }
it { is_expected.not_to have_details }
end
end
describe '#details_path' do
it 'links to the build details page' do
expect(subject.details_path).to include "builds/#{build.id}"
end
end
end

View file

@ -0,0 +1,141 @@
require 'spec_helper'
describe Gitlab::Ci::Status::Build::Factory do
let(:user) { create(:user) }
let(:project) { build.project }
subject { described_class.new(build, user) }
let(:status) { subject.fabricate! }
before { project.team << [user, :developer] }
context 'when build is successful' do
let(:build) { create(:ci_build, :success) }
it 'fabricates a retryable build status' do
expect(status).to be_a Gitlab::Ci::Status::Build::Retryable
end
it 'fabricates status with correct details' do
expect(status.text).to eq 'passed'
expect(status.icon).to eq 'icon_status_success'
expect(status.label).to eq 'passed'
expect(status).to have_details
expect(status).to have_action
end
end
context 'when build is failed' do
let(:build) { create(:ci_build, :failed) }
it 'fabricates a retryable build status' do
expect(status).to be_a Gitlab::Ci::Status::Build::Retryable
end
it 'fabricates status with correct details' do
expect(status.text).to eq 'failed'
expect(status.icon).to eq 'icon_status_failed'
expect(status.label).to eq 'failed'
expect(status).to have_details
expect(status).to have_action
end
end
context 'when build is a canceled' do
let(:build) { create(:ci_build, :canceled) }
it 'fabricates a retryable build status' do
expect(status).to be_a Gitlab::Ci::Status::Build::Retryable
end
it 'fabricates status with correct details' do
expect(status.text).to eq 'canceled'
expect(status.icon).to eq 'icon_status_canceled'
expect(status.label).to eq 'canceled'
expect(status).to have_details
expect(status).to have_action
end
end
context 'when build is running' do
let(:build) { create(:ci_build, :running) }
it 'fabricates a canceable build status' do
expect(status).to be_a Gitlab::Ci::Status::Build::Cancelable
end
it 'fabricates status with correct details' do
expect(status.text).to eq 'running'
expect(status.icon).to eq 'icon_status_running'
expect(status.label).to eq 'running'
expect(status).to have_details
expect(status).to have_action
end
end
context 'when build is pending' do
let(:build) { create(:ci_build, :pending) }
it 'fabricates a cancelable build status' do
expect(status).to be_a Gitlab::Ci::Status::Build::Cancelable
end
it 'fabricates status with correct details' do
expect(status.text).to eq 'pending'
expect(status.icon).to eq 'icon_status_pending'
expect(status.label).to eq 'pending'
expect(status).to have_details
expect(status).to have_action
end
end
context 'when build is skipped' do
let(:build) { create(:ci_build, :skipped) }
it 'fabricates a core skipped status' do
expect(status).to be_a Gitlab::Ci::Status::Skipped
end
it 'fabricates status with correct details' do
expect(status.text).to eq 'skipped'
expect(status.icon).to eq 'icon_status_skipped'
expect(status.label).to eq 'skipped'
expect(status).to have_details
expect(status).not_to have_action
end
end
context 'when build is a manual action' do
context 'when build is a play action' do
let(:build) { create(:ci_build, :playable) }
it 'fabricates a core skipped status' do
expect(status).to be_a Gitlab::Ci::Status::Build::Play
end
it 'fabricates status with correct details' do
expect(status.text).to eq 'manual'
expect(status.icon).to eq 'icon_status_manual'
expect(status.label).to eq 'manual play action'
expect(status).to have_details
expect(status).to have_action
end
end
context 'when build is an environment stop action' do
let(:build) { create(:ci_build, :playable, :teardown_environment) }
it 'fabricates a core skipped status' do
expect(status).to be_a Gitlab::Ci::Status::Build::Stop
end
it 'fabricates status with correct details' do
expect(status.text).to eq 'manual'
expect(status.icon).to eq 'icon_status_manual'
expect(status.label).to eq 'manual stop action'
expect(status).to have_details
expect(status).to have_action
end
end
end
end

View file

@ -0,0 +1,82 @@
require 'spec_helper'
describe Gitlab::Ci::Status::Build::Play do
let(:status) { double('core') }
let(:user) { double('user') }
subject { described_class.new(status) }
describe '#text' do
it { expect(subject.text).to eq 'manual' }
end
describe '#label' do
it { expect(subject.label).to eq 'manual play action' }
end
describe '#icon' do
it { expect(subject.icon).to eq 'icon_status_manual' }
end
describe 'action details' do
let(:user) { create(:user) }
let(:build) { create(:ci_build) }
let(:status) { Gitlab::Ci::Status::Core.new(build, user) }
describe '#has_action?' do
context 'when user is allowed to update build' do
before { build.project.team << [user, :developer] }
it { is_expected.to have_action }
end
context 'when user is not allowed to update build' do
it { is_expected.not_to have_action }
end
end
describe '#action_path' do
it { expect(subject.action_path).to include "#{build.id}/play" }
end
describe '#action_icon' do
it { expect(subject.action_icon).to eq 'play' }
end
describe '#action_title' do
it { expect(subject.action_title).to eq 'Play' }
end
end
describe '.matches?' do
subject { described_class.matches?(build, user) }
context 'when build is playable' do
context 'when build stops an environment' do
let(:build) do
create(:ci_build, :playable, :teardown_environment)
end
it 'does not match' do
expect(subject).to be false
end
end
context 'when build does not stop an environment' do
let(:build) { create(:ci_build, :playable) }
it 'is a correct match' do
expect(subject).to be true
end
end
end
context 'when build is not playable' do
let(:build) { create(:ci_build) }
it 'does not match' do
expect(subject).to be false
end
end
end
end

View file

@ -0,0 +1,86 @@
require 'spec_helper'
describe Gitlab::Ci::Status::Build::Retryable do
let(:status) { double('core status') }
let(:user) { double('user') }
subject do
described_class.new(status)
end
describe '#text' do
it 'does not override status text' do
expect(status).to receive(:text)
subject.text
end
end
describe '#icon' do
it 'does not override status icon' do
expect(status).to receive(:icon)
subject.icon
end
end
describe '#label' do
it 'does not override status label' do
expect(status).to receive(:label)
subject.label
end
end
describe 'action details' do
let(:user) { create(:user) }
let(:build) { create(:ci_build) }
let(:status) { Gitlab::Ci::Status::Core.new(build, user) }
describe '#has_action?' do
context 'when user is allowed to update build' do
before { build.project.team << [user, :developer] }
it { is_expected.to have_action }
end
context 'when user is not allowed to update build' do
it { is_expected.not_to have_action }
end
end
describe '#action_path' do
it { expect(subject.action_path).to include "#{build.id}/retry" }
end
describe '#action_icon' do
it { expect(subject.action_icon).to eq 'refresh' }
end
describe '#action_title' do
it { expect(subject.action_title).to eq 'Retry' }
end
end
describe '.matches?' do
subject { described_class.matches?(build, user) }
context 'when build is retryable' do
let(:build) do
create(:ci_build, :success)
end
it 'is a correct match' do
expect(subject).to be true
end
end
context 'when build is not retryable' do
let(:build) { create(:ci_build, :running) }
it 'does not match' do
expect(subject).to be false
end
end
end
end

View file

@ -0,0 +1,84 @@
require 'spec_helper'
describe Gitlab::Ci::Status::Build::Stop do
let(:status) { double('core status') }
let(:user) { double('user') }
subject do
described_class.new(status)
end
describe '#text' do
it { expect(subject.text).to eq 'manual' }
end
describe '#label' do
it { expect(subject.label).to eq 'manual stop action' }
end
describe '#icon' do
it { expect(subject.icon).to eq 'icon_status_manual' }
end
describe 'action details' do
let(:user) { create(:user) }
let(:build) { create(:ci_build) }
let(:status) { Gitlab::Ci::Status::Core.new(build, user) }
describe '#has_action?' do
context 'when user is allowed to update build' do
before { build.project.team << [user, :developer] }
it { is_expected.to have_action }
end
context 'when user is not allowed to update build' do
it { is_expected.not_to have_action }
end
end
describe '#action_path' do
it { expect(subject.action_path).to include "#{build.id}/play" }
end
describe '#action_icon' do
it { expect(subject.action_icon).to eq 'stop' }
end
describe '#action_title' do
it { expect(subject.action_title).to eq 'Stop' }
end
end
describe '.matches?' do
subject { described_class.matches?(build, user) }
context 'when build is playable' do
context 'when build stops an environment' do
let(:build) do
create(:ci_build, :playable, :teardown_environment)
end
it 'is a correct match' do
expect(subject).to be true
end
end
context 'when build does not stop an environment' do
let(:build) { create(:ci_build, :playable) }
it 'does not match' do
expect(subject).to be false
end
end
end
context 'when build is not playable' do
let(:build) { create(:ci_build) }
it 'does not match' do
expect(subject).to be false
end
end
end
end

View file

@ -1,7 +1,9 @@
require 'spec_helper'
describe Gitlab::Ci::Status::Canceled do
subject { described_class.new(double('subject')) }
subject do
described_class.new(double('subject'), double('user'))
end
describe '#text' do
it { expect(subject.label).to eq 'canceled' }
@ -14,8 +16,4 @@ describe Gitlab::Ci::Status::Canceled do
describe '#icon' do
it { expect(subject.icon).to eq 'icon_status_canceled' }
end
describe '#title' do
it { expect(subject.title).to eq 'Double: canceled' }
end
end

View file

@ -1,7 +1,9 @@
require 'spec_helper'
describe Gitlab::Ci::Status::Created do
subject { described_class.new(double('subject')) }
subject do
described_class.new(double('subject'), double('user'))
end
describe '#text' do
it { expect(subject.label).to eq 'created' }
@ -14,8 +16,4 @@ describe Gitlab::Ci::Status::Created do
describe '#icon' do
it { expect(subject.icon).to eq 'icon_status_created' }
end
describe '#title' do
it { expect(subject.title).to eq 'Double: created' }
end
end

View file

@ -2,11 +2,11 @@ require 'spec_helper'
describe Gitlab::Ci::Status::Extended do
subject do
Class.new.extend(described_class)
Class.new.include(described_class)
end
it 'requires subclass to implement matcher' do
expect { subject.matches?(double) }
expect { subject.matches?(double, double) }
.to raise_error(NotImplementedError)
end
end

View file

@ -2,15 +2,17 @@ require 'spec_helper'
describe Gitlab::Ci::Status::Factory do
subject do
described_class.new(object)
described_class.new(resource, user)
end
let(:user) { create(:user) }
let(:status) { subject.fabricate! }
context 'when object has a core status' do
HasStatus::AVAILABLE_STATUSES.each do |core_status|
context "when core status is #{core_status}" do
let(:object) { double(status: core_status) }
let(:resource) { double(status: core_status) }
it "fabricates a core status #{core_status}" do
expect(status).to be_a(

View file

@ -1,7 +1,9 @@
require 'spec_helper'
describe Gitlab::Ci::Status::Failed do
subject { described_class.new(double('subject')) }
subject do
described_class.new(double('subject'), double('user'))
end
describe '#text' do
it { expect(subject.label).to eq 'failed' }
@ -14,8 +16,4 @@ describe Gitlab::Ci::Status::Failed do
describe '#icon' do
it { expect(subject.icon).to eq 'icon_status_failed' }
end
describe '#title' do
it { expect(subject.title).to eq 'Double: failed' }
end
end

View file

@ -1,7 +1,9 @@
require 'spec_helper'
describe Gitlab::Ci::Status::Pending do
subject { described_class.new(double('subject')) }
subject do
described_class.new(double('subject'), double('user'))
end
describe '#text' do
it { expect(subject.label).to eq 'pending' }
@ -14,8 +16,4 @@ describe Gitlab::Ci::Status::Pending do
describe '#icon' do
it { expect(subject.icon).to eq 'icon_status_pending' }
end
describe '#title' do
it { expect(subject.title).to eq 'Double: pending' }
end
end

View file

@ -1,23 +1,36 @@
require 'spec_helper'
describe Gitlab::Ci::Status::Pipeline::Common do
let(:pipeline) { create(:ci_pipeline) }
let(:user) { create(:user) }
let(:project) { create(:empty_project, :private) }
let(:pipeline) { create(:ci_pipeline, project: project) }
subject do
Class.new(Gitlab::Ci::Status::Core)
.new(pipeline).extend(described_class)
Gitlab::Ci::Status::Core
.new(pipeline, user)
.extend(described_class)
end
it 'does not have action' do
expect(subject).not_to have_action
describe '#has_action?' do
it { is_expected.not_to have_action }
end
it 'has details' do
expect(subject).to have_details
describe '#has_details?' do
context 'when user has access to read pipeline' do
before { project.team << [user, :developer] }
it { is_expected.to have_details }
end
context 'when user does not have access to read pipeline' do
it { is_expected.not_to have_details }
end
end
it 'links to the pipeline details page' do
expect(subject.details_path)
.to include "pipelines/#{pipeline.id}"
describe '#details_path' do
it 'links to the pipeline details page' do
expect(subject.details_path)
.to include "pipelines/#{pipeline.id}"
end
end
end

View file

@ -1,14 +1,21 @@
require 'spec_helper'
describe Gitlab::Ci::Status::Pipeline::Factory do
let(:user) { create(:user) }
let(:project) { pipeline.project }
subject do
described_class.new(pipeline)
described_class.new(pipeline, user)
end
let(:status) do
subject.fabricate!
end
before do
project.team << [user, :developer]
end
context 'when pipeline has a core status' do
HasStatus::AVAILABLE_STATUSES.each do |core_status|
context "when core status is #{core_status}" do

View file

@ -29,13 +29,13 @@ describe Gitlab::Ci::Status::Pipeline::SuccessWithWarnings do
end
it 'is a correct match' do
expect(described_class.matches?(pipeline)).to eq true
expect(described_class.matches?(pipeline, double)).to eq true
end
end
context 'when pipeline does not have warnings' do
it 'does not match' do
expect(described_class.matches?(pipeline)).to eq false
expect(described_class.matches?(pipeline, double)).to eq false
end
end
end
@ -51,13 +51,13 @@ describe Gitlab::Ci::Status::Pipeline::SuccessWithWarnings do
end
it 'does not match' do
expect(described_class.matches?(pipeline)).to eq false
expect(described_class.matches?(pipeline, double)).to eq false
end
end
context 'when pipeline does not have warnings' do
it 'does not match' do
expect(described_class.matches?(pipeline)).to eq false
expect(described_class.matches?(pipeline, double)).to eq false
end
end
end

View file

@ -1,7 +1,9 @@
require 'spec_helper'
describe Gitlab::Ci::Status::Running do
subject { described_class.new(double('subject')) }
subject do
described_class.new(double('subject'), double('user'))
end
describe '#text' do
it { expect(subject.label).to eq 'running' }
@ -14,8 +16,4 @@ describe Gitlab::Ci::Status::Running do
describe '#icon' do
it { expect(subject.icon).to eq 'icon_status_running' }
end
describe '#title' do
it { expect(subject.title).to eq 'Double: running' }
end
end

View file

@ -1,7 +1,9 @@
require 'spec_helper'
describe Gitlab::Ci::Status::Skipped do
subject { described_class.new(double('subject')) }
subject do
described_class.new(double('subject'), double('user'))
end
describe '#text' do
it { expect(subject.label).to eq 'skipped' }
@ -14,8 +16,4 @@ describe Gitlab::Ci::Status::Skipped do
describe '#icon' do
it { expect(subject.icon).to eq 'icon_status_skipped' }
end
describe '#title' do
it { expect(subject.title).to eq 'Double: skipped' }
end
end

View file

@ -1,26 +1,43 @@
require 'spec_helper'
describe Gitlab::Ci::Status::Stage::Common do
let(:pipeline) { create(:ci_empty_pipeline) }
let(:stage) { build(:ci_stage, pipeline: pipeline, name: 'test') }
let(:user) { create(:user) }
let(:project) { create(:empty_project) }
let(:pipeline) { create(:ci_empty_pipeline, project: project) }
let(:stage) do
build(:ci_stage, pipeline: pipeline, name: 'test')
end
subject do
Class.new(Gitlab::Ci::Status::Core)
.new(stage).extend(described_class)
.new(stage, user).extend(described_class)
end
it 'does not have action' do
expect(subject).not_to have_action
end
it 'has details' do
expect(subject).to have_details
end
it 'links to the pipeline details page' do
expect(subject.details_path)
.to include "pipelines/#{pipeline.id}"
expect(subject.details_path)
.to include "##{stage.name}"
end
context 'when user has permission to read pipeline' do
before do
project.team << [user, :master]
end
it 'has details' do
expect(subject).to have_details
end
end
context 'when user does not have permission to read pipeline' do
it 'does not have details' do
expect(subject).not_to have_details
end
end
end

View file

@ -1,17 +1,26 @@
require 'spec_helper'
describe Gitlab::Ci::Status::Stage::Factory do
let(:pipeline) { create(:ci_empty_pipeline) }
let(:stage) { build(:ci_stage, pipeline: pipeline, name: 'test') }
let(:user) { create(:user) }
let(:project) { create(:empty_project) }
let(:pipeline) { create(:ci_empty_pipeline, project: project) }
let(:stage) do
build(:ci_stage, pipeline: pipeline, name: 'test')
end
subject do
described_class.new(stage)
described_class.new(stage, user)
end
let(:status) do
subject.fabricate!
end
before do
project.team << [user, :developer]
end
context 'when stage has a core status' do
HasStatus::AVAILABLE_STATUSES.each do |core_status|
context "when core status is #{core_status}" do

View file

@ -1,7 +1,9 @@
require 'spec_helper'
describe Gitlab::Ci::Status::Success do
subject { described_class.new(double('subject')) }
subject do
described_class.new(double('subject'), double('user'))
end
describe '#text' do
it { expect(subject.label).to eq 'passed' }
@ -14,8 +16,4 @@ describe Gitlab::Ci::Status::Success do
describe '#icon' do
it { expect(subject.icon).to eq 'icon_status_success' }
end
describe '#title' do
it { expect(subject.title).to eq 'Double: passed' }
end
end

View file

@ -0,0 +1,23 @@
require 'spec_helper'
describe Gitlab::Routing do
context 'when module is included' do
subject do
Class.new.include(described_class).new
end
it 'makes it possible to access url helpers' do
expect(subject).to respond_to(:namespace_project_path)
end
end
context 'when module is not included' do
subject do
Class.new.include(described_class.url_helpers).new
end
it 'exposes url helpers module through a method' do
expect(subject).to respond_to(:namespace_project_path)
end
end
end

View file

@ -899,21 +899,87 @@ describe Ci::Build, models: true do
end
end
describe '#retryable?' do
context 'when build is running' do
before do
build.run!
describe '#cancelable?' do
subject { build }
context 'when build is cancelable' do
context 'when build is pending' do
it { is_expected.to be_cancelable }
end
it { expect(build).not_to be_retryable }
context 'when build is running' do
before do
build.run!
end
it { is_expected.to be_cancelable }
end
end
context 'when build is finished' do
before do
build.success!
context 'when build is not cancelable' do
context 'when build is successful' do
before do
build.success!
end
it { is_expected.not_to be_cancelable }
end
it { expect(build).to be_retryable }
context 'when build is failed' do
before do
build.drop!
end
it { is_expected.not_to be_cancelable }
end
end
end
describe '#retryable?' do
subject { build }
context 'when build is retryable' do
context 'when build is successful' do
before do
build.success!
end
it { is_expected.to be_retryable }
end
context 'when build is failed' do
before do
build.drop!
end
it { is_expected.to be_retryable }
end
context 'when build is canceled' do
before do
build.cancel!
end
it { is_expected.to be_retryable }
end
end
context 'when build is not retryable' do
context 'when build is running' do
before do
build.run!
end
it { is_expected.not_to be_retryable }
end
context 'when build is skipped' do
before do
build.skip!
end
it { is_expected.not_to be_retryable }
end
end
end
@ -1180,4 +1246,13 @@ describe Ci::Build, models: true do
it { is_expected.to eq('review/master') }
end
end
describe '#detailed_status' do
let(:user) { create(:user) }
it 'returns a detailed status' do
expect(build.detailed_status(user))
.to be_a Gitlab::Ci::Status::Build::Cancelable
end
end
end

View file

@ -442,11 +442,15 @@ describe Ci::Pipeline, models: true do
end
describe '#detailed_status' do
let(:user) { create(:user) }
subject { pipeline.detailed_status(user) }
context 'when pipeline is created' do
let(:pipeline) { create(:ci_pipeline, status: :created) }
it 'returns detailed status for created pipeline' do
expect(pipeline.detailed_status.text).to eq 'created'
expect(subject.text).to eq 'created'
end
end
@ -454,7 +458,7 @@ describe Ci::Pipeline, models: true do
let(:pipeline) { create(:ci_pipeline, status: :pending) }
it 'returns detailed status for pending pipeline' do
expect(pipeline.detailed_status.text).to eq 'pending'
expect(subject.text).to eq 'pending'
end
end
@ -462,7 +466,7 @@ describe Ci::Pipeline, models: true do
let(:pipeline) { create(:ci_pipeline, status: :running) }
it 'returns detailed status for running pipeline' do
expect(pipeline.detailed_status.text).to eq 'running'
expect(subject.text).to eq 'running'
end
end
@ -470,7 +474,7 @@ describe Ci::Pipeline, models: true do
let(:pipeline) { create(:ci_pipeline, status: :success) }
it 'returns detailed status for successful pipeline' do
expect(pipeline.detailed_status.text).to eq 'passed'
expect(subject.text).to eq 'passed'
end
end
@ -478,7 +482,7 @@ describe Ci::Pipeline, models: true do
let(:pipeline) { create(:ci_pipeline, status: :failed) }
it 'returns detailed status for failed pipeline' do
expect(pipeline.detailed_status.text).to eq 'failed'
expect(subject.text).to eq 'failed'
end
end
@ -486,7 +490,7 @@ describe Ci::Pipeline, models: true do
let(:pipeline) { create(:ci_pipeline, status: :canceled) }
it 'returns detailed status for canceled pipeline' do
expect(pipeline.detailed_status.text).to eq 'canceled'
expect(subject.text).to eq 'canceled'
end
end
@ -494,7 +498,7 @@ describe Ci::Pipeline, models: true do
let(:pipeline) { create(:ci_pipeline, status: :skipped) }
it 'returns detailed status for skipped pipeline' do
expect(pipeline.detailed_status.text).to eq 'skipped'
expect(subject.text).to eq 'skipped'
end
end
@ -506,7 +510,7 @@ describe Ci::Pipeline, models: true do
end
it 'retruns detailed status for successful pipeline with warnings' do
expect(pipeline.detailed_status.label).to eq 'passed with warnings'
expect(subject.label).to eq 'passed with warnings'
end
end
end

View file

@ -68,7 +68,9 @@ describe Ci::Stage, models: true do
end
describe '#detailed_status' do
subject { stage.detailed_status }
let(:user) { create(:user) }
subject { stage.detailed_status(user) }
context 'when build is created' do
let!(:stage_build) { create_job(:ci_build, status: :created) }

View file

@ -234,4 +234,13 @@ describe CommitStatus, models: true do
end
end
end
describe '#detailed_status' do
let(:user) { create(:user) }
it 'returns a detailed status' do
expect(commit_status.detailed_status(user))
.to be_a Gitlab::Ci::Status::Success
end
end
end

View file

@ -1,8 +1,11 @@
require 'spec_helper'
describe GenericCommitStatus, models: true do
let(:pipeline) { FactoryGirl.create :ci_pipeline }
let(:generic_commit_status) { FactoryGirl.create :generic_commit_status, pipeline: pipeline }
let(:pipeline) { create(:ci_pipeline) }
let(:generic_commit_status) do
create(:generic_commit_status, pipeline: pipeline)
end
describe '#context' do
subject { generic_commit_status.context }
@ -17,6 +20,15 @@ describe GenericCommitStatus, models: true do
it { is_expected.to eq([:external]) }
end
describe '#detailed_status' do
let(:user) { create(:user) }
it 'returns detailed status object' do
expect(generic_commit_status.detailed_status(user))
.to be_a Gitlab::Ci::Status::Success
end
end
describe 'set_default_values' do
before do
generic_commit_status.context = nil

View file

@ -50,9 +50,8 @@ describe Group, models: true do
describe 'validations' do
it { is_expected.to validate_presence_of :name }
it { is_expected.to validate_uniqueness_of(:name) }
it { is_expected.to validate_uniqueness_of(:name).scoped_to(:parent_id) }
it { is_expected.to validate_presence_of :path }
it { is_expected.to validate_uniqueness_of(:path) }
it { is_expected.not_to validate_presence_of :owner }
end

View file

@ -6,20 +6,16 @@ describe Namespace, models: true do
it { is_expected.to have_many :projects }
it { is_expected.to validate_presence_of(:name) }
it { is_expected.to validate_uniqueness_of(:name) }
it { is_expected.to validate_uniqueness_of(:name).scoped_to(:parent_id) }
it { is_expected.to validate_length_of(:name).is_at_most(255) }
it { is_expected.to validate_length_of(:description).is_at_most(255) }
it { is_expected.to validate_presence_of(:path) }
it { is_expected.to validate_uniqueness_of(:path) }
it { is_expected.to validate_length_of(:path).is_at_most(255) }
it { is_expected.to validate_presence_of(:owner) }
describe "Mass assignment" do
end
describe "Respond to" do
it { is_expected.to respond_to(:human_name) }
it { is_expected.to respond_to(:to_param) }

View file

@ -475,7 +475,7 @@ describe API::Commits, api: true do
expect(response).to have_http_status(400)
expect(json_response['message']).to eq('Sorry, we cannot cherry-pick this commit automatically.
It may have already been cherry-pick, or a more recent commit may have updated some of its content.')
A cherry-pick may have already been performed with this commit, or a more recent commit may have updated some of its content.')
end
it 'returns 400 if you are not allowed to push to the target branch' do

View file

@ -66,7 +66,8 @@ describe Admin::ProjectsController, "routing" do
end
it "to #show" do
expect(get("/admin/projects/gitlab")).to route_to('admin/projects#show', namespace_id: 'gitlab')
expect(get("/admin/projects/gitlab/gitlab-ce")).to route_to('admin/projects#show', namespace_id: 'gitlab', id: 'gitlab-ce')
expect(get("/admin/projects/gitlab/subgroup/gitlab-ce")).to route_to('admin/projects#show', namespace_id: 'gitlab/subgroup', id: 'gitlab-ce')
end
end
@ -119,3 +120,14 @@ describe Admin::HealthCheckController, "routing" do
expect(get("/admin/health_check")).to route_to('admin/health_check#show')
end
end
describe Admin::GroupsController, "routing" do
it "to #index" do
expect(get("/admin/groups")).to route_to('admin/groups#index')
end
it "to #show" do
expect(get("/admin/groups/gitlab")).to route_to('admin/groups#show', id: 'gitlab')
expect(get("/admin/groups/gitlab/subgroup")).to route_to('admin/groups#show', id: 'gitlab/subgroup')
end
end