Angular 2 Unit Testing Services with HTTP requests - testing

I am new to testing services with Angular 2 and I am trying to test a service with Http basic requests (Get and GetBYId).
- How works my service? : I have a getAllMyProducts method which consumes a REST Api exposed in a Spring boot Backend application .this web api query the products and return products for the current user.(The http request is sent with headers ).
- What I want to do? : Now I have to test this GetAll method with Jasmine and I am not sure how to do that especially regarding the current user…
My GetAllMethod in my Service:
getAll(): Observable<Product[]> {
return this.baseapiService.getAll('/product/userProducts');
}
my baseapiService that attachs header to the request:
getAll(link){
this.header = this.createHeader();
return this.http.get(this.apiurl+link, this.header)
.map(this.extractData);
}
Any examlpes or suggestions would be great. Thanks in advance

Related

wiremock to mock public backend response

I am testing on an app that is making calls to a public backend.
I want to use wiremock to mock reponses from the public backends.
I was looking at something like
the app makes a request to api.example.com which is forced through the wiremock proxy on localhost:<port>
wiremock matches the URL based on the rules I provide and returns a mock response
The only examples I could find map localhost requests to real backends or mock responses to localhost.
If I'm understanding your question, the app behaves as follows:
App sends request to your backend
Your backend responds with a forwarding request to a public backend
App sends request to public backend
Public backend responds
As far as I'm aware WireMock can only achieve this if you mock out the response from your backend, and have that response's forwarding request point to another mocked out response. WireMock only knows to redirect and proxy when requests are made to WireMock. WireMock does not behave as a man-in-the-middle proxy, listening to all requests made (regardless of url) and selectively returning mocked responses. WireMock only knows to proxy/forward/respond when you hit WireMock directly. So you'd need to have something like...
{
"request" : {
"url" : "/my-backend",
"method": GET
},
"response" : {
"status" : 302,
"headers" : {
"location" : "/public-backend"
}
}
}
Which would return a forwarding request to the /public-backend url. (Depending on what your actual API looks like when it returns that forwarding request, the above response may not be accurate.) And then you'd need to mock out what that request/response mapping looks like
{
"request" : {
"url" : "/public-backend",
"method" : "GET"
},
"response" : {
// response
}
}
Depending on what you are using to run your tests, it is probably better to utilize an existing intercept/proxy functionality that the runner has to listen for requests to certain urls and return a mocked response that way. For example, TestCafe can intercept HTTP requests and return your custom responses. If you went about testing this way, then you'd be able to only have to mock out the response from the public API, and not from your backend as well.

Netflix Zuul 2 API gateway authentication/request validation approach (no Spring)

