-
Notifications
You must be signed in to change notification settings - Fork 34
fix issues with Void return type due to rxjs map operator null checks #236
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -132,7 +132,7 @@ public T invoke(NextcloudAPI nextcloudAPI, Object[] args) throws Exception { | |
| rBuilder.setUrl(url.replace(varName, String.valueOf(args[i]))); | ||
| } else if(annotation instanceof Header) { | ||
| Object value = args[i]; | ||
| String key =((Header) annotation).value(); | ||
| String key = ((Header) annotation).value(); | ||
| addHeader(rBuilder, key, value); | ||
| } else if(annotation instanceof FieldMap) { | ||
| if(args[i] != null) { | ||
|
|
@@ -188,13 +188,13 @@ public T invoke(NextcloudAPI nextcloudAPI, Object[] args) throws Exception { | |
| } | ||
| //fallback | ||
| return (T) nextcloudAPI.performRequestObservableV2(typeArgument, request).map(r -> r.getResponse()); | ||
|
|
||
| } else if(ownerType == Call.class) { | ||
| Type typeArgument = type.getActualTypeArguments()[0]; | ||
| return (T) Retrofit2Helper.WrapInCall(nextcloudAPI, request, typeArgument); | ||
| } | ||
| } else if(this.returnType == Observable.class) { | ||
| return (T) nextcloudAPI.performRequestObservableV2(Object.class, request).map(r -> r.getResponse()); | ||
| // Observables without any type information (see above for Observables with type info) | ||
| return (T) nextcloudAPI.performRequestObservableV2(Void.class, request).map(r -> r.getResponse()); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. here we go, here is the |
||
| } else if (this.returnType == Completable.class) { | ||
| return (T) ReactivexHelper.wrapInCompletable(nextcloudAPI, request); | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -36,7 +36,6 @@ | |
| import static org.mockito.Mockito.lenient; | ||
| import static org.mockito.Mockito.mock; | ||
| import static org.mockito.Mockito.verify; | ||
| import static org.mockito.Mockito.when; | ||
|
|
||
| public class TestRetrofitAPI { | ||
|
|
||
|
|
@@ -64,6 +63,16 @@ public void setUp() { | |
| mApi = new NextcloudRetrofitApiBuilder(nextcloudApiMock, mApiEndpoint).create(API.class); | ||
| } | ||
|
|
||
| @Test | ||
| public void callWithNoReturnType() throws Exception { | ||
| mApi.callWithNoReturnType(); | ||
| NextcloudRequest request = new NextcloudRequest.Builder() | ||
| .setMethod("GET") | ||
| .setUrl(mApiEndpoint + "callWithNoReturnType") | ||
| .build(); | ||
| verify(nextcloudApiMock).performRequestV2(eq(retrofit2.Call.class), eq(request)); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Doesn't this just verify the call is made? The problem is returning the async result, so I'm not sure if this a viable test... Does this test break if you bring the
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, that is indeed a problem. The data is coming from a mock and therefore the observable always returns an empty observable. If we want to add more checks I think we'd have to add dummy objects for all types.. right?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think a mocked test isn't the way to go here, at least we are mocking the wrong objects here... The mock would need to be much deeper, somewhere at the NC Files app interface I guess. We need a mock which instantly triggers the callbacks to see, if anything dies in this chain, but I didn't dig in this far yet. I'll have a look!
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree, the tests here are mostly to check that the type and url was extracted correctly and that the interface was called. However return types are not considered. Thank you for looking into it! |
||
| } | ||
|
|
||
| @Test | ||
| public void getRequest() { | ||
| mApi.getRequest(); | ||
|
|
@@ -74,6 +83,36 @@ public void getRequest() { | |
| verify(nextcloudApiMock).performRequestObservableV2(eq(String.class), eq(request)); | ||
| } | ||
|
|
||
| @Test | ||
| public void getListWithNoType() { | ||
| mApi.getListWithNoType(); | ||
| NextcloudRequest request = new NextcloudRequest.Builder() | ||
| .setMethod("GET") | ||
| .setUrl(mApiEndpoint + "getListWithNoType") | ||
| .build(); | ||
| verify(nextcloudApiMock).performRequestObservableV2(eq(List.class), eq(request)); | ||
| } | ||
|
|
||
| @Test | ||
| public void getWithNoReturnType() { | ||
| mApi.getWithNoReturnType(); | ||
| NextcloudRequest request = new NextcloudRequest.Builder() | ||
| .setMethod("GET") | ||
| .setUrl(mApiEndpoint + "getWithNoReturnType") | ||
| .build(); | ||
| verify(nextcloudApiMock).performRequestObservableV2(eq(Void.class), eq(request)); | ||
| } | ||
|
|
||
| @Test | ||
| public void getWithVoidReturnType() { | ||
| mApi.getWithVoidReturnType(); | ||
| NextcloudRequest request = new NextcloudRequest.Builder() | ||
| .setMethod("GET") | ||
| .setUrl(mApiEndpoint + "getWithVoidReturnType") | ||
| .build(); | ||
| verify(nextcloudApiMock).performRequestObservableV2(eq(Void.class), eq(request)); | ||
| } | ||
|
|
||
| @Test | ||
| public void getFolders() { | ||
| mApi.getFolders(); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a safe
ClassCastException, since we are casting the result... Correct me if I'm wrong, but i think you cast theObjectsomewhere toVoid, because I definitely don't. I used to get, what I defined I want to get, so the casting is done SSO-Internally, see comment below...There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ugh.. me being naive while thinking that I could just throw in some typescript-style code 🤷♂️ 😅 I think you might be right about the casting thing. However it would be interesting to see if it actually fails 🙈
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to be curious here, i mean look: you have a check above, if the target entity ( =
T) is NOT aVoid. Then, inelsethe first thing you do is casting anew Object()toT( =Void). One thing I can tell you for sure:Object.class != Void.class. Game over. Thats why I was going forNOTHING, since this is at least semi-safe, as long as the caller specifies a return type. Otherwise the worst thing that could happen is, when the return type is specified, but the server doesn't return anything (=null), then we would get the error from the mapper.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm yes, I get that point. I think I'm also good with the nothing option then. However I'm just thinking about other case. So if you specify
Listwithout a type, it'll be interpreted asVoidas well, right? But what if I'm too lazy as a programmer to write the type but I still want to somehow receive my response object..? Maybe I'm overthinking it a little here..There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope, would be a
List<Object>you could cast, if your're brave enough to guess the actual type. Would work in this case. The problem with your solution is only the void type, which is broken here. So we're back at the beginning of our problem 🤣. I'll have another look at it, maybe this weekend and see what I can do about this.