Difference between revisions of "JavaScript API with Mocha"

From Encyclopedia of Syriac Literature
Jump to navigationJump to search
 
(One intermediate revision by the same user not shown)
Line 1: Line 1:
 +
''See [[User:Roger_Pearse/JavaScript_Basics]]''
 +
 +
* [http://www.marcusoft.net/2014/02/mnb-express.html Using Express for APIs] - parsing parameters
 +
* [http://www.marcusoft.net/2014/02/mnb-supertest.html Supertest] - More stuff for POST, Express BodyParser, parameters
 +
 +
== Example ==
 +
 
* [[File:NoddyExpressWithTest.zip]] - the project
 
* [[File:NoddyExpressWithTest.zip]] - the project
  

Latest revision as of 14:43, 5 July 2017

See User:Roger_Pearse/JavaScript_Basics

Example

src/getApp.js:

// getApp.js - the webservice.  Run using node getApp.

// Require the module
var express = require("express");

// Create the express app
var app = express();

// Could do on one line
//var app= require('express')();

// The login credentials
const expectedAuthString = "Basic " + new Buffer("username:password").toString("base64");

// Define the GET endpoint
app.get("/users", function (req, res) {

	// Log the call
	// console.log("The req parameter contains request info");
	// console.log(req);

    // Parse the auth header - TODO needs separate function and tests
	const auth = req.header("Authorization");
	//console.log('Auth header=' + auth);

	const tmp = auth.split(' ');   // Split on a space, the original auth looks like  "Basic Y2hhcmxlczoxMjM0NQ==" and we need the 2nd part 
    const buf = new Buffer(tmp[1], 'base64'); // create a buffer and tell it the data coming in is base64 
    const plain_auth = buf.toString();        // read it back out as a string 
    console.log("Decoded Authorization ", plain_auth); 
    // At this point plain_auth = "username:password" 
    const creds = plain_auth.split(':');      // split on a ':' 
    const username = creds[0]; 
    const password = creds[1]; 

	// Check authentication
	if (req.header("Authorization") != expectedAuthString) {
		// throw some sort of error
		res.status(401)
			.send('Get lost');  // body

		return;
	}

	// Send a json packet instead of a string.  
	res.status(200)
		.send({ name: 'marcus' })  // body
		;

	// console.log("And the res the response information");
	// console.log(res);
});

// Other endpoints done the same way
app.post("/users", function (req, res) { res.send("all the HTTP verb looks the same");});
app.patch("/users", function (req, res) { res.send("all the HTTP verb looks the same");});
app.del("/users", function (req, res) { res.send("all the HTTP verb looks the same");});
// and HEAD and OPTIONS and what have you... 

// Set Express to listen on port 3000
app.listen(3000);
console.log("you can now post, delete, get, and patch to http://localhost:3000/users");

// In order to reach the app from other modules
// we need to export the express application
module.exports.getApp = app;

test/getAppTest.js:

'use strict'

var request = require('supertest');

// Here we get hold of the express application 
// by using the exported 'getApp'-property
var app = require("../src/getApp").getApp;

// Test the get method
describe('GET /users', function(){

  // Happy path
  it('Test it responds with json', function(done){

    // the request-object is the supertest top level api
    request(app)
      .get('/users')   // Make sure this is the same or you get "Error: expected "Content-Type" matching /json/, got "text/html; charset=utf-8""
      .set('Accept', 'application/json')
      .auth('username', 'password')   // Send the user and password on the request
      .expect('Content-Type', /json/)
      .expect(200, done); // note that we're passing the done as parameter to the expect
  });

  // Unhappy path
  it('Test Get /crap fails with 404', function(done){

    // the request-object is the supertest top level api - https://www.npmjs.com/package/supertest for examples
    // you can pass done straight to any of the .expect() calls
    request(app)
      .get('/crap')   // Make sure this is right or you get "Error: expected "Content-Type" matching /json/, got "text/html; charset=utf-8""
      .expect(404) 
      .end(function(err, res) {   // catch and log the error

          // Must rethrow or test will pass!
          //if (err) throw err;
          // Or mocha version:
          if (err) {
              // Log the error
              console.log('err=' + err);

              // rethrow
              return done(err);  // mocha version
          }

          // Tell mocha all done
          done();
      });

  });

  // Unhappy path
  it('Test Get fails wrong login', function(done){

    // We need to set the user and password on our request to the server
    //.auth('username', 'passwordXXX')   // from superAgent.  Basic auth.  https://stackoverflow.com/questions/28756543/setting-basic-auth-in-mocha-and-supertest
    // Or: .set("Authorization", "basic " + new Buffer("username:password").toString("base64"))  // basic auth

    // the request-object is the supertest top level api - https://www.npmjs.com/package/supertest for examples
    // you can pass done straight to any of the .expect() calls
    // Info: https://github.com/visionmedia/supertest
    request(app)
      .get('/users')
      .auth('username', 'passwordXXX')   // Send the user and wrong password on the request
      .expect(401, "Get lost") 
      .end(function(err, res) {   // catch and log the error

          // Must rethrow or test will pass!
          //if (err) throw err;
          // Or mocha version:
          if (err) {
              // Log the error
              console.log('err=' + err);

              // rethrow
              return done(err);  // mocha version
          }

          // Tell mocha all done
          done();
      });

  });

});

Run with npm test; or cd test and mocha getAppTest.js.