actionhero / ah-next-plugin

For booting a Next.JS React application inside of Actionhero
5 stars 4 forks source link

Trick to get ah-next-plugin into AH monorepo without breaking jest... #491

Open mfvargo opened 5 days ago

mfvargo commented 5 days ago

In upgrading to AH 29 I followed the advice and blew up the config subdir. (a bit questionable advice???) so I lost my next.ts. When I used the one from this README it took me a while to figure out why my jest tests would all fail with actionhero.start()

This is assuming a mono repo config with "api" and "web" subdirectories with AH running in api and next running in web...

In order for the jest tests to run in the actionhero api directory, you have to disable next so actionhero.start() will work in the tests. What I had before was a jest.setup.js in the api directory that says:

process.env.NEXT_DISABLED = "true";

The next.ts example in README.md does not skip enabling the plugin for tests.

// from src/config/next.ts
// learn more about the next.js app options here https://nextjs.org/docs/advanced-features/custom-server

const namespace = "next";

declare module "actionhero" {
  export interface ActionheroConfigInterface {
    [namespace]: ReturnType<typeof DEFAULT[typeof namespace]>;
  }
}

const env = process.env.NODE_ENV ? process.env.NODE_ENV : "development";

export const DEFAULT = {
  [namespace]: () => {
    return {
      enabled: true,
      dev: process.env.NEXT_DEVELOPMENT_MODE
        ? process.env.NEXT_DEVELOPMENT_MODE === "false"
          ? false
          : true
        : env === "development",
      quiet: false,
    };
  },
};

I had to change the logic on the enable: true line to read that NEXT_ENABLED from jest.setup.js and do

      enabled: process.env.NEXT_DISABLED === "true" ? false : true,

Now my jest tests will run in api. Maybe some note of this could be made in the README?

evantahler commented 5 days ago

Can you elaborate more about this commen:

you have to disable next so actionhero.start() will work in the tests

Would the server boot up and try to load your tests as actions or something like that?

mfvargo commented 5 days ago

In my specHelper I have an intializer that does

  export async function prepareForTest() {
    const actionhero = new Process();

    beforeAll(async () => {
      await actionhero.start();
      this.loadFactory();
    });
    afterAll(async () => {
      await this.truncate();
      await actionhero.stop();
    });
    afterEach(async () => {
      await factory.cleanUp();
    });
  }

If next.ts initializer returns enabled: true when you run jest, all tests fail when actionhero.start() runs. So actionhero.start() does not like to run in the jest environment.

I get this error:

mfvargo@mfvargo-XPS-13:~/projects/nation2/api$ npx jest -i models/Song.ts
  console.error
     ⨯ Failed to load next.config.js, see more info here https://nextjs.org/docs/messages/next-config-error

      53 |
      54 |     beforeAll(async () => {
    > 55 |       await actionhero.start();
         |       ^
      56 |       this.loadFactory();
      57 |     });
      58 |     afterAll(async () => {

      at prefixedLog (../node_modules/next/src/build/output/log.ts:34:27)
      at Object.prefixedLog (../node_modules/next/src/build/output/log.ts:47:3)
      at error (../node_modules/next/src/server/config.ts:1021:14)
      at initialize (../node_modules/next/src/server/lib/router-server.ts:82:18)
      at NextCustomServer.prepare (../node_modules/next/src/server/next.ts:282:24)
      at Next.start (../node_modules/ah-next-plugin/dist/initializers/next.js:68:9)
      at startFunction (../node_modules/actionhero/dist/classes/process.js:115:29)
      at Process.start (../node_modules/actionhero/dist/classes/process.js:195:17)
      at Object.<anonymous> (__tests__/utils/specHelper.ts:55:7)

with the default next.ts shown in this readme.

export const DEFAULT = {
  [namespace]: () => {
    return {
      enabled: true,
      dev: process.env.NEXT_DEVELOPMENT_MODE
        ? process.env.NEXT_DEVELOPMENT_MODE === "false"
          ? false
          : true
        : env === "development",
      quiet: false,
    };
  },
};

If I make sure enabled: false (when running jest) via the jest.setup.js

export const DEFAULT = {
  [namespace]: () => {
    return {
      enabled: process.env.NEXT_DISABLED === "true" ? false : true,
      dev: process.env.NEXT_DEVELOPMENT_MODE
        ? process.env.NEXT_DEVELOPMENT_MODE === "false"
          ? false
          : true
        : env === "development",
      quiet: false,
    };
  },
};

the tests all pass

mfvargo@mfvargo-XPS-13:~/projects/nation2/api$ npx jest -i models/Song.ts
 PASS  __tests__/models/Song.ts
  Song Model Test
    ✓ it should have info (23 ms)
    ✓ it should have apiData (8 ms)

Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        3.447 s, estimated 6 s
Ran all test suites matching /models\/Song.ts/i.