debian-mirror-gitlab/spec/lib/gitlab/tree_summary_spec.rb

292 lines
8.2 KiB
Ruby
Raw Normal View History

2019-12-04 20:38:33 +05:30
# frozen_string_literal: true
2018-11-20 20:47:30 +05:30
require 'spec_helper'
2020-07-28 23:09:34 +05:30
RSpec.describe Gitlab::TreeSummary do
2021-02-11 23:33:58 +05:30
include RepoHelpers
2018-11-20 20:47:30 +05:30
using RSpec::Parameterized::TableSyntax
let(:project) { create(:project, :empty_repo) }
let(:repo) { project.repository }
let(:commit) { repo.head_commit }
2020-05-24 23:13:21 +05:30
let_it_be(:user) { create(:user) }
2018-11-20 20:47:30 +05:30
let(:path) { nil }
let(:offset) { nil }
let(:limit) { nil }
2020-05-24 23:13:21 +05:30
subject(:summary) { described_class.new(commit, project, user, path: path, offset: offset, limit: limit) }
2018-11-20 20:47:30 +05:30
describe '#initialize' do
it 'defaults offset to 0' do
expect(summary.offset).to eq(0)
end
it 'defaults limit to 25' do
expect(summary.limit).to eq(25)
end
2022-10-11 01:57:18 +05:30
context 'when offset is larger than the maximum' do
let(:offset) { described_class::MAX_OFFSET + 1 }
it 'sets offset to the maximum' do
expect(subject.offset).to eq(described_class::MAX_OFFSET)
end
end
2018-11-20 20:47:30 +05:30
end
describe '#summarize' do
let(:project) { create(:project, :custom_repo, files: { 'a.txt' => '' }) }
2022-08-13 15:12:31 +05:30
subject(:entries) { summary.summarize }
2018-11-20 20:47:30 +05:30
2022-08-13 15:12:31 +05:30
it 'returns an array of entries' do
expect(entries).to be_a(Array)
expect(entries.size).to eq(1)
2018-11-20 20:47:30 +05:30
aggregate_failures do
expect(entries).to contain_exactly(
a_hash_including(file_name: 'a.txt', commit: have_attributes(id: commit.id))
)
2022-08-13 15:12:31 +05:30
expect(summary.resolved_commits.values).to match_array(entries.map { |entry| entry[:commit] })
2021-02-11 23:33:58 +05:30
end
end
2022-10-11 01:57:18 +05:30
context 'when offset is negative' do
let(:offset) { -1 }
it 'returns an empty array' do
expect(entries).to eq([])
end
end
2021-02-11 23:33:58 +05:30
context 'with caching', :use_clean_rails_memory_store_caching do
subject { Rails.cache.fetch(key) }
context 'Commits list cache' do
let(:offset) { 0 }
let(:limit) { 25 }
2022-08-13 15:12:31 +05:30
let(:key) { ['projects', project.id, 'last_commits', commit.id, path, offset, limit + 1] }
2021-02-11 23:33:58 +05:30
it 'creates a cache for commits list' do
2022-08-13 15:12:31 +05:30
entries
2021-04-17 20:07:23 +05:30
2021-02-11 23:33:58 +05:30
is_expected.to eq('a.txt' => commit.to_hash)
end
2021-04-17 20:07:23 +05:30
context 'when commit has a very long message' do
before do
repo.create_file(
project.creator,
'long.txt',
'',
message: message,
2021-06-08 01:23:25 +05:30
branch_name: project.default_branch
2021-04-17 20:07:23 +05:30
)
end
let(:message) { 'a' * 1025 }
let(:expected_message) { message[0...1021] + '...' }
it 'truncates commit message to 1 kilobyte' do
2022-08-13 15:12:31 +05:30
entries
2021-04-17 20:07:23 +05:30
is_expected.to include('long.txt' => a_hash_including(message: expected_message))
end
end
2021-02-11 23:33:58 +05:30
end
end
2018-11-20 20:47:30 +05:30
end
2022-08-13 15:12:31 +05:30
describe '#fetch_logs' do
2020-07-28 23:09:34 +05:30
let(:limit) { 4 }
2018-11-20 20:47:30 +05:30
custom_files = {
'a.txt' => '',
'b.txt' => '',
2020-07-28 23:09:34 +05:30
'directory/c.txt' => '',
':dir/test.txt' => '',
':file' => ''
2018-11-20 20:47:30 +05:30
}
2020-07-28 23:09:34 +05:30
let!(:project) { create(:project, :custom_repo, files: custom_files) }
2018-11-20 20:47:30 +05:30
let(:commit) { repo.head_commit }
2022-08-13 15:12:31 +05:30
subject(:entries) { summary.fetch_logs.first }
2018-11-20 20:47:30 +05:30
it 'summarizes the entries within the window' do
is_expected.to contain_exactly(
2022-08-13 15:12:31 +05:30
a_hash_including('file_name' => 'directory'),
a_hash_including('file_name' => 'a.txt'),
a_hash_including('file_name' => ':file'),
a_hash_including('file_name' => ':dir')
2018-11-20 20:47:30 +05:30
# b.txt is excluded by the limit
)
end
it 'references the commit and commit path in entries' do
2020-07-28 23:09:34 +05:30
# There are 2 trees and the summary is not ordered
2022-08-13 15:12:31 +05:30
entry = entries.find { |entry| entry['commit']['id'] == commit.id }
2018-11-20 20:47:30 +05:30
expected_commit_path = Gitlab::Routing.url_helpers.project_commit_path(project, commit)
2022-08-13 15:12:31 +05:30
expect(entry['commit_path']).to eq(expected_commit_path)
expect(entry['commit_title_html']).to eq(commit.message)
2018-11-20 20:47:30 +05:30
end
context 'in a good subdirectory' do
let(:path) { 'directory' }
it 'summarizes the entries in the subdirectory' do
2022-08-13 15:12:31 +05:30
is_expected.to contain_exactly(a_hash_including('file_name' => 'c.txt'))
2018-11-20 20:47:30 +05:30
end
end
2020-07-28 23:09:34 +05:30
context 'in a subdirectory with a pathspec character' do
let(:path) { ':dir' }
it 'summarizes the entries in the subdirectory' do
2022-08-13 15:12:31 +05:30
is_expected.to contain_exactly(a_hash_including('file_name' => 'test.txt'))
2020-07-28 23:09:34 +05:30
end
end
2018-11-20 20:47:30 +05:30
context 'in a non-existent subdirectory' do
let(:path) { 'tmp' }
it { is_expected.to be_empty }
end
context 'custom offset and limit' do
2020-07-28 23:09:34 +05:30
let(:offset) { 4 }
2018-11-20 20:47:30 +05:30
it 'returns entries from the offset' do
2022-08-13 15:12:31 +05:30
is_expected.to contain_exactly(a_hash_including('file_name' => 'b.txt'))
end
end
context 'next offset' do
subject { summary.fetch_logs.last }
context 'when there are more entries to fetch' do
it 'returns next offset' do
is_expected.to eq(4)
end
end
context 'when there are no more entries to fetch' do
let(:limit) { 5 }
it 'returns next offset' do
is_expected.to be_nil
end
2018-11-20 20:47:30 +05:30
end
end
end
describe '#summarize (commits)' do
# This is a commit in the master branch of the gitlab-test repository that
# satisfies certain assumptions these tests depend on
let(:test_commit_sha) { '7975be0116940bf2ad4321f79d02a55c5f7779aa' }
let(:whitespace_commit_sha) { '66eceea0db202bb39c4e445e8ca28689645366c5' }
let(:project) { create(:project, :repository) }
let(:commit) { repo.commit(test_commit_sha) }
let(:limit) { nil }
2022-08-13 15:12:31 +05:30
let(:entries) { summary.summarize }
2018-11-20 20:47:30 +05:30
subject(:commits) do
2022-08-13 15:12:31 +05:30
summary.summarize
summary.resolved_commits.values
2018-11-20 20:47:30 +05:30
end
it 'returns an Array of ::Commit objects' do
is_expected.not_to be_empty
is_expected.to all(be_kind_of(::Commit))
end
it 'deduplicates commits when multiple entries reference the same commit' do
expect(commits.size).to be < entries.size
end
context 'in a subdirectory' do
let(:path) { 'files' }
it 'returns commits for entries in the subdirectory' do
expect(commits).to satisfy_one { |c| c.id == whitespace_commit_sha }
end
end
2020-03-13 15:44:24 +05:30
context 'in a subdirectory with non-ASCII filenames' do
let(:path) { 'encoding' }
it 'returns commits for entries in the subdirectory' do
entry = entries.find { |x| x[:file_name] == 'テスト.txt' }
expect(entry).to be_a(Hash)
expect(entry).to include(:commit)
end
end
2020-05-24 23:13:21 +05:30
context 'rendering commits' do
it 'does not perform N + 1 request' do
summary
queries = ActiveRecord::QueryRecorder.new { summary.summarize }
expect(queries.count).to be <= 3
end
end
2018-11-20 20:47:30 +05:30
end
2021-02-11 23:33:58 +05:30
describe 'References in commit messages' do
let_it_be(:project) { create(:project, :empty_repo) }
let_it_be(:issue) { create(:issue, project: project) }
2021-04-29 21:17:54 +05:30
2022-08-13 15:12:31 +05:30
let(:entries) { summary.summarize }
2021-02-11 23:33:58 +05:30
let(:entry) { entries.find { |entry| entry[:file_name] == 'issue.txt' } }
before_all do
create_file_in_repo(project, 'master', 'master', 'issue.txt', '', commit_message: "Issue ##{issue.iid}")
end
where(:project_visibility, :user_role, :issue_confidential, :expected_result) do
'private' | :guest | false | true
'private' | :guest | true | false
'private' | :reporter | false | true
'private' | :reporter | true | true
'internal' | :guest | false | true
'internal' | :guest | true | false
'internal' | :reporter | false | true
'internal' | :reporter | true | true
'public' | :guest | false | true
'public' | :guest | true | false
'public' | :reporter | false | true
'public' | :reporter | true | true
end
with_them do
subject { entry[:commit_title_html].include?("title=\"#{issue.title}\"") }
before do
project.add_role(user, user_role)
project.update!(visibility_level: Gitlab::VisibilityLevel.level_value(project_visibility))
issue.update!(confidential: issue_confidential)
end
it { is_expected.to eq(expected_result) }
end
end
2018-11-20 20:47:30 +05:30
def create_file(unique, path:)
repo.create_file(
project.creator,
"#{path}/file-#{unique}.txt",
'content',
message: "Commit message #{unique}",
branch_name: 'master'
)
end
end