summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorDouwe Maan <douwe@gitlab.com>2016-12-09 01:52:36 +0000
committerDouwe Maan <douwe@gitlab.com>2016-12-09 01:52:36 +0000
commit05efd19e8956c5a507bbf22ca74786c1cc0ccc0a (patch)
tree1d020e1ad77f6802c6d16ea6bcee089e0ca3cf3c /spec
parentf23b1cb453deea2659c0cb9e9047c72d859bbf9d (diff)
parent83232be0e14cc8b35bf74532203a6e4371c15e70 (diff)
downloadgitlab-ce-05efd19e8956c5a507bbf22ca74786c1cc0ccc0a.tar.gz
Merge branch 'dz-nested-groups' into 'master'
Add nested groups support on data level ## What does this MR do? - [x] Add `parent_id` field to `Namespace`model. - [x] Create new database table `routes` that keeps information about full path to each group or project - [x] Remove uniq index from `namespaces.path` - [x] Add uniq index on `routes.path` - [x] Fill routes table with path data from namespaces and projects - [x] Change Namespace/Project URL lookup by routes table - [x] Rename related routes (nested groups, projects) when parent path changes This is solely backend preparation. UI, Permissions and API support will be added in separate merge request. ## Are there points in the code the reviewer needs to double check? migrations, Route model, Routable concern Will require downtime. See https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/7121#note_19490281 discussion ## Why was this MR needed? One step further to full nested groups support ## Screenshots (if relevant) No UI changes in this merge request so far ## Does this MR meet the acceptance criteria? - [x] [CHANGELOG](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CHANGELOG.md) entry added~~ - ~~[Documentation created/updated](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/development/doc_styleguide.md)~~ - ~~API support added~~ - Tests - [x] Added for this feature/bug - [x] All builds are passing - [x] Conform by the [merge request performance guides](http://docs.gitlab.com/ce/development/merge_request_performance_guidelines.html) - [x] Conform by the [style guides](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#style-guides) - [x] Branch has no merge conflicts with `master` (if it does - rebase it please) - [x] [Squashed related commits together](https://git-scm.com/book/en/Git-Tools-Rewriting-History#Squashing-Commits) ## What are the relevant issue numbers? https://gitlab.com/gitlab-org/gitlab-ce/issues/2772 See merge request !7121
Diffstat (limited to 'spec')
-rw-r--r--spec/lib/constraints/group_url_constrainer_spec.rb7
-rw-r--r--spec/lib/gitlab/import_export/all_models.yml1
-rw-r--r--spec/models/concerns/routable_spec.rb67
-rw-r--r--spec/models/namespace_spec.rb8
-rw-r--r--spec/models/project_spec.rb62
-rw-r--r--spec/models/route_spec.rb29
6 files changed, 112 insertions, 62 deletions
diff --git a/spec/lib/constraints/group_url_constrainer_spec.rb b/spec/lib/constraints/group_url_constrainer_spec.rb
index 892554f2870..96dacdc5cd2 100644
--- a/spec/lib/constraints/group_url_constrainer_spec.rb
+++ b/spec/lib/constraints/group_url_constrainer_spec.rb
@@ -10,6 +10,13 @@ describe GroupUrlConstrainer, lib: true do
it { expect(subject.matches?(request)).to be_truthy }
end
+ context 'valid request for nested group' do
+ let!(:nested_group) { create(:group, path: 'nested', parent: group) }
+ let!(:request) { build_request('gitlab/nested') }
+
+ it { expect(subject.matches?(request)).to be_truthy }
+ end
+
context 'invalid request' do
let(:request) { build_request('foo') }
diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml
index 7e00e214c6e..8e1a28f2723 100644
--- a/spec/lib/gitlab/import_export/all_models.yml
+++ b/spec/lib/gitlab/import_export/all_models.yml
@@ -188,6 +188,7 @@ project:
- project_feature
- authorized_users
- project_authorizations
+- route
award_emoji:
- awardable
- user
diff --git a/spec/models/concerns/routable_spec.rb b/spec/models/concerns/routable_spec.rb
new file mode 100644
index 00000000000..0acefc0c1d5
--- /dev/null
+++ b/spec/models/concerns/routable_spec.rb
@@ -0,0 +1,67 @@
+require 'spec_helper'
+
+describe Group, 'Routable' do
+ let!(:group) { create(:group) }
+
+ describe 'Associations' do
+ it { is_expected.to have_one(:route).dependent(:destroy) }
+ end
+
+ describe 'Callbacks' do
+ it 'creates route record on create' do
+ expect(group.route.path).to eq(group.path)
+ end
+
+ it 'updates route record on path change' do
+ group.update_attributes(path: 'wow')
+
+ expect(group.route.path).to eq('wow')
+ end
+
+ it 'ensure route path uniqueness across different objects' do
+ create(:group, parent: group, path: 'xyz')
+ duplicate = build(:project, namespace: group, path: 'xyz')
+
+ expect { duplicate.save! }.to raise_error(ActiveRecord::RecordInvalid, 'Validation failed: Route path has already been taken, Route is invalid')
+ end
+ end
+
+ describe '.find_by_full_path' do
+ let!(:nested_group) { create(:group, parent: group) }
+
+ it { expect(described_class.find_by_full_path(group.to_param)).to eq(group) }
+ it { expect(described_class.find_by_full_path(group.to_param.upcase)).to eq(group) }
+ it { expect(described_class.find_by_full_path(nested_group.to_param)).to eq(nested_group) }
+ it { expect(described_class.find_by_full_path('unknown')).to eq(nil) }
+ end
+
+ describe '.where_paths_in' do
+ context 'without any paths' do
+ it 'returns an empty relation' do
+ expect(described_class.where_paths_in([])).to eq([])
+ end
+ end
+
+ context 'without any valid paths' do
+ it 'returns an empty relation' do
+ expect(described_class.where_paths_in(%w[unknown])).to eq([])
+ end
+ end
+
+ context 'with valid paths' do
+ let!(:nested_group) { create(:group, parent: group) }
+
+ it 'returns the projects matching the paths' do
+ result = described_class.where_paths_in([group.to_param, nested_group.to_param])
+
+ expect(result).to contain_exactly(group, nested_group)
+ end
+
+ it 'returns projects regardless of the casing of paths' do
+ result = described_class.where_paths_in([group.to_param.upcase, nested_group.to_param.upcase])
+
+ expect(result).to contain_exactly(group, nested_group)
+ end
+ end
+ end
+end
diff --git a/spec/models/namespace_spec.rb b/spec/models/namespace_spec.rb
index ba0ed4a3603..7f82e85563b 100644
--- a/spec/models/namespace_spec.rb
+++ b/spec/models/namespace_spec.rb
@@ -124,4 +124,12 @@ describe Namespace, models: true do
expect(Namespace.clean_path("--%+--valid_*&%name=.git.%.atom.atom.@email.com")).to eq("valid_name")
end
end
+
+ describe '#full_path' do
+ let(:group) { create(:group) }
+ let(:nested_group) { create(:group, parent: group) }
+
+ it { expect(group.full_path).to eq(group.path) }
+ it { expect(nested_group.full_path).to eq("#{group.path}/#{nested_group.path}") }
+ end
end
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index 4d57330ed1c..21ff238841e 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -478,35 +478,6 @@ describe Project, models: true do
end
end
- describe '.find_with_namespace' do
- context 'with namespace' do
- before do
- @group = create :group, name: 'gitlab'
- @project = create(:project, name: 'gitlabhq', namespace: @group)
- end
-
- it { expect(Project.find_with_namespace('gitlab/gitlabhq')).to eq(@project) }
- it { expect(Project.find_with_namespace('GitLab/GitlabHQ')).to eq(@project) }
- it { expect(Project.find_with_namespace('gitlab-ci')).to be_nil }
- end
-
- context 'when multiple projects using a similar name exist' do
- let(:group) { create(:group, name: 'gitlab') }
-
- let!(:project1) do
- create(:empty_project, name: 'gitlab1', path: 'gitlab', namespace: group)
- end
-
- let!(:project2) do
- create(:empty_project, name: 'gitlab2', path: 'GITLAB', namespace: group)
- end
-
- it 'returns the row where the path matches literally' do
- expect(Project.find_with_namespace('gitlab/GITLAB')).to eq(project2)
- end
- end
- end
-
describe '#to_param' do
context 'with namespace' do
before do
@@ -1548,39 +1519,6 @@ describe Project, models: true do
end
end
- describe '.where_paths_in' do
- context 'without any paths' do
- it 'returns an empty relation' do
- expect(Project.where_paths_in([])).to eq([])
- end
- end
-
- context 'without any valid paths' do
- it 'returns an empty relation' do
- expect(Project.where_paths_in(%w[foo])).to eq([])
- end
- end
-
- context 'with valid paths' do
- let!(:project1) { create(:project) }
- let!(:project2) { create(:project) }
-
- it 'returns the projects matching the paths' do
- projects = Project.where_paths_in([project1.path_with_namespace,
- project2.path_with_namespace])
-
- expect(projects).to contain_exactly(project1, project2)
- end
-
- it 'returns projects regardless of the casing of paths' do
- projects = Project.where_paths_in([project1.path_with_namespace.upcase,
- project2.path_with_namespace.upcase])
-
- expect(projects).to contain_exactly(project1, project2)
- end
- end
- end
-
describe 'change_head' do
let(:project) { create(:project) }
diff --git a/spec/models/route_spec.rb b/spec/models/route_spec.rb
new file mode 100644
index 00000000000..6f491fdf9a0
--- /dev/null
+++ b/spec/models/route_spec.rb
@@ -0,0 +1,29 @@
+require 'spec_helper'
+
+describe Route, models: true do
+ let!(:group) { create(:group) }
+ let!(:route) { group.route }
+
+ describe 'relationships' do
+ it { is_expected.to belong_to(:source) }
+ end
+
+ describe 'validations' do
+ it { is_expected.to validate_presence_of(:source) }
+ it { is_expected.to validate_presence_of(:path) }
+ it { is_expected.to validate_uniqueness_of(:path) }
+ end
+
+ describe '#rename_children' do
+ let!(:nested_group) { create(:group, path: "test", parent: group) }
+ let!(:deep_nested_group) { create(:group, path: "foo", parent: nested_group) }
+
+ it "updates children routes with new path" do
+ route.update_attributes(path: 'bar')
+
+ expect(described_class.exists?(path: 'bar')).to be_truthy
+ expect(described_class.exists?(path: 'bar/test')).to be_truthy
+ expect(described_class.exists?(path: 'bar/test/foo')).to be_truthy
+ end
+ end
+end