Testing Event Handlers in React Testing

In this short article, you will learn how to test event handlers, such as button clicks, with React Testing.

First, we will create a simple component to test:

import React from "react";

export default function ButtonWrapper({ title, ...props }) {
  return <button {...props}>{title}</button>;
}

This ButtonWrapper component takes in a title prop and any other props and returns a standard JSX button element.

Now, create a testing file with the same name as the component file and a .test.js extension (or .test.tsx if you are using TypeScript) (i.e. ButtonWrapper.test.js)

First, import the following from React testing and import the component:

import React from "react";
import { render, screen, fireEvent } from "@testing-library/react";
import ButtonWrapper from "./ButtonWrapper";

Now, create the test and give it a name (i.e. "handles onClick")

test("handles onClick", () => {
 
})

Render the ButtonWrapper component:

render(<ButtonWrapper title={"Add"} />);

We will add an onClick property to the button and call the jest.fn() function whenever the component is clicked:

const onClick = jest.fn();
render(<ButtonWrapper onClick={onClick} title={"Add"} />);

jest.fn() is a function created by Jest which tracks how often it is called. In other words, it will keep track of how many times the button component is clicked.

Now, we will get access to the button and click it using fireEvent.click():

const buttonElement = screen.getByText("Add");
fireEvent.click(buttonElement);

fireEvent.click() simulates a click on the button element.

Next, we will write an assertion for how many times the button has been clicked. First, we will write an inaccurate assertion:

expect(onClick).toHaveBeenCalledTimes(0);

Now, we will run our test:

yarn test

This test will not pass because we know that the button was clicked once by the fireEvent call. The output should look like this:

Basically, React Testing is saying that it expected 0 calls to be made, but it received 1 call.

Now, let’s make a correct assertion:

expect(onClick).toHaveBeenCalledTimes(1);

The output should look like this:

Here is the final code:

import React from "react";
import { render, screen, fireEvent } from "@testing-library/react";
import ButtonWrapper from "./ButtonWrapper";

test("handles onClick", () => {
  const onClick = jest.fn();
  render(<ButtonWrapper onClick={onClick} title={"Add"} />);
  const buttonElement = screen.getByText("Add");
  fireEvent.click(buttonElement);
  expect(onClick).toHaveBeenCalledTimes(1);
});

Now, you can test event handlers in React Testing. Thanks for reading!

Basic Component Testing with React Testing and TypeScript

In this article, we will create a simple React component and do some basic testing on the component using React Testing. This will help you get acquainted with the React Testing library and how to write tests.

Installation

The React Testing library comes by default when you run create-react-app, so it should already be in your project if you created your React project with that command.

Create TypeScript component

First, we will create a component using TypeScript. Make a file called Container.tsx

In the Container component, we will have a div element with a h1 inside of it:

import React from "react";

export const Container = ({ title }: { title: string }) => (
  <div role="contentinfo">
    <h1>{title}</h1>
  </div>
);

We define a title prop with a type of string in TypeScript with the code: { title }: { title: string }

We also set an aria-role for the div element of type contentinfo

Write Tests

Now, let’s write some tests for this component

Create a test file called Container.test.tsx

First, we need to add some imports:

import React from "react";
import { render, screen } from "@testing-library/react";
import { Container } from "./Container";

As you can see, we are importing render and screen from the React testing library, which we will use momentarily.

To create a new test, we use the following structure (which is based on Jest, which is the underlying test framework):

test("Name of test", () => {
   // Function body of test
});

So, we will create a test named “renders title” and then define it:

test("renders title, () => {
    // Test will go here
})

First, render the Container component:

render(<Container title={"New Container"} />);

Next, get access to an element:

const titleElement = screen.getByText(/New Container/i);

There are many ways to get access to an element in the library

  • getByText
  • getByRole (aria-role)
  • getByLabelText
  • getByPlaceholderText

Make an assertion about the element:

expect(titleElement).toBeInDocument()

The above assertion is simply that the title element is in the Container component. This is just a very simple test.

So, here is the full test code:

test("renders title, () => {
    render(<Container title={"New Container"} />);
    const titleElement = screen.getByText(/New Container/i);
    expect(titleElement).toBeInDocument()
})

Run yarn test

The test output should look like this if it passed successfully:

Now, you have a basic introduction to testing components in React.

How to Open VS Code settings.json file

This short tutorial will be on how to open the settings.json file in VS Code on Mac.

In the menu bar, navigate to Code > Preferences > Settings.

This will open the Settings UI page, which looks like this:

In the upper right-hand corner of the page, click the Open Settings (JSON) icon.

