From 7323d30f44eaabbd8aad66a18ded233261a74718 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Wed, 31 Aug 2016 09:48:20 +0200 Subject: [PATCH] refactored specs based on feedback --- .../import_export/export_file_spec.rb | 90 +------------------ .../attribute_configuration_spec.rb | 10 ++- .../import_export/export_file_helper.rb | 81 +++++++++++++++++ 3 files changed, 92 insertions(+), 89 deletions(-) create mode 100644 spec/support/import_export/export_file_helper.rb diff --git a/spec/features/projects/import_export/export_file_spec.rb b/spec/features/projects/import_export/export_file_spec.rb index 8188403f18f..0fff533eb2e 100644 --- a/spec/features/projects/import_export/export_file_spec.rb +++ b/spec/features/projects/import_export/export_file_spec.rb @@ -2,6 +2,7 @@ require 'spec_helper' feature 'project export', feature: true, js: true do include Select2Helper + include ExportFileHelper let(:user) { create(:admin) } let(:export_path) { "#{Dir::tmpdir}/import_file_spec" } @@ -15,11 +16,11 @@ feature 'project export', feature: true, js: true do "token" => "token", "project_id" => nil, "deleted_at" => nil, - "gl_project_id" => 4 + "gl_project_id" => project.id }, { # Project hooks "id" => 1, - "project_id" => 4, + "project_id" => project.id, "service_id" => nil, "push_events" => true, "issues_events" => false, @@ -51,7 +52,7 @@ feature 'project export', feature: true, js: true do login_as(user) end - scenario 'user imports an exported project successfully' do + scenario 'exports a project successfully' do visit edit_namespace_project_path(project.namespace, project) expect(page).to have_content('Export project') @@ -76,87 +77,4 @@ feature 'project export', feature: true, js: true do end end end - - def setup_project - issue = create(:issue, assignee: user) - snippet = create(:project_snippet) - release = create(:release) - - project = create(:project, - :public, - issues: [issue], - snippets: [snippet], - releases: [release] - ) - label = create(:label, project: project) - create(:label_link, label: label, target: issue) - milestone = create(:milestone, project: project) - merge_request = create(:merge_request, source_project: project, milestone: milestone) - commit_status = create(:commit_status, project: project) - - ci_pipeline = create(:ci_pipeline, - project: project, - sha: merge_request.diff_head_sha, - ref: merge_request.source_branch, - statuses: [commit_status]) - - create(:ci_build, pipeline: ci_pipeline, project: project) - create(:milestone, project: project) - create(:note, noteable: issue, project: project) - create(:note, noteable: merge_request, project: project) - create(:note, noteable: snippet, project: project) - create(:note_on_commit, - author: user, - project: project, - commit_id: ci_pipeline.sha) - - create(:event, target: milestone, project: project, action: Event::CREATED, author: user) - create(:project_member, :master, user: user, project: project) - create(:ci_variable, project: project) - create(:ci_trigger, project: project) - key = create(:deploy_key) - key.projects << project - create(:service, project: project) - create(:project_hook, project: project, token: 'token') - create(:protected_branch, project: project) - - project - end - - # Expands the compressed file for an exported project into +tmpdir+ - def in_directory_with_expanded_export(project) - Dir.mktmpdir do |tmpdir| - export_file = project.export_project_path - _output, exit_status = Gitlab::Popen.popen(%W{tar -zxf #{export_file} -C #{tmpdir}}) - - yield(exit_status, tmpdir) - end - end - - # Recursively finds key/values including +key+ as part of the key, inside a nested hash - def deep_find_with_parent(key, object, found = nil) - if object.respond_to?(:key?) && object.keys.any? { |k| k.include?(key) } - [object[key], object] if object[key] - elsif object.is_a? Enumerable - object.find { |*a| found, object = deep_find_with_parent(key, a.last, found) } - [found, object] if found - end - end - - # Returns true if a sensitive word is found inside a hash, excluding safe hashes - def has_sensitive_attributes?(sensitive_word, project_hash) - loop do - object, parent = deep_find_with_parent(sensitive_word, project_hash) - parent.except!('created_at', 'updated_at', 'url', 'group_id') if parent - - if object && safe_hashes[sensitive_word.to_sym].include?(parent) - # It's in the safe list, remove hash and keep looking - parent.delete(object) - elsif object - return true - else - return false - end - end - end end diff --git a/spec/lib/gitlab/import_export/attribute_configuration_spec.rb b/spec/lib/gitlab/import_export/attribute_configuration_spec.rb index 9f95b46229a..b098e913a11 100644 --- a/spec/lib/gitlab/import_export/attribute_configuration_spec.rb +++ b/spec/lib/gitlab/import_export/attribute_configuration_spec.rb @@ -10,7 +10,7 @@ describe 'Attribute configuration', lib: true do let(:config_hash) { YAML.load_file(Gitlab::ImportExport.config_file).deep_stringify_keys } let(:relation_names) do names = config_hash['project_tree'].to_s.gsub(/[\[{}\]=>\"\:]/, ',').split(',').delete_if(&:blank?) - names.uniq - ['author', 'milestones', 'labels'] + ['project'] # Remove duplicated or add missing models + names.uniq - ['milestones', 'labels'] + ['project'] # Remove duplicated or add missing models end let(:safe_model_attributes) do @@ -35,7 +35,8 @@ describe 'Attribute configuration', lib: true do 'Service' => %w[id type title project_id created_at updated_at active properties template push_events issues_events merge_requests_events tag_push_events note_events pipeline_events build_events category default wiki_page_events], 'ProjectHook' => %w[id url project_id created_at updated_at type service_id push_events issues_events merge_requests_events tag_push_events note_events pipeline_events enable_ssl_verification build_events wiki_page_events token group_id], 'ProtectedBranch' => %w[id project_id name created_at updated_at], - 'Project' => %w[description issues_enabled merge_requests_enabled wiki_enabled snippets_enabled visibility_level archived] + 'Project' => %w[description issues_enabled merge_requests_enabled wiki_enabled snippets_enabled visibility_level archived], + 'Author' => %w[name] } end @@ -43,7 +44,7 @@ describe 'Attribute configuration', lib: true do relation_names.each do |relation_name| relation_class = relation_class_for_name(relation_name) - expect(safe_model_attributes[relation_class.to_s]).not_to be_nil + expect(safe_model_attributes[relation_class.to_s]).not_to be_nil, "Expected exported class #{relation_class.to_s} to exist in safe_model_attributes" current_attributes = parsed_attributes(relation_name, relation_class.attribute_names) safe_attributes = safe_model_attributes[relation_class.to_s] @@ -80,4 +81,7 @@ describe 'Attribute configuration', lib: true do attributes end + + class Author < User + end end diff --git a/spec/support/import_export/export_file_helper.rb b/spec/support/import_export/export_file_helper.rb new file mode 100644 index 00000000000..a2ff15c7bc5 --- /dev/null +++ b/spec/support/import_export/export_file_helper.rb @@ -0,0 +1,81 @@ +module ExportFileHelper + def setup_project + project = create(:project, :public) + + create(:release, project: project) + + issue = create(:issue, assignee: user, project: project) + snippet = create(:project_snippet, project: project) + label = create(:label, project: project) + milestone = create(:milestone, project: project) + merge_request = create(:merge_request, source_project: project, milestone: milestone) + commit_status = create(:commit_status, project: project) + + create(:label_link, label: label, target: issue) + + ci_pipeline = create(:ci_pipeline, + project: project, + sha: merge_request.diff_head_sha, + ref: merge_request.source_branch, + statuses: [commit_status]) + + create(:ci_build, pipeline: ci_pipeline, project: project) + create(:milestone, project: project) + create(:note, noteable: issue, project: project) + create(:note, noteable: merge_request, project: project) + create(:note, noteable: snippet, project: project) + create(:note_on_commit, + author: user, + project: project, + commit_id: ci_pipeline.sha) + + create(:event, target: milestone, project: project, action: Event::CREATED, author: user) + create(:project_member, :master, user: user, project: project) + create(:ci_variable, project: project) + create(:ci_trigger, project: project) + key = create(:deploy_key) + key.projects << project + create(:service, project: project) + create(:project_hook, project: project, token: 'token') + create(:protected_branch, project: project) + + project + end + + # Expands the compressed file for an exported project into +tmpdir+ + def in_directory_with_expanded_export(project) + Dir.mktmpdir do |tmpdir| + export_file = project.export_project_path + _output, exit_status = Gitlab::Popen.popen(%W{tar -zxf #{export_file} -C #{tmpdir}}) + + yield(exit_status, tmpdir) + end + end + + # Recursively finds key/values including +key+ as part of the key, inside a nested hash + def deep_find_with_parent(key, object, found = nil) + if object.respond_to?(:key?) && object.keys.any? { |k| k.include?(key) } + [object[key], object] if object[key] + elsif object.is_a? Enumerable + object.find { |*a| found, object = deep_find_with_parent(key, a.last, found) } + [found, object] if found + end + end + + # Returns true if a sensitive word is found inside a hash, excluding safe hashes + def has_sensitive_attributes?(sensitive_word, project_hash) + loop do + object, parent = deep_find_with_parent(sensitive_word, project_hash) + parent.except!('created_at', 'updated_at', 'url', 'group_id') if parent + + if object && safe_hashes[sensitive_word.to_sym].include?(parent) + # It's in the safe list, remove hash and keep looking + parent.delete(object) + elsif object + return true + else + return false + end + end + end +end