2019-03-30 03:23:56 -04:00
# frozen_string_literal: true
2012-10-02 18:57:13 -04:00
require 'spec_helper'
2020-06-24 14:09:03 -04:00
RSpec . describe Commit do
2020-02-13 10:08:52 -05:00
let_it_be ( :project ) { create ( :project , :public , :repository ) }
let_it_be ( :personal_snippet ) { create ( :personal_snippet , :repository ) }
let_it_be ( :project_snippet ) { create ( :project_snippet , :repository ) }
let ( :commit ) { project . commit }
2015-05-02 23:11:21 -04:00
describe 'modules' do
subject { described_class }
it { is_expected . to include_module ( Mentionable ) }
it { is_expected . to include_module ( Participable ) }
it { is_expected . to include_module ( Referable ) }
it { is_expected . to include_module ( StaticModel ) }
2019-01-28 07:12:30 -05:00
it { is_expected . to include_module ( Presentable ) }
2015-05-02 23:11:21 -04:00
end
2017-12-05 08:15:30 -05:00
describe '.lazy' do
2020-02-13 10:08:52 -05:00
shared_examples '.lazy checks' do
context 'when the commits are found' do
let ( :oids ) do
%w(
498214 de67004b1da3d820901307bed2a68a8ef6
c642fe9b8b9f28f9225d7ea953fe14e74748d53b
6 f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9
04 8721 d90c449b244b7b4c53a9186b04330174ec
281 d3a76f31c812dbf48abce82ccf6860adedd81
)
end
2017-12-05 08:15:30 -05:00
2020-02-13 10:08:52 -05:00
subject { oids . map { | oid | described_class . lazy ( container , oid ) } }
2017-12-05 08:15:30 -05:00
2020-02-13 10:08:52 -05:00
it 'batches requests for commits' do
expect ( container . repository ) . to receive ( :commits_by ) . once . and_call_original
2017-12-05 08:15:30 -05:00
2020-02-13 10:08:52 -05:00
subject . first . title
subject . last . title
end
2017-12-05 08:15:30 -05:00
2020-02-13 10:08:52 -05:00
it 'maintains ordering' do
subject . each_with_index do | commit , i |
expect ( commit . id ) . to eq ( oids [ i ] )
end
end
2017-12-05 08:15:30 -05:00
2020-02-13 10:08:52 -05:00
it 'does not attempt to replace methods via BatchLoader' do
subject . each do | commit |
expect ( commit ) . to receive ( :method_missing ) . and_call_original
commit . id
end
2017-12-05 08:15:30 -05:00
end
end
2019-06-13 16:50:27 -04:00
2020-02-13 10:08:52 -05:00
context 'when not found' do
it 'returns nil as commit' do
commit = described_class . lazy ( container , 'deadbeef' ) . __sync
2019-06-13 16:50:27 -04:00
2020-02-13 10:08:52 -05:00
expect ( commit ) . to be_nil
2019-06-13 16:50:27 -04:00
end
end
2017-12-05 08:15:30 -05:00
end
2020-02-13 10:08:52 -05:00
context 'with project' do
let ( :container ) { project }
2017-12-05 08:15:30 -05:00
2020-02-13 10:08:52 -05:00
it_behaves_like '.lazy checks'
end
context 'with personal snippet' do
let ( :container ) { personal_snippet }
it_behaves_like '.lazy checks'
end
context 'with project snippet' do
let ( :container ) { project_snippet }
it_behaves_like '.lazy checks'
2017-12-05 08:15:30 -05:00
end
end
2019-12-18 10:08:03 -05:00
describe '#diff_refs' do
it 'is equal to itself' do
expect ( commit . diff_refs ) . to eq ( commit . diff_refs )
end
context 'from a factory' do
let ( :commit ) { create ( :commit ) }
it 'is equal to itself' do
expect ( commit . diff_refs ) . to eq ( commit . diff_refs )
end
end
end
2018-05-07 12:22:07 -04:00
describe '#author' , :request_store do
2016-07-27 19:42:38 -04:00
it 'looks up the author in a case-insensitive way' do
user = create ( :user , email : commit . author_email . upcase )
expect ( commit . author ) . to eq ( user )
end
2018-05-07 12:22:07 -04:00
it 'caches the author' do
2016-07-27 19:42:38 -04:00
user = create ( :user , email : commit . author_email )
expect ( commit . author ) . to eq ( user )
2018-05-07 12:22:07 -04:00
2017-07-17 13:18:20 -04:00
key = " Commit:author: #{ commit . author_email . downcase } "
2016-07-27 19:42:38 -04:00
2018-09-20 18:40:15 -04:00
expect ( Gitlab :: SafeRequestStore [ key ] ) . to eq ( user )
2016-07-27 19:42:38 -04:00
expect ( commit . author ) . to eq ( user )
end
2018-05-07 12:22:07 -04:00
2019-12-06 19:07:51 -05:00
context 'with a user with an unconfirmed e-mail' do
before do
user = create ( :user )
create ( :email , user : user , email : commit . author_email )
end
it 'returns no user' do
expect ( commit . author ) . to be_nil
end
end
2018-05-07 12:22:07 -04:00
context 'using eager loading' do
let! ( :alice ) { create ( :user , email : 'alice@example.com' ) }
let! ( :bob ) { create ( :user , email : 'hunter2@example.com' ) }
2018-11-14 13:42:36 -05:00
let! ( :jeff ) { create ( :user ) }
2018-05-07 12:22:07 -04:00
let ( :alice_commit ) do
described_class . new ( RepoHelpers . sample_commit , project ) . tap do | c |
c . author_email = 'alice@example.com'
end
end
let ( :bob_commit ) do
# The commit for Bob uses one of his alternative Emails, instead of the
# primary one.
described_class . new ( RepoHelpers . sample_commit , project ) . tap do | c |
c . author_email = 'bob@example.com'
end
end
let ( :eve_commit ) do
described_class . new ( RepoHelpers . sample_commit , project ) . tap do | c |
c . author_email = 'eve@example.com'
end
end
2018-11-14 13:42:36 -05:00
let ( :jeff_commit ) do
# The commit for Jeff uses his private commit email
described_class . new ( RepoHelpers . sample_commit , project ) . tap do | c |
c . author_email = jeff . private_commit_email
end
end
let! ( :commits ) { [ alice_commit , bob_commit , eve_commit , jeff_commit ] }
2018-05-07 12:22:07 -04:00
before do
2019-12-06 19:07:51 -05:00
create ( :email , :confirmed , user : bob , email : 'bob@example.com' )
2018-05-07 12:22:07 -04:00
end
it 'executes only two SQL queries' do
recorder = ActiveRecord :: QueryRecorder . new do
# Running this first ensures we don't run one query for every
# commit.
commits . each ( & :lazy_author )
# This forces the execution of the SQL queries necessary to load the
# data.
commits . each { | c | c . author . try ( :id ) }
end
expect ( recorder . count ) . to eq ( 2 )
end
it " preloads the authors for Commits matching a user's primary Email " do
commits . each ( & :lazy_author )
expect ( alice_commit . author ) . to eq ( alice )
end
it " preloads the authors for Commits using a User's alternative Email " do
commits . each ( & :lazy_author )
expect ( bob_commit . author ) . to eq ( bob )
end
2018-11-14 13:42:36 -05:00
it " preloads the authors for Commits using a User's private commit Email " do
commits . each ( & :lazy_author )
expect ( jeff_commit . author ) . to eq ( jeff )
end
it " preloads the authors for Commits using a User's outdated private commit Email " do
jeff . update! ( username : 'new-username' )
commits . each ( & :lazy_author )
expect ( jeff_commit . author ) . to eq ( jeff )
end
2018-05-07 12:22:07 -04:00
it 'sets the author to Nil if an author could not be found for a Commit' do
commits . each ( & :lazy_author )
expect ( eve_commit . author ) . to be_nil
end
it 'does not execute SQL queries once the authors are preloaded' do
commits . each ( & :lazy_author )
commits . each { | c | c . author . try ( :id ) }
recorder = ActiveRecord :: QueryRecorder . new do
alice_commit . author
bob_commit . author
eve_commit . author
end
expect ( recorder . count ) . to be_zero
end
end
2016-07-27 19:42:38 -04:00
end
2019-12-06 19:07:51 -05:00
describe '#committer' do
context 'with a confirmed e-mail' do
it 'returns the user' do
user = create ( :user , email : commit . committer_email )
expect ( commit . committer ) . to eq ( user )
end
end
context 'with an unconfirmed e-mail' do
let ( :user ) { create ( :user ) }
before do
create ( :email , user : user , email : commit . committer_email )
end
it 'returns no user' do
expect ( commit . committer ) . to be_nil
end
it 'returns the user' do
expect ( commit . committer ( confirmed : false ) ) . to eq ( user )
end
end
end
2015-05-02 23:11:21 -04:00
describe '#to_reference' do
2020-02-13 10:08:52 -05:00
context 'with project' do
let ( :project ) { create ( :project , :repository , path : 'sample-project' ) }
it 'returns a String reference to the object' do
expect ( commit . to_reference ) . to eq commit . id
end
2016-11-02 19:49:13 -04:00
2020-02-13 10:08:52 -05:00
it 'supports a cross-project reference' do
another_project = build ( :project , :repository , name : 'another-project' , namespace : project . namespace )
expect ( commit . to_reference ( another_project ) ) . to eq " sample-project@ #{ commit . id } "
end
2015-05-02 23:11:21 -04:00
end
2020-02-13 10:08:52 -05:00
context 'with personal snippet' do
let ( :commit ) { personal_snippet . commit }
it 'returns a String reference to the object' do
expect ( commit . to_reference ) . to eq " $ #{ personal_snippet . id } @ #{ commit . id } "
end
it 'supports a cross-snippet reference' do
another_snippet = build ( :personal_snippet )
expect ( commit . to_reference ( another_snippet ) ) . to eq " $ #{ personal_snippet . id } @ #{ commit . id } "
end
end
context 'with project snippet' do
let ( :commit ) { project_snippet . commit }
it 'returns a String reference to the object' do
expect ( commit . to_reference ) . to eq " $ #{ project_snippet . id } @ #{ commit . id } "
end
it 'supports a cross-snippet project reference' do
another_snippet = build ( :personal_snippet )
expect ( commit . to_reference ( another_snippet ) ) . to eq " #{ project_snippet . project . path } $ #{ project_snippet . id } @ #{ commit . id } "
end
2015-12-01 06:58:45 -05:00
end
end
2019-08-28 01:48:24 -04:00
describe '.reference_valid?' do
using RSpec :: Parameterized :: TableSyntax
where ( :ref , :result ) do
'1234567' | true
'123456' | false
'1' | false
'0' * 40 | true
'c1acaa58bbcbc3eafe538cb8274ba387047b69f8' | true
'H1acaa58bbcbc3eafe538cb8274ba387047b69f8' | false
nil | false
end
with_them do
it { expect ( described_class . reference_valid? ( ref ) ) . to eq ( result ) }
end
end
2015-12-01 06:58:45 -05:00
describe '#reference_link_text' do
2017-01-26 17:44:58 -05:00
let ( :project ) { create ( :project , :repository , path : 'sample-project' ) }
2016-11-02 19:49:13 -04:00
2020-02-13 10:08:52 -05:00
context 'with project' do
it 'returns a String reference to the object' do
expect ( commit . reference_link_text ) . to eq commit . short_id
end
it 'supports a cross-project reference' do
another_project = build ( :project , :repository , name : 'another-project' , namespace : project . namespace )
expect ( commit . reference_link_text ( another_project ) ) . to eq " sample-project@ #{ commit . short_id } "
end
end
context 'with personal snippet' do
let ( :commit ) { personal_snippet . commit }
it 'returns a String reference to the object' do
expect ( commit . reference_link_text ) . to eq " $ #{ personal_snippet . id } @ #{ commit . short_id } "
end
it 'supports a cross-snippet reference' do
another_snippet = build ( :personal_snippet , :repository )
expect ( commit . reference_link_text ( another_snippet ) ) . to eq " $ #{ personal_snippet . id } @ #{ commit . short_id } "
end
2015-12-01 06:58:45 -05:00
end
2020-02-13 10:08:52 -05:00
context 'with project snippet' do
let ( :commit ) { project_snippet . commit }
it 'returns a String reference to the object' do
expect ( commit . reference_link_text ) . to eq " $ #{ project_snippet . id } @ #{ commit . short_id } "
end
it 'supports a cross-snippet project reference' do
another_snippet = build ( :project_snippet , :repository )
expect ( commit . reference_link_text ( another_snippet ) ) . to eq " #{ project_snippet . project . path } $ #{ project_snippet . id } @ #{ commit . short_id } "
end
2015-05-02 23:11:21 -04:00
end
end
2012-10-02 18:57:13 -04:00
2013-04-01 09:56:25 -04:00
describe '#title' do
it " returns no_commit_message when safe_message is blank " do
2015-02-12 13:17:35 -05:00
allow ( commit ) . to receive ( :safe_message ) . and_return ( '' )
2020-01-16 07:08:32 -05:00
expect ( commit . title ) . to eq ( " No commit message " )
2013-04-01 09:56:25 -04:00
end
2012-10-02 18:57:13 -04:00
2017-04-21 11:31:18 -04:00
it 'truncates a message without a newline at natural break to 80 characters' do
2014-08-01 11:06:28 -04:00
message = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec sodales id felis id blandit. Vivamus egestas lacinia lacus, sed rutrum mauris.'
2012-10-02 18:57:13 -04:00
2015-02-12 13:17:35 -05:00
allow ( commit ) . to receive ( :safe_message ) . and_return ( message )
2018-12-04 12:59:48 -05:00
expect ( commit . title ) . to eq ( 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec sodales id...' )
2013-04-01 09:56:25 -04:00
end
2012-10-02 18:57:13 -04:00
2013-04-01 09:56:25 -04:00
it " truncates a message with a newline before 80 characters at the newline " do
message = commit . safe_message . split ( " " ) . first
2012-10-02 18:57:13 -04:00
2015-02-12 13:17:35 -05:00
allow ( commit ) . to receive ( :safe_message ) . and_return ( message + " \n " + message )
expect ( commit . title ) . to eq ( message )
2013-04-01 09:56:25 -04:00
end
2012-10-02 18:57:13 -04:00
2014-08-01 11:06:28 -04:00
it " does not truncates a message with a newline after 80 but less 100 characters " do
2016-05-10 22:58:06 -04:00
message = <<eos
2014-08-01 11:06:28 -04:00
Lorem ipsum dolor sit amet , consectetur adipiscing elit . Donec sodales id felis id blandit .
Vivamus egestas lacinia lacus , sed rutrum mauris .
eos
2012-10-02 18:57:13 -04:00
2015-02-12 13:17:35 -05:00
allow ( commit ) . to receive ( :safe_message ) . and_return ( message )
expect ( commit . title ) . to eq ( message . split ( " \n " ) . first )
2012-10-02 18:57:13 -04:00
end
end
2013-01-03 12:11:14 -05:00
2016-07-26 00:49:06 -04:00
describe '#full_title' do
it " returns no_commit_message when safe_message is blank " do
allow ( commit ) . to receive ( :safe_message ) . and_return ( '' )
2020-01-16 07:08:32 -05:00
expect ( commit . full_title ) . to eq ( " No commit message " )
2016-07-26 00:49:06 -04:00
end
it " returns entire message if there is no newline " do
message = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec sodales id felis id blandit. Vivamus egestas lacinia lacus, sed rutrum mauris.'
allow ( commit ) . to receive ( :safe_message ) . and_return ( message )
expect ( commit . full_title ) . to eq ( message )
end
it " returns first line of message if there is a newLine " do
message = commit . safe_message . split ( " " ) . first
allow ( commit ) . to receive ( :safe_message ) . and_return ( message + " \n " + message )
expect ( commit . full_title ) . to eq ( message )
end
2021-02-01 04:09:28 -05:00
it 'truncates html representation if more than 1KiB' do
# Commit title is over 2KiB on a single line
huge_commit_title = ( 'panic ' * 350 ) + 'trailing text'
allow ( commit ) . to receive ( :safe_message ) . and_return ( huge_commit_title )
commit . refresh_markdown_cache
full_title_html = commit . full_title_html
expect ( full_title_html . bytesize ) . to be < 2 . kilobytes
expect ( full_title_html ) . not_to include ( 'trailing text' )
end
2016-07-26 00:49:06 -04:00
end
2017-04-21 11:31:18 -04:00
describe 'description' do
2018-08-21 05:53:43 -04:00
it 'returns no_commit_message when safe_message is blank' do
allow ( commit ) . to receive ( :safe_message ) . and_return ( nil )
2020-01-16 07:08:32 -05:00
expect ( commit . description ) . to eq ( 'No commit message' )
2018-02-07 10:30:30 -05:00
end
2018-08-21 05:53:43 -04:00
2017-04-21 11:31:18 -04:00
it 'returns description of commit message if title less than 100 characters' do
message = <<eos
Lorem ipsum dolor sit amet , consectetur adipiscing elit . Donec sodales id felis id blandit .
Vivamus egestas lacinia lacus , sed rutrum mauris .
eos
allow ( commit ) . to receive ( :safe_message ) . and_return ( message )
expect ( commit . description ) . to eq ( 'Vivamus egestas lacinia lacus, sed rutrum mauris.' )
end
it 'returns full commit message if commit title more than 100 characters' do
message = <<eos
Lorem ipsum dolor sit amet , consectetur adipiscing elit . Donec sodales id felis id blandit . Vivamus egestas lacinia lacus , sed rutrum mauris .
Vivamus egestas lacinia lacus , sed rutrum mauris .
eos
allow ( commit ) . to receive ( :safe_message ) . and_return ( message )
expect ( commit . description ) . to eq ( message )
end
2021-01-19 04:10:32 -05:00
it 'truncates html representation if more than 1Mib' do
# Commit message is over 2MiB
huge_commit_message = [ 'panic' , ( 'panic ' * 350000 ) , 'trailing text' ] . join ( " \n " )
allow ( commit ) . to receive ( :safe_message ) . and_return ( huge_commit_message )
commit . refresh_markdown_cache
description_html = commit . description_html
expect ( description_html . bytesize ) . to be < 2 . megabytes
expect ( description_html ) . not_to include ( 'trailing text' )
end
2017-04-21 11:31:18 -04:00
end
2013-01-03 12:11:14 -05:00
describe " delegation " do
subject { commit }
2015-02-12 13:17:35 -05:00
it { is_expected . to respond_to ( :message ) }
it { is_expected . to respond_to ( :authored_date ) }
it { is_expected . to respond_to ( :committed_date ) }
it { is_expected . to respond_to ( :committer_email ) }
it { is_expected . to respond_to ( :author_email ) }
it { is_expected . to respond_to ( :parents ) }
it { is_expected . to respond_to ( :date ) }
it { is_expected . to respond_to ( :diffs ) }
it { is_expected . to respond_to ( :id ) }
2013-01-03 12:11:14 -05:00
end
2013-05-30 19:16:49 -04:00
it_behaves_like 'a mentionable' do
2017-01-26 17:44:58 -05:00
subject { create ( :project , :repository ) . commit }
2015-04-16 16:25:25 -04:00
2015-10-12 10:23:15 -04:00
let ( :author ) { create ( :user , email : subject . author_email ) }
2015-12-01 06:58:45 -05:00
let ( :backref_text ) { " commit #{ subject . id } " }
2015-05-21 17:49:06 -04:00
let ( :set_mentionable_text ) do
- > ( txt ) { allow ( subject ) . to receive ( :safe_message ) . and_return ( txt ) }
end
2013-05-30 19:16:49 -04:00
# Include the subject in the repository stub.
let ( :extra_commits ) { [ subject ] }
end
2015-12-04 09:23:21 -05:00
describe '#hook_attrs' do
2015-12-07 08:13:06 -05:00
let ( :data ) { commit . hook_attrs ( with_changed_files : true ) }
2015-12-04 09:23:21 -05:00
it { expect ( data ) . to be_a ( Hash ) }
2016-10-03 08:11:16 -04:00
it { expect ( data [ :message ] ) . to include ( 'adds bar folder and branch-test text file to check Repository merged_to_root_ref method' ) }
2019-12-03 13:06:49 -05:00
it { expect ( data [ :timestamp ] ) . to eq ( '2016-09-27T14:37:46+00:00' ) }
2018-01-29 11:18:31 -05:00
it { expect ( data [ :added ] ) . to contain_exactly ( " bar/branch-test.txt " ) }
2016-10-03 08:11:16 -04:00
it { expect ( data [ :modified ] ) . to eq ( [ ] ) }
2015-12-04 09:23:21 -05:00
it { expect ( data [ :removed ] ) . to eq ( [ ] ) }
end
2016-02-22 09:46:39 -05:00
2017-08-16 07:18:07 -04:00
describe '#cherry_pick_message' do
2017-08-17 14:26:06 -04:00
let ( :user ) { create ( :user ) }
2017-08-16 07:18:07 -04:00
context 'of a regular commit' do
2017-08-17 14:26:06 -04:00
let ( :commit ) { project . commit ( 'video' ) }
it { expect ( commit . cherry_pick_message ( user ) ) . to include ( " \n \n (cherry picked from commit 88790590ed1337ab189bccaa355f068481c90bec) " ) }
2017-08-16 07:18:07 -04:00
end
context 'of a merge commit' do
2017-08-17 14:26:06 -04:00
let ( :repository ) { project . repository }
2017-08-21 15:05:11 -04:00
let ( :merge_request ) do
create ( :merge_request ,
source_branch : 'video' ,
target_branch : 'master' ,
source_project : project ,
author : user )
end
2017-08-17 14:26:06 -04:00
2017-08-21 15:05:11 -04:00
let ( :merge_commit ) do
2017-08-17 14:26:06 -04:00
merge_commit_id = repository . merge ( user ,
merge_request . diff_head_sha ,
merge_request ,
2017-09-08 08:00:53 -04:00
'Test message' )
2017-08-17 14:26:06 -04:00
2017-08-21 15:05:11 -04:00
repository . commit ( merge_commit_id )
end
2017-08-17 14:26:06 -04:00
2017-08-21 15:05:11 -04:00
context 'that is found' do
before do
# Artificially mark as completed.
merge_request . update ( merge_commit_sha : merge_commit . id )
end
2017-08-17 14:26:06 -04:00
2017-08-21 15:05:11 -04:00
it do
expected_appended_text = << ~ STR . rstrip
2017-08-17 14:26:06 -04:00
2017-08-21 15:05:11 -04:00
( cherry picked from commit #{merge_commit.sha})
2017-08-16 07:18:07 -04:00
2017-08-21 15:05:11 -04:00
467 dc98f Add new 'videos' directory
88790590 Upload new video file
STR
2017-08-16 07:18:07 -04:00
2017-08-21 15:05:11 -04:00
expect ( merge_commit . cherry_pick_message ( user ) ) . to include ( expected_appended_text )
end
end
2017-08-16 07:18:07 -04:00
2017-08-22 16:20:22 -04:00
context " that is existing but not found " do
it 'does not include details of the merged commits' do
2017-08-21 15:05:11 -04:00
expect ( merge_commit . cherry_pick_message ( user ) ) . to end_with ( " (cherry picked from commit #{ merge_commit . sha } ) " )
end
2017-08-16 07:18:07 -04:00
end
end
end
2016-02-22 09:46:39 -05:00
describe '#reverts_commit?' do
let ( :another_commit ) { double ( :commit , revert_description : " This reverts commit #{ commit . sha } " ) }
2016-11-29 08:47:43 -05:00
let ( :user ) { commit . author }
2016-02-22 09:46:39 -05:00
2016-11-29 08:47:43 -05:00
it { expect ( commit . reverts_commit? ( another_commit , user ) ) . to be_falsy }
2016-02-22 09:46:39 -05:00
context 'commit has no description' do
2017-06-14 14:18:56 -04:00
before do
allow ( commit ) . to receive ( :description? ) . and_return ( false )
end
2016-02-22 09:46:39 -05:00
2016-11-29 08:47:43 -05:00
it { expect ( commit . reverts_commit? ( another_commit , user ) ) . to be_falsy }
2016-02-22 09:46:39 -05:00
end
context " another_commit's description does not revert commit " do
2017-06-14 14:18:56 -04:00
before do
allow ( commit ) . to receive ( :description ) . and_return ( " Foo Bar " )
end
2016-02-22 09:46:39 -05:00
2016-11-29 08:47:43 -05:00
it { expect ( commit . reverts_commit? ( another_commit , user ) ) . to be_falsy }
2016-02-22 09:46:39 -05:00
end
context " another_commit's description reverts commit " do
2017-06-14 14:18:56 -04:00
before do
allow ( commit ) . to receive ( :description ) . and_return ( " Foo #{ another_commit . revert_description } Bar " )
end
2016-02-22 09:46:39 -05:00
2016-11-29 08:47:43 -05:00
it { expect ( commit . reverts_commit? ( another_commit , user ) ) . to be_truthy }
2016-02-22 09:46:39 -05:00
end
context " another_commit's description reverts merged merge request " do
before do
revert_description = " This reverts merge request !foo123 "
allow ( another_commit ) . to receive ( :revert_description ) . and_return ( revert_description )
allow ( commit ) . to receive ( :description ) . and_return ( " Foo #{ another_commit . revert_description } Bar " )
end
2016-11-29 08:47:43 -05:00
it { expect ( commit . reverts_commit? ( another_commit , user ) ) . to be_truthy }
2016-02-22 09:46:39 -05:00
end
end
2016-04-16 15:46:26 -04:00
2016-05-26 07:38:28 -04:00
describe '#participants' do
let ( :user1 ) { build ( :user ) }
let ( :user2 ) { build ( :user ) }
let! ( :note1 ) do
create ( :note_on_commit ,
commit_id : commit . id ,
project : project ,
note : 'foo' )
end
let! ( :note2 ) do
create ( :note_on_commit ,
commit_id : commit . id ,
project : project ,
note : 'bar' )
end
before do
allow ( commit ) . to receive ( :author ) . and_return ( user1 )
allow ( commit ) . to receive ( :committer ) . and_return ( user2 )
end
it 'includes the commit author' do
expect ( commit . participants ) . to include ( commit . author )
end
it 'includes the committer' do
expect ( commit . participants ) . to include ( commit . committer )
end
it 'includes the authors of the commit notes' do
expect ( commit . participants ) . to include ( note1 . author , note2 . author )
end
end
2016-06-21 10:53:16 -04:00
2019-03-07 16:53:22 -05:00
shared_examples '#uri_type' do
2018-06-26 08:12:08 -04:00
it 'returns the URI type at the given path' do
expect ( commit . uri_type ( 'files/html' ) ) . to be ( :tree )
expect ( commit . uri_type ( 'files/images/logo-black.png' ) ) . to be ( :raw )
2019-07-31 14:53:33 -04:00
expect ( commit . uri_type ( 'files/images/wm.svg' ) ) . to be ( :raw )
2019-10-09 08:06:13 -04:00
expect ( project . commit ( 'audio' ) . uri_type ( 'files/audio/clip.mp3' ) ) . to be ( :raw )
expect ( project . commit ( 'audio' ) . uri_type ( 'files/audio/sample.wav' ) ) . to be ( :raw )
2018-06-26 08:12:08 -04:00
expect ( project . commit ( 'video' ) . uri_type ( 'files/videos/intro.mp4' ) ) . to be ( :raw )
expect ( commit . uri_type ( 'files/js/application.js' ) ) . to be ( :blob )
2018-01-15 04:39:06 -05:00
end
2018-06-26 08:12:08 -04:00
it " returns nil if the path doesn't exists " do
expect ( commit . uri_type ( 'this/path/doesnt/exist' ) ) . to be_nil
expect ( commit . uri_type ( '../path/doesnt/exist' ) ) . to be_nil
2016-06-21 10:53:16 -04:00
end
2018-06-26 08:12:08 -04:00
it 'is nil if the path is nil or empty' do
expect ( commit . uri_type ( nil ) ) . to be_nil
expect ( commit . uri_type ( " " ) ) . to be_nil
2016-06-21 10:53:16 -04:00
end
end
2016-11-24 09:07:44 -05:00
2019-03-07 16:53:22 -05:00
describe '#uri_type with Gitaly enabled' do
it_behaves_like " # uri_type "
end
describe '#uri_type with Rugged enabled' , :enable_rugged do
it 'calls out to the Rugged implementation' do
allow_any_instance_of ( Rugged :: Tree ) . to receive ( :path ) . with ( 'files/html' ) . and_call_original
commit . uri_type ( 'files/html' )
end
it_behaves_like '#uri_type'
end
2016-11-24 09:07:44 -05:00
describe '.from_hash' do
2020-02-13 10:08:52 -05:00
subject { described_class . from_hash ( commit . to_hash , container ) }
2016-11-24 09:07:44 -05:00
2020-02-13 10:08:52 -05:00
shared_examples 'returns Commit' do
it 'returns a Commit' do
expect ( subject ) . to be_an_instance_of ( described_class )
end
it 'wraps a Gitlab::Git::Commit' do
expect ( subject . raw ) . to be_an_instance_of ( Gitlab :: Git :: Commit )
end
it 'stores the correct commit fields' do
expect ( subject . id ) . to eq ( commit . id )
expect ( subject . message ) . to eq ( commit . message )
end
end
context 'with project' do
let ( :container ) { project }
it_behaves_like 'returns Commit'
2016-11-24 09:07:44 -05:00
end
2020-02-13 10:08:52 -05:00
context 'with personal snippet' do
let ( :container ) { personal_snippet }
it_behaves_like 'returns Commit'
2016-11-24 09:07:44 -05:00
end
2020-02-13 10:08:52 -05:00
context 'with project snippet' do
let ( :container ) { project_snippet }
it_behaves_like 'returns Commit'
2016-11-24 09:07:44 -05:00
end
end
2016-12-15 15:48:26 -05:00
describe '#work_in_progress?' do
2020-07-08 17:09:09 -04:00
[
'squash! ' , 'fixup! ' , 'wip: ' , 'WIP: ' , '[WIP] ' ,
'draft: ' , 'Draft - ' , '[Draft] ' , '(draft) ' , 'Draft: '
] . each do | wip_prefix |
2016-12-15 15:48:26 -05:00
it " detects the ' #{ wip_prefix } ' prefix " do
commit . message = " #{ wip_prefix } #{ commit . message } "
expect ( commit ) . to be_work_in_progress
end
end
it " detects WIP for a commit just saying 'wip' " do
commit . message = " wip "
expect ( commit ) . to be_work_in_progress
end
2020-07-08 17:09:09 -04:00
it " detects WIP for a commit just saying 'draft' " do
commit . message = " draft "
expect ( commit ) . to be_work_in_progress
end
2016-12-15 15:48:26 -05:00
it " doesn't detect WIP for a commit that begins with 'FIXUP! ' " do
commit . message = " FIXUP! #{ commit . message } "
expect ( commit ) . not_to be_work_in_progress
end
it " doesn't detect WIP for words starting with WIP " do
commit . message = " Wipout #{ commit . message } "
expect ( commit ) . not_to be_work_in_progress
end
end
2016-12-08 09:54:45 -05:00
describe '.valid_hash?' do
it 'checks hash contents' do
expect ( described_class . valid_hash? ( 'abcdef01239ABCDEF' ) ) . to be true
expect ( described_class . valid_hash? ( " abcdef01239ABCD \n EF " ) ) . to be false
expect ( described_class . valid_hash? ( ' abcdef01239ABCDEF ' ) ) . to be false
expect ( described_class . valid_hash? ( 'Gabcdef01239ABCDEF' ) ) . to be false
expect ( described_class . valid_hash? ( 'gabcdef01239ABCDEF' ) ) . to be false
expect ( described_class . valid_hash? ( '-abcdef01239ABCDEF' ) ) . to be false
end
it 'checks hash length' do
expect ( described_class . valid_hash? ( 'a' * 6 ) ) . to be false
expect ( described_class . valid_hash? ( 'a' * 7 ) ) . to be true
expect ( described_class . valid_hash? ( 'a' * 40 ) ) . to be true
expect ( described_class . valid_hash? ( 'a' * 41 ) ) . to be false
end
end
2018-01-12 15:38:36 -05:00
2020-02-06 19:09:12 -05:00
describe 'signed commits' do
let ( :gpg_signed_commit ) { project . commit_by ( oid : '0b4bc9a49b562e85de7cc9e834518ea6828729b9' ) }
let ( :x509_signed_commit ) { project . commit_by ( oid : '189a6c924013fc3fe40d6f1ec1dc20214183bc97' ) }
let ( :unsigned_commit ) { project . commit_by ( oid : '54fcc214b94e78d7a41a9a8fe6d87a5e59500e51' ) }
let! ( :commit ) { create ( :commit , project : project ) }
it 'returns signature_type properly' do
expect ( gpg_signed_commit . signature_type ) . to eq ( :PGP )
expect ( x509_signed_commit . signature_type ) . to eq ( :X509 )
expect ( unsigned_commit . signature_type ) . to eq ( :NONE )
expect ( commit . signature_type ) . to eq ( :NONE )
end
it 'returns has_signature? properly' do
expect ( gpg_signed_commit . has_signature? ) . to be_truthy
expect ( x509_signed_commit . has_signature? ) . to be_truthy
expect ( unsigned_commit . has_signature? ) . to be_falsey
expect ( commit . has_signature? ) . to be_falsey
end
end
2020-03-10 20:09:09 -04:00
describe '#has_been_reverted?' do
let ( :user ) { create ( :user ) }
let ( :issue ) { create ( :issue , author : user , project : project ) }
it 'returns true if the commit has been reverted' do
create ( :note_on_issue ,
noteable : issue ,
system : true ,
note : commit . revert_description ( user ) ,
project : issue . project )
expect_next_instance_of ( Commit ) do | revert_commit |
expect ( revert_commit ) . to receive ( :reverts_commit? )
. with ( commit , user )
. and_return ( true )
end
expect ( commit . has_been_reverted? ( user , issue . notes_with_associations ) ) . to eq ( true )
end
it 'returns false if the commit has not been reverted' do
expect ( commit . has_been_reverted? ( user , issue . notes_with_associations ) ) . to eq ( false )
end
end
2012-10-02 18:57:13 -04:00
end