From fc548207d5717f0d54840a8d2d79a2fe15e86c82 Mon Sep 17 00:00:00 2001
From: James Lopez <james@jameslopez.es>
Date: Mon, 26 Sep 2016 11:32:26 +0200
Subject: [PATCH] fix model order in import/export config and 1to1 relation
 issue. Added relevant specs.

---
 CHANGELOG                                     |  1 +
 lib/gitlab/import_export/import_export.yml    |  6 +--
 .../import_export/project_tree_restorer.rb    |  8 +++-
 spec/lib/gitlab/import_export/project.json    | 38 ++++++++++++++++++-
 .../project_tree_restorer_spec.rb             |  6 +++
 5 files changed, 54 insertions(+), 5 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index fe7181e1681..2f3fe4703d4 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -11,6 +11,7 @@ v 8.12.2 (unreleased)
   - Fix snippets pagination
   - Fix List-Unsubscribe header in emails
   - Fix an issue with the "Commits" section of the cycle analytics summary. !6513
+  - Fix errors importing project feature and milestone models using GitLab project import
 
 v 8.12.1
   - Fix a memory leak in HTML::Pipeline::SanitizationFilter::WHITELIST
diff --git a/lib/gitlab/import_export/import_export.yml b/lib/gitlab/import_export/import_export.yml
index 1c42acab9c1..bb9d1080330 100644
--- a/lib/gitlab/import_export/import_export.yml
+++ b/lib/gitlab/import_export/import_export.yml
@@ -1,5 +1,8 @@
 # Model relationships to be included in the project import/export
 project_tree:
+  - :labels
+  - milestones:
+    - :events
   - issues:
     - :events
     - notes:
@@ -39,9 +42,6 @@ project_tree:
   - protected_branches:
     - :merge_access_levels
     - :push_access_levels
-  - :labels
-  - milestones:
-    - :events
   - :project_feature
 
 # Only include the following attributes for the models specified.
diff --git a/lib/gitlab/import_export/project_tree_restorer.rb b/lib/gitlab/import_export/project_tree_restorer.rb
index c7b3551b84c..35ff134ea19 100644
--- a/lib/gitlab/import_export/project_tree_restorer.rb
+++ b/lib/gitlab/import_export/project_tree_restorer.rb
@@ -61,11 +61,17 @@ module Gitlab
       def restore_project
         return @project unless @tree_hash
 
-        project_params = @tree_hash.reject { |_key, value| value.is_a?(Array) }
         @project.update(project_params)
         @project
       end
 
+      def project_params
+        @tree_hash.reject do |key, value|
+          # return params that are not 1 to many or 1 to 1 relations
+          value.is_a?(Array) || key == key.singularize
+        end
+      end
+
       # Given a relation hash containing one or more models and its relationships,
       # loops through each model and each object from a model type and
       # and assigns its correspondent attributes hash from +tree_hash+
diff --git a/spec/lib/gitlab/import_export/project.json b/spec/lib/gitlab/import_export/project.json
index 056eaa2d719..98323fe6be4 100644
--- a/spec/lib/gitlab/import_export/project.json
+++ b/spec/lib/gitlab/import_export/project.json
@@ -2231,6 +2231,31 @@
 
   ],
   "milestones": [
+    {
+      "id": 1,
+      "title": "test milestone",
+      "project_id": 8,
+      "description": "test milestone",
+      "due_date": null,
+      "created_at": "2016-06-14T15:02:04.415Z",
+      "updated_at": "2016-06-14T15:02:04.415Z",
+      "state": "active",
+      "iid": 1,
+      "events": [
+        {
+          "id": 487,
+          "target_type": "Milestone",
+          "target_id": 1,
+          "title": null,
+          "data": null,
+          "project_id": 46,
+          "created_at": "2016-06-14T15:02:04.418Z",
+          "updated_at": "2016-06-14T15:02:04.418Z",
+          "action": 1,
+          "author_id": 18
+        }
+      ]
+    },
     {
       "id": 20,
       "title": "v4.0",
@@ -7373,5 +7398,16 @@
         }
       ]
     }
-  ]
+  ],
+  "project_feature": {
+    "builds_access_level": 0,
+    "created_at": "2014-12-26T09:26:45.000Z",
+    "id": 2,
+    "issues_access_level": 0,
+    "merge_requests_access_level": 20,
+    "project_id": 4,
+    "snippets_access_level": 20,
+    "updated_at": "2016-09-23T11:58:28.000Z",
+    "wiki_access_level": 20
+  }
 }
\ No newline at end of file
diff --git a/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb b/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb
index 65d0aaf53d6..7582a732cdf 100644
--- a/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb
+++ b/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb
@@ -107,6 +107,12 @@ describe Gitlab::ImportExport::ProjectTreeRestorer, services: true do
         expect(Label.first.label_links.first.target).not_to be_nil
       end
 
+      it 'has a project feature' do
+        restored_project_json
+
+        expect(project.project_feature).not_to be_nil
+      end
+
       it 'restores the correct service' do
         restored_project_json
 
-- 
GitLab