PUT is blocking GET? - node.js

I am trying to intercept a PUT request using nock, but something is going really strange...
My code has 2 calls, a GET request
http://internal-jira.com/rest/api/2/issue/CCC-2142
and a PUT request with payload
http://internal-jira.com/rest/api/2/issue/CCC-2142
{ fields: { reporter: { name: '8778469' } } }
The process is that it does the GET then uses info from there to do the PUT.
So I have also created 2 mock calls, one for the GET
nock('http://internal-jira.com.com', {allowUnmocked: true}).persist()
.get(/\/rest\/api\/2\/issue\/.*/)
.reply(400, (uri) => {
console.log(`!!!! Mocked GET: ${uri} !!!`);
})
and one for the PUT
.put(/\/rest\/api\/2\/issue\/.*/)
.reply(400, (uri) => {
console.log(`!!!! Mocked PUT: ${uri} !!!`);
})
If the GET code is active and I run my code then I can see that the code is being caught as I get the console.log()
!!!! Mocked GET: /rest/api/2/issue/CCC-2144 !!!
But if I comment out the GET and enable the PUT when I run my code, it fails and errors at the GET without it being mocked.
Its as if the PUT mock, is somehow intercepting the GET request (I guess as the URL is the same) but not actually doing anything with it, but also not letting the GET request through?
What am I doing wrong?

Related

Axios in node.js check url before executing code

I dont find anything that works for me so I ask here:
I am trying to get some data from a website with axios. It works great, but if I input the wrong URL I get an error. I want to check if the URL with its complete path to the page I desire exists.
I tried npm package url-exists but it just said the path didn't exist eventho it did.
Is there a simple way to check if a path like for example "https://github.com/enterprise" exists or if it doesn't?
You have to make a request anyway to check if the url exists. So you can handle it when you got 404 status code in catch error block of axios function.
The only way is making the request, you can handle this scenario using a try/catch block
const getSomething = async () => {
try {
const something = await axios.get("www.website.fake")
} catch (err) {
throw new Error(err)
}
}

How to modify a response in Electron

