From 39067c751b7bb5bdd46968cb90ee21dd314b31f6 Mon Sep 17 00:00:00 2001 From: J Wyman Date: Fri, 23 Jun 2017 16:12:16 -0400 Subject: [PATCH] Convert non-Mircosoft test projects to Xunit. Required changing test project dependencies, changing code to use Xunit attribute markup (instead of mstest markup), and adding the Xunit.Wpf single-thread-apartment utility. --- .../AuthenticationTest.cs | 225 +++++++-------- .../Bitbucket.Authentication.Test.csproj | 48 ++-- .../BitbucketAuthTests.cs | 38 ++- Bitbucket.Authentication.Test/packages.config | 7 + .../Cli-CredentialHelper.Test.csproj | 10 +- Cli-CredentialHelper.Test/packages.config | 14 +- GitCredentialManager.sln | 3 +- .../ActionCommandTests.cs | 15 +- .../Controls/MaskedPasswordBoxTests.cs | 9 +- .../CredentialsViewModelTests.cs | 23 +- .../GitHub.Authentication.Test.csproj | 24 +- .../GitHubTokenScopeTests.cs | 79 +++--- .../TwoFactorViewModelTests.cs | 11 +- .../Validation/ModelValidatorTests.cs | 13 +- .../Validation/PropertyValidatorTests.cs | 35 ++- .../Validation/ValidationExtensionsTests.cs | 21 +- .../Validation/ValidationMessageTests.cs | 25 +- .../Xunit/WpfFactAttribute.cs.cs | 9 + .../Xunit/WpfFactDiscoverer.cs | 25 ++ .../Xunit/WpfTestCase.cs | 150 ++++++++++ .../Xunit/WpfTheoryAttribute.cs | 9 + .../Xunit/WpfTheoryDiscoverer.cs | 25 ++ GitHub.Authentication.Test/packages.config | 7 + .../CredentialTests.cs | 257 ++++++------------ .../Microsoft.Alm.Authentication.Test.csproj | 12 +- .../TokenTests.cs | 66 ++--- .../packages.config | 14 +- .../xunit.runner.json | 6 - Microsoft.Alm.Git.Test/ConfigurationTests.cs | 14 +- .../Microsoft.Alm.Git.Test.csproj | 13 +- Microsoft.Alm.Git.Test/app.config | 11 - Microsoft.Alm.Git.Test/packages.config | 14 +- Microsoft.Alm.Git.Test/xunit.runner.json | 7 - .../Microsoft.Vsts.Authentication.Test.csproj | 9 +- .../packages.config | 14 +- xunit.runner.json | 9 + 36 files changed, 698 insertions(+), 573 deletions(-) create mode 100644 GitHub.Authentication.Test/Xunit/WpfFactAttribute.cs.cs create mode 100644 GitHub.Authentication.Test/Xunit/WpfFactDiscoverer.cs create mode 100644 GitHub.Authentication.Test/Xunit/WpfTestCase.cs create mode 100644 GitHub.Authentication.Test/Xunit/WpfTheoryAttribute.cs create mode 100644 GitHub.Authentication.Test/Xunit/WpfTheoryDiscoverer.cs delete mode 100644 Microsoft.Alm.Authentication.Test/xunit.runner.json delete mode 100644 Microsoft.Alm.Git.Test/app.config delete mode 100644 Microsoft.Alm.Git.Test/xunit.runner.json create mode 100644 xunit.runner.json diff --git a/Bitbucket.Authentication.Test/AuthenticationTest.cs b/Bitbucket.Authentication.Test/AuthenticationTest.cs index b9e59bd..b3cf71a 100644 --- a/Bitbucket.Authentication.Test/AuthenticationTest.cs +++ b/Bitbucket.Authentication.Test/AuthenticationTest.cs @@ -1,34 +1,33 @@ using System; using System.Collections.Generic; using System.Linq; -using Microsoft.Alm.Authentication; -using Microsoft.VisualStudio.TestTools.UnitTesting; using System.Net; +using Microsoft.Alm.Authentication; +using Xunit; namespace Atlassian.Bitbucket.Authentication.Test { - [TestClass] public class AuthenticationTest { - [TestMethod] + [Fact] public void VerifyBitbucketOrgIsIdentified() { var targetUri = new TargetUri("https://bitbucket.org"); var bbAuth = Authentication.GetAuthentication(targetUri, new MockCredentialStore(), null, null); - Assert.IsNotNull(bbAuth); + Assert.NotNull(bbAuth); } - [TestMethod] + [Fact] public void VerifyNonBitbucketOrgIsIgnored() { var targetUri = new TargetUri("https://example.com"); var bbAuth = Authentication.GetAuthentication(targetUri, new MockCredentialStore(), null, null); - Assert.IsNull(bbAuth); + Assert.Null(bbAuth); } - [TestMethod] + [Fact] public void VerifySetCredentialStoresValidCredentials() { var targetUri = new TargetUri("https://example.com"); @@ -45,72 +44,82 @@ namespace Atlassian.Bitbucket.Authentication.Test && wc.Key.Contains(credentials.Username) && wc.Key.Contains(credentials.Password)); - Assert.AreEqual(writeCalls.Count(), 1); + Assert.Equal(writeCalls.Count(), 1); } - [TestMethod] - [ExpectedException(typeof(ArgumentNullException))] + [Fact] public void VerifySetCredentialDoesNotStoreForNullTargetUri() { - var credentialStore = new MockCredentialStore(); - var credentials = new Credential("a", "b"); - var bbAuth = new Authentication(credentialStore, null, null); + Assert.Throws(() => + { + var credentialStore = new MockCredentialStore(); + var credentials = new Credential("a", "b"); + var bbAuth = new Authentication(credentialStore, null, null); - bbAuth.SetCredentials(null, credentials); + bbAuth.SetCredentials(null, credentials); + }); } - [TestMethod] - [ExpectedException(typeof(ArgumentNullException))] + [Fact] public void VerifySetCredentialDoesNotStoresForNullCredentials() { - var targetUri = new TargetUri("https://example.com"); - var credentialStore = new MockCredentialStore(); - var bbAuth = new Authentication(credentialStore, null, null); + Assert.Throws(() => + { + var targetUri = new TargetUri("https://example.com"); + var credentialStore = new MockCredentialStore(); + var bbAuth = new Authentication(credentialStore, null, null); - bbAuth.SetCredentials(targetUri, null); + bbAuth.SetCredentials(targetUri, null); + }); } - [TestMethod] - [ExpectedException(typeof(ArgumentOutOfRangeException))] + [Fact] public void VerifySetCredentialDoesNotStoreForTooLongPassword() { - var targetUri = new TargetUri("https://example.com"); - var credentialStore = new MockCredentialStore(); - var credentials = new Credential("a", new string('x', 2047 + 1)); - var bbAuth = new Authentication(credentialStore, null, null); + Assert.Throws(() => + { + var targetUri = new TargetUri("https://example.com"); + var credentialStore = new MockCredentialStore(); + var credentials = new Credential("a", new string('x', 2047 + 1)); + var bbAuth = new Authentication(credentialStore, null, null); - bbAuth.SetCredentials(targetUri, credentials); + bbAuth.SetCredentials(targetUri, credentials); + }); } - [TestMethod] - [ExpectedException(typeof(ArgumentOutOfRangeException))] + [Fact] public void VerifySetCredentialDoesNotStoreForTooLongUsername() { - var targetUri = new TargetUri("https://example.com"); - var credentialStore = new MockCredentialStore(); - var credentials = new Credential(new string('x', 2047 + 1), "b"); - var bbAuth = new Authentication(credentialStore, null, null); + Assert.Throws(() => + { + var targetUri = new TargetUri("https://example.com"); + var credentialStore = new MockCredentialStore(); + var credentials = new Credential(new string('x', 2047 + 1), "b"); + var bbAuth = new Authentication(credentialStore, null, null); - bbAuth.SetCredentials(targetUri, credentials); + bbAuth.SetCredentials(targetUri, credentials); + }); } - [TestMethod] - [ExpectedException(typeof(ArgumentNullException))] + [Fact] public void VerifyDeleteCredentialDoesNotDeleteForNullTargetUri() { - var credentialStore = new MockCredentialStore(); - var bbAuth = new Authentication(credentialStore, null, null); + Assert.Throws(() => + { + var credentialStore = new MockCredentialStore(); + var bbAuth = new Authentication(credentialStore, null, null); - bbAuth.DeleteCredentials(null); + bbAuth.DeleteCredentials(null); - var deleteCalls = credentialStore.MethodCalls - .Where(mc => mc.Key.Equals("DeleteCredentials")) - .SelectMany(mc => mc.Value); + var deleteCalls = credentialStore.MethodCalls + .Where(mc => mc.Key.Equals("DeleteCredentials")) + .SelectMany(mc => mc.Value); - Assert.AreEqual(deleteCalls.Count(), 0); + Assert.Equal(deleteCalls.Count(), 0); + }); } - [TestMethod] + [Fact] public void VerifyDeleteCredentialForBasicAuthReadsTwiceDeletesOnce() { var credentialStore = new MockCredentialStore(); @@ -127,21 +136,21 @@ namespace Atlassian.Bitbucket.Authentication.Test .SelectMany(mc => mc.Value); // 2 read calls, 1 for the basic uri and 1 for /refresh_token - Assert.AreEqual(2, readCalls.Count()); - Assert.IsTrue(readCalls.Any(rc => rc.Key[0].Equals("https://example.com/"))); - Assert.IsTrue(readCalls.Any(rc => rc.Key[0].Equals("https://example.com/refresh_token"))); + Assert.Equal(2, readCalls.Count()); + Assert.True(readCalls.Any(rc => rc.Key[0].Equals("https://example.com/"))); + Assert.True(readCalls.Any(rc => rc.Key[0].Equals("https://example.com/refresh_token"))); var deleteCalls = credentialStore.MethodCalls .Where(mc => mc.Key.Equals("DeleteCredentials")) .SelectMany(mc => mc.Value); // 1 delete call, 1 for the basic uri 0 for /refresh_token as there isn't one - Assert.AreEqual(1, deleteCalls.Count()); - Assert.IsTrue(deleteCalls.Any(rc => rc.Key[0].Equals("https://example.com/"))); - Assert.IsFalse(deleteCalls.Any(rc => rc.Key[0].Equals("https://example.com/refresh_token"))); + Assert.Equal(1, deleteCalls.Count()); + Assert.True(deleteCalls.Any(rc => rc.Key[0].Equals("https://example.com/"))); + Assert.False(deleteCalls.Any(rc => rc.Key[0].Equals("https://example.com/refresh_token"))); } - [TestMethod] + [Fact] public void VerifyDeleteCredentialForOAuthReadsTwiceDeletesTwice() { var credentialStore = new MockCredentialStore(); @@ -159,21 +168,21 @@ namespace Atlassian.Bitbucket.Authentication.Test .SelectMany(mc => mc.Value); // 2 read calls, 1 for the basic uri and 1 for /refresh_token - Assert.AreEqual(2, readCalls.Count()); - Assert.IsTrue(readCalls.Any(rc => rc.Key[0].Equals("https://example.com/"))); - Assert.IsTrue(readCalls.Any(rc => rc.Key[0].Equals("https://example.com/refresh_token"))); + Assert.Equal(2, readCalls.Count()); + Assert.True(readCalls.Any(rc => rc.Key[0].Equals("https://example.com/"))); + Assert.True(readCalls.Any(rc => rc.Key[0].Equals("https://example.com/refresh_token"))); var deleteCalls = credentialStore.MethodCalls .Where(mc => mc.Key.Equals("DeleteCredentials")) .SelectMany(mc => mc.Value); // 2 delete call, 1 for the basic uri, 1 for /refresh_token as there is one - Assert.AreEqual(2, deleteCalls.Count()); - Assert.IsTrue(deleteCalls.Any(rc => rc.Key[0].Equals("https://example.com/"))); - Assert.IsTrue(deleteCalls.Any(rc => rc.Key[0].Equals("https://example.com/refresh_token"))); + Assert.Equal(2, deleteCalls.Count()); + Assert.True(deleteCalls.Any(rc => rc.Key[0].Equals("https://example.com/"))); + Assert.True(deleteCalls.Any(rc => rc.Key[0].Equals("https://example.com/refresh_token"))); } - [TestMethod] + [Fact] public void VerifyDeleteCredentialForBasicAuthReadsQuinceDeletesTwiceIfHostCredentialsExistAndShareUsername() { var credentialStore = new MockCredentialStore(); @@ -198,11 +207,11 @@ namespace Atlassian.Bitbucket.Authentication.Test // 1 for the basic uri to compare username // 1 for the basic uri without username // 1 for /refresh_token without username - Assert.AreEqual(5, readCalls.Count()); - Assert.AreEqual(1, readCalls.Count(rc => rc.Key[0].Equals("https://john@example.com/"))); - Assert.AreEqual(1, readCalls.Count(rc => rc.Key[0].Equals("https://john@example.com/refresh_token"))); - Assert.AreEqual(2, readCalls.Count(rc => rc.Key[0].Equals("https://example.com/"))); - Assert.AreEqual(1, readCalls.Count(rc => rc.Key[0].Equals("https://example.com/refresh_token"))); + Assert.Equal(5, readCalls.Count()); + Assert.Equal(1, readCalls.Count(rc => rc.Key[0].Equals("https://john@example.com/"))); + Assert.Equal(1, readCalls.Count(rc => rc.Key[0].Equals("https://john@example.com/refresh_token"))); + Assert.Equal(2, readCalls.Count(rc => rc.Key[0].Equals("https://example.com/"))); + Assert.Equal(1, readCalls.Count(rc => rc.Key[0].Equals("https://example.com/refresh_token"))); var deleteCalls = credentialStore.MethodCalls .Where(mc => mc.Key.Equals("DeleteCredentials")) @@ -211,13 +220,13 @@ namespace Atlassian.Bitbucket.Authentication.Test // 2 delete calls // 1 for the basic uri with username // 1 for the basic uri without username - Assert.AreEqual(2, deleteCalls.Count()); - Assert.AreEqual(1, deleteCalls.Count(rc => rc.Key[0].Equals("https://john@example.com/"))); - Assert.IsFalse(deleteCalls.Any(rc => rc.Key[0].Equals("https://example.com/refresh_token"))); - Assert.AreEqual(1, deleteCalls.Count(rc => rc.Key[0].Equals("https://example.com/"))); + Assert.Equal(2, deleteCalls.Count()); + Assert.Equal(1, deleteCalls.Count(rc => rc.Key[0].Equals("https://john@example.com/"))); + Assert.False(deleteCalls.Any(rc => rc.Key[0].Equals("https://example.com/refresh_token"))); + Assert.Equal(1, deleteCalls.Count(rc => rc.Key[0].Equals("https://example.com/"))); } - [TestMethod] + [Fact] public void VerifyDeleteCredentialForBasicAuthReadsThriceDeletesOnceIfHostCredentialsExistAndDoNotShareUsername() { var credentialStore = new MockCredentialStore(); @@ -240,11 +249,11 @@ namespace Atlassian.Bitbucket.Authentication.Test // 1 for the basic uri with username // 1 for /refresh_token with username // 1 for the basic uri to compare username - Assert.AreEqual(3, readCalls.Count()); - Assert.AreEqual(1, readCalls.Count(rc => rc.Key[0].Equals("https://john@example.com/"))); - Assert.AreEqual(1, readCalls.Count(rc => rc.Key[0].Equals("https://john@example.com/refresh_token"))); - Assert.AreEqual(1, readCalls.Count(rc => rc.Key[0].Equals("https://example.com/"))); - + Assert.Equal(3, readCalls.Count()); + Assert.Equal(1, readCalls.Count(rc => rc.Key[0].Equals("https://john@example.com/"))); + Assert.Equal(1, readCalls.Count(rc => rc.Key[0].Equals("https://john@example.com/refresh_token"))); + Assert.Equal(1, readCalls.Count(rc => rc.Key[0].Equals("https://example.com/"))); + var deleteCalls = credentialStore.MethodCalls .Where(mc => mc.Key.Equals("DeleteCredentials")) .SelectMany(mc => mc.Value); @@ -252,13 +261,13 @@ namespace Atlassian.Bitbucket.Authentication.Test // 1 delete calls // 1 for the basic uri with username // DOES NOT delete the Host credentials because they are for a different username. - Assert.AreEqual(1, deleteCalls.Count()); - Assert.AreEqual(1, deleteCalls.Count(rc => rc.Key[0].Equals("https://john@example.com/"))); - Assert.IsFalse(deleteCalls.Any(rc => rc.Key[0].Equals("https://example.com/refresh_token"))); - Assert.IsFalse(deleteCalls.Any(rc => rc.Key[0].Equals("https://example.com/"))); + Assert.Equal(1, deleteCalls.Count()); + Assert.Equal(1, deleteCalls.Count(rc => rc.Key[0].Equals("https://john@example.com/"))); + Assert.False(deleteCalls.Any(rc => rc.Key[0].Equals("https://example.com/refresh_token"))); + Assert.False(deleteCalls.Any(rc => rc.Key[0].Equals("https://example.com/"))); } - [TestMethod] + [Fact] public void VerifyGetPerUserTargetUriInsertsMissingUsernameToActualUri() { var credentialStore = new MockCredentialStore(); @@ -269,21 +278,21 @@ namespace Atlassian.Bitbucket.Authentication.Test var resultUri = targetUri.GetPerUserTargetUri(username); - Assert.AreEqual("/", resultUri.AbsolutePath); - Assert.AreEqual("https://johnsquire@example.com/", resultUri.ActualUri.AbsoluteUri); - Assert.AreEqual("example.com", resultUri.DnsSafeHost); - Assert.AreEqual("example.com", resultUri.Host); - Assert.AreEqual(true, resultUri.IsAbsoluteUri); - Assert.AreEqual(true, resultUri.IsDefaultPort); - Assert.AreEqual(443, resultUri.Port); - Assert.AreEqual(null, resultUri.ProxyUri); - Assert.AreEqual("https://johnsquire@example.com/", resultUri.QueryUri.AbsoluteUri); - Assert.AreEqual("https", resultUri.Scheme); - Assert.AreEqual(new WebProxy().Address, resultUri.WebProxy.Address); - Assert.AreEqual("https://example.com/", resultUri.ToString()); + Assert.Equal("/", resultUri.AbsolutePath); + Assert.Equal("https://johnsquire@example.com/", resultUri.ActualUri.AbsoluteUri); + Assert.Equal("example.com", resultUri.DnsSafeHost); + Assert.Equal("example.com", resultUri.Host); + Assert.Equal(true, resultUri.IsAbsoluteUri); + Assert.Equal(true, resultUri.IsDefaultPort); + Assert.Equal(443, resultUri.Port); + Assert.Equal(null, resultUri.ProxyUri); + Assert.Equal("https://johnsquire@example.com/", resultUri.QueryUri.AbsoluteUri); + Assert.Equal("https", resultUri.Scheme); + Assert.Equal(new WebProxy().Address, resultUri.WebProxy.Address); + Assert.Equal("https://example.com/", resultUri.ToString()); } - [TestMethod] + [Fact] public void VerifyGetPerUserTargetUriDoesNotDuplicateUsernameOnActualUri() { var credentialStore = new MockCredentialStore(); @@ -294,22 +303,22 @@ namespace Atlassian.Bitbucket.Authentication.Test var resultUri = targetUri.GetPerUserTargetUri(username); - Assert.AreEqual("/", resultUri.AbsolutePath); - Assert.AreEqual("https://johnsquire@example.com/", resultUri.ActualUri.AbsoluteUri); - Assert.AreEqual("example.com", resultUri.DnsSafeHost); - Assert.AreEqual("example.com", resultUri.Host); - Assert.AreEqual(true, resultUri.IsAbsoluteUri); - Assert.AreEqual(true, resultUri.IsDefaultPort); - Assert.AreEqual(443, resultUri.Port); - Assert.AreEqual(null, resultUri.ProxyUri); - Assert.AreEqual("https://johnsquire@example.com/", resultUri.QueryUri.AbsoluteUri); - Assert.AreEqual("https", resultUri.Scheme); - Assert.AreEqual(new WebProxy().Address, resultUri.WebProxy.Address); - Assert.AreEqual("https://example.com/", resultUri.ToString()); + Assert.Equal("/", resultUri.AbsolutePath); + Assert.Equal("https://johnsquire@example.com/", resultUri.ActualUri.AbsoluteUri); + Assert.Equal("example.com", resultUri.DnsSafeHost); + Assert.Equal("example.com", resultUri.Host); + Assert.Equal(true, resultUri.IsAbsoluteUri); + Assert.Equal(true, resultUri.IsDefaultPort); + Assert.Equal(443, resultUri.Port); + Assert.Equal(null, resultUri.ProxyUri); + Assert.Equal("https://johnsquire@example.com/", resultUri.QueryUri.AbsoluteUri); + Assert.Equal("https", resultUri.Scheme); + Assert.Equal(new WebProxy().Address, resultUri.WebProxy.Address); + Assert.Equal("https://example.com/", resultUri.ToString()); } } - public class MockCredentialStore: ICredentialStore + public class MockCredentialStore : ICredentialStore { public Dictionary, int>> MethodCalls = new Dictionary, int>>(); @@ -329,20 +338,20 @@ namespace Atlassian.Bitbucket.Authentication.Test public void DeleteCredentials(TargetUri targetUri) { // do nothing - RecordMethodCall("DeleteCredentials", new List() {targetUri.ActualUri.AbsoluteUri }); + RecordMethodCall("DeleteCredentials", new List() { targetUri.ActualUri.AbsoluteUri }); } public Credential ReadCredentials(TargetUri targetUri) { // do nothing - RecordMethodCall("ReadCredentials", new List() {targetUri.ActualUri.AbsoluteUri }); + RecordMethodCall("ReadCredentials", new List() { targetUri.ActualUri.AbsoluteUri }); return Credentials != null && Credentials.Keys.Contains(targetUri.ActualUri.AbsoluteUri) ? Credentials[targetUri.ActualUri.AbsoluteUri] : null; } public void WriteCredentials(TargetUri targetUri, Credential credentials) { // do nothing - RecordMethodCall("WriteCredentials", new List() {targetUri.ActualUri.AbsoluteUri, credentials.Username, credentials.Password }); + RecordMethodCall("WriteCredentials", new List() { targetUri.ActualUri.AbsoluteUri, credentials.Username, credentials.Password }); } private void RecordMethodCall(string methodName, List args) diff --git a/Bitbucket.Authentication.Test/Bitbucket.Authentication.Test.csproj b/Bitbucket.Authentication.Test/Bitbucket.Authentication.Test.csproj index 23bd29e..857fd07 100644 --- a/Bitbucket.Authentication.Test/Bitbucket.Authentication.Test.csproj +++ b/Bitbucket.Authentication.Test/Bitbucket.Authentication.Test.csproj @@ -1,5 +1,6 @@  + Debug @@ -39,19 +40,19 @@ + + ..\packages\xunit.abstractions.2.0.1\lib\net35\xunit.abstractions.dll + + + ..\packages\xunit.assert.2.2.0\lib\netstandard1.1\xunit.assert.dll + + + ..\packages\xunit.extensibility.core.2.2.0\lib\netstandard1.1\xunit.core.dll + + + ..\packages\xunit.extensibility.execution.2.2.0\lib\net452\xunit.execution.desktop.dll + - - - - - - - - - - - - @@ -68,26 +69,12 @@ + + xunit.runner.json + Always + - - - - - False - - - False - - - False - - - False - - - - @@ -95,6 +82,7 @@ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. +