Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
2742b871
Commit
2742b871
authored
Nov 20, 2018
by
Sean McGivern
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Revert "Merge branch 'zj-improve-gitaly-pb' into 'master'"
This reverts merge request !23140
parent
79948637
Changes
18
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
1275 additions
and
756 deletions
+1275
-756
changelogs/unreleased/zj-improve-gitaly-pb.yml
changelogs/unreleased/zj-improve-gitaly-pb.yml
+0
-5
lib/gitlab/git/blob.rb
lib/gitlab/git/blob.rb
+2
-0
lib/gitlab/git/repository.rb
lib/gitlab/git/repository.rb
+6
-0
lib/gitlab/gitaly_client.rb
lib/gitlab/gitaly_client.rb
+115
-10
spec/features/projects/wiki/user_updates_wiki_page_spec.rb
spec/features/projects/wiki/user_updates_wiki_page_spec.rb
+154
-144
spec/features/projects/wiki/user_views_wiki_page_spec.rb
spec/features/projects/wiki/user_views_wiki_page_spec.rb
+117
-107
spec/lib/extracts_path_spec.rb
spec/lib/extracts_path_spec.rb
+18
-8
spec/lib/gitlab/diff/file_collection/merge_request_diff_spec.rb
...ib/gitlab/diff/file_collection/merge_request_diff_spec.rb
+12
-2
spec/lib/gitlab/git/blob_spec.rb
spec/lib/gitlab/git/blob_spec.rb
+11
-1
spec/lib/gitlab/git/commit_spec.rb
spec/lib/gitlab/git/commit_spec.rb
+111
-83
spec/lib/gitlab/git/tag_spec.rb
spec/lib/gitlab/git/tag_spec.rb
+24
-6
spec/lib/gitlab/git/tree_spec.rb
spec/lib/gitlab/git/tree_spec.rb
+12
-2
spec/lib/gitlab/gitaly_client_spec.rb
spec/lib/gitlab/gitaly_client_spec.rb
+95
-6
spec/models/merge_request_spec.rb
spec/models/merge_request_spec.rb
+40
-22
spec/models/project_wiki_spec.rb
spec/models/project_wiki_spec.rb
+145
-105
spec/models/repository_spec.rb
spec/models/repository_spec.rb
+237
-135
spec/models/wiki_page_spec.rb
spec/models/wiki_page_spec.rb
+160
-120
spec/support/gitaly.rb
spec/support/gitaly.rb
+16
-0
No files found.
changelogs/unreleased/zj-improve-gitaly-pb.yml
deleted
100644 → 0
View file @
79948637
---
title
:
Show what RPC is called in the performance bar
merge_request
:
23140
author
:
type
:
other
lib/gitlab/git/blob.rb
View file @
2742b871
# frozen_string_literal: true
# frozen_string_literal: true
# Gitaly note: JV: seems to be completely migrated (behind feature flags).
module
Gitlab
module
Gitlab
module
Git
module
Git
class
Blob
class
Blob
...
...
lib/gitlab/git/repository.rb
View file @
2742b871
...
@@ -885,6 +885,12 @@ module Gitlab
...
@@ -885,6 +885,12 @@ module Gitlab
Gitlab
::
GitalyClient
::
ConflictsService
.
new
(
self
,
our_commit_oid
,
their_commit_oid
)
Gitlab
::
GitalyClient
::
ConflictsService
.
new
(
self
,
our_commit_oid
,
their_commit_oid
)
end
end
def
gitaly_migrate
(
method
,
status:
Gitlab
::
GitalyClient
::
MigrationStatus
::
OPT_IN
,
&
block
)
wrapped_gitaly_errors
do
Gitlab
::
GitalyClient
.
migrate
(
method
,
status:
status
,
&
block
)
end
end
def
clean_stale_repository_files
def
clean_stale_repository_files
wrapped_gitaly_errors
do
wrapped_gitaly_errors
do
gitaly_repository_client
.
cleanup
if
exists?
gitaly_repository_client
.
cleanup
if
exists?
...
...
lib/gitlab/gitaly_client.rb
View file @
2742b871
...
@@ -9,6 +9,11 @@ require 'grpc/health/v1/health_services_pb'
...
@@ -9,6 +9,11 @@ require 'grpc/health/v1/health_services_pb'
module
Gitlab
module
Gitlab
module
GitalyClient
module
GitalyClient
include
Gitlab
::
Metrics
::
Methods
include
Gitlab
::
Metrics
::
Methods
module
MigrationStatus
DISABLED
=
1
OPT_IN
=
2
OPT_OUT
=
3
end
class
TooManyInvocationsError
<
StandardError
class
TooManyInvocationsError
<
StandardError
attr_reader
:call_site
,
:invocation_count
,
:max_call_stack
attr_reader
:call_site
,
:invocation_count
,
:max_call_stack
...
@@ -26,7 +31,7 @@ module Gitlab
...
@@ -26,7 +31,7 @@ module Gitlab
end
end
end
end
SERVER_VERSION_FILE
=
'GITALY_SERVER_VERSION'
SERVER_VERSION_FILE
=
'GITALY_SERVER_VERSION'
.
freeze
MAXIMUM_GITALY_CALLS
=
35
MAXIMUM_GITALY_CALLS
=
35
CLIENT_NAME
=
(
Sidekiq
.
server?
?
'gitlab-sidekiq'
:
'gitlab-web'
).
freeze
CLIENT_NAME
=
(
Sidekiq
.
server?
?
'gitlab-sidekiq'
:
'gitlab-web'
).
freeze
...
@@ -38,6 +43,11 @@ module Gitlab
...
@@ -38,6 +43,11 @@ module Gitlab
self
.
query_time
=
0
self
.
query_time
=
0
define_histogram
:gitaly_migrate_call_duration_seconds
do
docstring
"Gitaly migration call execution timings"
base_labels
gitaly_enabled:
nil
,
feature:
nil
end
define_histogram
:gitaly_controller_action_duration_seconds
do
define_histogram
:gitaly_controller_action_duration_seconds
do
docstring
"Gitaly endpoint histogram by controller and action combination"
docstring
"Gitaly endpoint histogram by controller and action combination"
base_labels
Gitlab
::
Metrics
::
Transaction
::
BASE_LABELS
.
merge
(
gitaly_service:
nil
,
rpc:
nil
)
base_labels
Gitlab
::
Metrics
::
Transaction
::
BASE_LABELS
.
merge
(
gitaly_service:
nil
,
rpc:
nil
)
...
@@ -116,6 +126,7 @@ module Gitlab
...
@@ -116,6 +126,7 @@ module Gitlab
def
self
.
call
(
storage
,
service
,
rpc
,
request
,
remote_storage:
nil
,
timeout:
nil
)
def
self
.
call
(
storage
,
service
,
rpc
,
request
,
remote_storage:
nil
,
timeout:
nil
)
start
=
Gitlab
::
Metrics
::
System
.
monotonic_time
start
=
Gitlab
::
Metrics
::
System
.
monotonic_time
request_hash
=
request
.
is_a?
(
Google
::
Protobuf
::
MessageExts
)
?
request
.
to_h
:
{}
request_hash
=
request
.
is_a?
(
Google
::
Protobuf
::
MessageExts
)
?
request
.
to_h
:
{}
@current_call_id
||=
SecureRandom
.
uuid
enforce_gitaly_request_limits
(
:call
)
enforce_gitaly_request_limits
(
:call
)
...
@@ -134,7 +145,9 @@ module Gitlab
...
@@ -134,7 +145,9 @@ module Gitlab
current_transaction_labels
.
merge
(
gitaly_service:
service
.
to_s
,
rpc:
rpc
.
to_s
),
current_transaction_labels
.
merge
(
gitaly_service:
service
.
to_s
,
rpc:
rpc
.
to_s
),
duration
)
duration
)
add_call_details
(
feature:
"
#{
service
}
#
#{
rpc
}
"
,
duration:
duration
,
request:
request_hash
,
rpc:
rpc
)
add_call_details
(
id:
@current_call_id
,
feature:
service
,
duration:
duration
,
request:
request_hash
)
@current_call_id
=
nil
end
end
def
self
.
handle_grpc_unavailable!
(
ex
)
def
self
.
handle_grpc_unavailable!
(
ex
)
...
@@ -209,7 +222,7 @@ module Gitlab
...
@@ -209,7 +222,7 @@ module Gitlab
result
result
end
end
SERVER_FEATURE_FLAGS
=
%w[]
.
freeze
SERVER_FEATURE_FLAGS
=
%w[
gogit_findcommit
]
.
freeze
def
self
.
server_feature_flags
def
self
.
server_feature_flags
SERVER_FEATURE_FLAGS
.
map
do
|
f
|
SERVER_FEATURE_FLAGS
.
map
do
|
f
|
...
@@ -224,8 +237,82 @@ module Gitlab
...
@@ -224,8 +237,82 @@ module Gitlab
params
[
'gitaly_token'
].
presence
||
Gitlab
.
config
.
gitaly
[
'token'
]
params
[
'gitaly_token'
].
presence
||
Gitlab
.
config
.
gitaly
[
'token'
]
end
end
def
self
.
feature_enabled?
(
feature_name
)
# Evaluates whether a feature toggle is on or off
Feature
.
enabled?
(
"gitaly_
#{
feature_name
}
"
)
def
self
.
feature_enabled?
(
feature_name
,
status:
MigrationStatus
::
OPT_IN
)
# Disabled features are always off!
return
false
if
status
==
MigrationStatus
::
DISABLED
feature
=
Feature
.
get
(
"gitaly_
#{
feature_name
}
"
)
# If the feature has been set, always evaluate
if
Feature
.
persisted?
(
feature
)
if
feature
.
percentage_of_time_value
>
0
# Probabilistically enable this feature
return
Random
.
rand
()
*
100
<
feature
.
percentage_of_time_value
end
return
feature
.
enabled?
end
# If the feature has not been set, the default depends
# on it's status
case
status
when
MigrationStatus
::
OPT_OUT
true
when
MigrationStatus
::
OPT_IN
opt_into_all_features?
&&
!
explicit_opt_in_required
.
include?
(
feature_name
)
else
false
end
rescue
=>
ex
# During application startup feature lookups in SQL can fail
Rails
.
logger
.
warn
"exception while checking Gitaly feature status for
#{
feature_name
}
:
#{
ex
}
"
false
end
# We have a mechanism to let GitLab automatically opt in to all Gitaly
# features. We want to be able to exclude some features from automatic
# opt-in. This function has an override in EE.
def
self
.
explicit_opt_in_required
[]
end
# opt_into_all_features? returns true when the current environment
# is one in which we opt into features automatically
def
self
.
opt_into_all_features?
Rails
.
env
.
development?
||
ENV
[
"GITALY_FEATURE_DEFAULT_ON"
]
==
"1"
end
private_class_method
:opt_into_all_features?
def
self
.
migrate
(
feature
,
status:
MigrationStatus
::
OPT_IN
)
# Enforce limits at both the `migrate` and `call` sites to ensure that
# problems are not hidden by a feature being disabled
enforce_gitaly_request_limits
(
:migrate
)
is_enabled
=
feature_enabled?
(
feature
,
status:
status
)
metric_name
=
feature
.
to_s
metric_name
+=
"_gitaly"
if
is_enabled
Gitlab
::
Metrics
.
measure
(
metric_name
)
do
# Some migrate calls wrap other migrate calls
allow_n_plus_1_calls
do
feature_stack
=
Thread
.
current
[
:gitaly_feature_stack
]
||=
[]
feature_stack
.
unshift
(
feature
)
begin
start
=
Gitlab
::
Metrics
::
System
.
monotonic_time
@current_call_id
=
SecureRandom
.
uuid
call_details
=
{
id:
@current_call_id
}
yield
is_enabled
ensure
total_time
=
Gitlab
::
Metrics
::
System
.
monotonic_time
-
start
gitaly_migrate_call_duration_seconds
.
observe
({
gitaly_enabled:
is_enabled
,
feature:
feature
},
total_time
)
feature_stack
.
shift
Thread
.
current
[
:gitaly_feature_stack
]
=
nil
if
feature_stack
.
empty?
add_call_details
(
call_details
.
merge
(
feature:
feature
,
duration:
total_time
))
end
end
end
end
end
# Ensures that Gitaly is not being abuse through n+1 misuse etc
# Ensures that Gitaly is not being abuse through n+1 misuse etc
...
@@ -281,20 +368,38 @@ module Gitlab
...
@@ -281,20 +368,38 @@ module Gitlab
end
end
private_class_method
:decrement_call_count
private_class_method
:decrement_call_count
# Returns the of the number of Gitaly calls made for this request
# Returns an estimate of the number of Gitaly calls made for this
# request
def
self
.
get_request_count
def
self
.
get_request_count
get_call_count
(
"gitaly_call_actual"
)
return
0
unless
Gitlab
::
SafeRequestStore
.
active?
gitaly_migrate_count
=
get_call_count
(
"gitaly_migrate_actual"
)
gitaly_call_count
=
get_call_count
(
"gitaly_call_actual"
)
# Using the maximum of migrate and call_count will provide an
# indicator of how many Gitaly calls will be made, even
# before a feature is enabled. This provides us with a single
# metric, but not an exact number, but this tradeoff is acceptable
if
gitaly_migrate_count
>
gitaly_call_count
gitaly_migrate_count
else
gitaly_call_count
end
end
end
def
self
.
reset_counts
def
self
.
reset_counts
return
unless
Gitlab
::
SafeRequestStore
.
active?
return
unless
Gitlab
::
SafeRequestStore
.
active?
Gitlab
::
SafeRequestStore
[
"gitaly_call_actual"
]
=
0
%w[migrate call]
.
each
do
|
call_site
|
Gitlab
::
SafeRequestStore
[
"gitaly_call_permitted"
]
=
0
Gitlab
::
SafeRequestStore
[
"gitaly_
#{
call_site
}
_actual"
]
=
0
Gitlab
::
SafeRequestStore
[
"gitaly_
#{
call_site
}
_permitted"
]
=
0
end
end
end
def
self
.
add_call_details
(
details
)
def
self
.
add_call_details
(
details
)
return
unless
Gitlab
::
SafeRequestStore
[
:peek_enabled
]
id
=
details
.
delete
(
:id
)
return
unless
id
&&
Gitlab
::
SafeRequestStore
[
:peek_enabled
]
Gitlab
::
SafeRequestStore
[
'gitaly_call_details'
]
||=
{}
Gitlab
::
SafeRequestStore
[
'gitaly_call_details'
]
||=
{}
Gitlab
::
SafeRequestStore
[
'gitaly_call_details'
][
id
]
||=
{}
Gitlab
::
SafeRequestStore
[
'gitaly_call_details'
][
id
]
||=
{}
...
...
spec/features/projects/wiki/user_updates_wiki_page_spec.rb
View file @
2742b871
require
'spec_helper'
require
'spec_helper'
describe
'User updates wiki page'
do
describe
'User updates wiki page'
do
let
(
:user
)
{
create
(
:user
)
}
shared_examples
'wiki page user update'
do
let
(
:user
)
{
create
(
:user
)
}
before
do
project
.
add_maintainer
(
user
)
sign_in
(
user
)
end
context
'when wiki is empty'
do
before
do
before
do
visit
(
project_wikis_path
(
project
)
)
project
.
add_maintainer
(
user
)
click_link
"Create your first page"
sign_in
(
user
)
end
end
context
'in a user namespace'
do
context
'when wiki is empty'
do
let
(
:project
)
{
create
(
:project
,
:wiki_repo
)
}
before
do
visit
(
project_wikis_path
(
project
))
click_link
"Create your first page"
end
context
'in a user namespace'
do
let
(
:project
)
{
create
(
:project
,
:wiki_repo
,
namespace:
user
.
namespace
)
}
it
'redirects back to the home edit page'
do
it
'redirects back to the home edit page'
do
page
.
within
(
:css
,
'.wiki-form .form-actions'
)
do
page
.
within
(
:css
,
'.wiki-form .form-actions'
)
do
click_on
(
'Cancel'
)
click_on
(
'Cancel'
)
end
expect
(
current_path
).
to
eq
project_wiki_path
(
project
,
:home
)
end
end
expect
(
current_path
).
to
eq
project_wiki_path
(
project
,
:home
)
it
'updates a page that has a path'
,
:js
do
end
click_on
(
'New page'
)
it
'updates a page that has a path'
,
:js
do
page
.
within
(
'#modal-new-wiki'
)
do
click_on
(
'New page'
)
fill_in
(
:new_wiki_path
,
with:
'one/two/three-test'
)
click_on
(
'Create page'
)
end
page
.
within
(
'#modal-new-wiki'
)
do
page
.
within
'.wiki-form'
do
fill_in
(
:new_wiki_path
,
with:
'one/two/three-tes
t'
)
fill_in
(
:wiki_content
,
with:
'wiki conten
t'
)
click_on
(
'Create page'
)
click_on
(
'Create page'
)
end
end
page
.
within
'.wiki-form'
do
expect
(
current_path
).
to
include
(
'one/two/three-test'
)
fill_in
(
:wiki_content
,
with:
'wiki content'
)
expect
(
find
(
'.wiki-pages'
)).
to
have_content
(
'Three'
)
click_on
(
'Create page'
)
end
expect
(
current_path
).
to
include
(
'one/two/three-test'
)
first
(
:link
,
text:
'Three'
).
click
expect
(
find
(
'.wiki-pages'
)).
to
have_content
(
'Three'
)
first
(
:link
,
text:
'Three'
).
click
expect
(
find
(
'.nav-text'
)).
to
have_content
(
'Three'
)
expect
(
find
(
'.nav-text'
)).
to
have_content
(
'Three
'
)
click_on
(
'Edit
'
)
click_on
(
'Edit'
)
expect
(
current_path
).
to
include
(
'one/two/three-test'
)
expect
(
page
).
to
have_content
(
'Edit Page'
)
expect
(
current_path
).
to
include
(
'one/two/three-tes
t'
)
fill_in
(
'Content'
,
with:
'Updated Wiki Conten
t'
)
expect
(
page
).
to
have_content
(
'Edit Page
'
)
click_on
(
'Save changes
'
)
fill_in
(
'Content'
,
with:
'Updated Wiki Content'
)
expect
(
page
).
to
have_content
(
'Updated Wiki Content'
)
click_on
(
'Save changes'
)
end
expect
(
page
).
to
have_content
(
'Updated Wiki Content'
)
it_behaves_like
'wiki file attachments'
end
end
it_behaves_like
'wiki file attachments'
end
end
end
context
'when wiki is not empty'
do
context
'when wiki is not empty'
do
let
(
:project_wiki
)
{
create
(
:project_wiki
,
project:
project
,
user:
project
.
creator
)
}
let
(
:project_wiki
)
{
create
(
:project_wiki
,
project:
project
,
user:
project
.
creator
)
}
let!
(
:wiki_page
)
{
create
(
:wiki_page
,
wiki:
project_wiki
,
attrs:
{
title:
'home'
,
content:
'Home page'
})
}
let!
(
:wiki_page
)
{
create
(
:wiki_page
,
wiki:
project_wiki
,
attrs:
{
title:
'home'
,
content:
'Home page'
})
}
before
do
before
do
visit
(
project_wikis_path
(
project
))
visit
(
project_wikis_path
(
project
))
click_link
(
'Edit'
)
click_link
(
'Edit'
)
end
end
context
'in a user namespace'
do
context
'in a user namespace'
do
let
(
:project
)
{
create
(
:project
,
:wiki_repo
)
}
let
(
:project
)
{
create
(
:project
,
:wiki_repo
,
namespace:
user
.
namespace
)
}
it
'updates a page'
do
it
'updates a page'
do
# Commit message field should have correct value.
# Commit message field should have correct value.
expect
(
page
).
to
have_field
(
'wiki[message]'
,
with:
'Update home'
)
expect
(
page
).
to
have_field
(
'wiki[message]'
,
with:
'Update home'
)
fill_in
(
:wiki_content
,
with:
'My awesome wiki!'
)
fill_in
(
:wiki_content
,
with:
'My awesome wiki!'
)
click_button
(
'Save changes'
)
click_button
(
'Save changes'
)
expect
(
page
).
to
have_content
(
'Home'
)
expect
(
page
).
to
have_content
(
'Home'
)
expect
(
page
).
to
have_content
(
"Last edited by
#{
user
.
name
}
"
)
expect
(
page
).
to
have_content
(
"Last edited by
#{
user
.
name
}
"
)
expect
(
page
).
to
have_content
(
'My awesome wiki!'
)
expect
(
page
).
to
have_content
(
'My awesome wiki!'
)
end
end
it
'shows a validation error message'
do
it
'shows a validation error message'
do
fill_in
(
:wiki_content
,
with:
''
)
fill_in
(
:wiki_content
,
with:
''
)
click_button
(
'Save changes'
)
click_button
(
'Save changes'
)
expect
(
page
).
to
have_selector
(
'.wiki-form'
)
expect
(
page
).
to
have_selector
(
'.wiki-form'
)
expect
(
page
).
to
have_content
(
'Edit Page'
)
expect
(
page
).
to
have_content
(
'Edit Page'
)
expect
(
page
).
to
have_content
(
'The form contains the following error:'
)
expect
(
page
).
to
have_content
(
'The form contains the following error:'
)
expect
(
page
).
to
have_content
(
"Content can't be blank"
)
expect
(
page
).
to
have_content
(
"Content can't be blank"
)
expect
(
find
(
'textarea#wiki_content'
).
value
).
to
eq
(
''
)
expect
(
find
(
'textarea#wiki_content'
).
value
).
to
eq
(
''
)
end
end
it
'shows the emoji autocompletion dropdown'
,
:js
do
it
'shows the emoji autocompletion dropdown'
,
:js
do
find
(
'#wiki_content'
).
native
.
send_keys
(
''
)
find
(
'#wiki_content'
).
native
.
send_keys
(
''
)
fill_in
(
:wiki_content
,
with:
':'
)
fill_in
(
:wiki_content
,
with:
':'
)
expect
(
page
).
to
have_selector
(
'.atwho-view'
)
expect
(
page
).
to
have_selector
(
'.atwho-view'
)
end
end
it
'shows the error message'
do
it
'shows the error message'
do
wiki_page
.
update
(
content:
'Update'
)
wiki_page
.
update
(
content:
'Update'
)
click_button
(
'Save changes'
)
click_button
(
'Save changes'
)
expect
(
page
).
to
have_content
(
'Someone edited the page the same time you did.'
)
expect
(
page
).
to
have_content
(
'Someone edited the page the same time you did.'
)
end
end
it
'updates a page'
do
it
'updates a page'
do
fill_in
(
'Content'
,
with:
'Updated Wiki Content'
)
fill_in
(
'Content'
,
with:
'Updated Wiki Content'
)
click_on
(
'Save changes'
)
click_on
(
'Save changes'
)
expect
(
page
).
to
have_content
(
'Updated Wiki Content'
)
expect
(
page
).
to
have_content
(
'Updated Wiki Content'
)
end
end
it
'cancels editing of a page'
do
it
'cancels editing of a page'
do
page
.
within
(
:css
,
'.wiki-form .form-actions'
)
do
page
.
within
(
:css
,
'.wiki-form .form-actions'
)
do
click_on
(
'Cancel'
)
click_on
(
'Cancel'
)
end
expect
(
current_path
).
to
eq
(
project_wiki_path
(
project
,
wiki_page
))
end
end
expect
(
current_path
).
to
eq
(
project_wiki_path
(
project
,
wiki_page
))
it_behaves_like
'wiki file attachments'
end
end
it_behaves_like
'wiki file attachments'
context
'in a group namespace'
do
end
let
(
:project
)
{
create
(
:project
,
:wiki_repo
,
namespace:
create
(
:group
,
:public
))
}
context
'in a group namespace'
do
it
'updates a page'
do
let
(
:project
)
{
create
(
:project
,
:wiki_repo
,
namespace:
create
(
:group
,
:public
))
}
# Commit message field should have correct value.
expect
(
page
).
to
have_field
(
'wiki[message]'
,
with:
'Update home'
)
it
'updates a page'
do
fill_in
(
:wiki_content
,
with:
'My awesome wiki!'
)
# Commit message field should have correct value.
expect
(
page
).
to
have_field
(
'wiki[message]'
,
with:
'Update home'
)
fill_in
(
:wiki_content
,
with:
'My awesome wiki!
'
)
click_button
(
'Save changes
'
)
click_button
(
'Save changes'
)
expect
(
page
).
to
have_content
(
'Home'
)
expect
(
page
).
to
have_content
(
"Last edited by
#{
user
.
name
}
"
)
expect
(
page
).
to
have_content
(
'My awesome wiki!'
)
end
expect
(
page
).
to
have_content
(
'Home'
)
it_behaves_like
'wiki file attachments'
expect
(
page
).
to
have_content
(
"Last edited by
#{
user
.
name
}
"
)
expect
(
page
).
to
have_content
(
'My awesome wiki!'
)
end
end
it_behaves_like
'wiki file attachments'
end
end
end
context
'when the page is in a subdir'
do
context
'when the page is in a subdir'
do
let!
(
:project
)
{
create
(
:project
,
:wiki_repo
)
}
let!
(
:project
)
{
create
(
:project
,
:wiki_repo
,
namespace:
user
.
namespace
)
}
let
(
:project_wiki
)
{
create
(
:project_wiki
,
project:
project
,
user:
project
.
creator
)
}
let
(
:project_wiki
)
{
create
(
:project_wiki
,
project:
project
,
user:
project
.
creator
)
}
let
(
:page_name
)
{
'page_name'
}
let
(
:page_name
)
{
'page_name'
}
let
(
:page_dir
)
{
"foo/bar/
#{
page_name
}
"
}
let
(
:page_dir
)
{
"foo/bar/
#{
page_name
}
"
}
let!
(
:wiki_page
)
{
create
(
:wiki_page
,
wiki:
project_wiki
,
attrs:
{
title:
page_dir
,
content:
'Home page'
})
}
let!
(
:wiki_page
)
{
create
(
:wiki_page
,
wiki:
project_wiki
,
attrs:
{
title:
page_dir
,
content:
'Home page'
})
}
before
do
before
do
visit
(
project_wiki_edit_path
(
project
,
wiki_page
))
visit
(
project_wiki_edit_path
(
project
,
wiki_page
))
end
end
it
'moves the page to the root folder'
do
it
'moves the page to the root folder'
,
:skip_gitaly_mock
do
fill_in
(
:wiki_title
,
with:
"/
#{
page_name
}
"
)
fill_in
(
:wiki_title
,
with:
"/
#{
page_name
}
"
)
click_button
(
'Save changes'
)
click_button
(
'Save changes'
)
expect
(
current_path
).
to
eq
(
project_wiki_path
(
project
,
page_name
))
expect
(
current_path
).
to
eq
(
project_wiki_path
(
project
,
page_name
))
end
end
it
'moves the page to other dir'
do
it
'moves the page to other dir'
do
new_page_dir
=
"foo1/bar1/
#{
page_name
}
"
new_page_dir
=
"foo1/bar1/
#{
page_name
}
"
fill_in
(
:wiki_title
,
with:
new_page_dir
)
fill_in
(
:wiki_title
,
with:
new_page_dir
)
click_button
(
'Save changes'
)
click_button
(
'Save changes'
)
expect
(
current_path
).
to
eq
(
project_wiki_path
(
project
,
new_page_dir
))
expect
(
current_path
).
to
eq
(
project_wiki_path
(
project
,
new_page_dir
))
end
end
it
'remains in the same place if title has not changed'
do
original_path
=
project_wiki_path
(
project
,
wiki_page
)
it
'remains in the same place if title has not changed'
do
fill_in
(
:wiki_title
,
with:
page_name
)
original_path
=
project_wiki_path
(
project
,
wiki_page
)
fill_in
(
:wiki_title
,
with:
page_name
)
click_button
(
'Save changes'
)
click_button
(
'Save changes'
)
expect
(
current_path
).
to
eq
(
original_path
)
end
expect
(
current_path
).
to
eq
(
original_path
)
it
'can be moved to a different dir with a different name'
do
end
new_page_dir
=
"foo1/bar1/new_page_name"
it
'can be moved to a different dir with a different name'
do
fill_in
(
:wiki_title
,
with:
new_page_dir
)
new_page_dir
=
"foo1/bar1/new_page_name"
fill_in
(
:wiki_title
,
with:
new_page_dir
)
click_button
(
'Save changes'
)
click_button
(
'Save changes'
)
expect
(
current_path
).
to
eq
(
project_wiki_path
(
project
,
new_page_dir
))
end
expect
(
current_path
).
to
eq
(
project_wiki_path
(
project
,
new_page_dir
))
it
'can be renamed and moved to the root folder'
do
end
new_name
=
'new_page_name'
it
'can be renamed and moved to the root folder'
do
fill_in
(
:wiki_title
,
with:
"/
#{
new_name
}
"
)
new_name
=
'new_page_name'
fill_in
(
:wiki_title
,
with:
"/
#{
new_name
}
"
)
click_button
(
'Save changes'
)
click_button
(
'Save changes'
)
expect
(
current_path
).
to
eq
(
project_wiki_path
(
project
,
new_name
))
end
expect
(
current_path
).
to
eq
(
project_wiki_path
(
project
,
new_name
))
it
'squishes the title before creating the page'
do
end
new_page_dir
=
" foo1 / bar1 /
#{
page_name
}
"
it
'squishes the title before creating the page'
do
fill_in
(
:wiki_title
,
with:
new_page_dir
)
new_page_dir
=
" foo1 / bar1 /
#{
page_name
}
"
fill_in
(
:wiki_title
,
with:
new_page_dir
)
click_button
(
'Save changes'
)
click_button
(
'Save changes'
)
expect
(
current_path
).
to
eq
(
project_wiki_path
(
project
,
"foo1/bar1/
#{
page_name
}
"
))
end
expect
(
current_path
).
to
eq
(
project_wiki_path
(
project
,
"foo1/bar1/
#{
page_name
}
"
))
it_behaves_like
'wiki file attachments'
end
end
end
context
'when Gitaly is enabled'
do
it_behaves_like
'wiki page user update'
end
it_behaves_like
'wiki file attachments'
context
'when Gitaly is disabled'
,
:skip_gitaly_mock
do
it_behaves_like
'wiki page user update'
end
end
end
end
spec/features/projects/wiki/user_views_wiki_page_spec.rb
View file @
2742b871
require
'spec_helper'
require
'spec_helper'
describe
'User views a wiki page'
do
describe
'User views a wiki page'
do
include
WikiHelpers
shared_examples
'wiki page user view'
do
include
WikiHelpers
let
(
:user
)
{
create
(
:user
)
}
let
(
:project
)
{
create
(
:project
,
:wiki_repo
,
namespace:
user
.
namespace
)
}
let
(
:user
)
{
create
(
:user
)
}
let
(
:path
)
{
'image.png'
}
let
(
:project
)
{
create
(
:project
,
:wiki_repo
,
namespace:
user
.
namespace
)
}
let
(
:wiki_page
)
do
let
(
:path
)
{
'image.png'
}
create
(
:wiki_page
,
let
(
:wiki_page
)
do
wiki:
project
.
wiki
,
create
(
:wiki_page
,
attrs:
{
title:
'home'
,
content:
"Look at this [image](
#{
path
}
)
\n\n
![alt text](
#{
path
}
)"
})
wiki:
project
.
wiki
,
end
attrs:
{
title:
'home'
,
content:
"Look at this [image](
#{
path
}
)
\n\n
![alt text](
#{
path
}
)"
})
end
before
do
project
.
add_maintainer
(
user
)
sign_in
(
user
)
end
context
'when wiki is empty'
do
before
do
before
do
visit
(
project_wikis_path
(
project
))
project
.
add_maintainer
(
user
)
click_link
"Create your first page"
sign_in
(
user
)
end
click_on
(
'New page'
)
context
'when wiki is empty'
do
before
do
visit
(
project_wikis_path
(
project
))
click_link
"Create your first page"
page
.
within
(
'#modal-new-wiki'
)
do
click_on
(
'New page'
)
fill_in
(
:new_wiki_path
,
with:
'one/two/three-test'
)
click_on
(
'Create page'
)
page
.
within
(
'#modal-new-wiki'
)
do
end
fill_in
(
:new_wiki_path
,
with:
'one/two/three-test'
)
click_on
(
'Create page'
)
end
page
.
within
(
'.wiki-form'
)
do
page
.
within
(
'.wiki-form'
)
do
fill_in
(
:wiki_content
,
with:
'wiki content'
)
fill_in
(
:wiki_content
,
with:
'wiki content'
)
click_on
(
'Create page'
)
click_on
(
'Create page'
)
end
end
end
end
it
'shows the history of a page that has a path'
,
:js
do
it
'shows the history of a page that has a path'
,
:js
do
expect
(
current_path
).
to
include
(
'one/two/three-test'
)
expect
(
current_path
).
to
include
(
'one/two/three-test'
)
first
(
:link
,
text:
'Three'
).
click
first
(
:link
,
text:
'Three'
).
click
click_on
(
'Page history'
)
click_on
(
'Page history'
)
expect
(
current_path
).
to
include
(
'one/two/three-test'
)
expect
(
current_path
).
to
include
(
'one/two/three-test'
)
page
.
within
(
:css
,
'.nav-text'
)
do
page
.
within
(
:css
,
'.nav-text'
)
do
expect
(
page
).
to
have_content
(
'History'
)
expect
(
page
).
to
have_content
(
'History'
)
end
end
end
end
it
'shows an old version of a page'
,
:js
do
it
'shows an old version of a page'
,
:js
do
expect
(
current_path
).
to
include
(
'one/two/three-test'
)
expect
(
current_path
).
to
include
(
'one/two/three-test'
)
expect
(
find
(
'.wiki-pages'
)).
to
have_content
(
'Three'
)
expect
(
find
(
'.wiki-pages'
)).
to
have_content
(
'Three'
)
first
(
:link
,
text:
'Three'
).
click
first
(
:link
,
text:
'Three'
).
click
expect
(
find
(
'.nav-text'
)).
to
have_content
(
'Three'
)
expect
(
find
(
'.nav-text'
)).
to
have_content
(
'Three'
)
click_on
(
'Edit'
)
click_on
(
'Edit'
)
expect
(
current_path
).
to
include
(
'one/two/three-test'
)
expect
(
current_path
).
to
include
(
'one/two/three-test'
)
expect
(
page
).
to
have_content
(
'Edit Page'
)
expect
(
page
).
to
have_content
(
'Edit Page'
)
fill_in
(
'Content'
,
with:
'Updated Wiki Content'
)
fill_in
(
'Content'
,
with:
'Updated Wiki Content'
)
click_on
(
'Save changes'
)
click_on
(
'Save changes'
)
click_on
(
'Page history'
)
click_on
(
'Page history'
)
page
.
within
(
:css
,
'.nav-text'
)
do
page
.
within
(
:css
,
'.nav-text'
)
do
expect
(
page
).
to
have_content
(
'History'
)
expect
(
page
).
to
have_content
(
'History'
)
end
end
find
(
'a[href*="?version_id"]'
)
find
(
'a[href*="?version_id"]'
)
end
end
end
end
context
'when a page does not have history'
do
context
'when a page does not have history'
do
before
do
before
do
visit
(
project_wiki_path
(
project
,
wiki_page
))
visit
(
project_wiki_path
(
project
,
wiki_page
))
end
end
it
'shows all the pages'
do
it
'shows all the pages'
do
expect
(
page
).
to
have_content
(
user
.
name
)
expect
(
page
).
to
have_content
(
user
.
name
)
expect
(
find
(
'.wiki-pages'
)).
to
have_content
(
wiki_page
.
title
.
capitalize
)
expect
(
find
(
'.wiki-pages'
)).
to
have_content
(
wiki_page
.
title
.
capitalize
)
end
end
context
'shows a file stored in a page'
do
let
(
:path
)
{
upload_file_to_wiki
(
project
,
user
,
'dk.png'
)
}
it
do
expect
(
page
).
to
have_xpath
(
"//img[@data-src='
#{
project
.
wiki
.
wiki_base_path
}
/
#{
path
}
']"
)
expect
(
page
).
to
have_link
(
'image'
,
href:
"
#{
project
.
wiki
.
wiki_base_path
}
/
#{
path
}
"
)
click_on
(
'image'
)
context
'shows a file stored in a page'
do
expect
(
current_path
).
to
match
(
"wikis/
#{
path
}
"
)
let
(
:path
)
{
upload_file_to_wiki
(
project
,
user
,
'dk.png'
)
}
expect
(
page
).
not_to
have_xpath
(
'/html'
)
# Page should render the image which means there is no html involved
end
end
it
do
it
'shows the creation page if file does not exist'
do
expect
(
page
).
to
have_xpath
(
"//img[@data-src='
#{
project
.
wiki
.
wiki_base_path
}
/
#{
path
}
']"
)
expect
(
page
).
to
have_link
(
'image'
,
href:
"
#{
project
.
wiki
.
wiki_base_path
}
/
#{
path
}
"
)
expect
(
page
).
to
have_link
(
'image'
,
href:
"
#{
project
.
wiki
.
wiki_base_path
}
/
#{
path
}
"
)
click_on
(
'image'
)
click_on
(
'image'
)
expect
(
current_path
).
to
match
(
"wikis/
#{
path
}
"
)
expect
(
current_path
).
to
match
(
"wikis/
#{
path
}
"
)
expect
(
page
).
not_to
have_xpath
(
'/html'
)
# Page should render the image which means there is no html involved
expect
(
page
).
to
have_content
(
'New Wiki Page'
)
expect
(
page
).
to
have_content
(
'Create page'
)
end
end
end
end
it
'shows the creation page if file does not exist'
do
context
'when a page has history'
do
expect
(
page
).
to
have_link
(
'image'
,
href:
"
#{
project
.
wiki
.
wiki_base_path
}
/
#{
path
}
"
)
before
do
wiki_page
.
update
(
message:
'updated home'
,
content:
'updated [some link](other-page)'
)
end
click_on
(
'image'
)
it
'shows the page history'
do
visit
(
project_wiki_path
(
project
,
wiki_page
))
expect
(
current_path
).
to
match
(
"wikis/
#{
path
}
"
)
expect
(
page
).
to
have_selector
(
'a.btn'
,
text:
'Edit'
)
expect
(
page
).
to
have_content
(
'New Wiki Page'
)
expect
(
page
).
to
have_content
(
'Create page'
)
end
end
context
'when a page has history'
do
click_on
(
'Page history'
)
before
do
wiki_page
.
update
(
message:
'updated home'
,
content:
'updated [some link](other-page)'
)
end
it
'shows the page history'
do
expect
(
page
).
to
have_content
(
user
.
name
)
visit
(
project_wiki_path
(
project
,
wiki_page
)
)
expect
(
page
).
to
have_content
(
"
#{
user
.
username
}
created page: home"
)
expect
(
page
).
to
have_content
(
'updated home'
)
e
xpect
(
page
).
to
have_selector
(
'a.btn'
,
text:
'Edit'
)
e
nd
click_on
(
'Page history'
)
it
'does not show the "Edit" button'
do
visit
(
project_wiki_path
(
project
,
wiki_page
,
version_id:
wiki_page
.
versions
.
last
.
id
))
expect
(
page
).
to
have_content
(
user
.
name
)
expect
(
page
).
not_to
have_selector
(
'a.btn'
,
text:
'Edit'
)
expect
(
page
).
to
have_content
(
"
#{
user
.
username
}
created page: home"
)
end
expect
(
page
).
to
have_content
(
'updated home'
)
end
end
it
'does not show the "Edit" button
'
do
context
'when page has invalid content encoding
'
do
visit
(
project_wiki_path
(
project
,
wiki_page
,
version_id:
wiki_page
.
versions
.
last
.
id
))
let
(
:content
)
{
'whatever'
.
force_encoding
(
'ISO-8859-1'
)
}
expect
(
page
).
not_to
have_selector
(
'a.btn'
,
text:
'Edit'
)
before
do
end
allow
(
Gitlab
::
EncodingHelper
).
to
receive
(
:encode!
).
and_return
(
content
)
end
context
'when page has invalid content encoding'
do
visit
(
project_wiki_path
(
project
,
wiki_page
))
let
(
:content
)
{
'whatever'
.
force_encoding
(
'ISO-8859-1'
)
}
end
before
do
it
'does not show "Edit" button'
do
allow
(
Gitlab
::
EncodingHelper
).
to
receive
(
:encode!
).
and_return
(
content
)
expect
(
page
).
not_to
have_selector
(
'a.btn'
,
text:
'Edit'
)
end
visit
(
project_wiki_path
(
project
,
wiki_page
))
it
'shows error'
do
page
.
within
(
:css
,
'.flash-notice'
)
do
expect
(
page
).
to
have_content
(
'The content of this page is not encoded in UTF-8. Edits can only be made via the Git repository.'
)
end
end
end
end
it
'does not show "Edit" button'
do
it
'opens a default wiki page'
,
:js
do
expect
(
page
).
not_to
have_selector
(
'a.btn'
,
text:
'Edit'
)
visit
(
project_path
(
project
))
end
it
'shows error'
do
find
(
'.shortcuts-wiki'
).
click
page
.
within
(
:css
,
'.flash-notice'
)
do
click_link
"Create your first page"
expect
(
page
).
to
have_content
(
'The content of this page is not encoded in UTF-8. Edits can only be made via the Git repository.'
)
e
nd
e
xpect
(
page
).
to
have_content
(
'Home · Create Page'
)
end
end
end
end
it
'opens a default wiki page'
,
:js
do
context
'when Gitaly is enabled'
do
visit
(
project_path
(
project
))
it_behaves_like
'wiki page user view'
end
find
(
'.shortcuts-wiki'
).
click
click_link
"Create your first page"
expect
(
page
).
to
have_content
(
'Home · Create Page'
)
context
'when Gitaly is disabled'
,
:skip_gitaly_mock
do
it_behaves_like
'wiki page user view'
end
end
end
end
spec/lib/extracts_path_spec.rb
View file @
2742b871
...
@@ -205,18 +205,28 @@ describe ExtractsPath do
...
@@ -205,18 +205,28 @@ describe ExtractsPath do
end
end
describe
'#lfs_blob_ids'
do
describe
'#lfs_blob_ids'
do
let
(
:tag
)
{
@project
.
repository
.
add_tag
(
@project
.
owner
,
'my-annotated-tag'
,
'master'
,
'test tag'
)
}
shared_examples
'#lfs_blob_ids'
do
let
(
:ref
)
{
tag
.
target
}
let
(
:tag
)
{
@project
.
repository
.
add_tag
(
@project
.
owner
,
'my-annotated-tag'
,
'master'
,
'test tag'
)
}
let
(
:params
)
{
{
ref:
ref
,
path:
'README.md'
}
}
let
(
:ref
)
{
tag
.
target
}
let
(
:params
)
{
{
ref:
ref
,
path:
'README.md'
}
}
before
do
before
do
@project
=
create
(
:project
,
:repository
)
@project
=
create
(
:project
,
:repository
)
end
it
'handles annotated tags'
do
assign_ref_vars
expect
(
lfs_blob_ids
).
to
eq
([])
end
end
end
it
'handles annotated tags'
do
context
'when gitaly is enabled'
do
assign_ref_vars
it_behaves_like
'#lfs_blob_ids'
end
expect
(
lfs_blob_ids
).
to
eq
([])
context
'when gitaly is disabled'
,
:skip_gitaly_mock
do
it_behaves_like
'#lfs_blob_ids'
end
end
end
end
end
end
spec/lib/gitlab/diff/file_collection/merge_request_diff_spec.rb
View file @
2742b871
...
@@ -37,7 +37,17 @@ describe Gitlab::Diff::FileCollection::MergeRequestDiff do
...
@@ -37,7 +37,17 @@ describe Gitlab::Diff::FileCollection::MergeRequestDiff do
let
(
:stub_path
)
{
'.gitignore'
}
let
(
:stub_path
)
{
'.gitignore'
}
end
end
it
'returns a valid instance of a DiffCollection'
do
shared_examples
'initializes a DiffCollection'
do
expect
(
diff_files
).
to
be_a
(
Gitlab
::
Git
::
DiffCollection
)
it
'returns a valid instance of a DiffCollection'
do
expect
(
diff_files
).
to
be_a
(
Gitlab
::
Git
::
DiffCollection
)
end
end
context
'with Gitaly disabled'
,
:disable_gitaly
do
it_behaves_like
'initializes a DiffCollection'
end
context
'with Gitaly enabled'
do
it_behaves_like
'initializes a DiffCollection'
end
end
end
end
spec/lib/gitlab/git/blob_spec.rb
View file @
2742b871
...
@@ -128,7 +128,7 @@ describe Gitlab::Git::Blob, :seed_helper do
...
@@ -128,7 +128,7 @@ describe Gitlab::Git::Blob, :seed_helper do
end
end
end
end
describe
'.raw
'
do
shared_examples
'finding blobs by ID
'
do
let
(
:raw_blob
)
{
Gitlab
::
Git
::
Blob
.
raw
(
repository
,
SeedRepo
::
RubyBlob
::
ID
)
}
let
(
:raw_blob
)
{
Gitlab
::
Git
::
Blob
.
raw
(
repository
,
SeedRepo
::
RubyBlob
::
ID
)
}
let
(
:bad_blob
)
{
Gitlab
::
Git
::
Blob
.
raw
(
repository
,
SeedRepo
::
BigCommit
::
ID
)
}
let
(
:bad_blob
)
{
Gitlab
::
Git
::
Blob
.
raw
(
repository
,
SeedRepo
::
BigCommit
::
ID
)
}
...
@@ -166,6 +166,16 @@ describe Gitlab::Git::Blob, :seed_helper do
...
@@ -166,6 +166,16 @@ describe Gitlab::Git::Blob, :seed_helper do
end
end
end
end
describe
'.raw'
do
context
'when the blob_raw Gitaly feature is enabled'
do
it_behaves_like
'finding blobs by ID'
end
context
'when the blob_raw Gitaly feature is disabled'
,
:skip_gitaly_mock
do
it_behaves_like
'finding blobs by ID'
end
end
describe
'.batch'
do
describe
'.batch'
do
let
(
:blob_references
)
do
let
(
:blob_references
)
do
[
[
...
...
spec/lib/gitlab/git/commit_spec.rb
View file @
2742b871
...
@@ -183,100 +183,110 @@ describe Gitlab::Git::Commit, :seed_helper do
...
@@ -183,100 +183,110 @@ describe Gitlab::Git::Commit, :seed_helper do
end
end
end
end
context
'path is empty string'
do
shared_examples
'.where'
do
subject
do
context
'path is empty string'
do
commits
=
described_class
.
where
(
subject
do
repo:
repository
,
commits
=
described_class
.
where
(
ref:
'master'
,
repo:
repository
,
path:
''
,
ref:
'master'
,
limit:
10
path:
''
,
)
limit:
10
)
commits
.
map
{
|
c
|
c
.
id
}
commits
.
map
{
|
c
|
c
.
id
}
end
end
it
'has 10 elements'
do
it
'has 10 elements'
do
expect
(
subject
.
size
).
to
eq
(
10
)
expect
(
subject
.
size
).
to
eq
(
10
)
end
it
{
is_expected
.
to
include
(
SeedRepo
::
EmptyCommit
::
ID
)
}
end
end
it
{
is_expected
.
to
include
(
SeedRepo
::
EmptyCommit
::
ID
)
}
end
context
'path is nil'
do
context
'path is nil'
do
subject
do
subject
do
commits
=
described_class
.
where
(
commits
=
described_class
.
where
(
repo:
repository
,
repo:
repository
,
ref:
'master'
,
ref:
'master'
,
path:
nil
,
path:
nil
,
limit:
10
limit:
10
)
)
commits
.
map
{
|
c
|
c
.
id
}
commits
.
map
{
|
c
|
c
.
id
}
end
end
it
'has 10 elements'
do
it
'has 10 elements'
do
expect
(
subject
.
size
).
to
eq
(
10
)
expect
(
subject
.
size
).
to
eq
(
10
)
end
it
{
is_expected
.
to
include
(
SeedRepo
::
EmptyCommit
::
ID
)
}
end
end
it
{
is_expected
.
to
include
(
SeedRepo
::
EmptyCommit
::
ID
)
}
end
context
'ref is branch name'
do
context
'ref is branch name'
do
subject
do
subject
do
commits
=
described_class
.
where
(
commits
=
described_class
.
where
(
repo:
repository
,
repo:
repository
,
ref:
'master'
,
ref:
'master'
,
path:
'files'
,
path:
'files'
,
limit:
3
,
limit:
3
,
offset:
1
offset:
1
)
)
commits
.
map
{
|
c
|
c
.
id
}
commits
.
map
{
|
c
|
c
.
id
}
end
end
it
'has 3 elements'
do
it
'has 3 elements'
do
expect
(
subject
.
size
).
to
eq
(
3
)
expect
(
subject
.
size
).
to
eq
(
3
)
end
it
{
is_expected
.
to
include
(
"d14d6c0abdd253381df51a723d58691b2ee1ab08"
)
}
it
{
is_expected
.
not_to
include
(
"eb49186cfa5c4338011f5f590fac11bd66c5c631"
)
}
end
end
it
{
is_expected
.
to
include
(
"d14d6c0abdd253381df51a723d58691b2ee1ab08"
)
}
it
{
is_expected
.
not_to
include
(
"eb49186cfa5c4338011f5f590fac11bd66c5c631"
)
}
end
context
'ref is commit id'
do
context
'ref is commit id'
do
subject
do
subject
do
commits
=
described_class
.
where
(
commits
=
described_class
.
where
(
repo:
repository
,
repo:
repository
,
ref:
"874797c3a73b60d2187ed6e2fcabd289ff75171e"
,
ref:
"874797c3a73b60d2187ed6e2fcabd289ff75171e"
,
path:
'files'
,
path:
'files'
,
limit:
3
,
limit:
3
,
offset:
1
offset:
1
)
)
commits
.
map
{
|
c
|
c
.
id
}
commits
.
map
{
|
c
|
c
.
id
}
end
end
it
'has 3 elements'
do
it
'has 3 elements'
do
expect
(
subject
.
size
).
to
eq
(
3
)
expect
(
subject
.
size
).
to
eq
(
3
)
end
it
{
is_expected
.
to
include
(
"2f63565e7aac07bcdadb654e253078b727143ec4"
)
}
it
{
is_expected
.
not_to
include
(
SeedRepo
::
Commit
::
ID
)
}
end
end
it
{
is_expected
.
to
include
(
"2f63565e7aac07bcdadb654e253078b727143ec4"
)
}
it
{
is_expected
.
not_to
include
(
SeedRepo
::
Commit
::
ID
)
}
end
context
'ref is tag'
do
context
'ref is tag'
do
subject
do
subject
do
commits
=
described_class
.
where
(
commits
=
described_class
.
where
(
repo:
repository
,
repo:
repository
,
ref:
'v1.0.0'
,
ref:
'v1.0.0'
,
path:
'files'
,
path:
'files'
,
limit:
3
,
limit:
3
,
offset:
1
offset:
1
)
)
commits
.
map
{
|
c
|
c
.
id
}
commits
.
map
{
|
c
|
c
.
id
}
end
end
it
'has 3 elements'
do
it
'has 3 elements'
do
expect
(
subject
.
size
).
to
eq
(
3
)
expect
(
subject
.
size
).
to
eq
(
3
)
end
it
{
is_expected
.
to
include
(
"874797c3a73b60d2187ed6e2fcabd289ff75171e"
)
}
it
{
is_expected
.
not_to
include
(
SeedRepo
::
Commit
::
ID
)
}
end
end
it
{
is_expected
.
to
include
(
"874797c3a73b60d2187ed6e2fcabd289ff75171e"
)
}
end
it
{
is_expected
.
not_to
include
(
SeedRepo
::
Commit
::
ID
)
}
describe
'.where with gitaly'
do
it_should_behave_like
'.where'
end
describe
'.where without gitaly'
,
:skip_gitaly_mock
do
it_should_behave_like
'.where'
end
end
describe
'.between'
do
describe
'.between'
do
...
@@ -498,7 +508,7 @@ describe Gitlab::Git::Commit, :seed_helper do
...
@@ -498,7 +508,7 @@ describe Gitlab::Git::Commit, :seed_helper do
end
end
end
end
describe
'#stats'
do
shared_examples
'#stats'
do
subject
{
commit
.
stats
}
subject
{
commit
.
stats
}
describe
'#additions'
do
describe
'#additions'
do
...
@@ -517,6 +527,14 @@ describe Gitlab::Git::Commit, :seed_helper do
...
@@ -517,6 +527,14 @@ describe Gitlab::Git::Commit, :seed_helper do
end
end
end
end
describe
'#stats with gitaly on'
do
it_should_behave_like
'#stats'
end
describe
'#stats with gitaly disabled'
,
:skip_gitaly_mock
do
it_should_behave_like
'#stats'
end
describe
'#has_zero_stats?'
do
describe
'#has_zero_stats?'
do
it
{
expect
(
commit
.
has_zero_stats?
).
to
eq
(
false
)
}
it
{
expect
(
commit
.
has_zero_stats?
).
to
eq
(
false
)
}
end
end
...
@@ -559,15 +577,25 @@ describe Gitlab::Git::Commit, :seed_helper do
...
@@ -559,15 +577,25 @@ describe Gitlab::Git::Commit, :seed_helper do
commit_ids
.
map
{
|
id
|
described_class
.
get_message
(
repository
,
id
)
}
commit_ids
.
map
{
|
id
|
described_class
.
get_message
(
repository
,
id
)
}
end
end
it
'gets commit messages'
do
shared_examples
'getting commit messages'
do
expect
(
subject
).
to
contain_exactly
(
it
'gets commit messages'
do
"Added contributing guide
\n\n
Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
\n
"
,
expect
(
subject
).
to
contain_exactly
(
"Add submodule
\n\n
Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
\n
"
"Added contributing guide
\n\n
Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
\n
"
,
)
"Add submodule
\n\n
Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
\n
"
)
end
end
context
'when Gitaly commit_messages feature is enabled'
do
it_behaves_like
'getting commit messages'
it
'gets messages in one batch'
,
:request_store
do
expect
{
subject
.
map
(
&
:itself
)
}.
to
change
{
Gitlab
::
GitalyClient
.
get_request_count
}.
by
(
1
)
end
end
end
it
'gets messages in one batch'
,
:request_store
do
context
'when Gitaly commit_messages feature is disabled'
,
:disable_gitaly
do
expect
{
subject
.
map
(
&
:itself
)
}.
to
change
{
Gitlab
::
GitalyClient
.
get_request_count
}.
by
(
1
)
it_behaves_like
'getting commit messages'
end
end
end
end
...
...
spec/lib/gitlab/git/tag_spec.rb
View file @
2742b871
...
@@ -3,7 +3,7 @@ require "spec_helper"
...
@@ -3,7 +3,7 @@ require "spec_helper"
describe
Gitlab
::
Git
::
Tag
,
:seed_helper
do
describe
Gitlab
::
Git
::
Tag
,
:seed_helper
do
let
(
:repository
)
{
Gitlab
::
Git
::
Repository
.
new
(
'default'
,
TEST_REPO_PATH
,
''
)
}
let
(
:repository
)
{
Gitlab
::
Git
::
Repository
.
new
(
'default'
,
TEST_REPO_PATH
,
''
)
}
describe
'
#tags'
do
shared_examples
'Gitlab::Git::Repository
#tags'
do
describe
'first tag'
do
describe
'first tag'
do
let
(
:tag
)
{
repository
.
tags
.
first
}
let
(
:tag
)
{
repository
.
tags
.
first
}
...
@@ -25,6 +25,14 @@ describe Gitlab::Git::Tag, :seed_helper do
...
@@ -25,6 +25,14 @@ describe Gitlab::Git::Tag, :seed_helper do
it
{
expect
(
repository
.
tags
.
size
).
to
eq
(
SeedRepo
::
Repo
::
TAGS
.
size
)
}
it
{
expect
(
repository
.
tags
.
size
).
to
eq
(
SeedRepo
::
Repo
::
TAGS
.
size
)
}
end
end
context
'when Gitaly tags feature is enabled'
do
it_behaves_like
'Gitlab::Git::Repository#tags'
end
context
'when Gitaly tags feature is disabled'
,
:skip_gitaly_mock
do
it_behaves_like
'Gitlab::Git::Repository#tags'
end
describe
'.get_message'
do
describe
'.get_message'
do
let
(
:tag_ids
)
{
%w[f4e6814c3e4e7a0de82a9e7cd20c626cc963a2f8 8a2a6eb295bb170b34c24c76c49ed0e9b2eaf34b]
}
let
(
:tag_ids
)
{
%w[f4e6814c3e4e7a0de82a9e7cd20c626cc963a2f8 8a2a6eb295bb170b34c24c76c49ed0e9b2eaf34b]
}
...
@@ -32,13 +40,23 @@ describe Gitlab::Git::Tag, :seed_helper do
...
@@ -32,13 +40,23 @@ describe Gitlab::Git::Tag, :seed_helper do
tag_ids
.
map
{
|
id
|
described_class
.
get_message
(
repository
,
id
)
}
tag_ids
.
map
{
|
id
|
described_class
.
get_message
(
repository
,
id
)
}
end
end
it
'gets tag messages'
do
shared_examples
'getting tag messages'
do
expect
(
subject
[
0
]).
to
eq
(
"Release
\n
"
)
it
'gets tag messages'
do
expect
(
subject
[
1
]).
to
eq
(
"Version 1.1.0
\n
"
)
expect
(
subject
[
0
]).
to
eq
(
"Release
\n
"
)
expect
(
subject
[
1
]).
to
eq
(
"Version 1.1.0
\n
"
)
end
end
context
'when Gitaly tag_messages feature is enabled'
do
it_behaves_like
'getting tag messages'
it
'gets messages in one batch'
,
:request_store
do
expect
{
subject
.
map
(
&
:itself
)
}.
to
change
{
Gitlab
::
GitalyClient
.
get_request_count
}.
by
(
1
)
end
end
end
it
'gets messages in one batch'
,
:request_store
do
context
'when Gitaly tag_messages feature is disabled'
,
:disable_gitaly
do
expect
{
subject
.
map
(
&
:itself
)
}.
to
change
{
Gitlab
::
GitalyClient
.
get_request_count
}.
by
(
1
)
it_behaves_like
'getting tag messages'
end
end
end
end
...
...
spec/lib/gitlab/git/tree_spec.rb
View file @
2742b871
...
@@ -80,8 +80,18 @@ describe Gitlab::Git::Tree, :seed_helper do
...
@@ -80,8 +80,18 @@ describe Gitlab::Git::Tree, :seed_helper do
end
end
describe
'#where'
do
describe
'#where'
do
it
'returns an empty array when called with an invalid ref'
do
shared_examples
'#where'
do
expect
(
described_class
.
where
(
repository
,
'foobar-does-not-exist'
)).
to
eq
([])
it
'returns an empty array when called with an invalid ref'
do
expect
(
described_class
.
where
(
repository
,
'foobar-does-not-exist'
)).
to
eq
([])
end
end
context
'with gitaly'
do
it_behaves_like
'#where'
end
context
'without gitaly'
,
:skip_gitaly_mock
do
it_behaves_like
'#where'
end
end
end
end
end
end
spec/lib/gitlab/gitaly_client_spec.rb
View file @
2742b871
...
@@ -2,7 +2,7 @@ require 'spec_helper'
...
@@ -2,7 +2,7 @@ require 'spec_helper'
# We stub Gitaly in `spec/support/gitaly.rb` for other tests. We don't want
# We stub Gitaly in `spec/support/gitaly.rb` for other tests. We don't want
# those stubs while testing the GitalyClient itself.
# those stubs while testing the GitalyClient itself.
describe
Gitlab
::
GitalyClient
do
describe
Gitlab
::
GitalyClient
,
skip_gitaly_mock:
true
do
describe
'.stub_class'
do
describe
'.stub_class'
do
it
'returns the gRPC health check stub'
do
it
'returns the gRPC health check stub'
do
expect
(
described_class
.
stub_class
(
:health_check
)).
to
eq
(
::
Grpc
::
Health
::
V1
::
Health
::
Stub
)
expect
(
described_class
.
stub_class
(
:health_check
)).
to
eq
(
::
Grpc
::
Health
::
V1
::
Health
::
Stub
)
...
@@ -191,13 +191,102 @@ describe Gitlab::GitalyClient do
...
@@ -191,13 +191,102 @@ describe Gitlab::GitalyClient do
let
(
:feature_name
)
{
'my_feature'
}
let
(
:feature_name
)
{
'my_feature'
}
let
(
:real_feature_name
)
{
"gitaly_
#{
feature_name
}
"
}
let
(
:real_feature_name
)
{
"gitaly_
#{
feature_name
}
"
}
before
do
context
'when Gitaly is disabled'
do
allow
(
Feature
).
to
receive
(
:enabled?
).
and_return
(
false
)
before
do
allow
(
described_class
).
to
receive
(
:enabled?
).
and_return
(
false
)
end
it
'returns false'
do
expect
(
described_class
.
feature_enabled?
(
feature_name
)).
to
be
(
false
)
end
end
end
it
'returns false'
do
context
'when the feature status is DISABLED'
do
expect
(
Feature
).
to
receive
(
:enabled?
).
with
(
real_feature_name
)
let
(
:feature_status
)
{
Gitlab
::
GitalyClient
::
MigrationStatus
::
DISABLED
}
expect
(
described_class
.
feature_enabled?
(
feature_name
)).
to
be
(
false
)
it
'returns false'
do
expect
(
described_class
.
feature_enabled?
(
feature_name
,
status:
feature_status
)).
to
be
(
false
)
end
end
context
'when the feature_status is OPT_IN'
do
let
(
:feature_status
)
{
Gitlab
::
GitalyClient
::
MigrationStatus
::
OPT_IN
}
context
"when the feature flag hasn't been set"
do
it
'returns false'
do
expect
(
described_class
.
feature_enabled?
(
feature_name
,
status:
feature_status
)).
to
be
(
false
)
end
end
context
"when the feature flag is set to disable"
do
before
do
Feature
.
get
(
real_feature_name
).
disable
end
it
'returns false'
do
expect
(
described_class
.
feature_enabled?
(
feature_name
,
status:
feature_status
)).
to
be
(
false
)
end
end
context
"when the feature flag is set to enable"
do
before
do
Feature
.
get
(
real_feature_name
).
enable
end
it
'returns true'
do
expect
(
described_class
.
feature_enabled?
(
feature_name
,
status:
feature_status
)).
to
be
(
true
)
end
end
context
"when the feature flag is set to a percentage of time"
do
before
do
Feature
.
get
(
real_feature_name
).
enable_percentage_of_time
(
70
)
end
it
'bases the result on pseudo-random numbers'
do
expect
(
Random
).
to
receive
(
:rand
).
and_return
(
0.3
)
expect
(
described_class
.
feature_enabled?
(
feature_name
,
status:
feature_status
)).
to
be
(
true
)
expect
(
Random
).
to
receive
(
:rand
).
and_return
(
0.8
)
expect
(
described_class
.
feature_enabled?
(
feature_name
,
status:
feature_status
)).
to
be
(
false
)
end
end
context
"when a feature is not persisted"
do
it
'returns false when opt_into_all_features is off'
do
allow
(
Feature
).
to
receive
(
:persisted?
).
and_return
(
false
)
allow
(
described_class
).
to
receive
(
:opt_into_all_features?
).
and_return
(
false
)
expect
(
described_class
.
feature_enabled?
(
feature_name
,
status:
feature_status
)).
to
be
(
false
)
end
it
'returns true when the override is on'
do
allow
(
Feature
).
to
receive
(
:persisted?
).
and_return
(
false
)
allow
(
described_class
).
to
receive
(
:opt_into_all_features?
).
and_return
(
true
)
expect
(
described_class
.
feature_enabled?
(
feature_name
,
status:
feature_status
)).
to
be
(
true
)
end
end
end
context
'when the feature_status is OPT_OUT'
do
let
(
:feature_status
)
{
Gitlab
::
GitalyClient
::
MigrationStatus
::
OPT_OUT
}
context
"when the feature flag hasn't been set"
do
it
'returns true'
do
expect
(
described_class
.
feature_enabled?
(
feature_name
,
status:
feature_status
)).
to
be
(
true
)
end
end
context
"when the feature flag is set to disable"
do
before
do
Feature
.
get
(
real_feature_name
).
disable
end
it
'returns false'
do
expect
(
described_class
.
feature_enabled?
(
feature_name
,
status:
feature_status
)).
to
be
(
false
)
end
end
end
end
end
end
...
...
spec/models/merge_request_spec.rb
View file @
2742b871
...
@@ -30,38 +30,48 @@ describe MergeRequest do
...
@@ -30,38 +30,48 @@ describe MergeRequest do
end
end
describe
'#squash_in_progress?'
do
describe
'#squash_in_progress?'
do
let
(
:repo_path
)
do
shared_examples
'checking whether a squash is in progress'
do
Gitlab
::
GitalyClient
::
StorageSettings
.
allow_disk_access
do
let
(
:repo_path
)
do
subject
.
source_project
.
repository
.
path
Gitlab
::
GitalyClient
::
StorageSettings
.
allow_disk_access
do
subject
.
source_project
.
repository
.
path
end
end
end
end
let
(
:squash_path
)
{
File
.
join
(
repo_path
,
"gitlab-worktree"
,
"squash-
#{
subject
.
id
}
"
)
}
let
(
:squash_path
)
{
File
.
join
(
repo_path
,
"gitlab-worktree"
,
"squash-
#{
subject
.
id
}
"
)
}
before
do
before
do
system
(
*
%W(
#{
Gitlab
.
config
.
git
.
bin_path
}
-C
#{
repo_path
}
worktree add --detach
#{
squash_path
}
master)
)
system
(
*
%W(
#{
Gitlab
.
config
.
git
.
bin_path
}
-C
#{
repo_path
}
worktree add --detach
#{
squash_path
}
master)
)
end
end
it
'returns true when there is a current squash directory'
do
it
'returns true when there is a current squash directory'
do
expect
(
subject
.
squash_in_progress?
).
to
be_truthy
expect
(
subject
.
squash_in_progress?
).
to
be_truthy
end
end
it
'returns false when there is no squash directory'
do
it
'returns false when there is no squash directory'
do
FileUtils
.
rm_rf
(
squash_path
)
FileUtils
.
rm_rf
(
squash_path
)
expect
(
subject
.
squash_in_progress?
).
to
be_falsey
expect
(
subject
.
squash_in_progress?
).
to
be_falsey
end
end
it
'returns false when the squash directory has expired'
do
it
'returns false when the squash directory has expired'
do
time
=
20
.
minutes
.
ago
.
to_time
time
=
20
.
minutes
.
ago
.
to_time
File
.
utime
(
time
,
time
,
squash_path
)
File
.
utime
(
time
,
time
,
squash_path
)
expect
(
subject
.
squash_in_progress?
).
to
be_falsey
end
it
'returns false when the source project has been removed'
do
allow
(
subject
).
to
receive
(
:source_project
).
and_return
(
nil
)
expect
(
subject
.
squash_in_progress?
).
to
be_falsey
expect
(
subject
.
squash_in_progress?
).
to
be_falsey
end
end
end
it
'returns false when the source project has been removed'
do
context
'when Gitaly squash_in_progress is enabled'
do
allow
(
subject
).
to
receive
(
:source_project
).
and_return
(
nil
)
it_behaves_like
'checking whether a squash is in progress'
end
expect
(
subject
.
squash_in_progress?
).
to
be_falsey
context
'when Gitaly squash_in_progress is disabled'
,
:disable_gitaly
do
it_behaves_like
'checking whether a squash is in progress'
end
end
end
end
...
@@ -2577,6 +2587,14 @@ describe MergeRequest do
...
@@ -2577,6 +2587,14 @@ describe MergeRequest do
expect
(
subject
.
rebase_in_progress?
).
to
be_falsey
expect
(
subject
.
rebase_in_progress?
).
to
be_falsey
end
end
end
end
context
'when Gitaly rebase_in_progress is enabled'
do
it_behaves_like
'checking whether a rebase is in progress'
end
context
'when Gitaly rebase_in_progress is enabled'
,
:disable_gitaly
do
it_behaves_like
'checking whether a rebase is in progress'
end
end
end
describe
'#allow_collaboration'
do
describe
'#allow_collaboration'
do
...
...
spec/models/project_wiki_spec.rb
View file @
2742b871
...
@@ -130,53 +130,63 @@ describe ProjectWiki do
...
@@ -130,53 +130,63 @@ describe ProjectWiki do
end
end
describe
"#find_page"
do
describe
"#find_page"
do
before
do
shared_examples
'finding a wiki page'
do
create_page
(
"index page"
,
"This is an awesome Gollum Wiki"
)
before
do
end
create_page
(
"index page"
,
"This is an awesome Gollum Wiki"
)
end
after
do
after
do
subject
.
pages
.
each
{
|
page
|
destroy_page
(
page
.
page
)
}
subject
.
pages
.
each
{
|
page
|
destroy_page
(
page
.
page
)
}
end
end
it
"returns the latest version of the page if it exists"
do
it
"returns the latest version of the page if it exists"
do
page
=
subject
.
find_page
(
"index page"
)
page
=
subject
.
find_page
(
"index page"
)
expect
(
page
.
title
).
to
eq
(
"index page"
)
expect
(
page
.
title
).
to
eq
(
"index page"
)
end
end
it
"returns nil if the page does not exist"
do
it
"returns nil if the page does not exist"
do
expect
(
subject
.
find_page
(
"non-existent"
)).
to
eq
(
nil
)
expect
(
subject
.
find_page
(
"non-existent"
)).
to
eq
(
nil
)
end
end
it
"can find a page by slug"
do
it
"can find a page by slug"
do
page
=
subject
.
find_page
(
"index-page"
)
page
=
subject
.
find_page
(
"index-page"
)
expect
(
page
.
title
).
to
eq
(
"index page"
)
expect
(
page
.
title
).
to
eq
(
"index page"
)
end
end
it
"returns a WikiPage instance"
do
it
"returns a WikiPage instance"
do
page
=
subject
.
find_page
(
"index page"
)
page
=
subject
.
find_page
(
"index page"
)
expect
(
page
).
to
be_a
WikiPage
expect
(
page
).
to
be_a
WikiPage
end
end
context
'pages with multibyte-character title'
do
context
'pages with multibyte-character title'
do
before
do
before
do
create_page
(
"autre pagé"
,
"C'est un génial Gollum Wiki"
)
create_page
(
"autre pagé"
,
"C'est un génial Gollum Wiki"
)
end
it
"can find a page by slug"
do
page
=
subject
.
find_page
(
"autre pagé"
)
expect
(
page
.
title
).
to
eq
(
"autre pagé"
)
end
end
end
it
"can find a page by slug"
do
context
'pages with invalidly-encoded content'
do
page
=
subject
.
find_page
(
"autre pagé"
)
before
do
expect
(
page
.
title
).
to
eq
(
"autre pagé"
)
create_page
(
"encoding is fun"
,
"f
\xFC
r"
.
b
)
end
it
"can find the page"
do
page
=
subject
.
find_page
(
"encoding is fun"
)
expect
(
page
.
content
).
to
eq
(
"fr"
)
end
end
end
end
end
context
'pages with invalidly-encoded content'
do
context
'when Gitaly wiki_find_page is enabled'
do
before
do
it_behaves_like
'finding a wiki page'
create_page
(
"encoding is fun"
,
"f
\xFC
r"
.
b
)
end
end
it
"can find the page"
do
context
'when Gitaly wiki_find_page is disabled'
,
:skip_gitaly_mock
do
page
=
subject
.
find_page
(
"encoding is fun"
)
it_behaves_like
'finding a wiki page'
expect
(
page
.
content
).
to
eq
(
"fr"
)
end
end
end
end
end
...
@@ -197,80 +207,100 @@ describe ProjectWiki do
...
@@ -197,80 +207,100 @@ describe ProjectWiki do
end
end
describe
'#find_file'
do
describe
'#find_file'
do
let
(
:image
)
{
File
.
open
(
Rails
.
root
.
join
(
'spec'
,
'fixtures'
,
'big-image.png'
))
}
shared_examples
'finding a wiki file'
do
let
(
:image
)
{
File
.
open
(
Rails
.
root
.
join
(
'spec'
,
'fixtures'
,
'big-image.png'
))
}
before
do
before
do
subject
.
wiki
# Make sure the wiki repo exists
subject
.
wiki
# Make sure the wiki repo exists
repo_path
=
Gitlab
::
GitalyClient
::
StorageSettings
.
allow_disk_access
do
repo_path
=
Gitlab
::
GitalyClient
::
StorageSettings
.
allow_disk_access
do
subject
.
repository
.
path_to_repo
subject
.
repository
.
path_to_repo
end
BareRepoOperations
.
new
(
repo_path
).
commit_file
(
image
,
'image.png'
)
end
end
BareRepoOperations
.
new
(
repo_path
).
commit_file
(
image
,
'image.png'
)
it
'returns the latest version of the file if it exists'
do
end
file
=
subject
.
find_file
(
'image.png'
)
expect
(
file
.
mime_type
).
to
eq
(
'image/png'
)
end
it
'returns the latest version of the file if it exists'
do
it
'returns nil if the page does not exist'
do
file
=
subject
.
find_file
(
'image.png'
)
expect
(
subject
.
find_file
(
'non-existent'
)).
to
eq
(
nil
)
expect
(
file
.
mime_type
).
to
eq
(
'image/png'
)
end
end
it
'returns nil if the page does not exist'
do
it
'returns a Gitlab::Git::WikiFile instance'
do
expect
(
subject
.
find_file
(
'non-existent'
)).
to
eq
(
nil
)
file
=
subject
.
find_file
(
'image.png'
)
end
expect
(
file
).
to
be_a
Gitlab
::
Git
::
WikiFile
end
it
'returns the whole file'
do
file
=
subject
.
find_file
(
'image.png'
)
image
.
rewind
it
'returns a Gitlab::Git::WikiFile instance'
do
expect
(
file
.
raw_data
.
b
).
to
eq
(
image
.
read
.
b
)
file
=
subject
.
find_file
(
'image.png'
)
end
expect
(
file
).
to
be_a
Gitlab
::
Git
::
WikiFile
end
end
it
'returns the whole file
'
do
context
'when Gitaly wiki_find_file is enabled
'
do
file
=
subject
.
find_file
(
'image.png'
)
it_behaves_like
'finding a wiki file'
image
.
rewi
nd
e
nd
expect
(
file
.
raw_data
.
b
).
to
eq
(
image
.
read
.
b
)
context
'when Gitaly wiki_find_file is disabled'
,
:skip_gitaly_mock
do
it_behaves_like
'finding a wiki file'
end
end
end
end
describe
"#create_page"
do
describe
"#create_page"
do
after
do
shared_examples
'creating a wiki page'
do
destroy_page
(
subject
.
pages
.
first
.
page
)
after
do
end
destroy_page
(
subject
.
pages
.
first
.
page
)
end
it
"creates a new wiki page"
do
it
"creates a new wiki page"
do
expect
(
subject
.
create_page
(
"test page"
,
"this is content"
)).
not_to
eq
(
false
)
expect
(
subject
.
create_page
(
"test page"
,
"this is content"
)).
not_to
eq
(
false
)
expect
(
subject
.
pages
.
count
).
to
eq
(
1
)
expect
(
subject
.
pages
.
count
).
to
eq
(
1
)
end
end
it
"returns false when a duplicate page exists"
do
it
"returns false when a duplicate page exists"
do
subject
.
create_page
(
"test page"
,
"content"
)
subject
.
create_page
(
"test page"
,
"content"
)
expect
(
subject
.
create_page
(
"test page"
,
"content"
)).
to
eq
(
false
)
expect
(
subject
.
create_page
(
"test page"
,
"content"
)).
to
eq
(
false
)
end
end
it
"stores an error message when a duplicate page exists"
do
it
"stores an error message when a duplicate page exists"
do
2
.
times
{
subject
.
create_page
(
"test page"
,
"content"
)
}
2
.
times
{
subject
.
create_page
(
"test page"
,
"content"
)
}
expect
(
subject
.
error_message
).
to
match
(
/Duplicate page:/
)
expect
(
subject
.
error_message
).
to
match
(
/Duplicate page:/
)
end
end
it
"sets the correct commit message"
do
it
"sets the correct commit message"
do
subject
.
create_page
(
"test page"
,
"some content"
,
:markdown
,
"commit message"
)
subject
.
create_page
(
"test page"
,
"some content"
,
:markdown
,
"commit message"
)
expect
(
subject
.
pages
.
first
.
page
.
version
.
message
).
to
eq
(
"commit message"
)
expect
(
subject
.
pages
.
first
.
page
.
version
.
message
).
to
eq
(
"commit message"
)
end
end
it
'sets the correct commit email'
do
it
'sets the correct commit email'
do
subject
.
create_page
(
'test page'
,
'content'
)
subject
.
create_page
(
'test page'
,
'content'
)
expect
(
user
.
commit_email
).
not_to
eq
(
user
.
email
)
expect
(
user
.
commit_email
).
not_to
eq
(
user
.
email
)
expect
(
commit
.
author_email
).
to
eq
(
user
.
commit_email
)
expect
(
commit
.
author_email
).
to
eq
(
user
.
commit_email
)
expect
(
commit
.
committer_email
).
to
eq
(
user
.
commit_email
)
expect
(
commit
.
committer_email
).
to
eq
(
user
.
commit_email
)
end
end
it
'updates project activity'
do
it
'updates project activity'
do
subject
.
create_page
(
'Test Page'
,
'This is content'
)
subject
.
create_page
(
'Test Page'
,
'This is content'
)
project
.
reload
project
.
reload
expect
(
project
.
last_activity_at
).
to
be_within
(
1
.
minute
).
of
(
Time
.
now
)
expect
(
project
.
last_activity_at
).
to
be_within
(
1
.
minute
).
of
(
Time
.
now
)
expect
(
project
.
last_repository_updated_at
).
to
be_within
(
1
.
minute
).
of
(
Time
.
now
)
expect
(
project
.
last_repository_updated_at
).
to
be_within
(
1
.
minute
).
of
(
Time
.
now
)
end
end
context
'when Gitaly wiki_write_page is enabled'
do
it_behaves_like
'creating a wiki page'
end
context
'when Gitaly wiki_write_page is disabled'
,
:skip_gitaly_mock
do
it_behaves_like
'creating a wiki page'
end
end
end
end
...
@@ -321,31 +351,41 @@ describe ProjectWiki do
...
@@ -321,31 +351,41 @@ describe ProjectWiki do
end
end
describe
"#delete_page"
do
describe
"#delete_page"
do
before
do
shared_examples
'deleting a wiki page'
do
create_page
(
"index"
,
"some content"
)
before
do
@page
=
subject
.
wiki
.
page
(
title:
"index"
)
create_page
(
"index"
,
"some content"
)
end
@page
=
subject
.
wiki
.
page
(
title:
"index"
)
end
it
"deletes the page"
do
it
"deletes the page"
do
subject
.
delete_page
(
@page
)
subject
.
delete_page
(
@page
)
expect
(
subject
.
pages
.
count
).
to
eq
(
0
)
expect
(
subject
.
pages
.
count
).
to
eq
(
0
)
end
end
it
'sets the correct commit email'
do
it
'sets the correct commit email'
do
subject
.
delete_page
(
@page
)
subject
.
delete_page
(
@page
)
expect
(
user
.
commit_email
).
not_to
eq
(
user
.
email
)
expect
(
user
.
commit_email
).
not_to
eq
(
user
.
email
)
expect
(
commit
.
author_email
).
to
eq
(
user
.
commit_email
)
expect
(
commit
.
author_email
).
to
eq
(
user
.
commit_email
)
expect
(
commit
.
committer_email
).
to
eq
(
user
.
commit_email
)
expect
(
commit
.
committer_email
).
to
eq
(
user
.
commit_email
)
end
end
it
'updates project activity'
do
it
'updates project activity'
do
subject
.
delete_page
(
@page
)
subject
.
delete_page
(
@page
)
project
.
reload
project
.
reload
expect
(
project
.
last_activity_at
).
to
be_within
(
1
.
minute
).
of
(
Time
.
now
)
expect
(
project
.
last_activity_at
).
to
be_within
(
1
.
minute
).
of
(
Time
.
now
)
expect
(
project
.
last_repository_updated_at
).
to
be_within
(
1
.
minute
).
of
(
Time
.
now
)
expect
(
project
.
last_repository_updated_at
).
to
be_within
(
1
.
minute
).
of
(
Time
.
now
)
end
end
context
'when Gitaly wiki_delete_page is enabled'
do
it_behaves_like
'deleting a wiki page'
end
context
'when Gitaly wiki_delete_page is disabled'
,
:skip_gitaly_mock
do
it_behaves_like
'deleting a wiki page'
end
end
end
end
...
...
spec/models/repository_spec.rb
View file @
2742b871
...
@@ -38,29 +38,49 @@ describe Repository do
...
@@ -38,29 +38,49 @@ describe Repository do
end
end
describe
'#branch_names_contains'
do
describe
'#branch_names_contains'
do
set
(
:project
)
{
create
(
:project
,
:repository
)
}
shared_examples
'#branch_names_contains'
do
let
(
:repository
)
{
project
.
repository
}
set
(
:project
)
{
create
(
:project
,
:repository
)
}
let
(
:repository
)
{
project
.
repository
}
subject
{
repository
.
branch_names_contains
(
sample_commit
.
id
)
}
subject
{
repository
.
branch_names_contains
(
sample_commit
.
id
)
}
it
{
is_expected
.
to
include
(
'master'
)
}
it
{
is_expected
.
to
include
(
'master'
)
}
it
{
is_expected
.
not_to
include
(
'feature'
)
}
it
{
is_expected
.
not_to
include
(
'feature'
)
}
it
{
is_expected
.
not_to
include
(
'fix'
)
}
it
{
is_expected
.
not_to
include
(
'fix'
)
}
describe
'when storage is broken'
,
:broken_storage
do
describe
'when storage is broken'
,
:broken_storage
do
it
'should raise a storage error'
do
it
'should raise a storage error'
do
expect_to_raise_storage_error
do
expect_to_raise_storage_error
do
broken_repository
.
branch_names_contains
(
sample_commit
.
id
)
broken_repository
.
branch_names_contains
(
sample_commit
.
id
)
end
end
end
end
end
end
end
context
'when gitaly is enabled'
do
it_behaves_like
'#branch_names_contains'
end
context
'when gitaly is disabled'
,
:skip_gitaly_mock
do
it_behaves_like
'#branch_names_contains'
end
end
end
describe
'#tag_names_contains'
do
describe
'#tag_names_contains'
do
subject
{
repository
.
tag_names_contains
(
sample_commit
.
id
)
}
shared_examples
'#tag_names_contains'
do
subject
{
repository
.
tag_names_contains
(
sample_commit
.
id
)
}
it
{
is_expected
.
to
include
(
'v1.1.0'
)
}
it
{
is_expected
.
not_to
include
(
'v1.0.0'
)
}
end
context
'when gitaly is enabled'
do
it_behaves_like
'#tag_names_contains'
end
it
{
is_expected
.
to
include
(
'v1.1.0'
)
}
context
'when gitaly is enabled'
,
:skip_gitaly_mock
do
it
{
is_expected
.
not_to
include
(
'v1.0.0'
)
}
it_behaves_like
'#tag_names_contains'
end
end
end
describe
'tags_sorted_by'
do
describe
'tags_sorted_by'
do
...
@@ -218,41 +238,61 @@ describe Repository do
...
@@ -218,41 +238,61 @@ describe Repository do
end
end
describe
'#last_commit_for_path'
do
describe
'#last_commit_for_path'
do
subject
{
repository
.
last_commit_for_path
(
sample_commit
.
id
,
'.gitignore'
).
id
}
shared_examples
'getting last commit for path'
do
subject
{
repository
.
last_commit_for_path
(
sample_commit
.
id
,
'.gitignore'
).
id
}
it
{
is_expected
.
to
eq
(
'c1acaa58bbcbc3eafe538cb8274ba387047b69f8'
)
}
it
{
is_expected
.
to
eq
(
'c1acaa58bbcbc3eafe538cb8274ba387047b69f8'
)
}
describe
'when storage is broken'
,
:broken_storage
do
describe
'when storage is broken'
,
:broken_storage
do
it
'should raise a storage error'
do
it
'should raise a storage error'
do
expect_to_raise_storage_error
do
expect_to_raise_storage_error
do
broken_repository
.
last_commit_id_for_path
(
sample_commit
.
id
,
'.gitignore'
)
broken_repository
.
last_commit_id_for_path
(
sample_commit
.
id
,
'.gitignore'
)
end
end
end
end
end
end
end
context
'when Gitaly feature last_commit_for_path is enabled'
do
it_behaves_like
'getting last commit for path'
end
context
'when Gitaly feature last_commit_for_path is disabled'
,
:skip_gitaly_mock
do
it_behaves_like
'getting last commit for path'
end
end
end
describe
'#last_commit_id_for_path'
do
describe
'#last_commit_id_for_path'
do
subject
{
repository
.
last_commit_id_for_path
(
sample_commit
.
id
,
'.gitignore'
)
}
shared_examples
'getting last commit ID for path'
do
subject
{
repository
.
last_commit_id_for_path
(
sample_commit
.
id
,
'.gitignore'
)
}
it
"returns last commit id for a given path"
do
it
"returns last commit id for a given path"
do
is_expected
.
to
eq
(
'c1acaa58bbcbc3eafe538cb8274ba387047b69f8'
)
is_expected
.
to
eq
(
'c1acaa58bbcbc3eafe538cb8274ba387047b69f8'
)
end
end
it
"caches last commit id for a given path"
do
it
"caches last commit id for a given path"
do
cache
=
repository
.
send
(
:cache
)
cache
=
repository
.
send
(
:cache
)
key
=
"last_commit_id_for_path:
#{
sample_commit
.
id
}
:
#{
Digest
::
SHA1
.
hexdigest
(
'.gitignore'
)
}
"
key
=
"last_commit_id_for_path:
#{
sample_commit
.
id
}
:
#{
Digest
::
SHA1
.
hexdigest
(
'.gitignore'
)
}
"
expect
(
cache
).
to
receive
(
:fetch
).
with
(
key
).
and_return
(
'c1acaa5'
)
expect
(
cache
).
to
receive
(
:fetch
).
with
(
key
).
and_return
(
'c1acaa5'
)
is_expected
.
to
eq
(
'c1acaa5'
)
is_expected
.
to
eq
(
'c1acaa5'
)
end
end
describe
'when storage is broken'
,
:broken_storage
do
describe
'when storage is broken'
,
:broken_storage
do
it
'should raise a storage error'
do
it
'should raise a storage error'
do
expect_to_raise_storage_error
do
expect_to_raise_storage_error
do
broken_repository
.
last_commit_for_path
(
sample_commit
.
id
,
'.gitignore'
).
id
broken_repository
.
last_commit_for_path
(
sample_commit
.
id
,
'.gitignore'
).
id
end
end
end
end
end
end
end
context
'when Gitaly feature last_commit_for_path is enabled'
do
it_behaves_like
'getting last commit ID for path'
end
context
'when Gitaly feature last_commit_for_path is disabled'
,
:skip_gitaly_mock
do
it_behaves_like
'getting last commit ID for path'
end
end
end
describe
'#commits'
do
describe
'#commits'
do
...
@@ -334,57 +374,78 @@ describe Repository do
...
@@ -334,57 +374,78 @@ describe Repository do
describe
'#commits_by'
do
describe
'#commits_by'
do
set
(
:project
)
{
create
(
:project
,
:repository
)
}
set
(
:project
)
{
create
(
:project
,
:repository
)
}
let
(
:oids
)
{
TestEnv
::
BRANCH_SHA
.
values
}
subject
{
project
.
repository
.
commits_by
(
oids:
oids
)
}
shared_examples
'batch commits fetching'
do
let
(
:oids
)
{
TestEnv
::
BRANCH_SHA
.
values
}
it
'finds each commit'
do
subject
{
project
.
repository
.
commits_by
(
oids:
oids
)
}
expect
(
subject
).
not_to
include
(
nil
)
expect
(
subject
.
size
).
to
eq
(
oids
.
size
)
end
it
'returns only Commit instances'
do
it
'finds each commit'
do
expect
(
subject
).
to
all
(
be_a
(
Commit
)
)
expect
(
subject
).
not_to
include
(
nil
)
end
expect
(
subject
.
size
).
to
eq
(
oids
.
size
)
end
context
'when some commits are not found '
do
it
'returns only Commit instances'
do
let
(
:oids
)
do
expect
(
subject
).
to
all
(
be_a
(
Commit
)
)
[
'deadbeef'
]
+
TestEnv
::
BRANCH_SHA
.
values
.
first
(
10
)
end
end
it
'returns only found commits'
do
context
'when some commits are not found '
do
expect
(
subject
).
not_to
include
(
nil
)
let
(
:oids
)
do
expect
(
subject
.
size
).
to
eq
(
10
)
[
'deadbeef'
]
+
TestEnv
::
BRANCH_SHA
.
values
.
first
(
10
)
end
it
'returns only found commits'
do
expect
(
subject
).
not_to
include
(
nil
)
expect
(
subject
.
size
).
to
eq
(
10
)
end
end
end
end
context
'when no oids are passed'
do
context
'when no oids are passed'
do
let
(
:oids
)
{
[]
}
let
(
:oids
)
{
[]
}
it
'does not call #batch_by_oid'
do
it
'does not call #batch_by_oid'
do
expect
(
Gitlab
::
Git
::
Commit
).
not_to
receive
(
:batch_by_oid
)
expect
(
Gitlab
::
Git
::
Commit
).
not_to
receive
(
:batch_by_oid
)
subject
subject
end
end
end
end
end
context
'when Gitaly list_commits_by_oid is enabled'
do
it_behaves_like
'batch commits fetching'
end
context
'when Gitaly list_commits_by_oid is enabled'
,
:disable_gitaly
do
it_behaves_like
'batch commits fetching'
end
end
end
describe
'#find_commits_by_message'
do
describe
'#find_commits_by_message'
do
it
'returns commits with messages containing a given string'
do
shared_examples
'finding commits by message'
do
commit_ids
=
repository
.
find_commits_by_message
(
'submodule'
).
map
(
&
:id
)
it
'returns commits with messages containing a given string'
do
commit_ids
=
repository
.
find_commits_by_message
(
'submodule'
).
map
(
&
:id
)
expect
(
commit_ids
).
to
include
(
'5937ac0a7beb003549fc5fd26fc247adbce4a52e'
,
'6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9'
,
'cfe32cf61b73a0d5e9f13e774abde7ff789b1660'
)
expect
(
commit_ids
).
not_to
include
(
'913c66a37b4a45b9769037c55c2d238bd0942d2e'
)
end
it
'is case insensitive'
do
commit_ids
=
repository
.
find_commits_by_message
(
'SUBMODULE'
).
map
(
&
:id
)
expect
(
commit_ids
).
to
include
(
expect
(
commit_ids
).
to
include
(
'5937ac0a7beb003549fc5fd26fc247adbce4a52e'
)
'5937ac0a7beb003549fc5fd26fc247adbce4a52e'
,
end
'6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9'
,
'cfe32cf61b73a0d5e9f13e774abde7ff789b1660'
)
expect
(
commit_ids
).
not_to
include
(
'913c66a37b4a45b9769037c55c2d238bd0942d2e'
)
end
end
it
'is case insensitive'
do
context
'when Gitaly commits_by_message feature is enabled'
do
commit_ids
=
repository
.
find_commits_by_message
(
'SUBMODULE'
).
map
(
&
:id
)
it_behaves_like
'finding commits by message'
end
expect
(
commit_ids
).
to
include
(
'5937ac0a7beb003549fc5fd26fc247adbce4a52e'
)
context
'when Gitaly commits_by_message feature is disabled'
,
:skip_gitaly_mock
do
it_behaves_like
'finding commits by message'
end
end
describe
'when storage is broken'
,
:broken_storage
do
describe
'when storage is broken'
,
:broken_storage
do
...
@@ -1267,23 +1328,34 @@ describe Repository do
...
@@ -1267,23 +1328,34 @@ describe Repository do
describe
'#merge'
do
describe
'#merge'
do
let
(
:merge_request
)
{
create
(
:merge_request
,
source_branch:
'feature'
,
target_branch:
'master'
,
source_project:
project
)
}
let
(
:merge_request
)
{
create
(
:merge_request
,
source_branch:
'feature'
,
target_branch:
'master'
,
source_project:
project
)
}
let
(
:message
)
{
'Test \r\n\r\n message'
}
let
(
:message
)
{
'Test \r\n\r\n message'
}
it
'merges the code and returns the commit id'
do
shared_examples
'#merge'
do
expect
(
merge_commit
).
to
be_present
it
'merges the code and returns the commit id'
do
expect
(
repository
.
blob_at
(
merge_commit
.
id
,
'files/ruby/feature.rb'
)).
to
be_present
expect
(
merge_commit
).
to
be_present
end
expect
(
repository
.
blob_at
(
merge_commit
.
id
,
'files/ruby/feature.rb'
)).
to
be_present
end
it
'sets the `in_progress_merge_commit_sha` flag for the given merge request'
do
it
'sets the `in_progress_merge_commit_sha` flag for the given merge request'
do
merge_commit_id
=
merge
(
repository
,
user
,
merge_request
,
message
)
merge_commit_id
=
merge
(
repository
,
user
,
merge_request
,
message
)
expect
(
merge_request
.
in_progress_merge_commit_sha
).
to
eq
(
merge_commit_id
)
expect
(
merge_request
.
in_progress_merge_commit_sha
).
to
eq
(
merge_commit_id
)
end
it
'removes carriage returns from commit message'
do
merge_commit_id
=
merge
(
repository
,
user
,
merge_request
,
message
)
expect
(
repository
.
commit
(
merge_commit_id
).
message
).
to
eq
(
message
.
delete
(
"
\r
"
))
end
end
end
it
'removes carriage returns from commit message'
do
context
'with gitaly'
do
merge_commit_id
=
merge
(
repository
,
user
,
merge_request
,
message
)
it_behaves_like
'#merge'
end
expect
(
repository
.
commit
(
merge_commit_id
).
message
).
to
eq
(
message
.
delete
(
"
\r
"
))
context
'without gitaly'
,
:skip_gitaly_mock
do
it_behaves_like
'#merge'
end
end
def
merge
(
repository
,
user
,
merge_request
,
message
)
def
merge
(
repository
,
user
,
merge_request
,
message
)
...
@@ -1320,78 +1392,98 @@ describe Repository do
...
@@ -1320,78 +1392,98 @@ describe Repository do
end
end
describe
'#revert'
do
describe
'#revert'
do
let
(
:new_image_commit
)
{
repository
.
commit
(
'33f3729a45c02fc67d00adb1b8bca394b0e761d9'
)
}
shared_examples
'reverting a commit'
do
let
(
:update_image_commit
)
{
repository
.
commit
(
'2f63565e7aac07bcdadb654e253078b727143ec4'
)
}
let
(
:new_image_commit
)
{
repository
.
commit
(
'33f3729a45c02fc67d00adb1b8bca394b0e761d9'
)
}
let
(
:message
)
{
'revert message'
}
let
(
:update_image_commit
)
{
repository
.
commit
(
'2f63565e7aac07bcdadb654e253078b727143ec4'
)
}
let
(
:message
)
{
'revert message'
}
context
'when there is a conflict'
do
it
'raises an error'
do
context
'when there is a conflict'
do
expect
{
repository
.
revert
(
user
,
new_image_commit
,
'master'
,
message
)
}.
to
raise_error
(
Gitlab
::
Git
::
Repository
::
CreateTreeError
)
it
'raises an error'
do
expect
{
repository
.
revert
(
user
,
new_image_commit
,
'master'
,
message
)
}.
to
raise_error
(
Gitlab
::
Git
::
Repository
::
CreateTreeError
)
end
end
end
end
context
'when commit was already reverted'
do
context
'when commit was already reverted'
do
it
'raises an error'
do
it
'raises an error'
do
repository
.
revert
(
user
,
update_image_commit
,
'master'
,
message
)
repository
.
revert
(
user
,
update_image_commit
,
'master'
,
message
)
expect
{
repository
.
revert
(
user
,
update_image_commit
,
'master'
,
message
)
}.
to
raise_error
(
Gitlab
::
Git
::
Repository
::
CreateTreeError
)
expect
{
repository
.
revert
(
user
,
update_image_commit
,
'master'
,
message
)
}.
to
raise_error
(
Gitlab
::
Git
::
Repository
::
CreateTreeError
)
end
end
end
end
context
'when commit can be reverted'
do
context
'when commit can be reverted'
do
it
'reverts the changes'
do
it
'reverts the changes'
do
expect
(
repository
.
revert
(
user
,
update_image_commit
,
'master'
,
message
)).
to
be_truthy
expect
(
repository
.
revert
(
user
,
update_image_commit
,
'master'
,
message
)).
to
be_truthy
end
end
end
end
context
'reverting a merge commit'
do
context
'reverting a merge commit'
do
it
'reverts the changes'
do
it
'reverts the changes'
do
merge_commit
merge_commit
expect
(
repository
.
blob_at_branch
(
'master'
,
'files/ruby/feature.rb'
)).
to
be_present
expect
(
repository
.
blob_at_branch
(
'master'
,
'files/ruby/feature.rb'
)).
to
be_present
repository
.
revert
(
user
,
merge_commit
,
'master'
,
message
)
repository
.
revert
(
user
,
merge_commit
,
'master'
,
message
)
expect
(
repository
.
blob_at_branch
(
'master'
,
'files/ruby/feature.rb'
)).
not_to
be_present
expect
(
repository
.
blob_at_branch
(
'master'
,
'files/ruby/feature.rb'
)).
not_to
be_present
end
end
end
end
end
context
'when Gitaly revert feature is enabled'
do
it_behaves_like
'reverting a commit'
end
context
'when Gitaly revert feature is disabled'
,
:disable_gitaly
do
it_behaves_like
'reverting a commit'
end
end
end
describe
'#cherry_pick'
do
describe
'#cherry_pick'
do
let
(
:conflict_commit
)
{
repository
.
commit
(
'c642fe9b8b9f28f9225d7ea953fe14e74748d53b'
)
}
shared_examples
'cherry-picking a commit'
do
let
(
:pickable_commit
)
{
repository
.
commit
(
'7d3b0f7cff5f37573aea97cebfd5692ea1689924'
)
}
let
(
:conflict_commit
)
{
repository
.
commit
(
'c642fe9b8b9f28f9225d7ea953fe14e74748d53b'
)
}
let
(
:pickable_merge
)
{
repository
.
commit
(
'e56497bb5f03a90a51293fc6d516788730953899'
)
}
let
(
:pickable_commit
)
{
repository
.
commit
(
'7d3b0f7cff5f37573aea97cebfd5692ea1689924'
)
}
let
(
:message
)
{
'cherry-pick message'
}
let
(
:pickable_merge
)
{
repository
.
commit
(
'e56497bb5f03a90a51293fc6d516788730953899'
)
}
let
(
:message
)
{
'cherry-pick message'
}
context
'when there is a conflict'
do
it
'raises an error'
do
context
'when there is a conflict'
do
expect
{
repository
.
cherry_pick
(
user
,
conflict_commit
,
'master'
,
message
)
}.
to
raise_error
(
Gitlab
::
Git
::
Repository
::
CreateTreeError
)
it
'raises an error'
do
expect
{
repository
.
cherry_pick
(
user
,
conflict_commit
,
'master'
,
message
)
}.
to
raise_error
(
Gitlab
::
Git
::
Repository
::
CreateTreeError
)
end
end
end
end
context
'when commit was already cherry-picked'
do
context
'when commit was already cherry-picked'
do
it
'raises an error'
do
it
'raises an error'
do
repository
.
cherry_pick
(
user
,
pickable_commit
,
'master'
,
message
)
repository
.
cherry_pick
(
user
,
pickable_commit
,
'master'
,
message
)
expect
{
repository
.
cherry_pick
(
user
,
pickable_commit
,
'master'
,
message
)
}.
to
raise_error
(
Gitlab
::
Git
::
Repository
::
CreateTreeError
)
expect
{
repository
.
cherry_pick
(
user
,
pickable_commit
,
'master'
,
message
)
}.
to
raise_error
(
Gitlab
::
Git
::
Repository
::
CreateTreeError
)
end
end
end
end
context
'when commit can be cherry-picked'
do
context
'when commit can be cherry-picked'
do
it
'cherry-picks the changes'
do
it
'cherry-picks the changes'
do
expect
(
repository
.
cherry_pick
(
user
,
pickable_commit
,
'master'
,
message
)).
to
be_truthy
expect
(
repository
.
cherry_pick
(
user
,
pickable_commit
,
'master'
,
message
)).
to
be_truthy
end
end
end
end
context
'cherry-picking a merge commit'
do
context
'cherry-picking a merge commit'
do
it
'cherry-picks the changes'
do
it
'cherry-picks the changes'
do
expect
(
repository
.
blob_at_branch
(
'improve/awesome'
,
'foo/bar/.gitkeep'
)).
to
be_nil
expect
(
repository
.
blob_at_branch
(
'improve/awesome'
,
'foo/bar/.gitkeep'
)).
to
be_nil
cherry_pick_commit_sha
=
repository
.
cherry_pick
(
user
,
pickable_merge
,
'improve/awesome'
,
message
)
cherry_pick_commit_sha
=
repository
.
cherry_pick
(
user
,
pickable_merge
,
'improve/awesome'
,
message
)
cherry_pick_commit_message
=
project
.
commit
(
cherry_pick_commit_sha
).
message
cherry_pick_commit_message
=
project
.
commit
(
cherry_pick_commit_sha
).
message
expect
(
repository
.
blob_at_branch
(
'improve/awesome'
,
'foo/bar/.gitkeep'
)).
not_to
be_nil
expect
(
repository
.
blob_at_branch
(
'improve/awesome'
,
'foo/bar/.gitkeep'
)).
not_to
be_nil
expect
(
cherry_pick_commit_message
).
to
eq
(
message
)
expect
(
cherry_pick_commit_message
).
to
eq
(
message
)
end
end
end
end
end
context
'when Gitaly cherry_pick feature is enabled'
do
it_behaves_like
'cherry-picking a commit'
end
context
'when Gitaly cherry_pick feature is disabled'
,
:disable_gitaly
do
it_behaves_like
'cherry-picking a commit'
end
end
end
describe
'#before_delete'
do
describe
'#before_delete'
do
...
@@ -2098,23 +2190,33 @@ describe Repository do
...
@@ -2098,23 +2190,33 @@ describe Repository do
let
(
:commit
)
{
repository
.
commit
}
let
(
:commit
)
{
repository
.
commit
}
let
(
:ancestor
)
{
commit
.
parents
.
first
}
let
(
:ancestor
)
{
commit
.
parents
.
first
}
it
'it is an ancestor'
do
shared_examples
'#ancestor?'
do
expect
(
repository
.
ancestor?
(
ancestor
.
id
,
commit
.
id
)).
to
eq
(
true
)
it
'it is an ancestor'
do
end
expect
(
repository
.
ancestor?
(
ancestor
.
id
,
commit
.
id
)).
to
eq
(
true
)
end
it
'it is not an ancestor'
do
it
'it is not an ancestor'
do
expect
(
repository
.
ancestor?
(
commit
.
id
,
ancestor
.
id
)).
to
eq
(
false
)
expect
(
repository
.
ancestor?
(
commit
.
id
,
ancestor
.
id
)).
to
eq
(
false
)
end
it
'returns false on nil-values'
do
expect
(
repository
.
ancestor?
(
nil
,
commit
.
id
)).
to
eq
(
false
)
expect
(
repository
.
ancestor?
(
ancestor
.
id
,
nil
)).
to
eq
(
false
)
expect
(
repository
.
ancestor?
(
nil
,
nil
)).
to
eq
(
false
)
end
it
'returns false for invalid commit IDs'
do
expect
(
repository
.
ancestor?
(
commit
.
id
,
Gitlab
::
Git
::
BLANK_SHA
)).
to
eq
(
false
)
expect
(
repository
.
ancestor?
(
Gitlab
::
Git
::
BLANK_SHA
,
commit
.
id
)).
to
eq
(
false
)
end
end
end
it
'returns false on nil-values'
do
context
'with Gitaly enabled'
do
expect
(
repository
.
ancestor?
(
nil
,
commit
.
id
)).
to
eq
(
false
)
it_behaves_like
(
'#ancestor?'
)
expect
(
repository
.
ancestor?
(
ancestor
.
id
,
nil
)).
to
eq
(
false
)
expect
(
repository
.
ancestor?
(
nil
,
nil
)).
to
eq
(
false
)
end
end
it
'returns false for invalid commit IDs'
do
context
'with Gitaly disabled'
,
:skip_gitaly_mock
do
expect
(
repository
.
ancestor?
(
commit
.
id
,
Gitlab
::
Git
::
BLANK_SHA
)).
to
eq
(
false
)
it_behaves_like
(
'#ancestor?'
)
expect
(
repository
.
ancestor?
(
Gitlab
::
Git
::
BLANK_SHA
,
commit
.
id
)).
to
eq
(
false
)
end
end
end
end
...
...
spec/models/wiki_page_spec.rb
View file @
2742b871
...
@@ -200,160 +200,180 @@ describe WikiPage do
...
@@ -200,160 +200,180 @@ describe WikiPage do
end
end
describe
'#create'
do
describe
'#create'
do
context
'with valid attributes'
do
shared_examples
'create method'
do
it
'raises an error if a page with the same path already exists'
do
context
'with valid attributes'
do
create_page
(
'New Page'
,
'content'
)
it
'raises an error if a page with the same path already exists'
do
create_page
(
'foo/bar'
,
'content'
)
create_page
(
'New Page'
,
'content'
)
expect
{
create_page
(
'New Page'
,
'other content'
)
}.
to
raise_error
Gitlab
::
Git
::
Wiki
::
DuplicatePageError
create_page
(
'foo/bar'
,
'content'
)
expect
{
create_page
(
'foo/bar'
,
'other content'
)
}.
to
raise_error
Gitlab
::
Git
::
Wiki
::
DuplicatePageError
expect
{
create_page
(
'New Page'
,
'other content'
)
}.
to
raise_error
Gitlab
::
Git
::
Wiki
::
DuplicatePageError
expect
{
create_page
(
'foo/bar'
,
'other content'
)
}.
to
raise_error
Gitlab
::
Git
::
Wiki
::
DuplicatePageError
destroy_page
(
'New Page'
)
destroy_page
(
'bar'
,
'foo'
)
destroy_page
(
'New Page'
)
end
destroy_page
(
'bar'
,
'foo'
)
end
it
'if the title is preceded by a / it is removed'
do
it
'if the title is preceded by a / it is removed'
do
create_page
(
'/New Page'
,
'content'
)
create_page
(
'/New Page'
,
'content'
)
expect
(
wiki
.
find_page
(
'New Page'
)).
not_to
be_nil
expect
(
wiki
.
find_page
(
'New Page'
)).
not_to
be_nil
destroy_page
(
'New Page'
)
destroy_page
(
'New Page'
)
end
end
end
end
end
end
describe
"#update"
do
context
'when Gitaly is enabled'
do
before
do
it_behaves_like
'create method'
create_page
(
"Update"
,
"content"
)
@page
=
wiki
.
find_page
(
"Update"
)
end
end
after
do
context
'when Gitaly is disabled'
,
:skip_gitaly_mock
do
destroy_page
(
@page
.
title
,
@page
.
directory
)
it_behaves_like
'create method'
end
end
end
context
"with valid attributes"
do
describe
"#update"
do
it
"updates the content of the page"
do
shared_examples
'update method'
do
new_content
=
"new content"
before
do
create_page
(
"Update"
,
"content"
)
@page
.
update
(
content:
new_content
)
@page
=
wiki
.
find_page
(
"Update"
)
@page
=
wiki
.
find_page
(
"Update"
)
end
expect
(
@page
.
content
).
to
eq
(
"new content"
)
after
do
destroy_page
(
@page
.
title
,
@page
.
directory
)
end
end
it
"updates the title of the page"
do
context
"with valid attributes"
do
new_title
=
"Index v.1.2.4"
it
"updates the content of the page"
do
new_content
=
"new content"
@page
.
update
(
content:
new_content
)
@page
=
wiki
.
find_page
(
"Update"
)
@page
.
update
(
title:
new_title
)
expect
(
@page
.
content
).
to
eq
(
"new content"
)
@page
=
wiki
.
find_page
(
new_title
)
end
expect
(
@page
.
title
).
to
eq
(
new_title
)
it
"updates the title of the page"
do
end
new_title
=
"Index v.1.2.4"
it
"returns true"
do
@page
.
update
(
title:
new_title
)
expect
(
@page
.
update
(
content:
"more content"
)).
to
be_truthy
@page
=
wiki
.
find_page
(
new_title
)
expect
(
@page
.
title
).
to
eq
(
new_title
)
end
it
"returns true"
do
expect
(
@page
.
update
(
content:
"more content"
)).
to
be_truthy
end
end
end
end
context
'with same last commit sha'
do
context
'with same last commit sha'
do
it
'returns true'
do
it
'returns true'
do
expect
(
@page
.
update
(
content:
'more content'
,
last_commit_sha:
@page
.
last_commit_sha
)).
to
be_truthy
expect
(
@page
.
update
(
content:
'more content'
,
last_commit_sha:
@page
.
last_commit_sha
)).
to
be_truthy
end
end
end
end
context
'with different last commit sha'
do
context
'with different last commit sha'
do
it
'raises exception'
do
it
'raises exception'
do
expect
{
@page
.
update
(
content:
'more content'
,
last_commit_sha:
'xxx'
)
}.
to
raise_error
(
WikiPage
::
PageChangedError
)
expect
{
@page
.
update
(
content:
'more content'
,
last_commit_sha:
'xxx'
)
}.
to
raise_error
(
WikiPage
::
PageChangedError
)
end
end
end
end
context
'when renaming a page'
do
context
'when renaming a page'
do
it
'raises an error if the page already exists'
do
it
'raises an error if the page already exists'
do
create_page
(
'Existing Page'
,
'content'
)
create_page
(
'Existing Page'
,
'content'
)
expect
{
@page
.
update
(
title:
'Existing Page'
,
content:
'new_content'
)
}.
to
raise_error
(
WikiPage
::
PageRenameError
)
expect
{
@page
.
update
(
title:
'Existing Page'
,
content:
'new_content'
)
}.
to
raise_error
(
WikiPage
::
PageRenameError
)
expect
(
@page
.
title
).
to
eq
'Update'
expect
(
@page
.
title
).
to
eq
'Update'
expect
(
@page
.
content
).
to
eq
'new_content'
expect
(
@page
.
content
).
to
eq
'new_content'
destroy_page
(
'Existing Page'
)
destroy_page
(
'Existing Page'
)
end
end
it
'updates the content and rename the file'
do
it
'updates the content and rename the file'
do
new_title
=
'Renamed Page'
new_title
=
'Renamed Page'
new_content
=
'updated content'
new_content
=
'updated content'
expect
(
@page
.
update
(
title:
new_title
,
content:
new_content
)).
to
be_truthy
expect
(
@page
.
update
(
title:
new_title
,
content:
new_content
)).
to
be_truthy
@page
=
wiki
.
find_page
(
new_title
)
@page
=
wiki
.
find_page
(
new_title
)
expect
(
@page
).
not_to
be_nil
expect
(
@page
).
not_to
be_nil
expect
(
@page
.
content
).
to
eq
new_content
expect
(
@page
.
content
).
to
eq
new_content
end
end
end
end
context
'when moving a page'
do
context
'when moving a page'
do
it
'raises an error if the page already exists'
do
it
'raises an error if the page already exists'
do
create_page
(
'foo/Existing Page'
,
'content'
)
create_page
(
'foo/Existing Page'
,
'content'
)
expect
{
@page
.
update
(
title:
'foo/Existing Page'
,
content:
'new_content'
)
}.
to
raise_error
(
WikiPage
::
PageRenameError
)
expect
(
@page
.
title
).
to
eq
'Update'
expect
(
@page
.
content
).
to
eq
'new_content'
destroy_page
(
'Existing Page'
,
'foo'
)
expect
{
@page
.
update
(
title:
'foo/Existing Page'
,
content:
'new_content'
)
}.
to
raise_error
(
WikiPage
::
PageRenameError
)
end
expect
(
@page
.
title
).
to
eq
'Update'
expect
(
@page
.
content
).
to
eq
'new_content'
it
'updates the content and moves the file'
do
destroy_page
(
'Existing Page'
,
'foo'
)
new_title
=
'foo/Other Page'
end
new_content
=
'new_content'
expect
(
@page
.
update
(
title:
new_title
,
content:
new_content
)).
to
be_truthy
it
'updates the content and moves the file'
do
new_title
=
'foo/Other Page'
new_content
=
'new_content'
page
=
wiki
.
find_page
(
new_title
)
expect
(
@page
.
update
(
title:
new_title
,
content:
new_content
)).
to
be_truthy
expect
(
page
).
not_to
be_nil
page
=
wiki
.
find_page
(
new_title
)
expect
(
page
.
content
).
to
eq
new_content
end
context
'in subdir'
do
expect
(
page
).
not_to
be_nil
before
do
expect
(
page
.
content
).
to
eq
new_content
create_page
(
'foo/Existing Page'
,
'content'
)
@page
=
wiki
.
find_page
(
'foo/Existing Page'
)
end
end
it
'moves the page to the root folder if the title is preceded by /'
do
context
'in subdir'
do
expect
(
@page
.
slug
).
to
eq
'foo/Existing-Page'
before
do
expect
(
@page
.
update
(
title:
'/Existing Page'
,
content:
'new_content'
)).
to
be_truthy
create_page
(
'foo/Existing Page'
,
'content'
)
expect
(
@page
.
slug
).
to
eq
'Existing-Page'
@page
=
wiki
.
find_page
(
'foo/Existing Page'
)
end
it
'moves the page to the root folder if the title is preceded by /'
,
:skip_gitaly_mock
do
expect
(
@page
.
slug
).
to
eq
'foo/Existing-Page'
expect
(
@page
.
update
(
title:
'/Existing Page'
,
content:
'new_content'
)).
to
be_truthy
expect
(
@page
.
slug
).
to
eq
'Existing-Page'
end
it
'does nothing if it has the same title'
do
original_path
=
@page
.
slug
expect
(
@page
.
update
(
title:
'Existing Page'
,
content:
'new_content'
)).
to
be_truthy
expect
(
@page
.
slug
).
to
eq
original_path
end
end
end
it
'does nothing if it has the same title'
do
context
'in root dir'
do
original_path
=
@page
.
slug
it
'does nothing if the title is preceded by /'
do
original_path
=
@page
.
slug
expect
(
@page
.
update
(
title:
'Existing Page'
,
content:
'new_content'
)).
to
be_truthy
expect
(
@page
.
update
(
title:
'/Update'
,
content:
'new_content'
)).
to
be_truthy
expect
(
@page
.
slug
).
to
eq
original_path
expect
(
@page
.
slug
).
to
eq
original_path
end
end
end
end
end
context
'in root dir'
do
context
"with invalid attributes"
do
it
'does nothing if the title is preceded by /'
do
it
'aborts update if title blank'
do
original_path
=
@page
.
slug
expect
(
@page
.
update
(
title:
''
,
content:
'new_content'
)).
to
be_falsey
expect
(
@page
.
content
).
to
eq
'new_content'
expect
(
@page
.
update
(
title:
'/Update'
,
content:
'new_content'
)).
to
be_truthy
page
=
wiki
.
find_page
(
'Update'
)
expect
(
@page
.
slug
).
to
eq
original_path
expect
(
page
.
content
).
to
eq
'content'
@page
.
title
=
'Update'
end
end
end
end
end
end
context
"with invalid attributes"
do
context
'when Gitaly is enabled'
do
it
'aborts update if title blank'
do
it_behaves_like
'update method'
expect
(
@page
.
update
(
title:
''
,
content:
'new_content'
)).
to
be_falsey
end
expect
(
@page
.
content
).
to
eq
'new_content'
page
=
wiki
.
find_page
(
'Update'
)
expect
(
page
.
content
).
to
eq
'content'
@page
.
title
=
'Update'
context
'when Gitaly is disabled'
,
:skip_gitaly_mock
do
end
it_behaves_like
'update method'
end
end
end
end
...
@@ -374,24 +394,34 @@ describe WikiPage do
...
@@ -374,24 +394,34 @@ describe WikiPage do
end
end
describe
"#versions"
do
describe
"#versions"
do
let
(
:page
)
{
wiki
.
find_page
(
"Update"
)
}
shared_examples
'wiki page versions'
do
let
(
:page
)
{
wiki
.
find_page
(
"Update"
)
}
before
do
before
do
create_page
(
"Update"
,
"content"
)
create_page
(
"Update"
,
"content"
)
end
end
after
do
after
do
destroy_page
(
"Update"
)
destroy_page
(
"Update"
)
end
end
it
"returns an array of all commits for the page"
do
3
.
times
{
|
i
|
page
.
update
(
content:
"content
#{
i
}
"
)
}
it
"returns an array of all commits for the page"
do
expect
(
page
.
versions
.
count
).
to
eq
(
4
)
3
.
times
{
|
i
|
page
.
update
(
content:
"content
#{
i
}
"
)
}
end
expect
(
page
.
versions
.
count
).
to
eq
(
4
)
it
'returns instances of WikiPageVersion'
do
expect
(
page
.
versions
).
to
all
(
be_a
(
Gitlab
::
Git
::
WikiPageVersion
)
)
end
end
end
it
'returns instances of WikiPageVersion'
do
context
'when Gitaly is enabled'
do
expect
(
page
.
versions
).
to
all
(
be_a
(
Gitlab
::
Git
::
WikiPageVersion
)
)
it_behaves_like
'wiki page versions'
end
context
'when Gitaly is disabled'
,
:disable_gitaly
do
it_behaves_like
'wiki page versions'
end
end
end
end
...
@@ -525,13 +555,23 @@ describe WikiPage do
...
@@ -525,13 +555,23 @@ describe WikiPage do
end
end
describe
'#formatted_content'
do
describe
'#formatted_content'
do
it
'returns processed content of the page'
do
shared_examples
'fetching page formatted content'
do
subject
.
create
({
title:
"RDoc"
,
content:
"*bold*"
,
format:
"rdoc"
})
it
'returns processed content of the page'
do
page
=
wiki
.
find_page
(
'RDoc'
)
subject
.
create
({
title:
"RDoc"
,
content:
"*bold*"
,
format:
"rdoc"
})
page
=
wiki
.
find_page
(
'RDoc'
)
expect
(
page
.
formatted_content
).
to
eq
(
"
\n
<p><strong>bold</strong></p>
\n
"
)
expect
(
page
.
formatted_content
).
to
eq
(
"
\n
<p><strong>bold</strong></p>
\n
"
)
destroy_page
(
'RDoc'
)
end
end
context
'when Gitaly wiki_page_formatted_data is enabled'
do
it_behaves_like
'fetching page formatted content'
end
destroy_page
(
'RDoc'
)
context
'when Gitaly wiki_page_formatted_data is disabled'
,
:disable_gitaly
do
it_behaves_like
'fetching page formatted content'
end
end
end
end
...
...
spec/support/gitaly.rb
0 → 100644
View file @
2742b871
RSpec
.
configure
do
|
config
|
config
.
before
(
:each
)
do
|
example
|
if
example
.
metadata
[
:disable_gitaly
]
# Use 'and_wrap_original' to make sure the arguments are valid
allow
(
Gitlab
::
GitalyClient
).
to
receive
(
:feature_enabled?
).
and_wrap_original
{
|
m
,
*
args
|
m
.
call
(
*
args
)
&&
false
}
else
next
if
example
.
metadata
[
:skip_gitaly_mock
]
# Use 'and_wrap_original' to make sure the arguments are valid
allow
(
Gitlab
::
GitalyClient
).
to
receive
(
:feature_enabled?
).
and_wrap_original
do
|
m
,
*
args
|
m
.
call
(
*
args
)
!
Gitlab
::
GitalyClient
.
explicit_opt_in_required
.
include?
(
args
.
first
)
end
end
end
end
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment