I am making a handler library named handle_http.js:
module.exports.redirectHttpToHttps = (db,req,res)=>{
const sql = "SELECT * from redirect where use_in_http = 1 and exact_match = 1 and url_from = ? and exact_match=1 LIMIT 1";
// redirection logic
}
And I made a http server where consumes the library:
const http = require('node:http');
// A simple database connection generator
const db = require('./db.js');
const handler = require('./handle_http.js');
http.createServer((req,res){
handler.redirectHttpToHttps(db,req,res);
});
http.listen(80);
But before running into an actual code, I want to make some unit tests using jest (test_redirect.jest.js):
const db = require('../src/db.js');
const redirect = require('../src/handle_http.js');
test("redirect to https",()=>{
const dbHandler = db(':memory:');
database.exec(`
INSERT INTO redirect (url_from,url_to,method,http_status_code,use_in_http,exact_match) VALUES
('http://google.com/mytest','http://yahoo.com','GET',301,1,1),
('http://google.com/mytest2','http://yandex.com','GET',302,1,0),
('http://google.com?q=ikariam','http://yandex.com','GET',302,1,1),
('http://example.com/products','https://fakestoreapi.com/products','POST',308,1,1),
('http://example.net/products','https://fakestoreapi.com/products','POST',308,1,0),
('http://example.net','https://fakestoreapi.com/products','POST',308,1,0);
`,function(error){ err_callback(error); });
// need to make fake request so I can call the `redirectHttpToHttps`
redirect.redirectHttpToHttps(db,/*mocked_request*/,/*some way to assert the response*/)
});
As you can see, I am able to populate an in-memory database with fake data, but I do not know how:
How I can make a fake an incoming http request.
How I can assert that http response has appropriate status code and headers
The provided example does not cut in my case because I need to test the http handling logic in my own http server written in nodejs.
An approach is to use the supertest and create an http server on the fly:
const http = require('node:http');
const request = require('supertest');
const db = require('../src/db.js');
const redirect = require('../src/handle_http.js');
test("redirect to https",(done)=>{
const dbHandler = db(':memory:');
database.exec(`
INSERT INTO redirect (url_from,url_to,method,http_status_code,use_in_http,exact_match) VALUES
('http://google.com/mytest','http://yahoo.com','GET',301,1,1),
('http://google.com/mytest2','http://yandex.com','GET',302,1,0),
('http://google.com?q=ikariam','http://yandex.com','GET',302,1,1),
('http://example.com/products','https://fakestoreapi.com/products','POST',308,1,1),
('http://example.net/products','https://fakestoreapi.com/products','POST',308,1,0),
('http://example.net','https://fakestoreapi.com/products','POST',308,1,0);
`,function(error){ done(error); });
const server = http.createServer((req,res)=>{
redirect.redirectHttpToHttps(dbHandler,req,res)
});
request(server)
.get('/mytest')
.set('Host','google.com')
.expect(301,done);
});
Pay attention into the lines:
request(server)
.get('/mytest')
.set('Host','google.com')
.expect(301,done);
Using request function comming from supertest I provide a server instance that does not listen to any port:
const server = http.createServer((req,res)=>{
redirect.redirectHttpToHttps(dbHandler,req,res)
});
During testing, you can avoid the https at all and create pure non-ssl servers that call the http handling function you want to perform.
Miscelanous
Also, your code has an error at section:
database.exec(`
INSERT INTO redirect (url_from,url_to,method,http_status_code,use_in_http,exact_match) VALUES
('http://google.com/mytest','http://yahoo.com','GET',301,1,1),
('http://google.com/mytest2','http://yandex.com','GET',302,1,0),
('http://google.com?q=ikariam','http://yandex.com','GET',302,1,1),
('http://example.com/products','https://fakestoreapi.com/products','POST',308,1,1),
('http://example.net/products','https://fakestoreapi.com/products','POST',308,1,0),
('http://example.net','https://fakestoreapi.com/products','POST',308,1,0);
`,function(error){ err_callback(error); });
Function err_callback is not defined. Therfore I used the jest's done function as defined into documentation
So the refactored part of the test is:
database.exec(`
INSERT INTO redirect (url_from,url_to,method,http_status_code,use_in_http,exact_match) VALUES
('http://google.com/mytest','http://yahoo.com','GET',301,1,1),
('http://google.com/mytest2','http://yandex.com','GET',302,1,0),
('http://google.com?q=ikariam','http://yandex.com','GET',302,1,1),
('http://example.com/products','https://fakestoreapi.com/products','POST',308,1,1),
('http://example.net/products','https://fakestoreapi.com/products','POST',308,1,0),
('http://example.net','https://fakestoreapi.com/products','POST',308,1,0);
`,function(error){ done(error); });
I need to send GET request username=alison&date=2021 to file file.phpand send requests every 200 ms if I don't get one of two possible responses "yes" or "no", resend request needed to get right answer no blank and not error.
If get "yes" "no" do functions.
when receiving responses, perform different actions
function after receiving yes
function after receiving no
I'm not 100% sure what you're asking for here, but here is my method based on my own interpretation of your question using a call from GitHub's API. We are using fetch to pull the data. Our .then is our resolve, and our .catch is our reject.
const url = 'https://api.github.com/users'
const callApi = function(fetchUrl){
fetchUrl = url
fetch(fetchUrl)
.then(response=>{
return response.json(); // Turn data to JSON
})
.then(data=>{ // If it was successful, this below will run
console.log(data) // Do whatever you want with the data from the API here
})
.catch(err=>{ // If it was unsuccessful, this below will run
console.log(err); // Console log the error
setTimeout(callApi(url), 200); //If it failed, try again in 200ms
})
}
callApi(url) // Initial function call
Some things to note: If you're using an API that limits the number of calls you can make in a day/month, this will eat up through those allotted requests really quickly.
Is it possible to make two backend requests at once from react?
The code below is the first backend call. The post request gets send to the backend and then I would like to do another request. Is it possible at all? Or do I have to wait for the backend response until the next request could be made?
What I basically want is to get information about how many files have been uploaded. The upload could take 3 minutes and the user right now only sees a loading icon. I want to additionally add a text like "50 of 800 Literatures uploaded" and 10 seconds later "100 of 800 litereratures uploaded".
This is basically my code :
class ProjectLiterature extends Component {
constructor(props) {
super(props);
this.state = {
isLoading:"false",
}
}
addLiterature(data, project_name) {
this.setState({ isLoading:true }, () => {
axios.post("http://127.0.0.1:5000/sendLiterature", data })
.then(res => {
this.setState({ isLoading: false })
})
})
}
If both requests do not depend on each other, you can make use of JavaScript's Promise.all() for the above purpose.
const request1 = axios.get('http://127.0.0.1:5000/sendLiterature');
const request2 = axios.get(url2);
Promise.all([request1,request2]).then([res1, res2] => {
// handle the rest
}).catch((error) => {
console.error(error);
// carry out error handling
});
If the second request relies on the response of the first request, you will have to wait for the first request to be completed as both requests have to be carried out in sequence.
const res = await axios.get('http://127.0.0.1:5000/sendLiterature');
// carry out the rest
You can see axios docs for this purpose, they support multiple requests out of box.
You can use Promise.all instead of axios.all as well but if one of requests fails then you won't be able to get response of successful calls. If you want get successful response even though some calls fails then you can use Promise.allSettled.