require "spec_helper" require Rails.root.join("db", "migrate", "20170316163800_rename_system_namespaces.rb") describe RenameSystemNamespaces, truncate: true do let(:migration) { described_class.new } let(:test_dir) { File.join(Rails.root, "tmp", "tests", "rename_namespaces_test") } let(:uploads_dir) { File.join(test_dir, "public", "uploads") } let(:system_namespace) do namespace = build(:namespace, path: "system") namespace.save(validate: false) namespace end def save_invalid_routable(routable) routable.__send__(:prepare_route) routable.save(validate: false) end before do FileUtils.remove_dir(test_dir) if File.directory?(test_dir) FileUtils.mkdir_p(uploads_dir) FileUtils.remove_dir(TestEnv.repos_path) if File.directory?(TestEnv.repos_path) allow(migration).to receive(:say) allow(migration).to receive(:uploads_dir).and_return(uploads_dir) end describe "#system_namespace" do it "only root namespaces called with path `system`" do system_namespace system_namespace_with_parent = build(:namespace, path: 'system', parent: create(:namespace)) system_namespace_with_parent.save(validate: false) expect(migration.system_namespace.id).to eq(system_namespace.id) end end describe "#up" do before do system_namespace end it "doesn't break if there are no namespaces called system" do Namespace.delete_all migration.up end it "renames namespaces called system" do migration.up expect(system_namespace.reload.path).to eq("system0") end it "renames the route to the namespace" do migration.up expect(system_namespace.reload.full_path).to eq("system0") end it "renames the route for projects of the namespace" do project = build(:project, path: "project-path", namespace: system_namespace) save_invalid_routable(project) migration.up expect(project.route.reload.path).to eq("system0/project-path") end it "doesn't touch routes of namespaces that look like system" do namespace = create(:group, path: 'systemlookalike') project = create(:project, namespace: namespace, path: 'the-project') migration.up expect(project.route.reload.path).to eq('systemlookalike/the-project') expect(namespace.route.reload.path).to eq('systemlookalike') end it "moves the the repository for a project in the namespace" do project = build(:project, namespace: system_namespace, path: "system-project") save_invalid_routable(project) TestEnv.copy_repo(project, bare_repo: TestEnv.factory_repo_path_bare, refs: TestEnv::BRANCH_SHA) expected_repo = File.join(TestEnv.repos_path, "system0", "system-project.git") migration.up expect(File.directory?(expected_repo)).to be(true) end it "moves the uploads for the namespace" do allow(migration).to receive(:move_namespace_folders).with(Settings.pages.path, "system", "system0") expect(migration).to receive(:move_namespace_folders).with(uploads_dir, "system", "system0") migration.up end it "moves the pages for the namespace" do allow(migration).to receive(:move_namespace_folders).with(uploads_dir, "system", "system0") expect(migration).to receive(:move_namespace_folders).with(Settings.pages.path, "system", "system0") migration.up end describe "clears the markdown cache for projects in the system namespace" do let!(:project) do project = build(:project, namespace: system_namespace) save_invalid_routable(project) project end it 'removes description_html from projects' do migration.up expect(project.reload.description_html).to be_nil end it 'removes issue descriptions' do issue = create(:issue, project: project, description_html: 'Issue description') migration.up expect(issue.reload.description_html).to be_nil end it 'removes merge request descriptions' do merge_request = create(:merge_request, source_project: project, target_project: project, description_html: 'MergeRequest description') migration.up expect(merge_request.reload.description_html).to be_nil end it 'removes note html' do note = create(:note, project: project, noteable: create(:issue, project: project), note_html: 'note description') migration.up expect(note.reload.note_html).to be_nil end it 'removes milestone description' do milestone = create(:milestone, project: project, description_html: 'milestone description') migration.up expect(milestone.reload.description_html).to be_nil end end context "system namespace -> subgroup -> system0 project" do it "updates the route of the project correctly" do subgroup = build(:group, path: "subgroup", parent: system_namespace) save_invalid_routable(subgroup) project = build(:project, path: "system0", namespace: subgroup) save_invalid_routable(project) migration.up expect(project.route.reload.path).to eq("system0/subgroup/system0") end end end describe "#move_repositories" do let(:namespace) { create(:group, name: "hello-group") } it "moves a project for a namespace" do create(:project, namespace: namespace, path: "hello-project") expected_path = File.join(TestEnv.repos_path, "bye-group", "hello-project.git") migration.move_repositories(namespace, "hello-group", "bye-group") expect(File.directory?(expected_path)).to be(true) end it "moves a namespace in a subdirectory correctly" do child_namespace = create(:group, name: "sub-group", parent: namespace) create(:project, namespace: child_namespace, path: "hello-project") expected_path = File.join(TestEnv.repos_path, "hello-group", "renamed-sub-group", "hello-project.git") migration.move_repositories(child_namespace, "hello-group/sub-group", "hello-group/renamed-sub-group") expect(File.directory?(expected_path)).to be(true) end it "moves a parent namespace with subdirectories" do child_namespace = create(:group, name: "sub-group", parent: namespace) create(:project, namespace: child_namespace, path: "hello-project") expected_path = File.join(TestEnv.repos_path, "renamed-group", "sub-group", "hello-project.git") migration.move_repositories(child_namespace, "hello-group", "renamed-group") expect(File.directory?(expected_path)).to be(true) end end describe "#move_namespace_folders" do it "moves a namespace with files" do source = File.join(uploads_dir, "parent-group", "sub-group") FileUtils.mkdir_p(source) destination = File.join(uploads_dir, "parent-group", "moved-group") FileUtils.touch(File.join(source, "test.txt")) expected_file = File.join(destination, "test.txt") migration.move_namespace_folders(uploads_dir, File.join("parent-group", "sub-group"), File.join("parent-group", "moved-group")) expect(File.exist?(expected_file)).to be(true) end it "moves a parent namespace uploads" do source = File.join(uploads_dir, "parent-group", "sub-group") FileUtils.mkdir_p(source) destination = File.join(uploads_dir, "moved-parent", "sub-group") FileUtils.touch(File.join(source, "test.txt")) expected_file = File.join(destination, "test.txt") migration.move_namespace_folders(uploads_dir, "parent-group", "moved-parent") expect(File.exist?(expected_file)).to be(true) end end describe "#child_ids_for_parent" do it "collects child ids for all levels" do parent = create(:group) first_child = create(:group, parent: parent) second_child = create(:group, parent: parent) third_child = create(:group, parent: second_child) all_ids = [parent.id, first_child.id, second_child.id, third_child.id] collected_ids = migration.child_ids_for_parent(parent, ids: [parent.id]) expect(collected_ids).to contain_exactly(*all_ids) end end describe "#remove_last_ocurrence" do it "removes only the last occurance of a string" do input = "this/is/system/namespace/with/system" expect(migration.remove_last_occurrence(input, "system")).to eq("this/is/system/namespace/with/") end end end