Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#1107 Do no set default visibility and affiliation values to avoid mixing with type #1132

Merged

Conversation

AlexP11223
Copy link
Contributor

An attempt to fix mixing of visibility/affiliation and type described in #1107.

@AlexP11223 AlexP11223 changed the title #1107 Do no set visibility and affiliation value to avoid mixing with type #1107 Do no set default visibility and affiliation values to avoid mixing with type Mar 7, 2016
@M-Zuber
Copy link
Contributor

M-Zuber commented Mar 7, 2016

LGTM, but I would say there should be a check/manual set to default for the type parameter if either visibility or affiliation are set.
just my 2¢

@ryangribble
Copy link
Contributor

With this change, won't there still be an issue if you set a non Default value for visibility or affiliation, since the Type property still has a value specified that will cause a parameter item to be sent through?

So you'd either have to add your ParameterValue("")Default option to Type as well or perhaps another approach is to make the enum properties on RepositoryRequest be nullable, that way when they arent specified they wont set anything in the parameter array?

eg

public class RepositoryRequest : RequestParameters
{
    public RepositoryType? Type { get; set; }
    public RepositorySort? Sort { get; set; }
    public SortDirection? Direction { get; set; }
    public RepositoryVisibility? Visibility { get; set; }
    public RepositoryAffiliation? Affiliation { get; set; }
}

Whichever way it's done, I agree with @M-Zuber it would be useful to check the RepositoryRequest in GetAllForCurrent() and throw an error if "invalid" combination is specified by the consumer
eg:

if ((request.Visibility != null || request.Affiliation != null) && request.Type != null)
{
    throw new ArgumentException("If you specify Visibility or Affiliation, you cannot specify Type.");
}

Perhaps @shiftkey can advise between the preference of adding a Default enum element (that has a blank property value causing nothing to be specified) vs allowing nullable properties?

Also when I'm adding functionality to Octokit, I always try to add tests as well, so that from now on we can assert that this problem never re-appears down the track.

In this case I would add unit tests to cover:

  • RepositoryRequest - when null (in my example) or .Default (in your example) is specified for each property, that corresponding parameter name does not appear in the parameter dictionary created by request.ToParametersDictionary()
  • RepositoriesClient.GetAllForCurrent() throws the expected exception when incorrect combination of flags is provided

@shiftkey
Copy link
Member

shiftkey commented Mar 8, 2016

Perhaps @shiftkey can advise between the preference of adding a Default enum element (that has a blank property value causing nothing to be specified) vs allowing nullable properties?

I'd rather these be optional parameters as that's the precedence we have for handling values that may be set. And as per the docs, there's documented default behaviour here for all these values if they're not set:

screen shot 2016-03-08 at 5 40 35 pm

I have some concerns that I should have raised earlier. Consider this scenario:

var request = new RepositoryRequest
{
   Visibility = RepositoryVisibility.Public,
   Type = RepositoryType.Owner
};

This is a valid object to create, however it will fail during the request. Do we guard against that, or just bubble up the exception to the user? There's an escape hatch we have to override RequestParameters.ToParametersDictionary and verify that a valid set of parameters are provided - and throw otherwise.

Anyway, 👍 to throwing more unit tests into this area - RequestParameters is very important, and I'd hate to introduce something unexpected here.

@AlexP11223
Copy link
Contributor Author

I made the properties nullable instead of Default enum parameters and added unit tests for RepositoryRequest ToParamatersDictionary.

@@ -49,6 +49,9 @@ static List<PropertyParameter> GetPropertyParametersForType(Type type)
Justification = "GitHub API depends on lower case strings")]
static Func<PropertyInfo, object, string> GetValueFunc(Type propertyType)
{
// get underlying type if nullable
propertyType = Nullable.GetUnderlyingType(propertyType) ?? propertyType;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this line necessary? The parameter array was still created correctly for me, even without this line...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without this line it does not go into if (propertyType.IsEnumeration()) and somehow produces "All" instead of "all" + does not use [Parameter] attribute.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah fair enough, I must admit I just quickly put the nullable properties on the request object and ran the existing integration tests which passed... From what you're saying we might need more tests since the current ones didn't pick up the problem you highlighted... oops, obviously I don't have your new test which looks like it covers those scenarios 😀

@ryangribble
Copy link
Contributor

Nice work on the parameter array unit test :)

While we're here I wonder if we should tweak the DebuggerDisplay() on RepositoryRequest since it doesnt list the Affiliation or Visibility properties plus it outputs field names for the other fields that can now be blank?

@AlexP11223
Copy link
Contributor Author

Yeah, I was thinking about DebuggerDisplay too yesterday.:)

For null values, shoud we output something like Visibility: <null> or remove the property from the output?

@ryangribble
Copy link
Contributor

For null values, shoud we output something like Visibility: or remove the property from the output?

I think the way you've done it is good (if the values are null, don't mention them at all).

LGTM - I'll just wait for a +1 from @shiftkey before merging

@shiftkey shiftkey self-assigned this Mar 9, 2016
@shiftkey
Copy link
Member

Looks good to me! Thanks @AlexP11223!

And thanks @M-Zuber @ryangribble for helping out with the review!

shiftkey added a commit that referenced this pull request Mar 10, 2016
…lation-mix-1107

#1107 Do no set default visibility and affiliation values to avoid mixing with type
@shiftkey shiftkey merged commit ca025b9 into octokit:master Mar 10, 2016
@ryangribble ryangribble mentioned this pull request Mar 16, 2016
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants