Skip to content
Snippets Groups Projects
Commit 33cf8eda authored by Bob Van Landuyt's avatar Bob Van Landuyt
Browse files

Port changes for design management to CE

parent ee4ccd31
No related branches found
No related tags found
No related merge requests found
Loading
Loading
@@ -79,6 +79,7 @@ gem 'rack-cors', '~> 1.0.0', require: 'rack/cors'
# GraphQL API
gem 'graphql', '~> 1.8.0'
gem 'graphiql-rails', '~> 1.4.10'
gem 'apollo_upload_server', '~> 2.0.0.beta3'
 
# Disable strong_params so that Mash does not respond to :permitted?
gem 'hashie-forbidden_attributes'
Loading
Loading
Loading
Loading
@@ -52,6 +52,9 @@ GEM
public_suffix (>= 2.0.2, < 4.0)
aes_key_wrap (1.0.1)
akismet (2.0.0)
apollo_upload_server (2.0.0.beta.3)
graphql (>= 1.8)
rails (>= 4.2)
arel (8.0.0)
asana (0.8.1)
faraday (~> 0.9)
Loading
Loading
@@ -988,6 +991,7 @@ DEPENDENCIES
acts-as-taggable-on (~> 6.0)
addressable (~> 2.5.2)
akismet (~> 2.0)
apollo_upload_server (~> 2.0.0.beta3)
asana (~> 0.8.1)
asciidoctor (~> 1.5.8)
asciidoctor-plantuml (= 0.0.8)
Loading
Loading
Loading
Loading
@@ -44,6 +44,12 @@ module Resolvers
alias_method :project, :object
 
def resolve(**args)
# The project could have been loaded in batch by `BatchLoader`.
# At this point we need the `id` of the project to query for issues, so
# make sure it's loaded and not `nil` before continueing.
project.sync if project.respond_to?(:sync)
return Issue.none if project.nil?
# Will need to be be made group & namespace aware with
# https://gitlab.com/gitlab-org/gitlab-ce/issues/54520
args[:project_id] = project.id
Loading
Loading
Loading
Loading
@@ -1065,6 +1065,19 @@ class Repository
blob.data
end
 
def create_if_not_exists
return if exists?
raw.create_repository
after_create
end
def blobs_metadata(paths, ref = 'HEAD')
references = Array.wrap(paths).map { |path| [ref, path] }
Gitlab::Git::Blob.batch_metadata(raw, references).map { |raw_blob| Blob.decorate(raw_blob) }
end
private
 
# TODO Generice finder, later split this on finders by Ref or Oid
Loading
Loading
Loading
Loading
@@ -21,8 +21,10 @@ class PostReceive
 
if repo_type.wiki?
process_wiki_changes(post_received)
else
elsif repo_type.project?
process_project_changes(post_received)
else
# Other repos don't have hooks for now
end
end
 
Loading
Loading
Loading
Loading
@@ -118,6 +118,12 @@ module Gitlab
gitaly_repository_client.exists?
end
 
def create_repository
wrapped_gitaly_errors do
gitaly_repository_client.create_repository
end
end
# Returns an Array of branch names
# sorted by name ASC
def branch_names
Loading
Loading
Loading
Loading
@@ -85,7 +85,7 @@ module Gitlab
check_push_access!
end
 
::Gitlab::GitAccessResult::Success.new(console_messages: check_for_console_messages(cmd))
success_result(cmd)
end
 
def guest_can_download_code?
Loading
Loading
@@ -365,6 +365,10 @@ module Gitlab
 
protected
 
def success_result(cmd)
::Gitlab::GitAccessResult::Success.new(console_messages: check_for_console_messages(cmd))
end
def changes_list
@changes_list ||= Gitlab::ChangesList.new(changes == ANY ? [] : changes)
end
Loading
Loading
Loading
Loading
@@ -4,104 +4,119 @@ describe Resolvers::IssuesResolver do
include GraphqlHelpers
 
let(:current_user) { create(:user) }
set(:project) { create(:project) }
set(:issue1) { create(:issue, project: project, state: :opened, created_at: 3.hours.ago, updated_at: 3.hours.ago) }
set(:issue2) { create(:issue, project: project, state: :closed, title: 'foo', created_at: 1.hour.ago, updated_at: 1.hour.ago, closed_at: 1.hour.ago) }
set(:label1) { create(:label, project: project) }
set(:label2) { create(:label, project: project) }
before do
project.add_developer(current_user)
create(:label_link, label: label1, target: issue1)
create(:label_link, label: label1, target: issue2)
create(:label_link, label: label2, target: issue2)
end
describe '#resolve' do
it 'finds all issues' do
expect(resolve_issues).to contain_exactly(issue1, issue2)
end
 
