Skip to content

Commit

Permalink
adding support to Create and Delete tags. Issue #22
Browse files Browse the repository at this point in the history
  • Loading branch information
jlouros committed Jul 25, 2016
1 parent 9c0410d commit 3581425
Show file tree
Hide file tree
Showing 5 changed files with 191 additions and 5 deletions.
17 changes: 17 additions & 0 deletions src/Atlassian.Stash/Api/Repositories.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ public class Repositories
private const string MANY_REPOSITORIES = "rest/api/1.0/projects/{0}/repos";
private const string ONE_REPOSITORY = "rest/api/1.0/projects/{0}/repos/{1}";
private const string MANY_TAGS = "rest/api/1.0/projects/{0}/repos/{1}/tags";
private const string ONE_TAG = "rest/git/1.0/projects/{0}/repos/{1}/tags/{2}";
private const string MANY_FILES = "rest/api/1.0/projects/{0}/repos/{1}/files";
private const string ONE_FILE = "rest/api/1.0/projects/{0}/repos/{1}/browse/{2}";
private const string MANY_HOOKS = "rest/api/1.0/projects/{0}/repos/{1}/settings/hooks";
Expand Down Expand Up @@ -104,6 +105,22 @@ public async Task<ResponseWrapper<Tag>> GetTags(string projectKey, string reposi
return response;
}

public async Task<Tag> CreateTag(string projectKey, string repositorySlug, Tag tag)
{
string requestUrl = UrlBuilder.FormatRestApiUrl(MANY_TAGS, null, projectKey, repositorySlug);

Tag response = await _httpWorker.PostAsync<Tag>(requestUrl, tag, true).ConfigureAwait(false);

return response;
}

public async Task DeleteTag(string projectKey, string repositorySlug, string tagName)
{
string requestUrl = UrlBuilder.FormatRestApiUrl(ONE_TAG, null, projectKey, repositorySlug, tagName);

await _httpWorker.DeleteAsync(requestUrl).ConfigureAwait(false);
}

public async Task<ResponseWrapper<string>> GetFiles(string projectKey, string repositorySlug, RequestOptions requestOptions = null)
{
string requestUrl = UrlBuilder.FormatRestApiUrl(MANY_FILES, requestOptions, projectKey, repositorySlug);
Expand Down
58 changes: 57 additions & 1 deletion src/Atlassian.Stash/Entities/Tag.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@

using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System;

namespace Atlassian.Stash.Entities
{
public class Tag
Expand All @@ -7,5 +10,58 @@ public class Tag
public string DisplayId { get; set; }
public string LatestChangeset { get; set; }
public string Hash { get; set; }

// used for "create"
[JsonProperty("force")]
public bool Force { get; set; }
[JsonProperty("message")]
public string Message { get; set; }
[JsonProperty("name")]
public string Name { get; set; }

/// <summary>
/// Either a <see cref="Commit.Id"/> or a <see cref="Branch.Id"/>
/// </summary>
[JsonProperty("startPoint")]
public string StartPoint { get; set; }

[JsonProperty("type", NullValueHandling = NullValueHandling.Ignore)]
[JsonConverter(typeof(TagTypeEnumConverter))]
public TagType? Type { get; set; } // 'LIGHTWEIGHT' or 'ANNOTATED'
}

public enum TagType
{
Unknown,
LIGHTWEIGHT,
ANNOTATED
}

/// <summary>
/// Handles 'Unknown' and 'nulls' convertions of <see cref="TagType"/>
/// </summary>
public class TagTypeEnumConverter : StringEnumConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value.Equals(TagType.Unknown))
{
value = null;
}

base.WriteJson(writer, value, serializer);
}

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.Value == null ||
(!(reader?.Value?.ToString()).Equals(TagType.ANNOTATED.ToString(), StringComparison.OrdinalIgnoreCase) &&
!(reader?.Value?.ToString()).Equals(TagType.LIGHTWEIGHT.ToString(), StringComparison.OrdinalIgnoreCase)))
{
return null;
}

return base.ReadJson(reader, objectType, existingValue, serializer);
}
}
}
10 changes: 8 additions & 2 deletions src/Atlassian.Stash/Workers/HttpCommunicationWorker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,16 @@ public async Task<string> GetAsync(string requestUrl)
}
}

