How to write test driven programming in node.js? - javascript

Recently I got introduced to node.js and packages like express, mongodb and ejs. I have few questions :
As a learning purpose, I have created a github repo of user management which uses express, mongodb and ejs. I have all my functions in routes/users.js file. I need to write test cases all these functions. How to create a test driven programming with this example?
In my routes in app.js file.
app.get('/login', user.login);
app.post('/login', user.loginSubmit);
I need to write different routes to login page renders and submit etc. If there are some ajax request also, then we have lots of routes in app.js file when considering to routes of a single page. Is it like that or need to change my structure?

I recommend you Mocha, it's from the same guy of expressjs.
It supports test coverage for you code, hooks before, after, each and of course it supports async code.
I use it in combination with should.js or even chai.js
A test in mocha looks like, the code is from my own test where I'm using superagent, in order to make requests.
it('requests a permission with valid ticket', function (done){
agent
.post(route.server + '/preq')
.set('Content-Type', 'application/json')
.set('Authorization', 'Bearer ' + ACCESSTOKEN)
.send({ticket: TICKET})
.end(function (req,res) {
res.should.have.property('statusCode').that.equals(201);
var location = .....
res.headers.should.have.property('location').that.is.equal(location);
done();
});
})

Related

Using MySQL with Javascript (node.js)

I've just started learning Node.js. I come from a PHP background, so I started with MySQL.
So, I wanted to try executing some basic MySQL queries using javaScript.I write the queries, this way:
filename: test.js
var mysql = require('mysql');
var con = mysql.createConnection({
host: "localhost",
user: "root",
password: "",
database: "test",
});
con.connect(err => {
if (err) throw err;
console.log("Connected!");
const q = "INSERT INTO testing VALUES(3, 'MILLENNIAL', 19, 'STUDENT', 'CSE')";
con.query(q, (err, result) => {
if (err) throw err;
console.log("done");
});
});
When I run the only the javascript file this way: node test.js the query gets executed but when I connect the same file to a html file, this way:
<script src="test.js"></script>
the query doesn't get executed... It gives an error in console: Uncaught ReferenceError: require is not defined
I have feeling that I am not using something very important here. Am I missing something?? Please help me go further.
I am so sorry if this is very silly but, please help me with this. Thank you in advance.
node.js is javascript runtime which uses javascript syntax, which is meant for server-side language. What you trying is to use nodejs script in frontend. require is not defined - because its applicable only for node, to use other modules in plain javascript you will need to use cdn or packages like browserify, webpack. Checkout docs if you are interested.
I will try to explain from a PHP perspective.
When you write PHP, usually your resulting file is an HTML and you embed your PHP code in it, so it renders out without PHP to the requesting browser.
In node, this is different. We don't write the HTML with node code embedded. Node focuses more on backend and frontend separation. You write your backend to reply to your front end.
The backend is where you type var mysql = require('mysql');
You can use something like express vs koa to serve the resulting query to the front end.
Here's a good tutorial to start https://geshan.com.np/blog/2020/11/nodejs-mysql-tutorial/
I usually recommend Koa because it's up updated more regularly now, but express is basically the same thing!
Hope this directs you in the right direction.

ReactJS and NodeJS same server?

I build a project with nodejs and react. I don't know if I must split in 2 servers, one for the react app and one for API in nodejs and the react app ask request at nodejs server.
Or I must group both in only one nodejs process ? What's the difference ? There are a better choice ?
It's up to you React when builded is just static files, don't get confused by the development server. I would recommend you for the beginning to put them in one node process. Just declare the folder of the static files like this:
app.use('/app', express.static(path.join(__dirname + '/dist/app')));
Also if you are using React Router you should add this as your last router
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname + '/src/index.html'));
});
You can check my template repo with webpack here

Setting up Express with Angular