Now, you have opened the settings.json file!

How to Connect to a Remote Server with SSH on VSCode

Install VSCode

Please check the VSCode homepage. https://code.visualstudio.com/.

Install remote-ssh extension in VSCode

  1. Open the VSCode. On the left, there’s an Extension icon.
  2. Search for remote-ssh. Choose the first one and click install.
  3. You may need to reload VSCode to let the extension initialize.

Connect to the remote server

  1. Click View > Command Palette… or use the shortcut cmd+shift+p for Mac and ctrl+shift+p Windows. Type ssh and choose remote-ssh: connect to host.

2. Type the URL of the remote server

3. After that, it will open a new VSCode window.

Add your workspace

  1. After connect to the remote server, we need to cd to our workspace. Call your Command Palette again and type folder. Choose Add folder to your workspace in my case and enter your path to workspace.

How to Format on Save in VSCode

If format on save was previously not working for you, this is what fixed it for me.

  1. Install Prettier in VSCode (https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode)
  2. Open Settings pane (Command + ,)
  3. Make sure the Editor: Format on Save property is enabled (You can search and find the property in the search bar)
  4. Set the Editor: Default Formatter to Prettier – Code formatter

All About Logging

What is an application log?

There are multiple different types of logging including system logs, server logs, garbage collector logs, and application logs.

An application log is a file that contains information about events that have occurred within a software application. Every application produces logs which hold information about what the application is doing.

What type of information is included in a log? It varies by the application. The developers of the software application control what goes into the log file, but there are some commonly included components:

  • context info: Background information that provides insight into the state of the application at the time of the message
  • timestamps: A specific piece of contextual information for tracking and correlating issues
  • Log levels: Labels that help you calculate the level of importance for the entries in your log file. Frequently used levels include INFO, WARN, and ERROR

Why are logs important?

The main use for logs is diagnostics. Logs hold information that can help with

  • debugging
  • analytics
  • compliance
  • security

Logging Agent vs Logging Library

A logging agent is a separate service that reads logs from one location and sends them to another location. Think of it like a funnel.

Some benefits of logging agents include:

  1. minimal setup & config
  2. multi-threading & failure safety
  3. no code
  4. scalable (single agent instance can log for almost any number of applications)
  5. modify/update/replace agents w/o having to take down application
  6. format-agnostic

Some drawbacks of logging agents include:

  1. require interaction w/ host (not good w/ Serverless)
  2. requires CPU compute usage to track log files

A logging library (or logging framework) is code that you embed into your application to create and manage log events.

Some benefits of logging libraries include:

Some drawbacks of logging libraries include:

  • usually synchronous (application must wait for the library to finish writing a log event before continuing)
  • no failure safety (libraries only run as long as your application is running)
  • not scalable (each application runs its own instance of the library)

Setting up a Free Postgres Database in Heroku w/ PgAdmin

Step 1: Log into Heroku

Step 2: Create a New App

Create a new Heroku app by either clicking “Create a new app” in the center of the screen or “New” at the top right of the screen.

Choose an App Name and the Region (either the US or Europe) for your new app. The name can be anything you want. Then, just click the Create app button.

Step 3: Add a PostgreSQL Database

To attach a PostgreSQL database to the blank app you just made, you need to go to the Resources tab in the header of the new app’s dahsboard. Then type Heroku Postgres into the Add-ons search field. When shown, select the suggested Heroku Postgres add-on from the dropdown:

The next popup asks you to choose a pricing plan for the database. Select the Hobby Dev – Free plan and click Provision.

Now your PostgreSQL database is up !

Step 4: Get Heroku DB Information

To find the credentials and the connection URL for the PostgreSQL database, make sure you’re still in the Resources tab and click on the Heroku Postgres resource we just added.

That should bring you to this screen:

Select the Settings tab in the header of that screen. You will be navigated to a page where Here, you can click the View Credentials button to see the credentials of your PostgreSQL database.

You will need these values to input into your PgAdmin interface

Step 5: Configure PgAdmin w/ Heroku DB Credentials

Open up PgAdmin

Right-click on Servers at the very top of the left-side panel

Choose Create > Serve

Fill out the new server form with all of the corresponding information from the Heroku View Credentials page.

After you save the new server, it will become populated with a huge list of databases. You will not have access to any of them except the one with your Database name from Heroku. Scroll through and find this one.

Then, as you would with any other PgAdmin database, go to Schemas > public > Create new Table. Populate this table with the fields you want.

You’re all set.

Code Formatting with Prettier in VS Code

