Categories
JavaScript Tips

Node.js Tips — Scheduled Tasks, Jest Tests, and Headers for Tests

Like any kind of apps, there are difficult issues to solve when we write Node apps.

In this article, we’ll look at some solutions to common problems when writing Node apps.

Looping Through Dynamic Test Cases with Jest

We can use the tests.each method to loop through each tets.

For instance, we can write:

test.each([[4, 5, 9], [1, 2, 3], [2, 3, 5]])(
  'add(%i, %i)',
  (a, b, expected) => {
    expect(a + b).toBe(expected);
  },
);

The first argument is the items we want to pass into each test.

The nested array entries are the parameters for the callback.

The 2nd argument is the name of each test.

The 3rd is a callback to let the arguments and run our expectations.

Setting Default Headers with Supertest

We can create a header we can use with our test.

Then we can pass it into the set method.

For instance, we can write:

const request = require("supertest");

const baseUrl = 'http://localhost';
request = request(baseUrl);
const commonHeaders = { authorization: "abc" };

describe("testing", () => {
  it.should('present authorization header to server', (done) => {
    request.get('/foo')
      .set(commonHeaders)
      .set({ foo: "bar" })
      .expect(200, done)
  })

})

commonHeaders has the shared headers between multiple tests.

We just pass that into the set method.

Then we can pass other headers into the set method that are specific to the test.

Read a File Synchronously in Node.js

To read a file synchronously with Node, we can use the readFileSync method.

For instance, we can write:

const fs = require('fs');
const content = fs.readFileSync('file');
console.log(content);

We just pass in the path to the file and the content will be returned.

Base64 Encode a JavaScript Object

We can base64 encode a JavaScript object by converting it to a string with JSON.stringigy .

Then we can call Buffer.from to convert it to a buffer and then call toString to convert it to a base64 string.

For instance, we can write:

const str = JSON.stringify(obj);
const objJsonB64 = Buffer.from(str).toString("base64");

Buffer.from converts the stringified JSON object to a byte stream.

Then we call toString with the 'base64' argument to convert it to a base64 string.

Mongoose Populate Embedded

We can call populate on embedded documents with Mongoose if we define a schema with the related schemas.

For instance, if we have:

const UserSchema = new Schema({
  name: String,
  friends: [{ type: ObjectId, ref: 'User' }]
});

Then we have a self-referencing schema since friends is referencing another User document.

Now we can call populate with friends by writing:

User.
  findOne({ name: 'james' }).
  populate({
    path: 'friends',
    populate: { path: 'friends' }
  });

We call populate the friends to get friends.

And we can use the populate property to get friends of friends.

Running a Function Everyday

We can run a function in a scheduled manner by using the node-schedule package.

For instance, we can write:

import schedule from 'node-schedule'

schedule.scheduleJob('0 0 0 * * *', () => {
  //...
})

We run the schedule.scheduleJob to run the callback with the scheduled specified by the string.

It takes a string in that specifies the schedule in the same way as a cron job.

The first number is the second.

The 2nd is the minute.

The 3rd is the hour.

The 4th is the day of the month.

The 5th is the month.

The 6th is the day of the week.

We specify the hour, minute, and second to specify when it’ll run in the day.

Then the rest are asterisks to that it’ll run every day.

We can also specify the date instead of a cron format string.

For instance, we can write:

const schedule = require('node-schedule');
const date = new Date(2020, 0, 0, 0, 0, 0);

const j = schedule.scheduleJob(date, () => {
  console.log('hello');
});

Then the callback only runs on the given date.

We can also set recurrence rules.

For instance, we can write:

const schedule = require('node-schedule');

const rule = new schedule.RecurrenceRule();
rule.minute = 30;

const j = schedule.scheduleJob(rule, () => {
  console.log('half hour job');
});

We use the schedule.RecurrenceRule constructor to create a rule.

We set the minute in the example above.

But we can also set the second , hour , date , month , year , and dayOfWeek .

Conclusion

node-schedule is a useful scheduler package.

We can set headers for tests with supertest.

Jest can define and run tests dynamically.

MongoDB can reference related documents.

We can convert JavaScript objects into base64 strings.

Categories
JavaScript Tips

JavaScript Tips — Jest Mocks, React Background, and More

Like any kind of apps, there are difficult issues to solve when we write JavaScript apps.

In this article, we’ll look at some solutions to common JavaScript problems.

Regex to Check Whether a String Contains Only Numbers

We can use a regex to check if a string has only numbers.

For instance, we can write:

const reg = /^d+$/;

^ matches the string from the beginning, and d is the digit.

Javascript Filename Naming Convention

JavaScript filename should follow some common conventions.

We should use all lowercase filenames.

Also, we don’t want to use spaces in the filename.

We can optionally use a hyphen as a word separator.

And we may also add a version number in our file name if we have one.

By updating the version number in the file name, we always serve the latest one with the CDN alongside the older version.

Calling a Parent Window Function from an iframe

We can access the parent window with the window.parent property.

So if we want to call a function in the parent window from an iframe, we can write:

<a onclick="parent.foo();" href="#" >click me</a>

foo is a top-level function in the parent window.

Center a Popup Window on the Screen

To center a popup window on the screen, we can do some calculations to center the window and pass that off to the specification string.

For instance, we can write:

const openPopup = (url, title, w, h) => {
  const left = (screen.width / 2) - (w / 2);
  const top = (screen.height / 2) - (h / 2);
  return window.open(url, title, `width=${w}, height=${h}, top=${top}, left=${top}`);
}

We get the left coordinate by using the width divided by 2 minus the width divided by 2 to get the x coordinate of the top left corner.

Likewise, we do the same thing but replace the width with the height to get the y coordinate of the top left corner.

Then we pass those to the specification string and also do the same with the width and height.

Setting a Background Image With React Inline Styles

To set a background image with React inline styles, we can import the image as a module.

Then we can interpolate that into the CSS string for setting the background image.

For instance, we can write:

import Background from '../images/background.png';

const styles = {
  backgroundImage: `url(${Background})`
}

We set the backgroundImage property with the url string with the Background image we imported.

Remove Everything After a Given Character

To remove the part of a string after a given character from a string, we can use the split method.

For instance, we can write:

url.split('?')[0]

Then we get part of the url string before the ? .

A Practical Use for a Closure in JavaScript

Closures are great for hiding private things like variables and functions that we don’t want to expose to the outside.

For instance, we can write:

const obj = (() => {
  const private = () => {
    console.log('hello');
  }

  return {
    public() {
      private();
    }
  }
})();

private is a private function.

And public is a function that’s in obj , so it’s available to code outside.

Get the Real Width and Height of an Image

To get the real width and height of an image, we can use the naturalHeight property to get the real height and naturalWidth to get the real width.

For instance, we can write:

const height = document.querySelector('img').naturalHeight;

and:

const width = document.querySelector('img').naturalWidth;

This is available since HTML5.

Mock an ES6 Module Import Using Jest

To mock an ES6 module import using Jest, we can use the jest.fn() function to mock a function.

For instance, we can write:

logger.js

export const log = (y) => console.log(y)

module.js

import { log } from './logger';

export default (x) => {
  doSomething(x * 2);
}

module.test.js

import module from '../module';
import * as `logger` from '../`logger`';

describe('module test', () => {
  it('logs the double the input', () => {
    dependency.`log` = jest.fn();
    module(2);
    expect(dependency.`log`).toBeCalledWith(4);
  });
});

All we have to do is to call jest.fn to create a mock function.

We imported the whole module, so the members aren’t read-only.

Therefore, we can assign our own mock function to it.

Then we call our module function to test our function and check our results.

Conclusion

We should follow some common file naming conventions for naming JavaScript files.

Also, we can mock functions in Jest with the jest.fn() method.

A popup can be centered on the screen.

We can set a background image by importing it and interpolating it in a CSS string in a React component.