I would like to put Netflix Zuul 2 (https://github.com/Netflix/zuul) in front of my services and do some authentication/validation of the incoming requests.
Each request that goes through the API gateway, e.g. /api/service1/value would have an auth token and I would like to validate that token before routing the request to the appropriate backend service.
I have several questions and was hoping someone could point me in the right direction.
An inbound filter seems like the right place to put that logic.
At the moment, my understanding is that it could be done like this:
class RequestAuthenticationFilter extends HttpInboundSyncFilter {
#Override
HttpRequestMessage apply(HttpRequestMessage request) {
// extract header with token and call auth service to validate it
if (ifTokenNotValid) {
// returns a 401
request.getContext()
.setEndpoint(UnauthorizedRequestEndpoint.class.getCanonicalName())
}
// continue filter chain
return request
}
}
What I'm not sure about is how to make that call to the auth service and get the response in the inbound filter so that the response can be checked and appropriate action can be taken - either return a 401 or continue routing the /api/service1/value request to a downstream backend service.
Is there a standard approach for making that external call from the inbound filter to a service?
Would I need to import another library with a HttpClient, etc. to achieve this?
Is there a different/better approach to handle this flow?
I understand that for normal routing from an inbound filter to an endpoint a ProxyEndpoint can be used:
inbound filter config:
...
if (path in request matches) {
context.setEndpoint(ZuulEndPointRunner.PROXY_ENDPOINT_FILTER_NAME)
context.setRouteVIP("service1")
}
return request
Either Eureka config:
service1.ribbon.NIWSServerListClassName=com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList
service1.ribbon.DeploymentContextBasedVipAddresses=authservice
or a list of servers configured manually:
service1.ribbon.listOfServers=localhost:8080
service1.ribbon.client.NIWSServerListClassName=com.netflix.loadbalancer.ConfigurationBasedServerList
Is there a way to configure the auth service that way and plug it into the flow, i.e.
request >> validate auth token (auth service request, response) >> continue original request?

SignalR Core JS Client not passing Authorisation headrs on "Upgrade " Request

I Have to implement a push notification service using ASP .Net Core. as obvious choice is to use SignalR Core.
Our platform setup is using Azure App gateway and it is configured to not allow unauthenticated requests.
We have setup WebSockets communication with SignalR.
Under the hood , SignalR Core follows these steps:
POS ../negociate -> OK with hub_token and supported transport
GET (sends Upgrade header and WebSockets token)../Hub?id={hub_token} -? fail
when investigating why the step 2 does not upgrade the connection to a WebSocket connection , I have noticed that the GET request is missing Authorization header. Obviously AG block this request and doesn't even get to the API.
I have tried manually to make a "handshake" with postman.
the above steps :
OK
included Authorization JWT header -> result 101 ,and Fiddler confirm the connection is opened.
I have researched the documentation and found that Authorization headers are not supported.
did anyone tried any workaround ? hen is the next release of the #aspnet/signalr client?
Did you specified the accessTokenFactory?
let connection = new signalR.HubConnectionBuilder()
.withUrl("/myhub", {
accessTokenFactory: () => {
// Get and return the access token.
// This function can return a JavaScript Promise if asynchronous
// logic is required to retrieve the access token.
}
})
.build();
More info here.
so the final resolution is:
that in browsers is a limitation for sending JWT header along with HTTP 101 UPGRADE

Moqui REST API call fail with error code 403

From my Angular 2 application I am trying to get data from Moqui but the request always fails with the error code 403.
Here is the REST API call implementation
getExample() {
let url = 'http://localhost:8080/rest/s1/example/examples'
let headers = new Headers({ 'Authorization': 'Basic
am9obi5kb2U6bW9xdWk='});
headers.append('Accept', 'application/json, text/plain, */*');
headers.append('Content-Type', 'application/json; charset=UTF-8');
let options = new RequestOptions({ headers: headers });
let response = this.http.get(url, options).map(res => res.json());
return response;
}
The Moqui logs :-
REST Access Forbidden (no authz): User null is not authorized for View on REST Path /example/examples
There is also a similar question Moqui Rest Nginx but from the answer I do not know that where I have to change the settings in Moqui.
On the client console the error is :-
XMLHttpRequest cannot load http://localhost:8080/rest/s1/example/examples. Response for preflight has invalid HTTP status code 403
But with a rest client like YARC it works :-
You must authenticate for REST API calls except for Service REST API paths that are configured to not require authentication (like the /mantle/my end points in the mantle.rest.xml file in the mantle-usl component).
You have authentication but then there is one other step: authorization. In general if authc is required then authorization is also required. This is done with database records usually either in seed data and can also be added using the System app that is included in the default Moqui runtime (ie the moqui/moqui-runtime repository).
There is an example of authorization setup for Service REST API calls in the MantleSetupData.xml file. The main difference from screen authorization is that the artifact type to use is 'AT_REST_PATH'. Here is that file on GitHub (right near the top of the file):
https://github.com/moqui/mantle-usl/blob/master/data/MantleSetupData.xml
The best documentation for most things to do with REST requests in Moqui, is currently in the comments in the 'rest.xml' file that actually processes the incoming requests (ie handles the /rest path). You can see this on GitHub here:
https://github.com/moqui/moqui-runtime/blob/master/base-component/webroot/screen/webroot/rest.xml

"transparent" server side proxy for requests to ASP.NET Web API

Have an ASP.NET Web API endpoint that generates JSON responses. But due to two factors can't be consumed directly from a browser.
cross-domain issues
need to provide session ticket for the API that is known only server side
So I need a lightweight server side proxy for client(browser) requests to extend the request with session key. Do not want to impose an overhead deserializing client JSON requests or Web API JSON responses in the proxy code. Would like to pass the payload "as is" and deserialize client requests only Web API side and the Web API responses only client (browser) side. That is the proxy takes json from the browser and passes it directly to Web API. It also passes the JSON response from the Web API to the browser directly without deserialization. Just a dummy proxy that does not know anything about the data it transfers.
Please suggest is it feasible and what is the best way to implement it. The existing web application (the one that is used to generate the client pages) is implemented using ASP.NET MVC 4.
Thanks in advance.
update for 2021:
You should probably be looking at https://microsoft.github.io/reverse-proxy/ if you have found your way here
old answer:
I wrote one for a previous version of WebApi. The code should be fairly easy to update for your purposes.
The basic idea is that you create a WebApi DelegatingHandler that passes the request on to an HttpClient:
public class ForwardProxyMessageHandler : DelegatingHandler
{
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
request.Headers.Add("X-Forwarded-For", request.GetClientIp());
if (request.Method == HttpMethod.Get || request.Method == HttpMethod.Trace) request.Content = null;
request.RequestUri = new Uri(request.RequestUri.ToString().Replace(":3002", "")); //comes through with the port for the proxy, rewrite to port 80
request.Headers.AcceptEncoding.Clear();
var responseMessage = await new HttpClient().SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
responseMessage.Headers.TransferEncodingChunked = null; //throws an error on calls to WebApi results
if (request.Method == HttpMethod.Head) responseMessage.Content = null;
return responseMessage;
}
}