I can setup Angular in my web app using ASP/Visual Studio rather easily, but I want to get into the Node world, more specifically Express. I'm not truly understanding a basic route handler for Express, that will support the paradigms that Angular has.
For example, when setting up an Express file, there's a million examples, but almost all of them use Jade for templating, and I'm against Jade's syntax and have no desire to utilize it.
So far, I have this for my Express server (I have commented out some questions regarding my decisions made so far):
var express = require('express'),
path = require('path');
var app = express();
var env = process.env.NODE_ENV || 'development';
// 1) Is this really necessary if I'm going to utilize Angular routing for views?
app.set('views', path.join(__dirname, '/app/views'));
app.use(express.static(__dirname + '/public'));
// 2) I'm assuming this is the desired pattern for utilizing Angular.
// A catch-all handler that serves up an html file, which will then
// hand off the rest of the routing to Angular?
app.get('*', function(req, res) {
res.sendFile(path.join(__dirname + '/public/index.html'));
});
const PORT = 3000;
app.listen(PORT);
console.log('Listening on port: ' + PORT);
The questions I have are:
Is app.set('views', ...) necessary in an Angular app through Express or is it really intended for a Jade/EJS templating workflow? If it's useful to Angular, what path should I point it to? My Angular views? Or just the static html file that will serve as the container to all angular views?
I'm assuming app.use(express.static(...)) is still needed for ensuring Express can serve up public static resources, like css/javascript.
Is an app.get('*', ...) { res.sendFile('path/to/index.html') } route handler the accepted pattern for serving up one html file, which will contain all necessary Angular usage?
For Angular, is it normal to only have one html file for the entire of your application, and then just use Angular's routing and controllers/views to handle the rest?
Is app.set('views', ...) necessary in an Angular app through Express or is it really intended for a Jade/EJS templating workflow? If it's useful to Angular, what path should I point it to? My Angular views? Or just the static html file that will serve as the container to all angular views?
If you need to render a view on the server side and then send it to the client, you need this. Otherwise (in your case) no. You can just send the file to the user or generate a user-specific output based on the parameters that user has sent to the server. It could be anything, HTML file, json or just simple text.
I'm assuming app.use(express.static(...)) is still needed for ensuring Express can serve up public static resources, like css/javascript.
You are right. If you need to serve the static content as well, the best way is to use express.static, however you can catch the requests and serve the content by yourself.
Is an app.get('*', ...) { res.sendFile('path/to/index.html') } route handler the accepted pattern for serving up one html file, which will contain all necessary Angular usage?
If for each and every other requests that the previous routes didn't catch, you need to send the exact same file, yes it is fine.
Remember if you need to serve other HTML files as templates and they are not in the same directory as you pointed in express.static to, the client could not have access to html files. I'll discuss it in a bit.
However, I believe it is a good practice to define all the routes and not just put a * to catch them all. It is better to define a pattern at least, it would be easier to maintain the code later on.
For Angular, is it normal to only have one html file for the entirety of your application, and then just use Angular's routing and controllers/views to handle the rest?
Depends on your application. In most of the cases yes.
I've done several big angular projects, I only have one route that actually serves the main html file, and one that serves static files (pictures, js, css). I also have a route that points to the templates directory which should be served as static contents. Those are the templates that AngularJS need to work with.
For the communication between your angular app and the server, you'll probably need other routes as well. You could create RESTful API end-points to create a communication layer for the client and the server.
I usually have these two lines in the server code to keep the all the templates in the same folder. It makes it easier to manage and define work flows:
app.use(express.static(path.join(__dirname, 'public')));
app.use('/templates', express.static(path.join(__dirname, 'templates')));
For communication between the server and the client:
app.post('/login', function (req, res) {
// deal with login information ...
res.send({
done: true,
errors: []
});
});
app.post('/search', function (req, res) {
// do the search ...
res.send({
done: true,
results: []
});
});
Remember if you use * at some point in your app, the other routes that you defined after that, will never catch the request.
And
I'm against Jade's syntax and have no desire to utilize it.
Yes, me too! But there are other options as well, I personally prefer ejs. If you are using express-generator you can just pass -e switch and it'll create everything compatible with ejs.
$ express -e
Also, take a look at here.

Filesystem Module in Parse Web Server

I am currently attempting to use Parse Web Hosting to setup a website for my iOS application. I am attempting to show a PDF file in the web browser located within my website directory. I am using express and heres whats going on so far
var express = require('express');
var app = express();
var fs = require('fs');
// Global app configuration section
app.set('views', 'cloud/views'); // Specify the folder to find templates
app.set('view engine', 'ejs'); // Set the template engine
app.use(express.bodyParser()); // Middleware for reading request body
app.get('/terms', function(request, response){
fs.readFile("/public/terms_conditions_hotspot.pdf", function (err,data){
response.contentType("application/pdf");
response.render(data);
});
});
app.listen();
So when I navigate to mysite.parseapp.com/terms, I get a 500 error.
But to make sure everything is setup correctly, I used Parse's boilerplate code to render a hello message when you navigate to mysite.parseapp.com/hello.
app.get('/hello', function(request, response) {
response.render('hello', { message: 'Congrats, you just set up your app!' });
});
This seems to work fine. Anyone know what the issue is?
My goal is migrating my Django Web app to using Parse Web Hosting instead mainly because Parse supports SSL and supplies free certs, which makes building this application cheaper (free). Although, my Django Web App's purpose is to deal with Stripe Connect redirects and used oAuth2, which may be problematic with the migration, seeing as Parse may not support certain modules or whatever. I just feel Parse is very limited with their services but I am anxious to see what I can do with it.
EDIT
So I ran console.log(error) and it returned:
Object [object Object] has no method 'readFile'
readFile is definitely a method that fs ('filesystem') contains. So maybe the module 'fs' in Parse isn't up to date or refers to a different module?
What the deuce?
Parse doesn't appear to use NodeJS (fs is a Node module) even though they offer Express.
See: https://www.parse.com/questions/loading-nodejs-packages-to-cloud-code

How to serve HTTP requests over meteor

I am creating a live streaming application using meteor. Currently I have a need to create a live transcoding option, so I am trying to integrate this node.js module with our meteor application: https://github.com/mifi/hls-vod. However, the way it works is that you actually call the app.get(hls/) from your HTML5 video tag's src. I am wondering if there is a way to expect the call to this get using meteor. Since I can't integrate express with meteor I am having some trouble doing this. I am wondering if there is a way to have meteor receive HTTP requests and send back data as per the node module.
This post has been updated
To server http requests over meteor you need a router. I would recommend ironRouter. There was meteor router but Tom Coleman also built ironRouter.
You can use something like this:
Router.map(function () {
this.route('serverFile', {
path: '/pathonserver',
action: function () {
console.log(this.params); //Contains params
this.response.writeHead(200, {'Content-Type': 'text/html'});
this.response.end('hello from server');
}
});
});
Hopefully that should get the route working similar to the express router.
Meteor Router is now deprecated for Iron Router.
See here for Server Side Routing with Iron Router
You directly use the underlying webapp as illustrated here
or flow-router
or picker for SSR routes.

Categories