From f92f0b8194d7105cf08ca8f11eea6f25b9f642e7 Mon Sep 17 00:00:00 2001 From: Jan Verhaeghe Date: Mon, 11 Jul 2022 16:12:20 +0200 Subject: [PATCH] [FEAT] add Triage/Maintain permission (#2467) --- ...nseModelSetterlessAutoPropertyException.cs | 22 ++++++++++++++ Octokit.Tests.Conventions/ModelTests.cs | 29 ++++++++++++++++++- .../Models/Response/RepositoryPermissions.cs | 27 +++++++++++++---- 3 files changed, 71 insertions(+), 7 deletions(-) create mode 100644 Octokit.Tests.Conventions/Exception/ResponseModelSetterlessAutoPropertyException.cs diff --git a/Octokit.Tests.Conventions/Exception/ResponseModelSetterlessAutoPropertyException.cs b/Octokit.Tests.Conventions/Exception/ResponseModelSetterlessAutoPropertyException.cs new file mode 100644 index 00000000..4fe22e43 --- /dev/null +++ b/Octokit.Tests.Conventions/Exception/ResponseModelSetterlessAutoPropertyException.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; + +namespace Octokit.Tests.Conventions +{ + public class ResponseModelSetterlessAutoPropertyException : Exception + { + public ResponseModelSetterlessAutoPropertyException(Type modelType, IEnumerable setterlessProperties) + : base(CreateMessage(modelType, setterlessProperties)) + { } + + static string CreateMessage(Type modelType, IEnumerable setterlessProperties) + { + return string.Format("Model type '{0}' contains the following setterless properties: {1}{2}", + modelType.FullName, + Environment.NewLine, + string.Join(Environment.NewLine, setterlessProperties.Select(x => x.Name))); + } + } +} \ No newline at end of file diff --git a/Octokit.Tests.Conventions/ModelTests.cs b/Octokit.Tests.Conventions/ModelTests.cs index e6b19e9d..6b7c66c9 100644 --- a/Octokit.Tests.Conventions/ModelTests.cs +++ b/Octokit.Tests.Conventions/ModelTests.cs @@ -90,7 +90,7 @@ namespace Octokit.Tests.Conventions [Theory] [MemberData(nameof(ResponseModelTypes))] - public void ResponseModelsHaveGetterOnlyProperties(Type modelType) + public void ResponseModelsHaveNoPublicSettableProperties(Type modelType) { var mutableProperties = new List(); @@ -112,6 +112,33 @@ namespace Octokit.Tests.Conventions } } + [Theory] + [MemberData(nameof(ResponseModelTypes))] + public void ResponseModelsHaveNoSetterlessAutoPropertiesForReflection(Type modelType) + { + var setterlessAutoProperties = new List(); + + foreach (var property in modelType.GetProperties()) + { + var propertyHasNoSetter = property.GetSetMethod(true) is null; + if (IsAutoProperty(property) && propertyHasNoSetter) + { + setterlessAutoProperties.Add(property); + } + } + + if (setterlessAutoProperties.Any()) + { + throw new ResponseModelSetterlessAutoPropertyException(modelType, setterlessAutoProperties); + } + } + + private bool IsAutoProperty(PropertyInfo prop) + { + return prop.DeclaringType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance) + .Any(f => f.Name.Contains("<" + prop.Name + ">")); + } + [Theory] [MemberData(nameof(ResponseModelTypes))] public void ResponseModelsHaveReadOnlyCollections(Type modelType) diff --git a/Octokit/Models/Response/RepositoryPermissions.cs b/Octokit/Models/Response/RepositoryPermissions.cs index 41c1ec81..6e43cbd2 100644 --- a/Octokit/Models/Response/RepositoryPermissions.cs +++ b/Octokit/Models/Response/RepositoryPermissions.cs @@ -1,5 +1,5 @@ using System.Diagnostics; -using System.Globalization; +using System; namespace Octokit { @@ -8,31 +8,46 @@ namespace Octokit { public RepositoryPermissions() { } - public RepositoryPermissions(bool admin, bool push, bool pull) + public RepositoryPermissions(bool admin, bool maintain, bool push, bool triage, bool pull) { Admin = admin; + Maintain = maintain; Push = push; + Triage = triage; Pull = pull; } /// /// Whether the current user has administrative permissions /// - public bool Admin { get; protected set; } + public bool Admin { get; private set;} + + /// + /// Whether the current user has maintain permissions + /// + public bool Maintain { get; private set;} /// /// Whether the current user has push permissions /// - public bool Push { get; protected set; } + public bool Push { get; private set;} + + /// + /// Whether the current user has triage permissions + /// + public bool Triage { get; private set;} /// /// Whether the current user has pull permissions /// - public bool Pull { get; protected set; } + public bool Pull { get; private set;} internal string DebuggerDisplay { - get { return string.Format(CultureInfo.InvariantCulture, "Admin: {0}, Push: {1}, Pull: {2}", Admin, Push, Pull); } + get + { + return FormattableString.Invariant($"Admin: {Admin}, Maintain: {Maintain}, Push: {Push}, Triage: {Triage}, Pull: {Pull}"); + } } } }