From 13a977475aa813636c31f606e93ee2cc1a9e8d75 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Thu, 1 Sep 2016 17:59:36 +0200 Subject: [PATCH] add model configuration spec to check for new models. Also refactored attribute_configuration spec --- spec/lib/gitlab/import_export/all_models.json | 196 ++++++++++++++++++ .../attribute_configuration_spec.rb | 16 +- .../import_export/model_configuration_spec.rb | 58 ++++++ .../import_export/configuration_helper.rb | 15 ++ 4 files changed, 271 insertions(+), 14 deletions(-) create mode 100644 spec/lib/gitlab/import_export/all_models.json create mode 100644 spec/lib/gitlab/import_export/model_configuration_spec.rb create mode 100644 spec/support/import_export/configuration_helper.rb diff --git a/spec/lib/gitlab/import_export/all_models.json b/spec/lib/gitlab/import_export/all_models.json new file mode 100644 index 00000000000..81ebeeb64f9 --- /dev/null +++ b/spec/lib/gitlab/import_export/all_models.json @@ -0,0 +1,196 @@ +{ + "issues": [ + "subscriptions", + "award_emoji", + "author", + "assignee", + "updated_by", + "milestone", + "notes", + "label_links", + "labels", + "todos", + "user_agent_detail", + "project", + "moved_to", + "events" + ], + "events": [ + "author", + "project", + "target" + ], + "notes": [ + "award_emoji", + "project", + "noteable", + "author", + "updated_by", + "resolved_by", + "todos", + "events" + ], + "label_links": [ + "target", + "label" + ], + "label": [ + "subscriptions", + "project", + "lists", + "label_links", + "issues", + "merge_requests" + ], + "milestone": [ + "project", + "issues", + "labels", + "merge_requests", + "participants", + "events" + ], + "snippets": [ + "author", + "project", + "notes" + ], + "releases": [ + "project" + ], + "project_members": [ + "created_by", + "user", + "source", + "project" + ], + "merge_requests": [ + "subscriptions", + "award_emoji", + "author", + "assignee", + "updated_by", + "milestone", + "notes", + "label_links", + "labels", + "todos", + "target_project", + "source_project", + "merge_user", + "merge_request_diffs", + "merge_request_diff", + "events" + ], + "merge_request_diff": [ + "merge_request" + ], + "pipelines": [ + "project", + "user", + "statuses", + "builds", + "trigger_requests" + ], + "statuses": [ + "project", + "pipeline", + "user" + ], + "variables": [ + "project" + ], + "triggers": [ + "project", + "trigger_requests" + ], + "deploy_keys": [ + "user", + "deploy_keys_projects", + "projects" + ], + "services": [ + "project", + "service_hook" + ], + "hooks": [ + "project" + ], + "protected_branches": [ + "project", + "merge_access_levels", + "push_access_levels" + ], + "project": [ + "taggings", + "base_tags", + "tag_taggings", + "tags", + "creator", + "group", + "namespace", + "board", + "last_event", + "services", + "campfire_service", + "drone_ci_service", + "emails_on_push_service", + "builds_email_service", + "irker_service", + "pivotaltracker_service", + "hipchat_service", + "flowdock_service", + "assembla_service", + "asana_service", + "gemnasium_service", + "slack_service", + "buildkite_service", + "bamboo_service", + "teamcity_service", + "pushover_service", + "jira_service", + "redmine_service", + "custom_issue_tracker_service", + "bugzilla_service", + "gitlab_issue_tracker_service", + "external_wiki_service", + "forked_project_link", + "forked_from_project", + "forked_project_links", + "forks", + "merge_requests", + "fork_merge_requests", + "issues", + "labels", + "events", + "milestones", + "notes", + "snippets", + "hooks", + "protected_branches", + "project_members", + "users", + "requesters", + "deploy_keys_projects", + "deploy_keys", + "users_star_projects", + "starrers", + "releases", + "lfs_objects_projects", + "lfs_objects", + "project_group_links", + "invited_groups", + "todos", + "notification_settings", + "import_data", + "commit_statuses", + "pipelines", + "builds", + "runner_projects", + "runners", + "variables", + "triggers", + "environments", + "deployments" + ] +} \ No newline at end of file diff --git a/spec/lib/gitlab/import_export/attribute_configuration_spec.rb b/spec/lib/gitlab/import_export/attribute_configuration_spec.rb index 336da93c782..931b27ffb24 100644 --- a/spec/lib/gitlab/import_export/attribute_configuration_spec.rb +++ b/spec/lib/gitlab/import_export/attribute_configuration_spec.rb @@ -7,6 +7,8 @@ require 'spec_helper' # Likewise, new models added to import_export.yml, will need to be added with their correspondent attributes # to this spec. describe 'Attribute configuration', lib: true do + include ConfigurationHelper + let(:config_hash) { YAML.load_file(Gitlab::ImportExport.config_file).deep_stringify_keys } let(:relation_names) do names = names_from_tree(config_hash['project_tree']) @@ -58,20 +60,6 @@ describe 'Attribute configuration', lib: true do end end - # Returns a list of models from hashes/arrays contained in +project_tree+ - def names_from_tree(project_tree) - project_tree.map do |branch_or_model| - branch_or_model = branch_or_model.to_s if branch_or_model.is_a?(Symbol) - - branch_or_model.is_a?(String) ? branch_or_model : names_from_tree(branch_or_model) - end - end - - def relation_class_for_name(relation_name) - relation_name = Gitlab::ImportExport::RelationFactory::OVERRIDES[relation_name.to_sym] || relation_name - relation_name.to_s.classify.constantize - end - def failure_message(relation_class, new_attributes) <<-MSG It looks like #{relation_class}, which is exported using the project Import/Export, has new attributes: #{new_attributes.join(',')} diff --git a/spec/lib/gitlab/import_export/model_configuration_spec.rb b/spec/lib/gitlab/import_export/model_configuration_spec.rb new file mode 100644 index 00000000000..82bab7ac164 --- /dev/null +++ b/spec/lib/gitlab/import_export/model_configuration_spec.rb @@ -0,0 +1,58 @@ +require 'spec_helper' + +# Finds if a new model has been added that can potentially be part of the Import/Export +# If it finds a new model, it will show a +failure_message+ with the options available. +describe 'Model configuration', lib: true do + include ConfigurationHelper + + let(:config_hash) { YAML.load_file(Gitlab::ImportExport.config_file).deep_stringify_keys } + let(:relation_names) do + names = names_from_tree(config_hash['project_tree']) + + # Remove duplicated or add missing models + # - project is not part of the tree, so it has to be added manually. + # - milestone, labels have both singular and plural versions in the tree, so remove the duplicates. + # - User, Author... Models we don not care about for checking relations + names.flatten.uniq - ['milestones', 'labels', 'user', 'author'] + ['project'] + end + + let(:all_models_json) { 'spec/lib/gitlab/import_export/all_models.json' } + let(:all_models) { JSON.parse(File.read(all_models_json)) } + let(:current_models) { setup_models } + + it 'has no new models' do + relation_names.each do |relation_name| + new_models = current_models[relation_name] - all_models[relation_name] + expect(new_models).to be_empty, failure_message(relation_name.classify, new_models) + end + end + + # List of current relations between models, in the format of + # {model: [model_2, model3], ...} + def setup_models + all_models_hash = {} + + relation_names.each do |relation_name| + relation_class = relation_class_for_name(relation_name) + + all_models_hash[relation_name] = relation_class.reflect_on_all_associations.map do |association| + association.name.to_s + end + end + + all_models_hash + end + + def failure_message(relation_name, new_models) + <<-MSG + New model(s) <#{new_models.join(',')}> have been added, related to #{relation_name}, which is exported by + the Import/Export feature. + + If you don't think this should be exported, please add it to MODELS_JSON, inside the #{relation_name} hash. + If you think we should export this new model, please add it to IMPORT_EXPORT_CONFIG. + + MODELS_JSON: #{File.expand_path(all_models_json)} + IMPORT_EXPORT_CONFIG: #{Gitlab::ImportExport.config_file} + MSG + end +end diff --git a/spec/support/import_export/configuration_helper.rb b/spec/support/import_export/configuration_helper.rb new file mode 100644 index 00000000000..fec83765253 --- /dev/null +++ b/spec/support/import_export/configuration_helper.rb @@ -0,0 +1,15 @@ +module ConfigurationHelper + # Returns a list of models from hashes/arrays contained in +project_tree+ + def names_from_tree(project_tree) + project_tree.map do |branch_or_model| + branch_or_model = branch_or_model.to_s if branch_or_model.is_a?(Symbol) + + branch_or_model.is_a?(String) ? branch_or_model : names_from_tree(branch_or_model) + end + end + + def relation_class_for_name(relation_name) + relation_name = Gitlab::ImportExport::RelationFactory::OVERRIDES[relation_name.to_sym] || relation_name + relation_name.to_s.classify.constantize + end +end