I'm working on a project which uses middy and we have a custom middleware set up to validate auth tokens sent with Auth0. As part of this Auth0 makes an external request. I've been using Nock to mock these requests. What I'm finding is that if I test a function that is not wrapped in middy(), Nock works as expected and intercepts the request. However, if I try to test the function wrapped in middy() ( e.g. to ensure that all middlewares are being applied correctly ) then it fails. I've set up a very very basic example here. It just tests two functions, exactly the same, one wrapped and one not wrapped. Notice how as soon as the function is wrapped, something happens which causes Nock to not apply the interceptor correctly. I'm not sure if this is an issue with middy or Nock. I opened an issue with middy but have so far heard nothing.
Any help is greatly appreciated!
I'm not sure if this is your core issue or just in your example repo, but the reason your test fails in your repo is because you only tell Nock to mock one request and then make two separate attempts.
I can got the tests to pass by adding a call to persist, or twice, or skipping the first test, or creating a whole other Nock Interceptor.
READ THIS! - About interceptors
When you setup an interceptor for a URL and that interceptor is used, it is removed from the interceptor list. This means that you can intercept 2 or more calls to the same URL and return different things on each of them. It also means that you must setup one interceptor for each request you are going to have, otherwise nock will throw an error because that URL was not present in the interceptor list. If you don’t want interceptors to be removed as they are used, you can use the .persist() method.
If that doesn't solve a deeper problem for you, and you're having issues trying to determine why Nock is not matching a request, I recommend using the debug option.
Related
I have two Vuex actions that both issue an axios request. I need to call one after the other, however, the second should only be called on the client side.
The first one, let's call it fetchContent is going to give me an object with details about the content that I need to fetch. The second one, fetchAd is going to fetch an ad, and it needs to know the id of the content object.
Due to various constraints, the ad should only be fetched on the client side, so just doing two awaits inside fetch will not.
I also thought about handling fetchContent inside fetch and then calling fetchAd inside mounted, but then I can't be sure by the time the page is mounted I actually have the response from fetchContent.
Another scenario I thought of is to just issue the fetchAd call from inside fetchContent, but there are several different variations of fetchContent and embedding fetchAd in every one of them would yield unnecessary complexity.
What's a clean, best-practice solution here?
I have recently implemented Serilog logging into my ASP.NET Core/.NET5 web app that uses SignalR. I'm using the Elasticsearch sink and everything is largely working as expected. I decided to add some additional HttpContext properties to be logged on each request, so I went down the road of extending the call to UseSerilogRequestLogging() in StartUp.cs as to enrich the diagnostic context with a couple of extra properties (mainly because this seemed like the simplest way to do it):
app.UseSerilogRequestLogging(options =>
{
options.EnrichDiagnosticContext = (diagnosticContext, httpContext) =>
{
diagnosticContext.Set("HttpRequestClientIP", httpContext.Connection.RemoteIpAddress);
diagnosticContext.Set("UserName", httpContext.User?.Identity?.Name == null ? "(anonymous)" : httpContext.User.Identity.Name);
};
});
At first, this seemed to work as expected until I noticed it wasn't always working. I really want the extra properties logged on all log records written, and it seems to work fine on log records that are written automatically by Serilog when typical HTTP GETs, HTTP POSTs, etc. occur... But in my Signalr Hub class, I have a couple of places where I'm manually writing my own log records like Logger.Log(LogLevel.Information, "whatever.."), but these extra properties are simply not there on these records.
What am I missing here? Is it something about this being in a Signalr Hub that makes them unavailable? Or perhaps there's something I'm doing wrong with my Logger.Log() calls?
Any ideas would be appreciated.
Thanks-
It's not gonna to work with signalR.
Behind the screen, app.UseSerilogRequestLogging make use of a middleware in the request pipeline, that call RequestLoggingMiddleware as what you can see in detail here.
SignalR use the first Http request to setting to connection up to websocket, which won't goes through the pipeline at all. Therefore, doesn't have anything to do with RequestLoggingMiddleware, which you are using to logging out the request.
I finally ended up going with a couple of custom Enrichers. I did experiment briefly with middleware vs enrichers and they both seem to work as expected. Both always added the additional properties to all log entries. I'm still not quite sure I understand why the DiagnosticContext option behaves the way it does, unless it is simply due to the logging in question being in a SignalR hub as #Gordon Khanh Ng. posted. If that were the root of the problem though, you wouldn't think the enrichers or middleware would work either.
I've been trying to make use of service.getNavigation() method, but apparently the Request URI is too long which causes this error:
Request-URI Too Long
The requested URL's length exceeds the capacity limit for this server.
Is there a spartacus config that can resolve this issue?
Or is this supposed to be handled in the cloud (ccv2) config?
Not sure which service are you talking about specifically and what data are you passing there. For starters, please read this: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/414
Additionally it would benefit everyone if you could say something about the service you're using and the data you are trying to pass/get.
The navigation component is firing a request for all componentIds. If you have a navigation with a lot of (root?) elements, the maximum length of HTTP GET request might be too long for the given client or server.
The initial implementation of loading components was actually done by a POST request, but the impression was that we would not need to support requests with so many components. I guess we were wrong.
Luckily, the legacy POST based request is still in the code base, it's OccCmsComponentAdapter.findComponentsByIdsLegacy.
The easiest way for you to use this code, is to provide a CustomOccCmsComponentAdapter, that extends from OccCmsComponentAdapter. Then you can override the findComponentsByIds method and simply call the super.findComponentsByIdsLegacy and pass in a copy of the arguments.
A more cleaner way would be to override the CmsComponentConnector and directly delegate the load to the adapter.findComponentsByIdsLegacy. I would not start here, as it's more complicated. Do a POC with the first suggested approach.
I've researched and found three different possibilities to solving my case: I'd like to make an async API call (using dotenv variables to store the credentials) and commit the returned data to Vuex on app init --keeping the creds secure.
Currently I'm attempting using serverMiddleware, but I'm having trouble accessing the context. Is this possible? Currently just getting a "store is not defined" error.
Also, after researching, I keep seeing that it's not a good idea to use regular middleware, as running any code on the client-side exposes the env variable... But I'm confused. Doesn't if (!process.client) { ... } take care of this? Or am I missing the bigger picture.
Additionally, if it does turn out to be okay to use middleware to secure the credentials, would using the separate-env-module be wise to make doubly sure that nothing gets leaked client-side?
Thanks, I'm looking forward to understanding this more thoroughly.
You can use serverMiddleware.
You can do it like this:
client -> call serverMiddleware -> servermiddleware calls API.
that way API key is not in client but remains on the server.
Example:
remote api is: https://maps.google.com/api/something
your api: https://awesome.herokuapp.com
since your own api has access to environment variables and you don't want the api key to be included in the generated client-side build, you create a serverMiddleware that will proxy the request for you.
So that in the end, your client will just make a call to https://awesome.herokuapp.com/api/maps, but that endpoint will just call https://maps.google.com/api/something?apikey=123456 and return the response back to you
A header (Authorizathion) I set in the one scenario still exists when second scenario is ran.
I've looked through the documentation http://docs.behat.org/en/v3.0/ but I could find anything about my problem there.
Why is that ?
Use #insulated feature tag, this will start a clean browser for each scenario.
If this is not the issue use a method in #BeforeScenario hook where you can call reset/restart session methods.