it 'filters by state' do
expect(resolve_issues(state: 'opened')).to contain_exactly(issue1)
expect(resolve_issues(state: 'closed')).to contain_exactly(issue2)
context "with a project" do
set(:project) { create(:project) }
set(:issue1) { create(:issue, project: project, state: :opened, created_at: 3.hours.ago, updated_at: 3.hours.ago) }
set(:issue2) { create(:issue, project: project, state: :closed, title: 'foo', created_at: 1.hour.ago, updated_at: 1.hour.ago, closed_at: 1.hour.ago) }
set(:label1) { create(:label, project: project) }
set(:label2) { create(:label, project: project) }
before do
project.add_developer(current_user)
create(:label_link, label: label1, target: issue1)
create(:label_link, label: label1, target: issue2)
create(:label_link, label: label2, target: issue2)
end
 
it 'filters by labels' do
expect(resolve_issues(label_name: [label1.title])).to contain_exactly(issue1, issue2)
expect(resolve_issues(label_name: [label1.title, label2.title])).to contain_exactly(issue2)
end
describe '#resolve' do
it 'finds all issues' do
expect(resolve_issues).to contain_exactly(issue1, issue2)
end
 
describe 'filters by created_at' do
it 'filters by created_before' do
expect(resolve_issues(created_before: 2.hours.ago)).to contain_exactly(issue1)
it 'filters by state' do
expect(resolve_issues(state: 'opened')).to contain_exactly(issue1)
expect(resolve_issues(state: 'closed')).to contain_exactly(issue2)
end
 
it 'filters by created_after' do
expect(resolve_issues(created_after: 2.hours.ago)).to contain_exactly(issue2)
it 'filters by labels' do
expect(resolve_issues(label_name: [label1.title])).to contain_exactly(issue1, issue2)
expect(resolve_issues(label_name: [label1.title, label2.title])).to contain_exactly(issue2)
end
end
 
describe 'filters by updated_at' do
it 'filters by updated_before' do
expect(resolve_issues(updated_before: 2.hours.ago)).to contain_exactly(issue1)
describe 'filters by created_at' do
it 'filters by created_before' do
expect(resolve_issues(created_before: 2.hours.ago)).to contain_exactly(issue1)
end
it 'filters by created_after' do
expect(resolve_issues(created_after: 2.hours.ago)).to contain_exactly(issue2)
end
end
 
it 'filters by updated_after' do
expect(resolve_issues(updated_after: 2.hours.ago)).to contain_exactly(issue2)
describe 'filters by updated_at' do
it 'filters by updated_before' do
expect(resolve_issues(updated_before: 2.hours.ago)).to contain_exactly(issue1)
end
it 'filters by updated_after' do
expect(resolve_issues(updated_after: 2.hours.ago)).to contain_exactly(issue2)
end
end
end
 
describe 'filters by closed_at' do
let!(:issue3) { create(:issue, project: project, state: :closed, closed_at: 3.hours.ago) }
describe 'filters by closed_at' do
let!(:issue3) { create(:issue, project: project, state: :closed, closed_at: 3.hours.ago) }
 
it 'filters by closed_before' do
expect(resolve_issues(closed_before: 2.hours.ago)).to contain_exactly(issue3)
it 'filters by closed_before' do
expect(resolve_issues(closed_before: 2.hours.ago)).to contain_exactly(issue3)
end
it 'filters by closed_after' do
expect(resolve_issues(closed_after: 2.hours.ago)).to contain_exactly(issue2)
end
end
 
it 'filters by closed_after' do
expect(resolve_issues(closed_after: 2.hours.ago)).to contain_exactly(issue2)
it 'searches issues' do
expect(resolve_issues(search: 'foo')).to contain_exactly(issue2)
end
end
 
it 'searches issues' do
expect(resolve_issues(search: 'foo')).to contain_exactly(issue2)
end
it 'sort issues' do
expect(resolve_issues(sort: 'created_desc')).to eq [issue2, issue1]
end
 
it 'sort issues' do
expect(resolve_issues(sort: 'created_desc')).to eq [issue2, issue1]
end
it 'returns issues user can see' do
project.add_guest(current_user)
 
it 'returns issues user can see' do
project.add_guest(current_user)
create(:issue, confidential: true)
 
create(:issue, confidential: true)
expect(resolve_issues).to contain_exactly(issue1, issue2)
end
 
expect(resolve_issues).to contain_exactly(issue1, issue2)
end
it 'finds a specific issue with iid' do
expect(resolve_issues(iid: issue1.iid)).to contain_exactly(issue1)
end
 
it 'finds a specific issue with iid' do
expect(resolve_issues(iid: issue1.iid)).to contain_exactly(issue1)
end
it 'finds a specific issue with iids' do
expect(resolve_issues(iids: issue1.iid)).to contain_exactly(issue1)
end
 
