From 9cec3e31521cc32128874149717d99f911313e30 Mon Sep 17 00:00:00 2001
From: Troy Dai <troy.dai@outlook.com>
Date: Sun, 3 Apr 2016 19:29:23 -0700
Subject: [PATCH] Add two tests for project model server

---
 .../src/EmptyNetCoreApp/Program.cs            |  13 ++
 .../src/EmptyNetCoreApp/project.json          |  15 +++
 .../DthTests.cs                               | 118 ++++++++++++++++--
 .../Helpers/JArrayExtensions.cs               |  15 +++
 4 files changed, 153 insertions(+), 8 deletions(-)
 create mode 100644 TestAssets/ProjectModelServer/DthTestProjects/src/EmptyNetCoreApp/Program.cs
 create mode 100644 TestAssets/ProjectModelServer/DthTestProjects/src/EmptyNetCoreApp/project.json

diff --git a/TestAssets/ProjectModelServer/DthTestProjects/src/EmptyNetCoreApp/Program.cs b/TestAssets/ProjectModelServer/DthTestProjects/src/EmptyNetCoreApp/Program.cs
new file mode 100644
index 000000000..9e6dde0c3
--- /dev/null
+++ b/TestAssets/ProjectModelServer/DthTestProjects/src/EmptyNetCoreApp/Program.cs
@@ -0,0 +1,13 @@
+using System;
+
+namespace Misc.DthTestProjects.SimpleConsoleApp
+{
+    public class Program
+    {
+        public int Main(string[] args)
+        {
+            Console.WriteLine("Hello, world.");
+            return 0;
+        }
+    }
+}
diff --git a/TestAssets/ProjectModelServer/DthTestProjects/src/EmptyNetCoreApp/project.json b/TestAssets/ProjectModelServer/DthTestProjects/src/EmptyNetCoreApp/project.json
new file mode 100644
index 000000000..3621ef882
--- /dev/null
+++ b/TestAssets/ProjectModelServer/DthTestProjects/src/EmptyNetCoreApp/project.json
@@ -0,0 +1,15 @@
+{
+  "dependencies": {},
+  "frameworks": {
+    "netcoreapp1.0": {
+      "imports": "dnxcore50",
+      "dependencies": {
+        "Microsoft.NETCore.App": {
+          "type": "platform",
+          "version": "1.0.0-rc2-23931"
+        },
+        "Newtonsoft.Json": "8.0.3"
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/test/dotnet-projectmodel-server.Tests/DthTests.cs b/test/dotnet-projectmodel-server.Tests/DthTests.cs
index 92df20c70..878bf8acd 100644
--- a/test/dotnet-projectmodel-server.Tests/DthTests.cs
+++ b/test/dotnet-projectmodel-server.Tests/DthTests.cs
@@ -412,13 +412,13 @@ namespace Microsoft.DotNet.ProjectModel.Server.Tests
                 }
             }
         }
-        
+
         [Fact]
         public void MSBuildReferenceTest()
         {
             var testProject = Path.Combine(RepoRoot, "TestAssets",
                                                      "ProjectModelServer",
-                                                     "MSBuildReferencesProjects", 
+                                                     "MSBuildReferencesProjects",
                                                      "ValidCase01",
                                                      "src",
                                                      "MainApp");
@@ -428,12 +428,12 @@ namespace Microsoft.DotNet.ProjectModel.Server.Tests
             {
                 client.Initialize(testProject);
                 var messages = client.DrainAllMessages();
-                
+
                 var classLibraries = new HashSet<string>(new string[] { "ClassLibrary1", "ClassLibrary2", "ClassLibrary3" });
                 var dependencies = messages.RetrieveSingleMessage(MessageTypes.Dependencies);
                 var testProjectRoot = Path.Combine(RepoRoot, "TestAssets", "ProjectModelServer", "MSBuildReferencesProjects", "ValidCase01");
                 foreach (var classLibrary in classLibraries)
-                {                    
+                {
                     dependencies.RetrieveDependency(classLibrary)
                                 .AssertProperty("Type", LibraryType.MSBuildProject.ToString())
                                 .AssertProperty("Path", NormalizePathString(Path.Combine(testProjectRoot, classLibrary, $"{classLibrary}.csproj")))
@@ -442,21 +442,21 @@ namespace Microsoft.DotNet.ProjectModel.Server.Tests
                                 .AssertProperty<JArray>("Errors", array => array.Count == 0)
                                 .AssertProperty<JArray>("Warnings", array => array.Count == 0);
                 }
-                
+
                 var references = messages.RetrieveSingleMessage(MessageTypes.References)
                                          .RetrievePayloadAs<JObject>();
-                                         
+
                 var projectReferences = references.RetrievePropertyAs<JArray>("ProjectReferences");
                 Assert.Equal(3, projectReferences.Count);
                 for (int i = 0; i < 3; ++i)
                 {
                     var projectRef = projectReferences.RetrieveArraryElementAs<JObject>(i);
                     var name = projectRef["Name"].Value<string>();
-                    
+
                     Assert.True(classLibraries.Contains(name));
                     projectRef.AssertProperty("Path", NormalizePathString(Path.Combine(testProjectRoot, name, $"{name}.csproj")));
                 }
-                
+
                 var fileReferences = references.RetrievePropertyAs<JArray>("FileReferences")
                                                .Select(each => each.Value<string>())
                                                .ToArray();
@@ -467,9 +467,111 @@ namespace Microsoft.DotNet.ProjectModel.Server.Tests
             }
         }
 
+        [Fact]
+        public void RemovePackageDependencyFromProjectJson()
+        {
+            // Remove a package dependency from project.json and then request refreshing dependency before
+            // restore.
+
+            var appName = "EmptyNetCoreApp";
+            var projectPath = _testAssetsManager.CreateTestInstance(appName)
+                                                .WithLockFiles()
+                                                .TestRoot;
+
+            using (var server = new DthTestServer(_loggerFactory))
+            using (var client = new DthTestClient(server, _loggerFactory))
+            {
+                client.Initialize(projectPath);
+
+                client.DrainAllMessages()
+                      .AssertDoesNotContain(MessageTypes.Error)
+                      .RetrieveSingleMessage(MessageTypes.Dependencies)
+                      .RetrieveDependency(appName)
+                      .RetrievePropertyAs<JArray>("Dependencies")
+                      .AssertJArrayCount(2);
+
+                var projectFilePath = Path.Combine(projectPath, Project.FileName);
+                var projectJson = JsonConvert.DeserializeObject<JObject>(File.ReadAllText(projectFilePath));
+
+                // Remove newtonsoft.json dependency
+                var dependencies = projectJson["frameworks"]["netcoreapp1.0"]["dependencies"] as JObject;
+                dependencies.Remove("Newtonsoft.Json");
+
+                File.WriteAllText(projectFilePath, JsonConvert.SerializeObject(projectJson));
+
+                client.SendPayLoad(projectPath, MessageTypes.RefreshDependencies);
+
+                var afterDependencies = client.DrainTillFirst(MessageTypes.Dependencies);
+                afterDependencies.RetrieveDependency(appName)
+                                 .RetrievePropertyAs<JArray>("Dependencies")
+                                 .AssertJArrayCount(1)
+                                 .RetrieveArraryElementAs<JObject>(0)
+                                 .AssertProperty("Name", "Microsoft.NETCore.App");
+                afterDependencies.RetrieveDependency("Newtonsoft.Json");
+            }
+        }
+
+        [Fact]
+        public void RemoveMSBuildDependencyFromProjectJson()
+        {
+            // Remove a msbuild project dependency from project.json and then request refreshing dependency before
+            // restore.
+
+            var tam = new TestAssetsManager(
+                Path.Combine(RepoRoot, "TestAssets", "ProjectModelServer", "MSBuildReferencesProjects"));
+
+            // var appName = "EmptyNetCoreApp";
+            var projectPath = tam.CreateTestInstance("ValidCase01").WithLockFiles().TestRoot;
+            projectPath = Path.Combine(projectPath, "src", "MainApp");
+
+            using (var server = new DthTestServer(_loggerFactory))
+            using (var client = new DthTestClient(server, _loggerFactory))
+            {
+                client.Initialize(projectPath);
+
+                client.DrainAllMessages()
+                      .AssertDoesNotContain(MessageTypes.Error)
+                      .RetrieveSingleMessage(MessageTypes.Dependencies)
+                      .RetrieveDependency("MainApp")
+                      .RetrievePropertyAs<JArray>("Dependencies")
+                      .AssertJArrayContains<JObject>(dep => dep["Name"].Value<string>() == "ClassLibrary1")
+                      .AssertJArrayContains<JObject>(dep => dep["Name"].Value<string>() == "ClassLibrary2")
+                      .AssertJArrayContains<JObject>(dep => dep["Name"].Value<string>() == "ClassLibrary3");
+
+                var projectFilePath = Path.Combine(projectPath, Project.FileName);
+                var projectJson = JsonConvert.DeserializeObject<JObject>(File.ReadAllText(projectFilePath));
+
+                // Remove ClassLibrary2 and ClassLibrary3 dependency
+                var dependencies = projectJson["frameworks"]["net46"]["dependencies"] as JObject;
+                dependencies.Remove("ClassLibrary2");
+                dependencies.Remove("ClassLibrary3");
+
+                File.WriteAllText(projectFilePath, JsonConvert.SerializeObject(projectJson));
+
+                client.SendPayLoad(projectPath, MessageTypes.RefreshDependencies);
+
+                var afterDependencies = client.DrainTillFirst(MessageTypes.Dependencies);
+                afterDependencies.RetrieveDependency("MainApp")
+                                 .RetrievePropertyAs<JArray>("Dependencies")
+                                 .AssertJArrayNotContains<JObject>(dep => dep["Name"].Value<string>() == "ClassLibrary2")
+                                 .AssertJArrayNotContains<JObject>(dep => dep["Name"].Value<string>() == "ClassLibrary3");
+
+                afterDependencies.RetrieveDependency("ClassLibrary2");
+                afterDependencies.RetrieveDependency("ClassLibrary3");
+            }
+        }
+
         private static string NormalizePathString(string original)
         {
             return original.Replace('/', Path.DirectorySeparatorChar).Replace('\\', Path.DirectorySeparatorChar);
         }
+
+        private static void PrintAllMessages(IEnumerable<DthMessage> messages)
+        {
+            foreach (var message in messages)
+            {
+                Console.WriteLine($"{message.MessageType} => {message.Payload.ToString()}");
+            }
+        }
     }
 }
diff --git a/test/dotnet-projectmodel-server.Tests/Helpers/JArrayExtensions.cs b/test/dotnet-projectmodel-server.Tests/Helpers/JArrayExtensions.cs
index f7cddb8bb..8dcd21861 100644
--- a/test/dotnet-projectmodel-server.Tests/Helpers/JArrayExtensions.cs
+++ b/test/dotnet-projectmodel-server.Tests/Helpers/JArrayExtensions.cs
@@ -70,6 +70,21 @@ namespace Microsoft.DotNet.ProjectModel.Server.Tests
             return array;
         }
 
+        public static JArray AssertJArrayNotContains<T>(this JArray array, Func<T, bool> critiera)
+        {
+            foreach (var element in array)
+            {
+                var value = element.Value<T>();
+
+                if (critiera(value))
+                {
+                    Assert.True(false, "JArray contains unexpected element.");
+                }
+            }
+
+            return array;
+        }
+
         public static T RetrieveArraryElementAs<T>(this JArray json, int index)
             where T : JToken
         {