public async Task<T> PostAsync<T>(string requestUrl, T data)
public async Task<T> PostAsync<T>(string requestUrl, T data, bool ignoreNullFields = false)
{
string strData = JsonConvert.SerializeObject(data, new JsonSerializerSettings
{
NullValueHandling = ignoreNullFields ? NullValueHandling.Ignore : NullValueHandling.Include
});
HttpContent contentToPost = new StringContent(strData, Encoding.UTF8, "application/json");

using (HttpClient httpClient = CreateHttpClient())
using (HttpResponseMessage httpResponse = await httpClient.PostAsync<T>(requestUrl, data, new JsonMediaTypeFormatter()).ConfigureAwait(false))
using (HttpResponseMessage httpResponse = await httpClient.PostAsync(requestUrl, contentToPost))
{
if (httpResponse.StatusCode != HttpStatusCode.Created && httpResponse.StatusCode != HttpStatusCode.OK && httpResponse.StatusCode != HttpStatusCode.NoContent)
{
Expand Down
14 changes: 12 additions & 2 deletions test/Atlassian.Stash.IntegrationTests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Modify 'App.config' with your local configuration settings.
## Setting up Integrations to run locally

* Local running instance at 'http://localhost:7990/'
* (do not use TestUser as an Admin user)
* Create a new user account using the following credentials 'TestUser':'password'
* Go to global permissions and add 'Administrator' access to 'TestUser' (need to revisit this)
* Create a new group named 'TestGroup'
Expand All @@ -27,6 +28,11 @@ Modify 'App.config' with your local configuration settings.
* make another change in 'test.txt'; commit and push this change to the server (you should have 2 branches now)
* create a pull request from the new branch targeting master

(to fix)
- master needs 2 commits
- initial script set branch permissions
- create a admin user, do not use TestUser as admin


REM script.bat! Trying to automate the steps described above with in a batch script

Expand All @@ -45,12 +51,16 @@ Modify 'App.config' with your local configuration settings.
git tag -a TestTag -m "my test tag"
git push origin --tags

echo.more text>>test.txt
git add --all
git commit -m "small change"

git branch develop
git checkout develop

echo.more text>>test.txt
echo.even more text>>test.txt
git add --all
git commit -m "small change"
git commit -m "develop change"
git push --set-upstream origin develop


Expand Down
97 changes: 97 additions & 0 deletions test/Atlassian.Stash.IntegrationTests/StashClientTester.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Atlassian.Stash.Entities;
using Atlassian.Stash.Helpers;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
Expand Down Expand Up @@ -118,6 +119,39 @@ public async Task Can_GetAllTags_WithRequestOptions()
Assert.AreEqual(requestLimit, tags.Count());
}

[TestMethod]
public async Task Can_Create_And_Delete_Tags()
{
var initialResponse = await stashClient.Repositories.GetTags(EXISTING_PROJECT, EXISTING_REPOSITORY);
int initialTagCount = initialResponse.Values.Count();

// create tag
Tag createTag = new Tag
{
Force = true,
Name = "integration-test-tag",
Message = "integration test tag",
StartPoint = "refs/heads/master",
Type = TagType.ANNOTATED
};
var createResponse = await stashClient.Repositories.CreateTag(EXISTING_PROJECT, EXISTING_REPOSITORY, createTag);

// mid-step get tags again
var midResponse = await stashClient.Repositories.GetTags(EXISTING_PROJECT, EXISTING_REPOSITORY);
int midTagCount = midResponse.Values.Count();
Assert.AreEqual(initialTagCount + 1, midTagCount);
Assert.IsTrue(midResponse.Values.Any(x => x.Id.Contains(createTag.Name)));

// delete tag
await stashClient.Repositories.DeleteTag(EXISTING_PROJECT, EXISTING_REPOSITORY, createTag.Name);

// final check to ensure the tag count didn't change
var finalResponse = await stashClient.Repositories.GetTags(EXISTING_PROJECT, EXISTING_REPOSITORY);
int finalTagCount = initialResponse.Values.Count();

Assert.AreEqual(initialTagCount, finalTagCount);
}

[TestMethod]
public async Task Can_GetAllFiles()
{
Expand Down Expand Up @@ -286,6 +320,69 @@ public async Task Can_GetChangesUntil_And_Since_MoreThanOneResult()
Assert.AreEqual(EXISTING_NUMBER_OF_CHANGES, changes.ListOfChanges.Count());
}

[TestMethod]
public async Task Can_GetCommitsUntil()
{
var commits = await stashClient.Commits.GetCommits(EXISTING_PROJECT, EXISTING_REPOSITORY, EXISTING_COMMIT);

Assert.IsNotNull(commits);
Assert.IsInstanceOfType(commits, typeof(ResponseWrapper<Commit>));
Assert.IsTrue(commits.Values.Count() > 1);
Assert.IsTrue(commits.Values.Any(x => x.Id.Equals(EXISTING_COMMIT, StringComparison.OrdinalIgnoreCase)));
}

[TestMethod]
public async Task Can_GetCommitsUntil_WithRequestOptions()
{
int requestLimit = 1;
var commits = await stashClient.Commits.GetCommits(EXISTING_PROJECT, EXISTING_REPOSITORY, EXISTING_COMMIT, null, new RequestOptions { Limit = requestLimit });

Assert.IsNotNull(commits);
Assert.IsInstanceOfType(commits, typeof(ResponseWrapper<Commit>));
Assert.IsTrue(commits.Values.Count() > 0);
Assert.IsTrue(commits.Values.Any(x => x.Id.Equals(EXISTING_COMMIT, StringComparison.OrdinalIgnoreCase)));
}

[TestMethod]
public async Task Can_GetCommitsUntil_And_Since()
{
var commits = await stashClient.Commits.GetCommits(EXISTING_PROJECT, EXISTING_REPOSITORY, EXISTING_COMMIT, EXISTING_OLDER_COMMIT);

Assert.IsNotNull(commits);
Assert.IsInstanceOfType(commits, typeof(ResponseWrapper<Commit>));
Assert.IsTrue(commits.Values.Count() > 0);
Assert.IsTrue(commits.Values.Any(x => x.Id.Equals(EXISTING_COMMIT, StringComparison.OrdinalIgnoreCase)));
// excluside call (excludes 'since' commit)
Assert.IsFalse(commits.Values.Any(x => x.Id.Equals(EXISTING_OLDER_COMMIT, StringComparison.OrdinalIgnoreCase)));
}

[TestMethod]
public async Task Can_GetCommitsUntil_And_Since_WithRequestOptions()
{
int requestLimit = 1;
var commits = await stashClient.Commits.GetCommits(EXISTING_PROJECT, EXISTING_REPOSITORY, EXISTING_COMMIT, EXISTING_OLDER_COMMIT, new RequestOptions { Limit = requestLimit });

Assert.IsNotNull(commits);
Assert.IsInstanceOfType(commits, typeof(ResponseWrapper<Commit>));
Assert.IsTrue(commits.Values.Count() > 0);
Assert.IsTrue(commits.Values.Any(x => x.Id.Equals(EXISTING_COMMIT, StringComparison.OrdinalIgnoreCase)));
// excluside call (excludes 'since' commit)
Assert.IsFalse(commits.Values.Any(x => x.Id.Equals(EXISTING_OLDER_COMMIT, StringComparison.OrdinalIgnoreCase)));
}

[TestMethod]
public async Task Can_GetCommitsUntil_And_Since_MoreThanOneResult()
{
var commits = await stashClient.Commits.GetCommits(EXISTING_PROJECT, EXISTING_REPOSITORY, EXISTING_COMMIT, EXISTING_OLDER_COMMIT);

Assert.IsNotNull(commits);
Assert.IsInstanceOfType(commits, typeof(ResponseWrapper<Commit>));
Assert.IsTrue(commits.Values.Count() > 0);
Assert.IsTrue(commits.Values.Any(x => x.Id.Equals(EXISTING_COMMIT, StringComparison.OrdinalIgnoreCase)));
// excluside call (excludes 'since' commit)
Assert.IsFalse(commits.Values.Any(x => x.Id.Equals(EXISTING_OLDER_COMMIT, StringComparison.OrdinalIgnoreCase)));
}

[TestMethod]
public async Task Can_GetRepository_Hooks()
{
Expand Down

0 comments on commit 3581425

Please sign in to comment.