Let's say that I'm using a GET request on https://example.com and the response is this:
This is a response message.
How would I modify it in a way so that in my code, so that it can change the response to say something like this:
This is a MODIFIED response message.
For example, if my Electron app were to navigate to https://example.com, the screen would show me the modified content instead of the original content.
Essentially, I am trying to literally modify the request.
I have based my code off of this question but it only shows a proof of concept with a pre-typed Buffer, as in my situation I'd like modify the response instead of outright replacing it. So, my code looks like this:
protocol.interceptBufferProtocol("http", (req, CALLBACK) => {
if(req.url.includes("special url here")) {
var request = net.request({
method: req.method,
headers: req.headers,
url: req.url
});
request.on("response", (rp) => {
var d = [];
rp.on("data", c => d.push(c));
rp.on("end", () => {
var e = Buffer.concat(d);
console.log(e.toString());
// do SOMETHING with 'e', the response, then callback it.
CALLBACK(e);
});
});
request.end();
} else {
// Is supposedly going to carry out the request without interception
protocol.uninterceptProtocol("http");
}
}
This is supposed to manually request the URL, grab the response and return it. Without the protocol event, it works and gives me a response, but after some debugging, this piece of code consistently calls the same URL over and over with no response.
There is also the WebRequest API, but there is no way of modifying the response body, you can only modify the request headers & related content.
I haven't looked fully into Chromium-based solutions, but after looking at this, I'm not sure if it is possible to modify the response so it appears on my app's end in the first place. Additionally, I'm not familiar with the Chromium/Puppeteer messages that get sent all over the place.
Is there an elegant way to have Electron to get a URL response/request, call the URL using the headers/body/etc., then save & modify the response to appear different in Electron?

Why would my server make a proxy request to the same put function from two different pages and only work on one?

I am getting a proxy error from a PUT action only when its called from a certain page. When I call it from a different page, it works fine.
My code is that doesn't work is:
const startedWorkout = () => {
if (workout?.exercises && selectedWorkout) {
if (selectedWorkout.started && selectedWorkout.completed) {
// restarts workout session
dispatch(toggleWorkoutIncomplete(selectedWorkout));
}
dispatch(startWorkout(selectedWorkout));
dispatch(startExercise(selectedWorkout, workout.exercises));
}
};
When my frontend's URL is http://localhost:8101/workout-started/WKsp5Odze1WuAGm6txWx
All 3 of those functions get the same error:
Proxy error: Could not proxy request /workout/WKsp5Odze1WuAGm6txWx from localhost:8101 to https://us-central1-traineraid-283616.cloudfunctions.net/api.
[react-scripts] See https://nodejs.org/api/errors.html#errors_common_system_errors for more information (ECONNRESET).
This is the request for each of the function calls:
axios.put(`workout/${workoutId}`, newValues)
I call the exact same functions that use the PUT request above from a different URL: http://localhost:8101/workouts/list
and it works fine.
I have never seen an error so specific and I have no idea where to start looking for a backend call that doesn't work on specific frontend URLs.
Let me know if i am missing something obvious. I tried to cut down on the code because it would be a lot of stuff to have to copy here but I can post here at any request for more info.
I solved it myself. It turned out that I was navigating to the next page before the functions could load.
I removed the href from the button and changed the code from the onclick function to:
const startedWorkout = () => {
if (workout?.exercises && selectedWorkout) {
if (selectedWorkout.started && selectedWorkout.completed) {
// restarts workout session
dispatch(toggleWorkoutIncomplete(selectedWorkout));
}
dispatch(startWorkout(selectedWorkout));
dispatch(startExercise(selectedWorkout, workout.exercises));
props.history.push(`/workout-started/${workout?.id}`)
}
};

Axios Get not resolving

I'm trying to make a simple GET request with axios that follows the redirect until network idle, but I can't get the promise to resolve. It seems to work for most urls, but not the below url, specifically - not sure if there's an issue with my code or something peculiar to this one redirect (others of similar format work fine, ie with different mid=XXXX parameters.
A GET request (with no headers or authorization) redirects fine in Postman, but axios won't return anything.
async function axiosGet() {
try {
const response = await axios.get("http://www.awin1.com/awclick.php?mid=4802");
console.log(response);
return response;
} catch (err) {
console.log(err);
}
}
Running this I only get back back my bash prompt with nothing logged. Assigning my axiosGet() function to a variable, and then logging that variable only yields Promise { <pending> }. Just looking to get a resolved promise object, good to go from there.

Mock network requests in Cypress

I've been tearing my hair out over this for ages now - and I hope someone can help me :)
I've been trying to stub a network request in Cypress for ages now.
commands.js
Cypress.Commands.add('login', (
email = 'email',
password = 'pass'
) => {
cy.server();
cy.visit('url');
cy.get('input[name="username"').type(email);
cy.get('form').submit();
cy.get('input[name="password"').type(password);
cy.get('form').submit();
});
mock.js
describe('mock', function() {
it('user can login', function() {
cy.login();
cy.get('main[role="main"]');
cy.route('GET',
'**/getIncentives*',
{info: {}, results: {}}
).as('oppty');
cy.wait('#oppty');
});
});
Chrome dev tools request
Cypress request failed
Any help here would be really appreciated - I've been going crazy!
Thanks so much,
Ollie
Currently, Cypress cy.route can only stub network requests that use XHRs
Native HTML form elements don't use XMLHTTPRequest, hence you cannot use cy.route to stub it.
Most people don't run into this issue because using native HTML forms is not as common nowadays
Edit:
You are also waiting on the route, but haven't actually done anything in your test. Your test should look something like this:
cy.route('GET',
'**/getIncentives*',
{info: {}, results: {}}
).as('oppty');
// cypress code that would cause a network request.
cy.wait('#oppty');
Also, make sure the request is of type:XHR:
Cypress will only find the network request after it's been aliased. The code in your question indicated you're not doing an action that would cause a network request:
cy.route('GET',
'**/getIncentives*',
{info: {}, results: {}}
).as('oppty');
// cypress expected something to cause a network request here
cy.wait('#oppty');
You should either move the call to route earlier in the test, or move the code that causes the request after the call to route.
Also note that cy.route() may not work with server side rendering (apparently).
I've had this problem when using NextJs, and solved it by first calling some other page, then navigate on the client to the page I actually want to test.
Like so:
describe('test cy.route', function() {
it( 'test 1', () => {
cy.server();
cy.route({
method: 'GET',
url: /.*\/api\/someApiCall/,
response: { 'someApiResponse': 'ok' },
status: 200
} ).as('myRouteAlias');
// go to start page: first page is server side rendered. cy.route doesn't work.
cy.visit('/');
// go to page to be tested: client side, cy.route works then.
cy.get( `a[href="/pageToBeTested"` ).should('exist').click();
// wait for page loaded
cy.url().should('include', 'pageToBeTested' );
// do something that requests '/api/someApiCall'.
invokeFunctionThatDoesTheRequest();
// wait for the request
cy.wait('#myRouteAlias');
});
});

Resources