npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

pusher-js-mock

v0.3.8

Published

Mock Pusher.js in your JavaScript tests with ease

Downloads

152,538

Readme

Installing ⏬

Using yarn:

yarn add --dev pusher-js-mock

Or using npm:

npm install -D pusher-js-mock

Usage 🛠

For more detailed examples, check out examples directory inside the project!

Also, you can check out the Docs for even more information.

Emitting an event 📶

If you need to mock a Pusher object in your tests that can subscribe to channel, it's best to use PusherMock.

import { PusherMock } from "pusher-js-mock";

// initializing PusherMock
const pusher = new PusherMock();

// subscribing to a Pusher channel
const channel = pusher.subscribe("my-channel");

// emitting an event
channel.emit("event-name");

Listening for an event 👂

If you want to check whether your callback is getting called properly, you can bind a callback to your channel, and then emit an event.

import { PusherMock } from "pusher-js-mock";

descibe("listening for an event", () => {
  // initializing PusherMock
  const pusher = new PusherMock();

  // subscribing to a Pusher channel
  const channel = pusher.subscribe("my-channel");

  // define and attach a listener
  const listener = jest.fn();
  channel.bind("event-name", listener);

  // emitting an event
  channel.emit("event-name");

  // Expect listener to have been called
  expect(listener).toHaveBeenCalled();
});

Emitting an event from connection 📶

The connection within pusher is mocked and can be used much like a channel channel. There's no need to subscribe to subscription as it's subscribed by default on pusher.

import { PusherMock } from "pusher-js-mock";

// initializing PusherMock
const pusher = new PusherMock();

// emitting connection event
pusher.connection.emit("event-name");

Listening for an event from connection 👂

As with channels, you can also listen to connection for events.

import { PusherMock } from "pusher-js-mock";

descibe("listening for an event", () => {
  // initializing PusherMock
  const pusher = new PusherMock();

  // define and attach a listener
  const listener = jest.fn();
  pusher.connection.bind("event-name", listener);

  // emitting an event
  pusher.connection.emit("event-name");

  // Expect listener to have been called
  expect(listener).toHaveBeenCalled();
});

Stubbing Pusher when imported from pusher-js package 📦

If you're using Pusher in your code in this or similar manner:

import Pusher from "pusher-js";

You will need to mock Pusher in a specific way.

I suggest you use Jest to test your code. To do this in Jest, you'll need something like this:

jest.mock("pusher-js", () => {
  const Pusher = require("pusher-js-mock").PusherMock;
  return Pusher;
});

If you have tips on how to mock this using other testing frameworks, please submit an issue or a pull request.

Stubbing Pusher when used as a global variable 🌍

This shows how to stub a pusher if you're attaching it to window object in your project. If you're attaching a PusherFactory to a window object like this in your code:

window.PusherFactory = {
  pusherClient: function(pusherKey) {
    return new Pusher(pusherKey);
  }
};

It's best for you to use PusherFactoryMock.

import { PusherFactoryMock } from "pusher-js-mock";

// initialize instance of PusherFactoryMock
const pusherFactoryMock = new PusherFactoryMock();
// replace it with the object that is attached to a window
window.PusherFactory = pusherFactoryMock;

// get the Pusher client reference
pusher = pusherFactoryMock.pusherClient();

This way you'll just replace your PusherFactory with PusherFactoryMock.

Mocking presence channels

This package also supports using presence channels for multiple clients. The mock will automatically detect when presence- is in the channel name and return a presence channel with channel.members filled out as expected. You can pass in IDs and info via a custom authorizer, just as you would with the real package.

Using custom authorizer

If you want, you can pass in a custom authorizer when creating a Pusher client.

// create-client.js
import Pusher from "pusher-js";
import { getAuthSomehow } from "./getAuthSomehow";

export const createClient = ({ id, info }) =>
  new Pusher("APP_KEY", {
    cluster: "APP_CLUSTER",
    // see https://github.com/pusher/pusher-js#authorizer-function
    authorizer: ({ name }) => ({
      authorize: (socketId, callback) => {
        const auth = getAuthSomehow(id, info);
        callback(false, auth);
      }
    })
  });

export default createClient;
// create-client.spec.js
import createClient from "../create-client";

// mock the authorize function and pusher
jest.mock("pusher-js", () => require("pusher-js-mock"));
jest.mock("../getAuthSomehow", () => ({
  getAuthSomehow: (id, info) => ({ id, info })
}));

it("should create a presence channel", async () => {
  // arrange: create pusher client
  const pusher = createClient({ id: "my-id", info: { role: "moderator" } });

  // act: required to ensure pusher events are called, i.e. pusher:member_added
  const presenceChannel = await pusher.subscribe("presence-channel");

  // assert: presenceChannel has the properties we expect it to.
  expect(presenceChannel.members.myID).toBe("my-id");
  expect(presenceChannel.members.me).toEqual({
    id: "my-id",
    info: { role: "moderator" }
  });
  expect(presenceChannel.members.members).toEqual({
    "my-id": { role: "moderator" }
  });
});

Check out a code example of using presence channels

Pusher events emitted by presence channels

The mocked Pusher instance will also emit pusher internal events pusher:subscription_succeeded, pusher:member_added and pusher:member_removed to the relevant clients:

it("should emit presence-channel events", async () => {
  const client = createClient({ id: "my-id" });
  const channel = client.subscribe("presence-channel");
  const listener = jest.fn();

  /**
   * On bind, pusher:subscription_succeded will trigger
   * for the client subscribing. Other clients will be
   * notified via pusher:member_added as below.
   */
  await channel.bind("pusher:subscription_succeeded", listener);
  expect(listener).toHaveBeenCalledTimes(1);

  /**
   * Create and subscribe a new client that will trigger the
   * pusher:member_added event. This only gets triggered for
   * clients are not the client subscribing
   */
  channel.bind("pusher:member_added", listener);
  const otherClient = createClient({ id: "your-id" });
  await otherClient.subscribe("presence-channel");
  expect(listener).toHaveBeenCalledTimes(2);

  /**
   * Unsubscribe the otherClient to trigger pusher:member_removed.
   * This only gets triggered for clients that are not the client
   * unsubscribing.
   */
  channel.bind("pusher:member_removed", listener);
  await otherClient.unsubscribe("presence-channel");
  expect(listener).toHaveBeenCalledTimes(3);
});

Code of Conduct

Contributing

Credits

Photo by Octavian Rosca on Unsplash