forked from JetBrains/YouTrackSharp
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
https://github.com/JetBrains/YouTrackSharp/issues/40
- Loading branch information
1 parent
711e181
commit c113e41
Showing
9 changed files
with
442 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
using System; | ||
using System.Net.Http; | ||
using Newtonsoft.Json; | ||
|
||
namespace YouTrackSharp.Projects | ||
{ | ||
/// <summary> | ||
/// Custom field for a project | ||
/// </summary> | ||
public class CustomField | ||
{ | ||
/// <summary> | ||
/// Creates an instance of the <see cref="CustomField" /> class. | ||
/// </summary> | ||
public CustomField() | ||
{ | ||
Name = string.Empty; | ||
Url = string.Empty; | ||
Type = string.Empty; | ||
CanBeEmpty = false; | ||
EmptyText= string.Empty; | ||
} | ||
|
||
/// <summary> | ||
/// Name of project custom field. | ||
/// </summary> | ||
[JsonProperty("name")] | ||
public string Name { get; set; } | ||
|
||
/// <summary> | ||
/// The Url of the custom field. | ||
/// </summary> | ||
[JsonProperty("url")] | ||
public string Url { get; set; } | ||
|
||
/// <summary> | ||
/// Type of this custom field. | ||
/// </summary> | ||
[JsonProperty("type")] | ||
public string Type { get; set; } | ||
|
||
/// <summary> | ||
/// Mandatory binary parameter defining if the field can have empty value or not. | ||
/// </summary> | ||
[JsonProperty("canBeEmpty")] | ||
public bool CanBeEmpty { get; set; } | ||
|
||
/// <summary> | ||
/// Text that is shown when the custom field has no value. | ||
/// </summary> | ||
[JsonProperty("emptyText")] | ||
public string EmptyText { get;set; } | ||
|
||
// param Additional parameter of custom field. For example, a bundle that is attached with custom field. | ||
} | ||
} |
150 changes: 150 additions & 0 deletions
150
src/YouTrackSharp/Projects/ProjectCustomFieldsService.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Net; | ||
using System.Net.Http; | ||
using System.Net.Http.Headers; | ||
using System.Threading.Tasks; | ||
using Newtonsoft.Json; | ||
using Newtonsoft.Json.Linq; | ||
using YouTrackSharp.Management; | ||
|
||
namespace YouTrackSharp.Projects | ||
{ | ||
/// <summary> | ||
/// A class that represents a REST API client for <a href="https://www.jetbrains.com/help/youtrack/standalone/Project-Custom-Fields.html"> methods related to operations with custom fields of a project</a>. | ||
/// It uses a <see cref="Connection" /> implementation to connect to the remote YouTrack server instance. | ||
/// </summary> | ||
public class ProjectCustomFieldsService | ||
{ | ||
private readonly Connection _connection; | ||
|
||
/// <summary> | ||
/// Creates an instance of the <see cref="ProjectCustomFieldsService" /> class. | ||
/// </summary> | ||
/// <param name="connection">A <see cref="Connection" /> instance that provides a connection to the remote YouTrack server instance.</param> | ||
public ProjectCustomFieldsService(Connection connection) | ||
{ | ||
_connection = connection ?? throw new ArgumentNullException(nameof(connection)); | ||
} | ||
|
||
/// <summary> | ||
/// Get custom fields used in a project. | ||
/// </summary> | ||
/// <remarks>Uses the REST API <a href="https://www.jetbrains.com/help/youtrack/standalone/GET-Project-Custom-Fields.html">Get Project Custom Fields</a>.</remarks> | ||
/// <param name="projectId">Id of the project to get the custom fields for.</param> | ||
/// <returns>A <see cref="T:System.Collections.Generic.ICollection`1" /> of <see cref="CustomField" /> that are accessible for currently logged in user.</returns> | ||
/// <exception cref="T:System.Net.HttpRequestException">When the call to the remote YouTrack server instance failed.</exception> | ||
public async Task<ICollection<CustomField>> GetProjectCustomFields(string projectId) | ||
{ | ||
var client = await _connection.GetAuthenticatedHttpClient(); | ||
var response = await client.GetAsync($"rest/admin/project/{projectId}/customfield"); | ||
|
||
response.EnsureSuccessStatusCode(); | ||
|
||
return JsonConvert.DeserializeObject<ICollection<CustomField>>(await response.Content.ReadAsStringAsync()); | ||
} | ||
|
||
/// <summary> | ||
/// Get a project's custom field by its name. | ||
/// </summary> | ||
/// <remarks>Uses the REST API <a href="https://www.jetbrains.com/help/youtrack/standalone/GET-Project-Custom-Field.html">Get Project Custom Field</a>.</remarks> | ||
/// <param name="projectId">Id of the project to get the custom field for.</param> | ||
/// <param name="customFieldName">Name of the custom field to get.</param> | ||
/// <returns><see cref="CustomField" />.</returns> | ||
/// <exception cref="T:System.Net.HttpRequestException">When the call to the remote YouTrack server instance failed.</exception> | ||
public async Task<CustomField> GetProjectCustomField(string projectId, string customFieldName) | ||
{ | ||
var client = await _connection.GetAuthenticatedHttpClient(); | ||
var response = await client.GetAsync($"rest/admin/project/{projectId}/customfield/{customFieldName}"); | ||
|
||
response.EnsureSuccessStatusCode(); | ||
|
||
return JsonConvert.DeserializeObject<CustomField>(await response.Content.ReadAsStringAsync()); | ||
} | ||
|
||
/// <summary> | ||
/// Remove specified custom field from a project. | ||
/// </summary> | ||
/// <remarks>Uses the REST API <a href="https://www.jetbrains.com/help/youtrack/standalone/DELETE-Project-Custom-Field.html">Delete a project custom field</a>.</remarks> | ||
/// <param name="projectId">Id of the project to delete the custom field for.</param> | ||
/// <param name="customFieldName">Name of the custom field to delete.</param> | ||
/// <exception cref="T:System.ArgumentNullException">When the <paramref name="projectId"/> is null or empty.</exception> | ||
/// <exception cref="T:System.ArgumentNullException">When the <paramref name="customFieldName"/> is null or empty.</exception> | ||
/// <exception cref="T:System.Net.HttpRequestException">When the call to the remote YouTrack server instance failed.</exception> | ||
public async Task DeleteProjectCustomField(string projectId, string customFieldName) | ||
{ | ||
if (string.IsNullOrEmpty(projectId)) | ||
{ | ||
throw new ArgumentNullException(nameof(projectId)); | ||
} | ||
|
||
var client = await _connection.GetAuthenticatedHttpClient(); | ||
var response = await client.DeleteAsync($"rest/admin/project/{projectId}/customfield/{customFieldName}"); | ||
|
||
if (response.StatusCode == HttpStatusCode.NotFound) | ||
{ | ||
return; | ||
} | ||
|
||
response.EnsureSuccessStatusCode(); | ||
} | ||
|
||
/// <summary> | ||
/// Adds a custom field to a specific project. | ||
/// </summary> | ||
/// <remarks>Uses the REST API <a href="https://www.jetbrains.com/help/youtrack/standalone/PUT-Project-Custom-Field.html">Create a project custom field</a>.</remarks> | ||
/// <param name="projectId">Id of the project to add a custom field.</param> | ||
/// <param name="customField"><see cref="CustomField" /> to add to the project.</param> | ||
/// <exception cref="T:System.ArgumentNullException">When the <paramref name="projectId"/> is null or empty.</exception> | ||
/// <exception cref="T:System.ArgumentNullException">When the <paramref name="customField"/> is null or empty.</exception> | ||
/// <exception cref="T:YouTrackErrorException">When the call to the remote YouTrack server instance failed and YouTrack reported an error message.</exception> | ||
/// <exception cref="T:System.Net.HttpRequestException">When the call to the remote YouTrack server instance failed.</exception> | ||
public async Task CreateProjectCustomField(string projectId, CustomField customField) | ||
{ | ||
var queryString = new Dictionary<string, string>(); | ||
if (string.IsNullOrEmpty(customField?.Name)) | ||
{ | ||
throw new ArgumentNullException(nameof(customField)); | ||
} | ||
|
||
if (!string.IsNullOrEmpty(customField.EmptyText)) | ||
{ | ||
queryString.Add("emptyFieldText", WebUtility.UrlEncode(customField.EmptyText)); | ||
} | ||
|
||
var client = await _connection.GetAuthenticatedHttpClient(); | ||
var response = await client.PutAsync($"rest/admin/project/{projectId}/customfield/{customField.Name}?emptyFieldText=leer", new MultipartContent()); //, new FormUrlEncodedContent(queryString)); | ||
|
||
response.EnsureSuccessStatusCode(); | ||
} | ||
|
||
/// <summary> | ||
/// Updates a custom field to a specific project. | ||
/// </summary> | ||
/// <remarks>Uses the REST API <a href="https://www.jetbrains.com/help/youtrack/standalone/POST-Project-Custom-Field.html">Updates a project custom field</a>.</remarks> | ||
/// <param name="projectId">Id of the project.</param> | ||
/// <param name="customField"><see cref="CustomField" /> to update in project.</param> | ||
/// <exception cref="T:System.ArgumentNullException">When the <paramref name="projectId"/> is null or empty.</exception> | ||
/// <exception cref="T:System.ArgumentNullException">When the <paramref name="customField"/> is null or empty.</exception> | ||
/// <exception cref="T:YouTrackErrorException">When the call to the remote YouTrack server instance failed and YouTrack reported an error message.</exception> | ||
/// <exception cref="T:System.Net.HttpRequestException">When the call to the remote YouTrack server instance failed.</exception> | ||
public async Task UpdateProjectCustomField(string projectId, CustomField customField) | ||
{ | ||
var queryString = new Dictionary<string, string>(); | ||
if (string.IsNullOrEmpty(customField?.Name)) | ||
{ | ||
throw new ArgumentNullException(nameof(customField)); | ||
} | ||
|
||
if (!string.IsNullOrEmpty(customField.EmptyText)) | ||
{ | ||
queryString.Add("emptyFieldText", WebUtility.UrlEncode(customField.EmptyText)); | ||
} | ||
|
||
var client = await _connection.GetAuthenticatedHttpClient(); | ||
var response = await client.PostAsync($"rest/admin/project/{projectId}/customfield/{customField.Name}", new FormUrlEncodedContent(queryString)); | ||
|
||
response.EnsureSuccessStatusCode(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
47 changes: 47 additions & 0 deletions
47
tests/YouTrackSharp.Tests/Integration/Projects/CreateProjectCustomField.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
using System; | ||
using System.Linq; | ||
using System.Threading.Tasks; | ||
using Xunit; | ||
using YouTrackSharp.Projects; | ||
using YouTrackSharp.Tests.Infrastructure; | ||
|
||
namespace YouTrackSharp.Tests.Integration.Projects | ||
{ | ||
public partial class ProjectCustomFieldsServiceTests | ||
{ | ||
public class CreateProjectCustomField | ||
{ | ||
[Fact] | ||
public async Task Valid_Connection_Creates_CustomField_For_Project() | ||
{ | ||
// Arrange | ||
var connection = Connections.Demo1Token; | ||
var service = connection.ProjectCustomFieldsService(); | ||
|
||
var customField = new CustomField() {Name = "TestField", EmptyText = "empty"}; | ||
|
||
// Act | ||
await service.CreateProjectCustomField("DP1", customField); | ||
|
||
//var created = await service.GetProjectCustomField("DP1", customField.Name); | ||
|
||
//// Assert | ||
//Assert.NotNull(created); | ||
|
||
//Assert.Equal(customField.Name, created.Name); | ||
//Assert.Equal(customField.EmptyText, created.EmptyText); | ||
} | ||
|
||
[Fact] | ||
public async Task Invalid_Connection_Throws_UnauthorizedConnectionException() | ||
{ | ||
// Arrange | ||
var service = Connections.UnauthorizedConnection.ProjectCustomFieldsService(); | ||
|
||
// Act & Assert | ||
await Assert.ThrowsAsync<UnauthorizedConnectionException>( | ||
async () => await service.GetProjectCustomField("DP1", "TestField")); | ||
} | ||
} | ||
} | ||
} |
40 changes: 40 additions & 0 deletions
40
tests/YouTrackSharp.Tests/Integration/Projects/DeleteProjectCustomField.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
using System; | ||
using System.Linq; | ||
using System.Threading.Tasks; | ||
using Xunit; | ||
using YouTrackSharp.Tests.Infrastructure; | ||
|
||
namespace YouTrackSharp.Tests.Integration.Projects | ||
{ | ||
public partial class ProjectCustomFieldsServiceTests | ||
{ | ||
public class DeleteProjectCustomField | ||
{ | ||
[Fact] | ||
public async Task Valid_Connection_Deletes_CustomField_For_Project() | ||
{ | ||
// Arrange | ||
var connection = Connections.Demo1Token; | ||
var service = connection.ProjectCustomFieldsService(); | ||
|
||
// Act & Assert | ||
var acted = false; | ||
await service.DeleteProjectCustomField("DP1", " TestField"); | ||
acted = true; | ||
|
||
Assert.True(acted); | ||
} | ||
|
||
[Fact] | ||
public async Task Invalid_Connection_Throws_UnauthorizedConnectionException() | ||
{ | ||
// Arrange | ||
var service = Connections.UnauthorizedConnection.ProjectCustomFieldsService(); | ||
|
||
// Act & Assert | ||
await Assert.ThrowsAsync<UnauthorizedConnectionException>( | ||
async () => await service.DeleteProjectCustomField("DP1", "TestField")); | ||
} | ||
} | ||
} | ||
} |
45 changes: 45 additions & 0 deletions
45
tests/YouTrackSharp.Tests/Integration/Projects/GetProjectCustomField.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
using System; | ||
using System.Linq; | ||
using System.Threading.Tasks; | ||
using Xunit; | ||
using YouTrackSharp.Tests.Infrastructure; | ||
|
||
namespace YouTrackSharp.Tests.Integration.Projects | ||
{ | ||
public partial class ProjectCustomFieldsServiceTests | ||
{ | ||
public class GetProjectCustomField | ||
{ | ||
[Fact] | ||
public async Task Valid_Connection_Gets_CustomFields_For_Project() | ||
{ | ||
// Arrange | ||
var connection = Connections.Demo1Token; | ||
var service = connection.ProjectCustomFieldsService(); | ||
|
||
// Act | ||
var result = await service.GetProjectCustomField("DP1", "Assignee"); | ||
|
||
// Assert | ||
Assert.NotNull(result); | ||
|
||
Assert.Equal("Assignee", result.Name); | ||
Assert.Equal(string.Empty, result.Url); | ||
Assert.Equal("user[1]", result.Type); | ||
Assert.True(result.CanBeEmpty); | ||
Assert.Equal("Unassigned", result.EmptyText); | ||
} | ||
|
||
[Fact] | ||
public async Task Invalid_Connection_Throws_UnauthorizedConnectionException() | ||
{ | ||
// Arrange | ||
var service = Connections.UnauthorizedConnection.ProjectCustomFieldsService(); | ||
|
||
// Act & Assert | ||
await Assert.ThrowsAsync<UnauthorizedConnectionException>( | ||
async () => await service.GetProjectCustomField("DP1", "Assignee")); | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.