summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/models/fork_network.rb4
-rw-r--r--app/models/namespace.rb4
-rw-r--r--app/models/project.rb5
-rw-r--r--app/models/user.rb10
-rw-r--r--spec/factories/fork_networks.rb5
-rw-r--r--spec/models/fork_network_spec.rb12
-rw-r--r--spec/models/namespace_spec.rb23
-rw-r--r--spec/models/user_spec.rb17
8 files changed, 70 insertions, 10 deletions
diff --git a/app/models/fork_network.rb b/app/models/fork_network.rb
index fd2510d0a4c..218e37a5312 100644
--- a/app/models/fork_network.rb
+++ b/app/models/fork_network.rb
@@ -8,4 +8,8 @@ class ForkNetwork < ActiveRecord::Base
def add_root_as_member
projects << root_project
end
+
+ def find_forks_in(other_projects)
+ projects.where(id: other_projects)
+ end
end
diff --git a/app/models/namespace.rb b/app/models/namespace.rb
index e279d8dd8c5..4672881e220 100644
--- a/app/models/namespace.rb
+++ b/app/models/namespace.rb
@@ -139,7 +139,9 @@ class Namespace < ActiveRecord::Base
end
def find_fork_of(project)
- projects.joins(:forked_project_link).find_by('forked_project_links.forked_from_project_id = ?', project.id)
+ return nil unless project.fork_network
+
+ project.fork_network.find_forks_in(projects).first
end
def lfs_enabled?
diff --git a/app/models/project.rb b/app/models/project.rb
index 4a883552a8d..ad1c339ae78 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -1009,6 +1009,11 @@ class Project < ActiveRecord::Base
end
def forked?
+ return true if fork_network && fork_network.root_project != self
+
+ # TODO: Use only the above conditional using the `fork_network`
+ # This is the old conditional that looks at the `forked_project_link`, we
+ # fall back to this while we're migrating the new models
!(forked_project_link.nil? || forked_project_link.forked_from_project.nil?)
end
diff --git a/app/models/user.rb b/app/models/user.rb
index 959738ba608..c3f115ca074 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -697,15 +697,7 @@ class User < ActiveRecord::Base
end
def fork_of(project)
- links = ForkedProjectLink.where(
- forked_from_project_id: project,
- forked_to_project_id: personal_projects.unscope(:order)
- )
- if links.any?
- links.first.forked_to_project
- else
- nil
- end
+ namespace.find_fork_of(project)
end
def ldap_user?
diff --git a/spec/factories/fork_networks.rb b/spec/factories/fork_networks.rb
new file mode 100644
index 00000000000..f42d36f3d19
--- /dev/null
+++ b/spec/factories/fork_networks.rb
@@ -0,0 +1,5 @@
+FactoryGirl.define do
+ factory :fork_network do
+ association :root_project, factory: :project
+ end
+end
diff --git a/spec/models/fork_network_spec.rb b/spec/models/fork_network_spec.rb
index 4781a959846..605ccd6db06 100644
--- a/spec/models/fork_network_spec.rb
+++ b/spec/models/fork_network_spec.rb
@@ -12,6 +12,18 @@ describe ForkNetwork do
end
end
+ describe '#find_fork_in' do
+ it 'finds all fork of the current network in al collection' do
+ network = create(:fork_network)
+ root_project = network.root_project
+ another_project = fork_project(root_project)
+ create(:project)
+
+ expect(network.find_forks_in(Project.all))
+ .to contain_exactly(another_project, root_project)
+ end
+ end
+
context 'for a deleted project' do
it 'keeps the fork network' do
project = create(:project, :public)
diff --git a/spec/models/namespace_spec.rb b/spec/models/namespace_spec.rb
index 3ea614776ca..2ebf6acd42a 100644
--- a/spec/models/namespace_spec.rb
+++ b/spec/models/namespace_spec.rb
@@ -1,6 +1,8 @@
require 'spec_helper'
describe Namespace do
+ include ProjectForksHelper
+
let!(:namespace) { create(:namespace) }
describe 'associations' do
@@ -520,4 +522,25 @@ describe Namespace do
end
end
end
+
+ describe '#has_forks_of?' do
+ let(:project) { create(:project, :public) }
+ let!(:forked_project) { fork_project(project, namespace.owner, namespace: namespace) }
+
+ before do
+ # Reset the fork network relation
+ project.reload
+ end
+
+ it 'knows if there is a direct fork in the namespace' do
+ expect(namespace.find_fork_of(project)).to eq(forked_project)
+ end
+
+ it 'knows when there is as fork-of-fork in the namespace' do
+ other_namespace = create(:namespace)
+ other_fork = fork_project(forked_project, other_namespace.owner, namespace: other_namespace)
+
+ expect(other_namespace.find_fork_of(project)).to eq(other_fork)
+ end
+ end
end
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 52ca068f9a4..ece6968dde6 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -1456,6 +1456,23 @@ describe User do
end
end
+ describe '#fork_of' do
+ let(:user) { create(:user) }
+
+ it "returns a user's fork of a project" do
+ project = create(:project, :public)
+ user_fork = fork_project(project, user, namespace: user.namespace)
+
+ expect(user.fork_of(project)).to eq(user_fork)
+ end
+
+ it 'returns nil if the project does not have a fork network' do
+ project = create(:project)
+
+ expect(user.fork_of(project)).to be_nil
+ end
+ end
+
describe '#can_be_removed?' do
subject { create(:user) }