Coder Social home page Coder Social logo

Comments (3)

jneurock avatar jneurock commented on June 15, 2024 1

Super delayed response from my side...

Very cool. It seems this is largely an issue with Mirage itself lacking WebSocket support. There's some interest in refactoring Mirage and decoupling it from Pretender to enable usage of other server mocking libraries: miragejs/miragejs#1013. It would be awesome to just support mocking subscriptions out-of-the-box.

from graphql.

jneurock avatar jneurock commented on June 15, 2024

Sorry, I don't personally have any suggestions. It would be really nice to have an official way to do this. AFAIK, Mirage doesn't have a built-in solution for dealing with web sockets but discussions have been had on a proposed API miragejs/discuss#23.

Feel free to share a use case here and any ideas you have for a good API and I'd be happy to put some work into it. I've been hesitant to add anything to this library so it may be good to use this project as a proving ground for a solution and then see if we can get something official into Mirage itself.

from graphql.

chrismllr avatar chrismllr commented on June 15, 2024

@jneurock Thanks for the response!

I attempted to go so far as to using graphql-subscriptions and subscriptions-transport-ws libraries in my mirage server, but that felt pretty heavy handed.

For the time being, I opted to create a test helper method to add the mocked server to the mirage server context, being sure to use the same wsURL im using to set up the Apollo WebsocketLink:

// Note-- this is the only lib that worked, mock-socket did not work properly
import { Server } from 'mock-socket-with-protocol';

import type { TestContext } from 'ember-test-helpers';
import Config from 'app/config/environment';
import { assert } from '@ember/debug';

let operationMap: Record<string, string> = {};

export function buildSubscriptionMessage(
  operationName: string,
  payload: Record<string, any>
): string {
  return JSON.stringify({
    type: 'data',
    payload,
    id: operationMap[operationName],
  });
}


export function setupWebsocketServer(hooks: NestedHooks): void {
  hooks.beforeEach(function (this: TestContext) {
    assert(
      '[setupWebsocketServer] You must place `setupWebsocketServer` after `setupMirage`.',
      this.server
    );

    this.server.ws = new Server(Config.apollo.wsURL);

    this.server.ws.on('connection', (socket: WebSocket) => {
      socket.on('message', (data: string) => {
        const msg = JSON.parse(data);
        if (!msg.payload?.operationName) {
          return;
        }
        operationMap[msg.payload.operationName] = msg.id;
      });
    });
  });

  hooks.afterEach(function (this: TestContext) {
    operationMap = {};
    this.server.ws.stop();
  });
}

The utility function buildSubscriptionMessage is used to mock-send messages "from the backend":

// send example message
describe('a test suite!', function(hooks) {
  setupMirage(hooks)
  setupWebsocketServer(hooks)
  
  test('a test', function(this: TestContext, assert) {
    const done = assert.async();

    this.server.ws.send(
      buildSubscriptionMessage(
        'SubOperationName', 
        {
          id: '123',
          moreData: 'Data'
        }
      )
    );
  
    // use a mocked handler somewhere to call done();
    assert.verifySteps();
  });
});

This is obviously Very pared down; subscriptions-ws-transport has a very thorough API for building the messages that are delivered to the UI -- this naive buildSubscriptionMessage will surely need to be fleshed out more to get more types of messages covered but for now, it seems to be getting the job done simply without re-building too much backend logic 🤷

Edit: Updated the solution based on how it has evolved for us!

from graphql.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.