it 'finds a specific issue with iids' do
expect(resolve_issues(iids: issue1.iid)).to contain_exactly(issue1)
end
it 'finds multiple issues with iids' do
expect(resolve_issues(iids: [issue1.iid, issue2.iid]))
.to contain_exactly(issue1, issue2)
end
 
it 'finds multiple issues with iids' do
expect(resolve_issues(iids: [issue1.iid, issue2.iid]))
.to contain_exactly(issue1, issue2)
end
it 'finds only the issues within the project we are looking at' do
another_project = create(:project)
iids = [issue1, issue2].map(&:iid)
iids.each do |iid|
create(:issue, project: another_project, iid: iid)
end
 
it 'finds only the issues within the project we are looking at' do
another_project = create(:project)
iids = [issue1, issue2].map(&:iid)
expect(resolve_issues(iids: iids)).to contain_exactly(issue1, issue2)
end
end
end
 
iids.each do |iid|
create(:issue, project: another_project, iid: iid)
context "when passing a non existent, batch loaded project" do
let(:project) do
BatchLoader.for("non-existent-path").batch do |_fake_paths, loader, _|
loader.call("non-existent-path", nil)
end
end
 
expect(resolve_issues(iids: iids)).to contain_exactly(issue1, issue2)
it "returns nil without breaking" do
expect(resolve_issues(iids: ["don't", "break"])).to be_empty
end
end
 
Loading
Loading
Loading
Loading
@@ -95,6 +95,12 @@ describe Gitlab::Git::Repository, :seed_helper do
end
end
 
describe '#create_repository' do
it_behaves_like 'wrapping gRPC errors', Gitlab::GitalyClient::RepositoryService, :create_repository do
subject { repository.create_repository }
end
end
describe '#branch_names' do
subject { repository.branch_names }
 
Loading
Loading
Loading
Loading
@@ -2487,4 +2487,69 @@ describe Repository do
repository.merge_base('master', 'fix')
end
end
describe '#create_if_not_exists' do
let(:project) { create(:project) }
let(:repository) { project.repository }
it 'creates the repository if it did not exist' do
expect { repository.create_if_not_exists }.to change { repository.exists? }.from(false).to(true)
end
it 'calls out to the repository client to create a repo' do
expect(repository.raw.gitaly_repository_client).to receive(:create_repository)
repository.create_if_not_exists
end
context 'it does nothing if the repository already existed' do
let(:project) { create(:project, :repository) }
it 'does nothing if the repository already existed' do
expect(repository.raw.gitaly_repository_client).not_to receive(:create_repository)
repository.create_if_not_exists
end
end
context 'when the repository exists but the cache is not up to date' do
let(:project) { create(:project, :repository) }
it 'does not raise errors' do
allow(repository).to receive(:exists?).and_return(false)
expect(repository.raw).to receive(:create_repository).and_call_original
expect { repository.create_if_not_exists }.not_to raise_error
end
end
end
describe "#blobs_metadata" do
set(:project) { create(:project, :repository) }
let(:repository) { project.repository }
def expect_metadata_blob(thing)
expect(thing).to be_a(Blob)
expect(thing.data).to be_empty
end
it "returns blob metadata in batch for HEAD" do
result = repository.blobs_metadata(["bar/branch-test.txt", "README.md", "does/not/exist"])
expect_metadata_blob(result.first)
expect_metadata_blob(result.second)
expect(result.size).to eq(2)
end
it "returns blob metadata for a specified ref" do
result = repository.blobs_metadata(["files/ruby/feature.rb"], "feature")
expect_metadata_blob(result.first)
end
it "performs a single gitaly call", :request_store do
expect { repository.blobs_metadata(["bar/branch-test.txt", "readme.txt", "does/not/exist"]) }
.to change { Gitlab::GitalyClient.get_request_count }.by(1)
end
end
end
Loading
Loading
@@ -61,7 +61,14 @@ module GraphqlHelpers
 
def variables_for_mutation(name, input)
graphql_input = input.map { |name, value| [GraphqlHelpers.fieldnamerize(name), value] }.to_h
{ input_variable_name_for_mutation(name) => graphql_input }.to_json
result = { input_variable_name_for_mutation(name) => graphql_input }
# Avoid trying to serialize multipart data into JSON
if graphql_input.values.none? { |value| io_value?(value) }
result.to_json
else
result
end
end
 
def input_variable_name_for_mutation(mutation_name)
Loading
Loading
@@ -162,6 +169,10 @@ module GraphqlHelpers
field.arguments.values.any? { |argument| argument.type.non_null? }
end
 
def io_value?(value)
Array.wrap(value).any? { |v| v.respond_to?(:to_io) }
end
def field_type(field)
field_type = field.type
 
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment