Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using Microsoft.TeamFoundation.SourceControl.WebApi;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using MigrationTools.Tools;

namespace MigrationTools.Tests.Tools
{
[TestClass()]
public class TfsGitRepositoryInfoTests
{
/// <summary>
/// Helper method to create a mock ExternalLink using reflection to avoid complex TFS object model setup
/// </summary>
private ExternalLink CreateMockExternalLink(string uri)
{
// Create a mock RegisteredLinkType using reflection
var linkTypeConstructor = typeof(RegisteredLinkType).GetConstructor(
BindingFlags.NonPublic | BindingFlags.Instance,
null,
new Type[] { typeof(string), typeof(string) },
null);

var linkType = (RegisteredLinkType)linkTypeConstructor.Invoke(new object[] { "MockLinkType", "Mock Link Type" });

// Create ExternalLink using the mock link type
return new ExternalLink(linkType, uri);
}

[TestMethod(), TestCategory("L0")]
public void CreateFromGit_ValidLinkWithThreeParts_ShouldSucceed()
{
// Arrange
var validLink = "vstfs:///Git/Commit/25f94570-e3e7-4b79-ad19-4b434787fd5a%2f50477259-3058-4dff-ba4c-e8c179ec5327%2f41dd2754058348d72a6417c0615c2543b9b55535";
var externalLink = CreateMockExternalLink(validLink);
var possibleRepos = new List<GitRepository>
{
new GitRepository { Id = Guid.Parse("50477259-3058-4dff-ba4c-e8c179ec5327") }
};

// Act
var result = TfsGitRepositoryInfo.CreateFromGit(externalLink, possibleRepos);

// Assert
Assert.IsNotNull(result);
Assert.AreEqual("50477259-3058-4dff-ba4c-e8c179ec5327", result.RepoID);
Assert.AreEqual("41dd2754058348d72a6417c0615c2543b9b55535", result.CommitID);
}

[TestMethod(), TestCategory("L0")]
public void CreateFromGit_ValidLinkWithMultipleCommitParts_ShouldSucceed()
{
// Arrange
var validLink = "vstfs:///Git/Commit/25f94570-e3e7-4b79-ad19-4b434787fd5a%2f50477259-3058-4dff-ba4c-e8c179ec5327%2f41dd2754058348d72a6417c0615c2543b9b55535%2fextra%2fparts";
var externalLink = CreateMockExternalLink(validLink);
var possibleRepos = new List<GitRepository>
{
new GitRepository { Id = Guid.Parse("50477259-3058-4dff-ba4c-e8c179ec5327") }
};

// Act
var result = TfsGitRepositoryInfo.CreateFromGit(externalLink, possibleRepos);

// Assert
Assert.IsNotNull(result);
Assert.AreEqual("50477259-3058-4dff-ba4c-e8c179ec5327", result.RepoID);
Assert.AreEqual("41dd2754058348d72a6417c0615c2543b9b55535%2fextra%2fparts", result.CommitID);
}

[TestMethod(), TestCategory("L0")]
public void CreateFromGit_InvalidLinkWithOnePart_ShouldReturnNull()
{
// Arrange
var invalidLink = "vstfs:///Git/Commit/25f94570-e3e7-4b79-ad19-4b434787fd5a";
var externalLink = CreateMockExternalLink(invalidLink);
var possibleRepos = new List<GitRepository>();

// Act
var result = TfsGitRepositoryInfo.CreateFromGit(externalLink, possibleRepos);

// Assert
Assert.IsNull(result);
}

[TestMethod(), TestCategory("L0")]
public void CreateFromGit_InvalidLinkWithTwoParts_ShouldReturnNull()
{
// Arrange
var invalidLink = "vstfs:///Git/Commit/25f94570-e3e7-4b79-ad19-4b434787fd5a%2f50477259-3058-4dff-ba4c-e8c179ec5327";
var externalLink = CreateMockExternalLink(invalidLink);
var possibleRepos = new List<GitRepository>();

// Act
var result = TfsGitRepositoryInfo.CreateFromGit(externalLink, possibleRepos);

// Assert
Assert.IsNull(result);
}

[TestMethod(), TestCategory("L0")]
public void CreateFromGit_EmptyLink_ShouldReturnNull()
{
// Arrange
var emptyLink = "vstfs:///Git/Commit/";
var externalLink = CreateMockExternalLink(emptyLink);
var possibleRepos = new List<GitRepository>();

// Act
var result = TfsGitRepositoryInfo.CreateFromGit(externalLink, possibleRepos);

// Assert
Assert.IsNull(result);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -94,18 +94,20 @@ public static TfsGitRepositoryInfo CreateFromGit(ExternalLink gitExternalLink, I
//vstfs:///Git/Commit/25f94570-e3e7-4b79-ad19-4b434787fd5a%2f50477259-3058-4dff-ba4c-e8c179ec5327%2f41dd2754058348d72a6417c0615c2543b9b55535
string guidbits = gitExternalLink.LinkedArtifactUri.Substring(gitExternalLink.LinkedArtifactUri.LastIndexOf('/') + 1);
string[] bits = Regex.Split(guidbits, "%2f", RegexOptions.IgnoreCase);
repoID = bits[1];
if (bits.Count() >= 3)

// Validate that we have at least 3 parts (projectId, repoId, commitId)
// This ensures bits[0], bits[1], and bits[2] are all accessible
if (bits.Length < 3)
{
commitID = $"{bits[2]}";
for (int i = 3; i < bits.Count(); i++)
{
commitID += $"%2f{bits[i]}";
}
Log.Warning("GitRepositoryInfo: Invalid Git external link format. Expected at least 3 parts separated by %2f, but got {count} parts. Link: {link}", bits.Length, gitExternalLink.LinkedArtifactUri);
return null;
}
else

repoID = bits[1]; // Safe to access after length validation
commitID = $"{bits[2]}"; // Safe to access after length validation
for (int i = 3; i < bits.Count(); i++)
{
commitID = bits[2];
commitID += $"%2f{bits[i]}";
}
gitRepo =
(from g in possibleRepos where string.Equals(g.Id.ToString(), repoID, StringComparison.OrdinalIgnoreCase) select g)
Expand Down
Loading