No one likes messy code, but no one likes painstakingly formatting their code as they write it either. The Prettier plugin on VS Code takes care of that for us.

To install it, navigate to the fifth panel on the VS Code sidebar

Type “Prettier” into the search bar and it should be the first option in the list

It’s installed now, but we’re not done. We have to do some set up to get Prettier working in our files.

Navigate to the Settings at the bottom left corner of the screen.

Type “format on save” into the search bar. Change this property to true. This will make it so that whenever we save a file that we’re working on, Prettier will automatically format it for us.

Type “prettier” into the search bar. You will see a list of around 20 properties that dictate the formatting rules Prettier will follow. Change these settings to your preference.

For example, you can change “prettier.singleQuote” to true if you don’t want to deal with some of your code using double quotes and other parts using single quotes.

Save your new settings, close VS Code, and you’re good to go!

How to Toggle the Minimap in Visual Studio Code

What is the minimap?

On the far-right side of your Visual Studio workspace, you may have a small file preview panel that shows a faint outline of the entire file that you’re currently in.

This little panel is called the minimap. Visual Studio Code’s definition of the minimap is as follows:

“A Minimap (code outline) gives you a high-level overview of your source code, which is useful for quick navigation and code understanding. A file’s minimap is shown on the right side of the editor. You can click or drag the shaded area to quickly jump to different sections of your file.”

The minimap can be annoying in some circumstances; for example, by limiting the length of your coding window.

How to Toggle the Minimap

  1. Go to View > Command Palette (Ctrl + Shift + P on Windows, Cmd + Shift + P on Mac)
  2. Type “minimap”
  3. Press on ‘View: Toggle Minimap’ to toggle it on and off

JWTs (JSON Web Tokens)

What is JWT used for?

It is used for authorization, not authentication. Authentication is checking if a username and password are correct then logging a user in. Authorization is making sure that the user that is sending requests to your server is the same user that actually logged in during the authentication process.

The basic idea of JWT is a simple way for securely transmitting information between parties as a JSON object

What is the JSON Web Token structure?

A JWT is basically just a bunch of random characters. The token is separated into 3 sections: Header, Payload, and Signature. These sections are separated by dots (.) The structure looks like the following:

xxxxx.yyyyy.zzzzz

The JWT website (https://jwt.io) offers a great breakdown of an actual token:

Header

The header typically consists of two parts: the type of the token, which is JWT, and the signing algorithm being used. Here’s an example:

{
   "alg": "SHA256", 
   "typ": "JWT" 
}

Then, this JSON is Base64Url encoded to form the first part of the JWT.

Payload

The payload is the data that you want to send within the token. In the example, the data being sent is a variable called name with a value of John Doe.

{ 
   "sub": "1234567890", 
   "name": "John Doe",
   "admin": true 
}

Another example might be sending an id variable with a unique value that differentiates all of the users of a website.

Signature

To create the signature part you have to take the encoded header, the encoded payload, a secret, the algorithm specified in the header, and sign that.

To create the signature part you have to take the encoded header, the encoded payload, a secret, the algorithm specified in the header, and sign that.

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

The signature is used to verify the message wasn’t changed along the way, and, in the case of tokens signed with a private key, it can also verify that the sender of the JWT is who it says it is.

The output is three Base64-URL strings separated by dots that can be easily passed in HTML and HTTP environments.

Implementing JWT in Node applications

First, install the jsonwebtoken package with npm.

npm i jsonwebtoken

Get access to JWT in the file

const jwt = require("jsonwebtoken");

Create the payload

const payload = { 
   user: { 
      id: user.id 
   }
}

Sign the token. Pass in the payload, pass in the secret, and inside the callback, we’ll either get the error or a token. If we get a token, we’ll send a response back to the client with that token.

jwt.sign(
   payload, 
   config.get('jwtSecret'), 
   { expiresIn: 360000 }, 
   (err, token) => {
      if (err) throw err;
      res.json({ token });
});

When you create a new user, if everything is successful, the callback should return a token like this:

{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7ImlkIjoiNWYwMjY2ZWM3ZjE4Y2JmNTg0NjgwZDM0In0sImlhdCI6MTU5Mzk5Mjk0MCwiZXhwIjoxNTk0MzUyOTQwfQ.8qiRsqHH-mSSrr9itAQzmSLUu8easVTNdeoUxg0AC0U"
}

If we paste this token that we’ve just created into the website that I showed you earlier, we can breakdown it’s header, payload, and signature:

In the payload, you can see our User object with its unique Mongo id (“user”, “id”), the date that the token was issued at (“iat”), and the expiration date that we defined (“exp”).