@jest/globals#afterEach TypeScript Examples

The following examples show how to use @jest/globals#afterEach. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: checksums.test.ts    From wrapper-validation-action with MIT License 6 votes vote down vote up
describe('retry', () => {
  afterEach(() => {
    nock.cleanAll()
  })

  describe('for /versions/all API', () => {
    test('retry three times', async () => {
      nock('https://services.gradle.org', {allowUnmocked: true})
        .get('/versions/all')
        .times(3)
        .replyWithError({
          message: 'connect ECONNREFUSED 104.18.191.9:443',
          code: 'ECONNREFUSED'
        })

      const validChecksums = await checksums.fetchValidChecksums(false)
      expect(validChecksums.length).toBeGreaterThan(10)
      nock.isDone()
    })
  })
})
Example #2
Source File: framework.test.ts    From slice-machine with Apache License 2.0 6 votes vote down vote up
describe("framework.fancyName", () => {
  afterEach(() => {
    jest.resetAllMocks();
  });

  test("it should return a fancy name", () => {
    expect(FrameworkUtils.fancyName(Frameworks.gatsby)).toEqual("Gatsby");
  });

  test("it should return a Next.js for next (special case)", () => {
    expect(FrameworkUtils.fancyName(Frameworks.next)).toEqual("Next.js");
  });
});
Example #3
Source File: framework.test.ts    From slice-machine with Apache License 2.0 6 votes vote down vote up
describe("framework.isFrameworkSupported", () => {
  afterEach(() => {
    jest.resetAllMocks();
  });

  const supportedFramework = SupportedFrameworks[0];
  const unsupportedFramework = FrameworkUtils.UnsupportedFrameWorks[0];

  test("it should return true to supported frameworks", () => {
    expect(FrameworkUtils.isFrameworkSupported(supportedFramework)).toEqual(
      true
    );
  });

  test("it should return false to unsupported frameworks", () => {
    expect(FrameworkUtils.isFrameworkSupported(unsupportedFramework)).toEqual(
      false
    );
  });
});
Example #4
Source File: framework.test.ts    From slice-machine with Apache License 2.0 6 votes vote down vote up
describe("framework.detectFramework", () => {
  afterEach(() => {
    jest.resetAllMocks();
  });

  test("it should detect a supported framework", () => {
    const pkg: JsonPackage = {
      name: "fake",
      version: "fakeBeta",
      dependencies: {
        [Frameworks.next]: "beta",
      },
    };

    const result: Frameworks = FrameworkUtils.detectFramework(pkg);
    expect(result).toEqual(Frameworks.next);
  });

  test("it should not detect an unsupported framework and fallback to vanillajs", () => {
    const pkg: JsonPackage = {
      name: "fake",
      version: "fakeBeta",
      dependencies: {
        [Frameworks.next]: "beta",
      },
    };

    // simulate supporting 0 frameworks.
    const result: Frameworks = FrameworkUtils.detectFramework(pkg, []);
    expect(result).toEqual(Frameworks.vanillajs);
  });
});
Example #5
Source File: PureLanguageHelper.test.ts    From legend-studio with Apache License 2.0 5 votes vote down vote up
afterEach(() => {
  // running all pending timers and switching to real timers using Jest
  // See https://testing-library.com/docs/using-fake-timers/
  jest.runOnlyPendingTimers();
  // NOTE: since `jest.useFakeTimers()` is global, it can leak across tests, we need to reset after every test
  jest.useRealTimers();
});
Example #6
Source File: mainfest.test.ts    From slice-machine with Apache License 2.0 5 votes vote down vote up
describe("maybeRepoNameFromSMFile", () => {
  afterEach(() => {
    jest.resetAllMocks();
  });

  jest.spyOn(console, "log").mockImplementationOnce(() => undefined);

  test("should return null if sm.json is not found", () => {
    jest.spyOn(fs, "lstatSync").mockImplementationOnce(() => undefined);
    const result = maybeRepoNameFromSMFile(__dirname, "https://prismic.io");
    expect(result).toBeNull();
  });

  test("should return null if apiEndpoint is not defined", () => {
    jest.spyOn(fs, "lstatSync").mockImplementationOnce(() => ({} as fs.Stats));
    jest.spyOn(fs, "readFileSync").mockReturnValueOnce(JSON.stringify({}));

    const result = maybeRepoNameFromSMFile(__dirname, "https://prismic.io");
    expect(result).toBeNull();
  });

  test("should return null if sm.json is unreadable", () => {
    jest.spyOn(fs, "lstatSync").mockImplementationOnce(() => ({} as fs.Stats));
    jest
      .spyOn(fs, "readFileSync")
      .mockReturnValueOnce("fake value that isn't a regular json");

    const result = maybeRepoNameFromSMFile(__dirname, "https://prismic.io");
    expect(result).toBeNull();
  });

  test("should return null if apiEndpoint is malformed", () => {
    jest.spyOn(fs, "lstatSync").mockImplementationOnce(() => ({} as fs.Stats));
    jest
      .spyOn(fs, "readFileSync")
      .mockReturnValueOnce(
        JSON.stringify({ apiEndpoint: "fake value that is not a valid url" })
      );

    const result = maybeRepoNameFromSMFile(__dirname, "https://prismic.io");
    expect(result).toBeNull();
  });

  test("should return null if apiEndpoint is on a different base", () => {
    const fakeConfig = { apiEndpoint: "https://example.com" };

    jest.spyOn(fs, "lstatSync").mockImplementationOnce(() => ({} as fs.Stats));
    jest
      .spyOn(fs, "readFileSync")
      .mockReturnValueOnce(JSON.stringify(fakeConfig));

    const result = maybeRepoNameFromSMFile(__dirname, "https://prismic.io");
    expect(result).toBeNull();
  });

  test("should return the repo name from the apiEdinpoint", () => {
    const fakeConfig = { apiEndpoint: "https://foo-bar.prismic.io/api/v2" };

    jest.spyOn(fs, "lstatSync").mockImplementationOnce(() => ({} as fs.Stats));
    jest
      .spyOn(fs, "readFileSync")
      .mockReturnValueOnce(JSON.stringify(fakeConfig));

    const result = maybeRepoNameFromSMFile(__dirname, "https://prismic.io");
    expect(result).toBe("foo-bar");
  });
});
Example #7
Source File: slices.spec.tsx    From slice-machine with Apache License 2.0 5 votes vote down vote up
afterEach(() => server.resetHandlers());
Example #8
Source File: cookie.test.ts    From slice-machine with Apache License 2.0 5 votes vote down vote up
describe("cookie", () => {
  afterEach(() => {
    jest.clearAllMocks();
  });

  describe("parsePrismicAuthToken", () => {
    test("should extract correctly cookie from a well formed cookie string", () => {
      const cookieString =
        "SESSION=0a41c2a9944577c6000b5b1ffdbae884492641d6-T=_9T%27X0%2BIZM%3EPN8Y%3F7H44MRX8%3CD%5B%5EZ%2BW%27Q%2B+_G%3CSE7%5BAR6WS%3EB8%2BR%5C6V%2B%25D%29RGXSJ%3B&U=kevinj%40overlay-tech.com&I=09c00b56e4&C=19719956967e75293da8612c36d44427be2223f376e27bd9bbcf5080b072620e-1634750164799-1fdc0de28b3028b1196c2bfdfe6432242e6b8d0a05620980cc9405f6a8a5494648&D=1634725810; Path=/; SameSite=None; prismic-auth=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVC.eyJ0eXBlIjoidXNlciIsImlkIjoiNjBjMGUzNzIxMTAwMDAyMjAwZDQxMGExIiwiZGF0ZSI6MTYzNDc1MDE2NCwiaWF0IjoxNjM0NzUwMTY0fQ.BuhlVAJATAPeQi-HQWEh0LwuXBoU4UpXk1XxWDILU38";
      const result = parsePrismicAuthToken(cookieString);
      expect(result).toBe(
        "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVC.eyJ0eXBlIjoidXNlciIsImlkIjoiNjBjMGUzNzIxMTAwMDAyMjAwZDQxMGExIiwiZGF0ZSI6MTYzNDc1MDE2NCwiaWF0IjoxNjM0NzUwMTY0fQ.BuhlVAJATAPeQi-HQWEh0LwuXBoU4UpXk1XxWDILU38"
      );
    });

    test("should return empty string from a empty cookie string", () => {
      const result = parsePrismicAuthToken("");
      expect(result).toBe("");
    });

    test("should return empty string from a wrong formed cookie string", () => {
      const wrongCookieString =
        "SESSION=0a41c2a9944577c6000b5b1ffdbae884492641d6-T=_9T%27X0%2BIZM%3EPN8Y%3F7H44MRX8%3CD%5B%5EZ%2BW%27Q%2B+_G%3CSE7%5BAR6WS%3EB8%2BR%5C6V%2B%25D%29RGXSJ%3B&U=kevinj%40overlay-tech.com&I=09c00b56e4&C=19719956967e75293da8612c36d44427be2223f376e27bd9bbcf5080b072620e-1634750164799-1fdc0de28b3028b1196c2bfdfe6432242e6b8d0a05620980cc9405f6a8a5494648&D=1634725810; Path=/; SameSite=None; fake-auth=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVC.eyJ0eXBlIjoidXNlciIsImlkIjoiNjBjMGUzNzIxMTAwMDAyMjAwZDQxMGExIiwiZGF0ZSI6MTYzNDc1MDE2NCwiaWF0IjoxNjM0NzUwMTY0fQ.BuhlVAJATAPeQi-HQWEh0LwuXBoU4UpXk1XxWDILU38";
      const result = parsePrismicAuthToken(wrongCookieString);
      expect(result).toBe("");
    });
  });

  describe("serializeCookies", () => {
    test("should create an cookie string with multiple cookies", () => {
      const cookies = [
        "SESSION=0a41c2a9944577c6000b5b1ffdbae884492641d6-T=_9T%27X0%2BIZM%3EPN8Y%3F7H44MRX8%3CD%5B%5EZ%2BW%27Q%2B+_G%3CSE7%5BAR6WS%3EB8%2BR%5C6V%2B%25D%29RGXSJ%3B&U=kevinj%40overlay-tech.com&I=09c00b56e4&C=19719956967e75293da8612c36d44427be2223f376e27bd9bbcf5080b072620e-1634750164799-1fdc0de28b3028b1196c2bfdfe6432242e6b8d0a05620980cc9405f6a8a5494648&D=1634725810; Path=/; SameSite=None; fake-auth=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVC.eyJ0eXBlIjoidXNlciIsImlkIjoiNjBjMGUzNzIxMTAwMDAyMjAwZDQxMGExIiwiZGF0ZSI6MTYzNDc1MDE2NCwiaWF0IjoxNjM0NzUwMTY0fQ.BuhlVAJATAPeQi-HQWEh0LwuXBoU4UpXk1XxWDILU38",
        "prismic-auth=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVC.eyJ0eXBlIjoidXNlciIsImlkIjoiNjBjMGUzNzIxMTAwMDAyMjAwZDQxMGExIiwiZGF0ZSI6MTYzNDc1MDE2NCwiaWF0IjoxNjM0NzUwMTY0fQ.BuhlVAJATAPeQi-HQWEh0LwuXBoU4UpXk1XxWDILU38; Path=/; SameSite=None",
      ];
      const result = serializeCookies(cookies);
      expect(result).toBe(
        "SESSION=0a41c2a9944577c6000b5b1ffdbae884492641d6-T=_9T%27X0%2BIZM%3EPN8Y%3F7H44MRX8%3CD%5B%5EZ%2BW%27Q%2B+_G%3CSE7%5BAR6WS%3EB8%2BR%5C6V%2B%25D%29RGXSJ%3B&U=kevinj%40overlay-tech.com&I=09c00b56e4&C=19719956967e75293da8612c36d44427be2223f376e27bd9bbcf5080b072620e-1634750164799-1fdc0de28b3028b1196c2bfdfe6432242e6b8d0a05620980cc9405f6a8a5494648&D=1634725810; Path=/; SameSite=None; fake-auth=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVC.eyJ0eXBlIjoidXNlciIsImlkIjoiNjBjMGUzNzIxMTAwMDAyMjAwZDQxMGExIiwiZGF0ZSI6MTYzNDc1MDE2NCwiaWF0IjoxNjM0NzUwMTY0fQ.BuhlVAJATAPeQi-HQWEh0LwuXBoU4UpXk1XxWDILU38; prismic-auth=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVC.eyJ0eXBlIjoidXNlciIsImlkIjoiNjBjMGUzNzIxMTAwMDAyMjAwZDQxMGExIiwiZGF0ZSI6MTYzNDc1MDE2NCwiaWF0IjoxNjM0NzUwMTY0fQ.BuhlVAJATAPeQi-HQWEh0LwuXBoU4UpXk1XxWDILU38"
      );
    });
  });

  describe("serializeCookie", () => {
    test("should extract correctly cookie from a well formed cookie string", () => {
      const result = serializeCookie(
        "prismic-auth",
        "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVC.eyJ0eXBlIjoidXNlciIsImlkIjoiNjBjMGUzNzIxMTAwMDAyMjAwZDQxMGExIiwiZGF0ZSI6MTYzNDc1MDE2NCwiaWF0IjoxNjM0NzUwMTY0fQ.BuhlVAJATAPeQi-HQWEh0LwuXBoU4UpXk1XxWDILU38"
      );
      expect(result).toBe(
        "prismic-auth=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVC.eyJ0eXBlIjoidXNlciIsImlkIjoiNjBjMGUzNzIxMTAwMDAyMjAwZDQxMGExIiwiZGF0ZSI6MTYzNDc1MDE2NCwiaWF0IjoxNjM0NzUwMTY0fQ.BuhlVAJATAPeQi-HQWEh0LwuXBoU4UpXk1XxWDILU38"
      );
    });
  });
});
Example #9
Source File: cts.spec.tsx    From slice-machine with Apache License 2.0 5 votes vote down vote up
afterEach(() => server.resetHandlers());
Example #10
Source File: communication.test.ts    From slice-machine with Apache License 2.0 5 votes vote down vote up
afterEach(() => {
  jest.clearAllMocks();
});
Example #11
Source File: logInOrBypass.test.ts    From slice-machine with Apache License 2.0 5 votes vote down vote up
afterEach(() => {
  jest.clearAllMocks();
});
Example #12
Source File: slices.spec.tsx    From slice-machine with Apache License 2.0 4 votes vote down vote up
describe("slices", () => {
  const fakeTracker = jest.fn().mockImplementation(() => Promise.resolve());

  beforeAll(async () => {
    const div = document.createElement("div");
    div.setAttribute("id", "__next");
    document.body.appendChild(div);

    const fakeAnalytics = jest
      .spyOn(AnalyticsBrowser, "standalone")
      .mockResolvedValue({
        track: fakeTracker,
      } as any);

    await Tracker.get().initialize("foo", "repoName");
    expect(fakeAnalytics).toHaveBeenCalled();
  });

  afterEach(() => {
    jest.clearAllMocks();
  });

  beforeEach(async () => {
    mockRouter.setCurrentUrl("/slices");
  });

  test("When user creates a slice it should send a tracking event", async () => {
    const environment = {
      framework: "next",
      mockConfig: { _cts: {} },
    };

    const libraries = [
      {
        path: "./slices",
        isLocal: true,
        name: "slices",
        meta: {
          isNodeModule: false,
          isDownloaded: false,
          isManual: true,
        },
        components: [
          {
            from: "slices",
            href: "slices",
            pathToSlice: "./slices",
            fileName: "index",
            extension: "js",
            screenshotPaths: {},
            mock: [
              {
                variation: "default",
                name: "Default",
                slice_type: "test_slice",
                items: [],
                primary: {
                  title: [
                    {
                      type: "heading1",
                      text: "Cultivate granular e-services",
                      spans: [],
                    },
                  ],
                  description: [
                    {
                      type: "paragraph",
                      text: "Anim in commodo exercitation qui. Elit cillum officia mollit dolore. Commodo voluptate sit est proident ea proident dolor esse ad.",
                      spans: [],
                    },
                  ],
                },
              },
            ],
            model: {
              id: "test_slice",
              type: "SharedSlice",
              name: "TestSlice",
              description: "TestSlice",
              variations: [
                {
                  id: "default",
                  name: "Default",
                  docURL: "...",
                  version: "sktwi1xtmkfgx8626",
                  description: "TestSlice",
                  primary: [
                    {
                      key: "title",
                      value: {
                        type: "StructuredText",
                        config: {
                          single: "heading1",
                          label: "Title",
                          placeholder: "This is where it all begins...",
                        },
                      },
                    },
                    {
                      key: "description",
                      value: {
                        type: "StructuredText",
                        config: {
                          single: "paragraph",
                          label: "Description",
                          placeholder: "A nice description of your feature",
                        },
                      },
                    },
                  ],
                  items: [],
                  imageUrl:
                    "https://images.prismic.io/slice-machine/621a5ec4-0387-4bc5-9860-2dd46cbc07cd_default_ss.png?auto=compress,format",
                },
              ],
            },
            screenshotUrls: {},
            __status: "NEW_SLICE",
          },
        ],
      },
    ];
    const App = render(
      <LibrariesProvider
        env={environment}
        libraries={libraries}
        remoteSlices={[]}
      >
        <SlicesIndex />
      </LibrariesProvider>,
      {
        preloadedState: {
          environment,
          slices: {
            libraries,
            remoteSlices: [],
          },
        },
      }
    );

    const createOneButton = document.querySelector('[data-cy="create-slice"]');
    await act(async () => {
      fireEvent.click(createOneButton);
    });

    const nameInput = document.querySelector('[data-cy="slice-name-input"]');
    await act(async () => {
      fireEvent.change(nameInput, { target: { value: "FooBar" } });
    });

    const submitButton = screen.getByText("Create");
    await act(async () => {
      fireEvent.click(submitButton);
    });

    // very hacky, done because of bug where calling Router.router.push causes issues with re-renders and context
    delete window.location;
    window.location = {} as Location;

    await waitFor(() => {
      expect(fakeTracker).toHaveBeenCalledWith(
        "SliceMachine Slice Created",
        { id: "FooBar", name: "FooBar", library: "slices" },
        { context: { groupId: { Repository: "repoName" } } }
      );
    });
  });
});
Example #13
Source File: cts.spec.tsx    From slice-machine with Apache License 2.0 4 votes vote down vote up
describe("Custom Type Builder", () => {
  const fakeTracker = jest.fn().mockImplementation(() => Promise.resolve());

  beforeAll(async () => {
    const div = document.createElement("div");
    div.setAttribute("id", "__next");
    document.body.appendChild(div);

    const fakeAnalytics = jest
      .spyOn(AnalyticsBrowser, "standalone")
      .mockResolvedValue({
        track: fakeTracker,
      } as any);

    await Tracker.get().initialize("foo", "repoName");
    expect(fakeAnalytics).toHaveBeenCalled();
  });

  afterEach(() => {
    jest.clearAllMocks();
  });

  beforeEach(async () => {
    mockRouter.setCurrentUrl("/");
  });

  test("should send a tracking event when the user adds a field", async () => {
    const customTypeId = "a-page";

    singletonRouter.push({
      pathname: "cts/[ct]",
      query: { ct: customTypeId },
    });

    const App = render(<CreateCustomTypeBuilder />, {
      preloadedState: {
        environment: {
          framework: "next",
          mockConfig: { _cts: { [customTypeId]: {} } },
        },
        availableCustomTypes: {
          [customTypeId]: {
            local: {
              id: customTypeId,
              label: customTypeId,
              repeatable: true,
              status: true,
              tabs: [
                {
                  key: "Main",
                  value: [],
                },
              ],
            },
          },
        },
        selectedCustomType: {
          model: {
            id: "a-page",
            label: "a-page",
            repeatable: true,
            status: true,
            tabs: [
              {
                key: "Main",
                value: [],
              },
            ],
          },
          initialModel: {
            id: "a-page",
            label: "a-page",
            repeatable: true,
            status: true,
            tabs: [
              {
                key: "Main",
                value: [],
              },
            ],
          },
          mockConfig: {},
          initialMockConfig: {},
        },
      },
    });

    const addButton = screen.getByTestId("empty-zone-add-new-field");
    fireEvent.click(addButton);

    const uid = screen.getByText("UID");
    fireEvent.click(uid);

    const saveFieldButton = screen.getByText("Add");

    await act(async () => {
      fireEvent.click(saveFieldButton);
    });

    expect(fakeTracker).toHaveBeenCalledWith(
      "SliceMachine Custom Type Field Added",
      { id: "uid", name: "a-page", type: "UID", zone: "static" },
      { context: { groupId: { Repository: "repoName" } } }
    );
  });

  test("should send a tracking event when the user adds a slice", async () => {
    const customTypeId = "a-page";

    singletonRouter.push({
      pathname: "cts/[ct]",
      query: { ct: customTypeId },
    });

    // duplicated state for library context :/

    const environment = {
      framework: "next",
      mockConfig: { _cts: { [customTypeId]: {} } },
    };

    const libraries = [
      {
        path: "./slices",
        isLocal: true,
        name: "slices",
        meta: {
          isNodeModule: false,
          isDownloaded: false,
          isManual: true,
        },
        components: [
          {
            from: "slices",
            href: "slices",
            pathToSlice: "./slices",
            fileName: "index",
            extension: "js",
            screenshotPaths: {},
            mock: [
              {
                variation: "default",
                name: "Default",
                slice_type: "test_slice",
                items: [],
                primary: {
                  title: [
                    {
                      type: "heading1",
                      text: "Cultivate granular e-services",
                      spans: [],
                    },
                  ],
                  description: [
                    {
                      type: "paragraph",
                      text: "Anim in commodo exercitation qui. Elit cillum officia mollit dolore. Commodo voluptate sit est proident ea proident dolor esse ad.",
                      spans: [],
                    },
                  ],
                },
              },
            ],
            model: {
              id: "test_slice",
              type: "SharedSlice",
              name: "TestSlice",
              description: "TestSlice",
              variations: [
                {
                  id: "default",
                  name: "Default",
                  docURL: "...",
                  version: "sktwi1xtmkfgx8626",
                  description: "TestSlice",
                  primary: [
                    {
                      key: "title",
                      value: {
                        type: "StructuredText",
                        config: {
                          single: "heading1",
                          label: "Title",
                          placeholder: "This is where it all begins...",
                        },
                      },
                    },
                    {
                      key: "description",
                      value: {
                        type: "StructuredText",
                        config: {
                          single: "paragraph",
                          label: "Description",
                          placeholder: "A nice description of your feature",
                        },
                      },
                    },
                  ],
                  items: [],
                  imageUrl:
                    "https://images.prismic.io/slice-machine/621a5ec4-0387-4bc5-9860-2dd46cbc07cd_default_ss.png?auto=compress,format",
                },
              ],
            },
            screenshotUrls: {},
            __status: "NEW_SLICE",
          },
        ],
      },
    ];

    const App = render(
      <LibrariesProvider
        env={environment}
        libraries={libraries}
        remoteSlices={[]}
      >
        <CreateCustomTypeBuilder />
      </LibrariesProvider>,
      {
        preloadedState: {
          environment,
          availableCustomTypes: {
            [customTypeId]: {
              local: {
                id: customTypeId,
                label: customTypeId,
                repeatable: true,
                status: true,
                tabs: [
                  {
                    key: "Main",
                    value: [],
                  },
                ],
              },
            },
          },
          selectedCustomType: {
            model: {
              id: "a-page",
              label: "a-page",
              repeatable: true,
              status: true,
              tabs: [
                {
                  key: "Main",
                  value: [],
                },
              ],
            },
            initialModel: {
              id: "a-page",
              label: "a-page",
              repeatable: true,
              status: true,
              tabs: [
                {
                  key: "Main",
                  value: [],
                },
              ],
            },
            mockConfig: {},
            initialMockConfig: {},
          },
          slices: {
            libraries,
            remoteSlices: [],
          },
        },
      }
    );

    const addButton = screen.getByTestId("empty-zone-add-a-new-slice");
    await act(async () => {
      fireEvent.click(addButton);
    });

    const slicesToSelect = screen.getAllByTestId("slicezone-modal-item");

    for (const elem of slicesToSelect) {
      await act(async () => {
        fireEvent.click(elem);
      });
    }

    const saveButton = screen.getByText("Save");

    await act(async () => {
      fireEvent.click(saveButton);
    });

    expect(fakeTracker).toHaveBeenCalledWith(
      "SliceMachine Slicezone Updated",
      { customTypeId },
      { context: { groupId: { Repository: "repoName" } } }
    );
  });

  test("it should send a tracking event when the user saves a custom-type", async () => {
    const customTypeId = "a-page";

    singletonRouter.push({
      pathname: "cts/[ct]",
      query: { ct: customTypeId },
    });

    const App = render(<CreateCustomTypeBuilder />, {
      preloadedState: {
        environment: {
          framework: "next",
          mockConfig: { _cts: { [customTypeId]: {} } },
        },
        availableCustomTypes: {
          [customTypeId]: {
            local: {
              id: customTypeId,
              label: customTypeId,
              repeatable: true,
              status: true,
              tabs: [
                {
                  key: "Main",
                  value: [],
                },
              ],
            },
          },
        },
        selectedCustomType: {
          model: {
            id: "a-page",
            label: "a-page",
            repeatable: true,
            status: true,
            tabs: [
              {
                key: "Main",
                value: [],
              },
            ],
          },
          initialModel: {
            id: "a-page",
            label: "a-page",
            repeatable: true,
            status: true,
            tabs: [
              {
                key: "Main",
                value: [],
              },
            ],
          },
          mockConfig: {},
          initialMockConfig: {},
        },
      },
    });

    const addButton = screen.getByTestId("empty-zone-add-new-field");
    fireEvent.click(addButton);

    const uid = screen.getByText("UID");
    fireEvent.click(uid);

    const saveFieldButton = screen.getByText("Add");

    await act(async () => {
      fireEvent.click(saveFieldButton);
    });

    expect(fakeTracker).toHaveBeenCalledWith(
      "SliceMachine Custom Type Field Added",
      { id: "uid", name: customTypeId, type: "UID", zone: "static" },
      { context: { groupId: { Repository: "repoName" } } }
    );

    const saveCustomType = screen.getByText("Save to File System");

    await act(async () => {
      fireEvent.click(saveCustomType);
    });

    await waitFor(() => {
      expect(fakeTracker).toHaveBeenLastCalledWith(
        "SliceMachine Custom Type Saved",
        { type: "repeatable", id: customTypeId, name: customTypeId },
        { context: { groupId: { Repository: "repoName" } } }
      );
    });
  });

  test("if saving fails a it should not send the save event", async () => {
    server.use(
      rest.post("/api/custom-types/save", (_, res, ctx) => {
        return res(ctx.status(500), ctx.json({}));
      })
    );
    const customTypeId = "a-page";

    singletonRouter.push({
      pathname: "cts/[ct]",
      query: { ct: customTypeId },
    });

    const App = render(<CreateCustomTypeBuilder />, {
      preloadedState: {
        environment: {
          framework: "next",
          mockConfig: { _cts: { [customTypeId]: {} } },
        },
        availableCustomTypes: {
          [customTypeId]: {
            local: {
              id: customTypeId,
              label: customTypeId,
              repeatable: true,
              status: true,
              tabs: [
                {
                  key: "Main",
                  value: [],
                },
              ],
            },
          },
        },
        selectedCustomType: {
          model: {
            id: "a-page",
            label: "a-page",
            repeatable: true,
            status: true,
            tabs: [
              {
                key: "Main",
                value: [],
              },
            ],
          },
          initialModel: {
            id: "a-page",
            label: "a-page",
            repeatable: true,
            status: true,
            tabs: [
              {
                key: "Main",
                value: [],
              },
            ],
          },
          mockConfig: {},
          initialMockConfig: {},
        },
      },
    });

    const addButton = screen.getByTestId("empty-zone-add-new-field");
    fireEvent.click(addButton);

    const uid = screen.getByText("UID");
    fireEvent.click(uid);

    const saveFieldButton = screen.getByText("Add");

    await act(async () => {
      fireEvent.click(saveFieldButton);
    });

    expect(fakeTracker).toHaveBeenCalledWith(
      "SliceMachine Custom Type Field Added",
      { id: "uid", name: customTypeId, type: "UID", zone: "static" },
      { context: { groupId: { Repository: "repoName" } } }
    );

    const saveCustomType = screen.getByText("Save to File System");

    await act(async () => {
      fireEvent.click(saveCustomType);
    });

    await new Promise((r) => setTimeout(r, 1000));

    expect(fakeTracker).toHaveBeenCalledTimes(1);
  });

  test("when the user pushes a custom-type it should send a tracking event", async () => {
    const customTypeId = "a-page";

    server.use(
      rest.get("/api/custom-types/push", (req, res, ctx) => {
        expect(req.url.searchParams.get("id")).toEqual(customTypeId);
        return res(ctx.json({}));
      })
    );

    singletonRouter.push({
      pathname: "cts/[ct]",
      query: { ct: customTypeId },
    });

    const App = render(<CreateCustomTypeBuilder />, {
      preloadedState: {
        environment: {
          framework: "next",
          mockConfig: { _cts: { [customTypeId]: {} } },
        },
        availableCustomTypes: {
          [customTypeId]: {
            local: {
              id: customTypeId,
              label: customTypeId,
              repeatable: true,
              status: true,
              tabs: [
                {
                  key: "Main",
                  value: [],
                },
              ],
            },
          },
        },
        selectedCustomType: {
          model: {
            id: "a-page",
            label: "a-page",
            repeatable: true,
            status: true,
            tabs: [
              {
                key: "Main",
                value: [],
              },
            ],
          },
          initialModel: {
            id: "a-page",
            label: "a-page",
            repeatable: true,
            status: true,
            tabs: [
              {
                key: "Main",
                value: [],
              },
            ],
          },
          mockConfig: {},
          initialMockConfig: {},
        },
      },
    });

    const pushButton = screen.getByText("Push to Prismic");
    await act(async () => {
      fireEvent.click(pushButton);
    });

    await waitFor(() => {
      expect(fakeTracker).toHaveBeenCalledWith(
        "SliceMachine Custom Type Pushed",
        { id: customTypeId, name: customTypeId, type: "repeatable" },
        { context: { groupId: { Repository: "repoName" } } }
      );
    });
  });
});
Example #14
Source File: auth.test.ts    From slice-machine with Apache License 2.0 4 votes vote down vote up
describe("auth", () => {
  beforeEach(() => nock.cleanAll());

  afterEach(() => {
    jest.clearAllMocks();
  });

  const fakeBase = "https://fake.io";
  const endpoints = Endpoints.buildEndpoints(fakeBase);

  test("login should always have the same parameters", async () => {
    const fakeProfile = {
      email: "[email protected]",
      type: "USER",
      repositories: {},
    };

    jest.spyOn(fs, "lstatSync").mockReturnValue({} as fs.Stats);
    const fakeCookie = {
      base: fakeBase,
      cookies: "prismic-auth=biscuits",
    };

    jest.spyOn(fs, "readFileSync").mockReturnValue(JSON.stringify(fakeCookie)); // called more than once?

    nock("https://auth.fake.io")
      .get("/validate?token=biscuits")
      .reply(200, fakeProfile);

    const spy = jest.spyOn(authHelpers, "startServerAndOpenBrowser"); // untestable code, should be refactored
    spy.mockImplementation((url, action, base) => {
      expect(url).toEqual(endpoints.Dashboard.cliLogin);
      expect(action).toEqual("login");
      expect(base).toEqual(fakeBase);
      return Promise.resolve({ onLoginFail: () => null });
    });

    await Auth.login(fakeBase);
  });

  test("signup should always open the browser at the same url", async () => {
    const fakeProfile = {
      email: "[email protected]",
      type: "USER",
      repositories: {},
    };

    jest.spyOn(fs, "lstatSync").mockReturnValue({} as fs.Stats);
    const fakeCookie = {
      base: fakeBase,
      cookies: "prismic-auth=biscuits",
    };

    jest.spyOn(fs, "readFileSync").mockReturnValue(JSON.stringify(fakeCookie)); // called more than once?

    nock("https://auth.fake.io")
      .get("/validate?token=biscuits")
      .reply(200, fakeProfile);
    const spy = jest.spyOn(authHelpers, "startServerAndOpenBrowser");

    spy.mockImplementation((url, action, base) => {
      expect(url).toEqual(endpoints.Dashboard.cliSignup);
      expect(action).toEqual("signup");
      expect(base).toEqual(fakeBase);
      return Promise.resolve({ onLoginFail: () => null });
    });

    await Auth.signup(fakeBase);
  });

  test("isHandler should work", () => {
    const handlerData: authHelpers.HandlerData = {
      email: "fake",
      cookies: ["bla", "ta", "cla"],
    };

    const nonHandlerData = "this should not work";
    const nonHandlerData2 = {
      email: "this should not work",
    };
    const nonHandlerData3 = {
      cookies: {
        status: "this is not an array",
      },
    };
    const nonHandlerData4 = {
      email: "this should not work",
      cookies: {
        status: "this is not an array",
      },
    };
    const nonHandlerData5 = {
      email: "this should not work",
      cookies: ["2", 3, 4],
    };

    expect(authHelpers.isHandlerData(handlerData)).toBe(true);
    expect(authHelpers.isHandlerData(nonHandlerData)).toBe(false);
    expect(authHelpers.isHandlerData(nonHandlerData2)).toBe(false);
    expect(authHelpers.isHandlerData(nonHandlerData3)).toBe(false);
    expect(authHelpers.isHandlerData(nonHandlerData4)).toBe(false);
    expect(authHelpers.isHandlerData(nonHandlerData5)).toBe(false);
  });

  test("validate session should return null if there is no cookies", async () => {
    jest.spyOn(fs, "lstatSync").mockReturnValueOnce({} as fs.Stats);
    jest
      .spyOn(fs, "readFileSync")
      .mockReturnValueOnce(JSON.stringify({ base: fakeBase, cookies: "" }));

    const result = await Auth.validateSession(fakeBase);
    expect(result).toBe(null);
  });

  test("validate session should return null if there is different bases", async () => {
    jest.spyOn(fs, "lstatSync").mockReturnValueOnce({} as fs.Stats);
    const fakeCookie = {
      base: "https://prismic.io",
      cookies: "prismic-auth=biscuits",
    };
    jest
      .spyOn(fs, "readFileSync")
      .mockReturnValueOnce(JSON.stringify(fakeCookie));

    const result = await Auth.validateSession(fakeBase);
    expect(result).toBe(null);
  });

  test("validate session should return null when validate session reject the promise", async () => {
    const fakeCookie = {
      base: "https://prismic.io",
      cookies: "prismic-auth=biscuits",
    };
    jest.spyOn(fs, "lstatSync").mockReturnValueOnce({} as fs.Stats);
    jest
      .spyOn(fs, "readFileSync")
      .mockReturnValueOnce(JSON.stringify(fakeCookie));

    nock("https://auth.prismic.io").get("/validate?token=biscuits").reply(401);

    const result = await Auth.validateSession(fakeBase);
    expect(result).toBe(null);
  });

  test("validate session should work", async () => {
    const fakeCookie = {
      base: "https://prismic.io",
      cookies: "prismic-auth=biscuits",
    };

    const wanted = {
      email: "[email protected]",
      type: "USER",
      repositories: {
        "foo-repo": { dbid: "abcd", role: Roles.PUBLISHER },
        qwerty: { dbid: "efgh", role: Roles.WRITER },
      },
    };

    jest.spyOn(fs, "lstatSync").mockReturnValueOnce({} as fs.Stats);
    // readFileSync seems to be called more than once :/
    jest
      .spyOn(fs, "readFileSync")
      .mockReturnValueOnce(JSON.stringify(fakeCookie));

    nock("https://auth.prismic.io")
      .get("/validate?token=biscuits")
      .reply(200, wanted);

    const got = await Auth.validateSession(fakeCookie.base);
    expect(got).toEqual(wanted);
  });
});
Example #15
Source File: install-required-dependencies.test.ts    From slice-machine with Apache License 2.0 4 votes vote down vote up
describe("install required dependency", () => {
  void afterEach(() => {
    jest.clearAllMocks();
  });

  const fakeCWD = "..";

  test("it should use yarn to install Slice Machine", async () => {
    const spy = jest
      .spyOn(initUtils, "execCommand")
      .mockImplementation(() => Promise.resolve({ stderr: "", stdout: "" }));

    jest
      .spyOn(fs, "lstatSync")
      .mockReturnValueOnce({} as fs.Stats) // verify if yarn lock file exists
      .mockReturnValueOnce({} as fs.Stats); // verify package has been installed

    stderr.start();

    await installRequiredDependencies(fakeCWD, Models.Frameworks.nuxt);

    stderr.stop();

    expect(spy).toHaveBeenCalled();
    expect(spy).toHaveBeenCalledWith(`yarn add -D ${CONSTS.SM_PACKAGE_NAME}`);

    expect(stderr.output).toContain("Downloading Slice Machine");
    expect(stderr.output).toContain(
      "✔ Slice Machine was installed successfully"
    );
  });

  test("it should use npm to install Slice Machine", async () => {
    const spy = jest
      .spyOn(initUtils, "execCommand")
      .mockImplementation(() => Promise.resolve({ stderr: "", stdout: "" }));

    jest
      .spyOn(fs, "lstatSync")
      .mockImplementationOnce(() => {
        const e = new ErrnoException();
        e.code = "ENOENT";
        throw e;
      })
      .mockReturnValueOnce({} as fs.Stats);

    stderr.start();

    await installRequiredDependencies(fakeCWD, Models.Frameworks.nuxt);

    stderr.stop();

    expect(spy).toHaveBeenCalled();
    expect(spy).toHaveBeenCalledWith(
      `npm install --save-dev ${CONSTS.SM_PACKAGE_NAME}`
    );

    expect(stderr.output).toContain("Downloading Slice Machine");
    expect(stderr.output).toContain(
      "✔ Slice Machine was installed successfully"
    );
  });

  test("when using react it should install @prismicio/client and @prismicio/react and @prismicio/helpers", async () => {
    const spy = jest
      .spyOn(initUtils, "execCommand")
      .mockImplementation(() => Promise.resolve({ stderr: "", stdout: "" }));

    jest
      .spyOn(fs, "lstatSync")
      .mockImplementationOnce(() => {
        const e = new ErrnoException();
        e.code = "ENOENT";
        throw e;
      })
      .mockReturnValueOnce({} as fs.Stats);

    const fakedir = path.join(os.tmpdir(), "install-deps");

    stderr.start();

    await installRequiredDependencies(fakedir, Models.Frameworks.react);

    stderr.stop();

    expect(spy).toHaveBeenCalled();
    expect(spy).toHaveBeenCalledWith(
      "npm install --save @prismicio/react @prismicio/client @prismicio/helpers"
    );

    expect(stderr.output).toContain("Downloading Slice Machine");
    expect(stderr.output).toContain(
      "✔ Slice Machine was installed successfully"
    );
  });

  test("when using next it should install next deps and next-slicezone", async () => {
    const spy = jest
      .spyOn(initUtils, "execCommand")
      .mockImplementation(() => Promise.resolve({ stderr: "", stdout: "" }));

    jest
      .spyOn(fs, "lstatSync")
      .mockImplementationOnce(() => {
        const e = new ErrnoException();
        e.code = "ENOENT";
        throw e;
      })
      .mockReturnValueOnce({} as fs.Stats);

    const fakedir = path.join(os.tmpdir(), "install-deps");

    stderr.start();

    await installRequiredDependencies(fakedir, Models.Frameworks.next);

    stderr.stop();

    expect(spy).toHaveBeenCalled();
    expect(spy).toHaveBeenCalledWith(
      "npm install --save @prismicio/react @prismicio/client @prismicio/slice-simulator-react @prismicio/helpers"
    );

    expect(stderr.output).toContain("Downloading Slice Machine");
    expect(stderr.output).toContain(
      "✔ Slice Machine was installed successfully"
    );
  });

  test("when using svelte it should install prismic-dom", async () => {
    const spy = jest
      .spyOn(initUtils, "execCommand")
      .mockImplementation(() => Promise.resolve({ stderr: "", stdout: "" }));

    jest
      .spyOn(fs, "lstatSync")
      .mockImplementationOnce(() => {
        const e = new ErrnoException();
        e.code = "ENOENT";
        throw e;
      })
      .mockReturnValueOnce({} as fs.Stats);

    const fakedir = path.join(os.tmpdir(), "install-deps");

    stderr.start();

    await installRequiredDependencies(fakedir, Models.Frameworks.svelte);

    stderr.stop();

    expect(spy).toHaveBeenCalled();
    expect(spy).toHaveBeenCalledWith(
      "npm install --save prismic-dom @prismicio/client"
    );

    expect(stderr.output).toContain("Downloading Slice Machine");
    expect(stderr.output).toContain(
      "✔ Slice Machine was installed successfully"
    );
  });

  test("when using nuxt is should install @nuxtjs/prismic", async () => {
    const spy = jest
      .spyOn(initUtils, "execCommand")
      .mockImplementation(() => Promise.resolve({ stderr: "", stdout: "" }));

    jest
      .spyOn(fs, "lstatSync")
      .mockImplementationOnce(() => {
        const e = new ErrnoException();
        e.code = "ENOENT";
        throw e;
      })
      .mockReturnValueOnce({} as fs.Stats);

    const fakedir = path.join(os.tmpdir(), "install-deps");

    stderr.start();

    await installRequiredDependencies(fakedir, Models.Frameworks.nuxt);

    stderr.stop();

    expect(spy).toHaveBeenCalled();
    expect(spy).toHaveBeenCalledWith(
      "npm install --save @nuxtjs/prismic @prismicio/slice-simulator-vue"
    );

    expect(stderr.output).toContain("Downloading Slice Machine");
    expect(stderr.output).toContain(
      "✔ Slice Machine was installed successfully"
    );
  });

  test("when using vue is should install @prismicio/vue @prismicio/client prismic-dom", async () => {
    const spy = jest
      .spyOn(initUtils, "execCommand")
      .mockImplementation(() => Promise.resolve({ stderr: "", stdout: "" }));

    jest
      .spyOn(fs, "lstatSync")
      .mockImplementationOnce(() => {
        const e = new ErrnoException();
        e.code = "ENOENT";
        throw e;
      })
      .mockReturnValueOnce({} as fs.Stats);

    const fakedir = path.join(os.tmpdir(), "install-deps");

    stderr.start();

    await installRequiredDependencies(fakedir, Models.Frameworks.vue);

    stderr.stop();

    expect(spy).toHaveBeenCalled();
    expect(spy).toHaveBeenCalledWith(
      "npm install --save @prismicio/vue @prismicio/client prismic-dom"
    );

    expect(stderr.output).toContain("Downloading Slice Machine");
    expect(stderr.output).toContain(
      "✔ Slice Machine was installed successfully"
    );
  });
});
Example #16
Source File: install-lib.test.ts    From slice-machine with Apache License 2.0 4 votes vote down vote up
describe("install-lib", () => {
  const fakeCWD = path.join(os.tmpdir(), "install-lib-test");
  jest.spyOn(process, "exit").mockReturnValue(void 0 as never);

  afterEach(() => {
    jest.clearAllMocks();
  });

  beforeAll(() => {
    if (fs.existsSync(fakeCWD)) {
      fs.rmSync(fakeCWD, { recursive: true, force: true });
    }
    fs.mkdirSync(fakeCWD, { recursive: true });
  });

  test("by default it downloads zip form the HEAD branch from github", async () => {
    const user = "prismicio";
    const project = "foo";
    const gitpath = path.posix.join(user, project);
    const branch = "HEAD";

    const Theme = new AdmZip();
    const themePath = path.join(__dirname, "__stubs__", "fake-project");

    Theme.addLocalFolder(themePath, `${project}-${branch}`);

    const zip = Theme.toBuffer();

    nock("https://codeload.github.com")
      .get(`/${gitpath}/zip/${branch}`)
      .reply(200, zip, {
        "Content-Type": "application/zip",
        "content-length": zip.length.toString(),
      });

    // quick fix, I would rather mock child_process.exec
    jest
      .spyOn(utils, "execCommand")
      .mockResolvedValue({ stderr: "", stdout: "" });

    stderr.start();
    stdout.start();
    const libs = await installLib(fakeCWD, gitpath);

    stderr.stop();
    stdout.stop();

    expect(
      fs.existsSync(path.join(fakeCWD, `${user}-${project}`, "meta.json"))
    ).toBeTruthy();

    expect(stderr.output).toContain(
      'Slice library "prismicio/foo" was installed successfully'
    );
    expect(libs).toContain(
      path.posix.join("~", `${user}-${project}`, "slices")
    );
  });

  test("it can take a branch as an argument", async () => {
    const user = "prismicio";
    const project = "baz";
    const gitpath = path.posix.join(user, project);
    const branch = "not-main-or-master";

    const Theme = new AdmZip();
    const themePath = path.join(__dirname, "__stubs__", "fake-project");

    Theme.addLocalFolder(themePath, `${project}-${branch}`);

    const zip = Theme.toBuffer();

    nock("https://codeload.github.com")
      .get(`/${gitpath}/zip/${branch}`)
      .reply(200, zip, {
        "Content-Type": "application/zip",
        "content-length": zip.length.toString(),
      });

    // quick fix, I would rather mock child_process.exec
    jest
      .spyOn(utils, "execCommand")
      .mockResolvedValue({ stderr: "", stdout: "" });

    stderr.start();
    stdout.start();
    const libs = await installLib(fakeCWD, gitpath, branch);
    stderr.stop();
    stderr.stop();

    expect(stderr.output).toContain(
      'Slice library "prismicio/baz" was installed successfully'
    );

    expect(
      fs.existsSync(path.join(fakeCWD, `${user}-${project}`, "meta.json"))
    ).toBeTruthy();

    expect(libs).toContain(
      path.posix.join("~", `${user}-${project}`, "slices")
    );
  });

  test("when given branch or project does not exist.", async () => {
    const user = "prismicio";
    const project = "batman";
    const gitpath = path.posix.join(user, project);
    const branch = "nope";

    nock("https://codeload.github.com")
      .get(`/${gitpath}/zip/${branch}`)
      .reply(404);

    // quick fix, I would rather mock child_process.exec
    jest
      .spyOn(utils, "execCommand")
      .mockResolvedValue({ stderr: "", stdout: "" });

    jest.spyOn(console, "error").mockImplementation(() => jest.fn());

    stderr.start();
    stdout.start();
    await installLib(fakeCWD, gitpath, branch);
    stderr.stop();
    stderr.stop();

    expect(console.error).toHaveBeenLastCalledWith(
      "Request failed with status code 404"
    );
  });
});
Example #17
Source File: detect-framework.test.ts    From slice-machine with Apache License 2.0 4 votes vote down vote up
describe("detect-framework", () => {
  void afterEach(() => {
    jest.resetAllMocks();
  });

  test("when supported framework is found", async () => {
    const mockedFs = mocked(fs, true);
    mockedFs.lstatSync.mockReturnValue({ dev: 1 } as fs.Stats); // linting error?
    mockedFs.readFileSync.mockReturnValue(
      JSON.stringify({
        dependencies: {
          [Models.Frameworks.next]: "beta",
        },
      })
    );

    stderr.start();
    const result = await detectFramework(__dirname).catch();
    stderr.stop();
    expect(fs.lstatSync).toHaveBeenCalled();
    expect(result).toEqual({
      value: Models.Frameworks.next,
      manuallyAdded: false,
    });
  });

  test("framework not found in package.json", async () => {
    jest.spyOn(fs, "lstatSync").mockReturnValueOnce({ dev: 1 } as fs.Stats); // linting error?
    jest.spyOn(fs, "readFileSync").mockReturnValueOnce(
      JSON.stringify({
        dependencies: {},
      })
    );

    jest.spyOn(inquirer, "prompt").mockReturnValue(
      Promise.resolve({
        framework: Models.Frameworks.next,
      }) as ReturnType<typeof inquirer.prompt>
    );

    const fakeError = jest
      .spyOn(console, "error")
      .mockImplementationOnce(() => undefined);

    stderr.start();
    const result = await detectFramework(__dirname);
    stderr.stop();
    expect(result).toEqual({
      value: Models.Frameworks.next,
      manuallyAdded: true,
    });
    expect(fs.lstatSync).toHaveBeenCalled();
    expect(fakeError).toBeCalledWith(
      `${logs.error("Error!")} Framework not detected`
    );
  });

  test("package.json not found", async () => {
    jest.spyOn(fs, "lstatSync").mockReturnValue(undefined);

    const exitSpy = jest
      .spyOn(process, "exit")
      .mockImplementation(() => "next" as never);
    const errorSpy = jest
      .spyOn(console, "error")
      .mockImplementation(() => undefined);

    stderr.start();
    await detectFramework(__dirname);
    stderr.stop();

    expect(errorSpy).toHaveBeenCalledWith(
      "[api/env]: Unrecoverable error. Could not find package.json. Exiting.."
    );
    expect(stderr.output).toContain("package.json not found");
    expect(exitSpy).toHaveBeenCalled();
  });

  test("Unsupported framework: gatsby", async () => {
    jest.spyOn(fs, "lstatSync").mockReturnValueOnce({ dev: 1 } as fs.Stats);
    jest.spyOn(fs, "readFileSync").mockReturnValueOnce(
      JSON.stringify({
        dependencies: {
          [Models.Frameworks.gatsby]: "beta",
          [Models.Frameworks.react]: "beta",
        },
      })
    );

    const exitSpy = jest
      .spyOn(process, "exit")
      .mockImplementationOnce(() => undefined as never);
    const errorSpy = jest
      .spyOn(console, "error")
      .mockImplementation(() => undefined);

    const logSpy = jest
      .spyOn(console, "log")
      .mockImplementation(() => undefined);

    stderr.start();
    await detectFramework(__dirname);
    stderr.stop();

    expect(exitSpy).toHaveBeenCalled();
    expect(errorSpy).toHaveBeenCalledWith(
      `${logs.error("Error!")} Gatsby is currently not supported`
    );
    expect(logSpy).toHaveBeenCalledWith(
      `Please run ${logs.bold(
        "npx @slicemachine/init"
      )} in a Nuxt or Next.js project`
    );
  });
});
Example #18
Source File: configure-project.test.ts    From slice-machine with Apache License 2.0 4 votes vote down vote up
describe("configure-project", () => {
  void beforeEach(() => {
    jest.spyOn(process, "exit").mockImplementation((number) => number as never);
    Tracker.get().initialize("foo");
    Tracker.get().setRepository("repoName");
  });

  void afterEach(() => {
    jest.clearAllMocks();
  });

  const fakeCwd = "./";
  const fakeBase = "https://music.to.my.hears.io" as Prismic.Endpoints.Base;
  const fakeRepository = "testing-repo";
  const fakeFrameworkStats = {
    value: Models.Frameworks.react,
    manuallyAdded: false,
  };

  const retrieveManifestMock = NodeUtils.retrieveManifest as jest.Mock;
  const createManifestMock = NodeUtils.createManifest as jest.Mock;
  const patchManifestMock = NodeUtils.patchManifest as jest.Mock;
  const addJsonPackageSmScriptMock =
    NodeUtils.addJsonPackageSmScript as jest.Mock;

  const { exists, mkdir } = NodeUtils.Files;
  const fileExistsMock = exists as jest.Mock;
  const mkdirMock = mkdir as jest.Mock;

  test("it should create a new manifest if it doesn't exist yet", async () => {
    retrieveManifestMock.mockReturnValue({
      exists: false,
      content: null,
    });
    addJsonPackageSmScriptMock.mockReturnValue(true);

    await configureProject(
      fakeCwd,
      fakeBase,
      fakeRepository,
      fakeFrameworkStats,
      []
    );

    expect(retrieveManifestMock).toBeCalled();
    expect(createManifestMock).toHaveBeenCalledWith("./", {
      _latest: "0.0.41",
      apiEndpoint: "https://testing-repo.music.to.my.hears.io/api/v2",
      libraries: ["@/slices"],
    });
    expect(patchManifestMock).not.toBeCalled();

    expect(successFn).toHaveBeenCalled();
    expect(failFn).not.toHaveBeenCalled();
    expect(MockTracker).toHaveBeenCalled();
  });

  test("it should patch the existing manifest", async () => {
    retrieveManifestMock.mockReturnValue({
      exists: true,
      content: {
        framework: Models.Frameworks.react,
      },
    });
    addJsonPackageSmScriptMock.mockReturnValue(true);

    await configureProject(
      fakeCwd,
      fakeBase,
      fakeRepository,
      fakeFrameworkStats,
      []
    );

    expect(retrieveManifestMock).toBeCalled();
    expect(patchManifestMock).toHaveBeenCalledWith("./", {
      apiEndpoint: "https://testing-repo.music.to.my.hears.io/api/v2",
      framework: "react",
      libraries: ["@/slices"],
    });

    expect(successFn).toHaveBeenCalled();
    expect(failFn).not.toHaveBeenCalled();
    expect(MockTracker).toHaveBeenCalled();
  });

  test("it should patch the existing manifest with external lib", async () => {
    retrieveManifestMock.mockReturnValue({
      exists: true,
      content: {
        framework: Models.Frameworks.react,
      },
    });
    addJsonPackageSmScriptMock.mockReturnValue(true);

    await configureProject(
      fakeCwd,
      fakeBase,
      fakeRepository,
      fakeFrameworkStats,
      ["@/material/slices"]
    );

    expect(retrieveManifestMock).toBeCalled();
    expect(patchManifestMock).toHaveBeenCalledWith("./", {
      apiEndpoint: "https://testing-repo.music.to.my.hears.io/api/v2",
      framework: "react",
      libraries: ["@/slices", "@/material/slices"],
    });

    expect(successFn).toHaveBeenCalled();
    expect(failFn).not.toHaveBeenCalled();
    expect(MockTracker).toHaveBeenCalled();
  });

  test("it should fail if retrieve manifest throws", async () => {
    retrieveManifestMock.mockImplementation(() => {
      throw new Error("fake error to test the catch");
    });

    // process.exit should throw
    await configureProject(
      fakeCwd,
      fakeBase,
      fakeRepository,
      fakeFrameworkStats,
      []
    );

    expect(retrieveManifestMock).toBeCalled();
    expect(createManifestMock).not.toBeCalled();
    expect(patchManifestMock).not.toBeCalled();

    expect(successFn).not.toHaveBeenCalled();
    expect(failFn).toHaveBeenCalled();
    expect(MockTracker).not.toHaveBeenCalled();
  });

  test("it should fail if create or update manifest throws", async () => {
    retrieveManifestMock.mockReturnValue({
      exists: false,
      content: null,
    });
    createManifestMock.mockImplementation(() => {
      throw new Error("fake error to test the catch");
    });

    await configureProject(
      fakeCwd,
      fakeBase,
      fakeRepository,
      fakeFrameworkStats,
      []
    );

    expect(retrieveManifestMock).toBeCalled();
    expect(createManifestMock).toBeCalled();
    expect(patchManifestMock).not.toBeCalled();

    expect(successFn).not.toHaveBeenCalled();
    expect(failFn).toHaveBeenCalled();
    expect(MockTracker).not.toHaveBeenCalled();
  });

  test("it should fail if add SM script throws", async () => {
    retrieveManifestMock.mockReturnValue({
      exists: false,
      content: null,
    });
    createManifestMock.mockReturnValue(null); // we don't care about this void.
    addJsonPackageSmScriptMock.mockImplementation(() => {
      throw new Error("fake error to test the catch");
    });

    await configureProject(
      fakeCwd,
      fakeBase,
      fakeRepository,
      fakeFrameworkStats,
      []
    );

    expect(retrieveManifestMock).toBeCalled();
    expect(createManifestMock).toBeCalled();
    expect(patchManifestMock).not.toBeCalled();

    expect(successFn).not.toHaveBeenCalled();
    expect(failFn).toHaveBeenCalled();
    expect(MockTracker).not.toHaveBeenCalled();
  });

  test("it should create a slice folder if it doesnt exists.", async () => {
    // situation where the SM.Json doesn't exists.
    retrieveManifestMock.mockReturnValue({
      exists: false,
      content: null,
    });
    addJsonPackageSmScriptMock.mockReturnValue(true);

    // only called to verify if slice folder exists.
    fileExistsMock.mockReturnValue(false);

    await configureProject(
      fakeCwd,
      fakeBase,
      fakeRepository,
      fakeFrameworkStats
    );

    expect(mkdirMock).toHaveBeenCalled();
    expect(MockTracker).toHaveBeenCalled();
  });

  test("it shouldn' create a slice folder if it exists.", async () => {
    // situation where the SM.Json doesn't exists.
    retrieveManifestMock.mockReturnValue({
      exists: false,
      content: null,
    });
    addJsonPackageSmScriptMock.mockReturnValue(true);
    // only called to verify if slice folder exists.
    fileExistsMock.mockReturnValue(true);

    await configureProject(
      fakeCwd,
      fakeBase,
      fakeRepository,
      fakeFrameworkStats
    );

    expect(mkdirMock).not.toHaveBeenCalled();
    expect(MockTracker).toHaveBeenCalled();
  });
});
Example #19
Source File: choose-or-create-repo.test.ts    From slice-machine with Apache License 2.0 4 votes vote down vote up
describe("choose-or-create-repo", () => {
  void afterEach(() => {
    jest.restoreAllMocks();
  });

  const fakeCwd = "./";
  const framework = Models.Frameworks.svelte;

  test("prompts user to select a repo", async () => {
    const repoDomain = "test";
    const base = "https://prismic.io";

    jest
      .spyOn(inquirer, "prompt")
      .mockReturnValue(
        Promise.resolve({ repoDomain }) as ReturnType<typeof inquirer.prompt>
      );
    jest.spyOn(console, "log").mockImplementationOnce(() => undefined);
    const result = await promptForRepoDomain(base);

    expect(inquirer.prompt).toHaveBeenCalledTimes(1);
    expect(createRepositoryMock).toHaveBeenCalledTimes(0);
    expect(result).toBe(repoDomain);
  });

  test("if user has no repos it asks them to create a repo", async () => {
    const repoDomain = "repoDomain";
    const base = "https://prismic.io";
    const cookies = "prismic-auth=biscuits;";
    const userServiceURL = "https://user.internal-prismic.io";

    nock(userServiceURL).get("/repositories").reply(200, []);

    jest
      .spyOn(inquirer, "prompt")
      .mockReturnValue(
        Promise.resolve({ repoDomain }) as ReturnType<typeof inquirer.prompt>
      );
    createRepositoryMock.mockImplementation(() => repoDomain);
    jest.spyOn(console, "log").mockImplementationOnce(() => undefined);

    const result = await chooseOrCreateARepository(
      fakeCwd,
      framework,
      cookies,
      base
    );

    expect(createRepositoryMock).toHaveBeenCalledWith(
      repoDomain,
      framework,
      cookies,
      base
    );
    expect(inquirer.prompt).toHaveBeenCalledTimes(1);
    expect(result).toEqual(repoDomain);
  });

  test("it allows a user to create a new repo", async () => {
    const repoDomain = "test";
    const base = "https://prismic.io";
    const userServiceURL = "https://user.internal-prismic.io";
    const cookies = "prismic-auth=biscuits;";

    nock(userServiceURL)
      .get("/repositories")
      .reply(200, [{ domain: "foo", name: "foo", role: Models.Roles.OWNER }]);

    jest
      .spyOn(inquirer, "prompt")
      .mockReturnValueOnce(
        Promise.resolve({ chosenRepo: CREATE_REPO }) as ReturnType<
          typeof inquirer.prompt
        >
      )
      .mockReturnValueOnce(
        Promise.resolve({ repoDomain }) as ReturnType<typeof inquirer.prompt>
      );

    createRepositoryMock.mockImplementation(() => Promise.resolve(repoDomain));
    jest.spyOn(console, "log").mockImplementationOnce(() => undefined);

    const result = await chooseOrCreateARepository(
      fakeCwd,
      framework,
      cookies,
      base
    );

    expect(createRepositoryMock).toHaveBeenCalledWith(
      repoDomain,
      framework,
      cookies,
      base
    );
    expect(inquirer.prompt).toHaveBeenCalledTimes(2);
    expect(result).toEqual(repoDomain);
  });

  test("when given project and project exists, the project is pre-selected and the user is not asked to select a project", async () => {
    const domain = "foo-bar";
    const base = "https://prismic.io";
    const userServiceURL = "https://user.internal-prismic.io";
    const cookies = "prismic-auth=biscuits;";

    nock(userServiceURL)
      .get("/repositories")
      .reply(200, [
        { domain: domain, name: "Foo Bar", role: Models.Roles.OWNER },
      ]);

    const promptSpy = jest.spyOn(inquirer, "prompt");

    const result = await chooseOrCreateARepository(
      fakeCwd,
      framework,
      cookies,
      base,
      domain
    );

    expect(promptSpy).not.toHaveBeenCalled();
    expect(result).toEqual(domain);
  });

  test("when the given a project and the project does not exist in the users repo's it should prompt them for a repo", async () => {
    const domain = "foo-bar";
    const base = "https://prismic.io";
    const userServiceURL = "https://user.internal-prismic.io";
    const cookies = "prismic-auth=biscuits;";

    nock(userServiceURL).get("/repositories").reply(200, []);

    createRepositoryMock.mockImplementation(() => Promise.resolve(domain));

    jest.spyOn(console, "log").mockImplementationOnce(() => undefined);

    const promptSpy = jest
      .spyOn(inquirer, "prompt")
      .mockReturnValue(
        Promise.resolve({ repoDomain: domain }) as ReturnType<
          typeof inquirer.prompt
        >
      );

    const result = await chooseOrCreateARepository(
      fakeCwd,
      framework,
      cookies,
      base,
      domain
    );

    expect(promptSpy).toHaveBeenCalledTimes(1);
    expect(promptSpy).toHaveBeenLastCalledWith(
      expect.arrayContaining([expect.objectContaining({ default: domain })])
    );
    expect(result).toEqual(domain);
  });
});
Example #20
Source File: communication.test.ts    From slice-machine with Apache License 2.0 4 votes vote down vote up
describe("communication", () => {
  afterEach(() => {
    jest.clearAllMocks();
  });

  afterAll(() => {
    return nock.restore();
  });

  const fakeCookie = "prismic-auth=biscuits;";
  test("validateSession, default base", async () => {
    const responseData = {
      email: "[email protected]",
      type: "USER",
      repositories: {
        "foo-repo": { dbid: "abcd", role: Roles.OWNER },
        qwerty: { dbid: "efgh", role: Roles.WRITER },
      },
    };
    nock("https://auth.prismic.io")
      .get("/validate?token=biscuits")
      .reply(200, responseData);

    return communication.validateSession(fakeCookie).then((data) => {
      expect(data).toEqual(responseData);
    });
  });

  test("validateSession, custom base", async () => {
    const responseData = {
      email: "[email protected]",
      type: "USER",
      repositories: {
        "foo-repo": { dbid: "abcd", role: Roles.OWNER },
        qwerty: { dbid: "efgh", role: Roles.WRITER },
      },
    };
    nock("https://auth.wroom.io")
      .get("/validate?token=biscuits")
      .reply(200, responseData);

    return communication
      .validateSession(fakeCookie, "https://wroom.io")
      .then((data) => {
        expect(data).toEqual(responseData);
      });
  });

  test("refreshSession", async () => {
    const token = "biscuits";
    const base = "https://prismic.io";
    const wanted = "some-new-token";
    nock("https://auth.prismic.io")
      .get(`/refreshtoken?token=${token}`)
      .reply(200, wanted);
    const result = await communication.refreshSession(
      `prismic-auth=${token}`,
      base
    );
    expect(result).toEqual(wanted);
  });

  test("listRepositories", async () => {
    const responseData = [
      { domain: "foo-repo", name: "foo-repo", role: "Administrator" },
      { domain: "qwerty", name: "qwerty", role: "Administrator" },
    ];
    nock("https://user.internal-prismic.io")
      .get("/repositories")
      .reply(200, responseData);

    const result = await communication.listRepositories(fakeCookie);
    expect(result).toEqual(responseData);
  });

  describe("validateRepositoryName", () => {
    const fakeBase = "https://prismic.io";

    test("should fail if subdomain is not defined", () => {
      const fn = () => communication.validateRepositoryName();
      return expect(fn).rejects.toThrow("repository name is required");
    });

    test("no upper case letters", () => {
      const fn = () => communication.validateRepositoryName("Abcd");
      return expect(fn).rejects.toThrow(
        "Must contain only lowercase letters, numbers and hyphens"
      );
    });

    test("should fail if name length is less than 4", () => {
      const fn = () => communication.validateRepositoryName("abc");
      return expect(fn).rejects.toThrow(
        "Must have four or more alphanumeric characters and/or hyphens."
      );
    });

    test("should fail if the name contains non alphanumeric characters", () => {
      const fn = () => communication.validateRepositoryName("a.bc");
      return expect(fn).rejects.toThrow(
        "Must contain only lowercase letters, numbers and hyphens"
      );
    });

    test("should fail if the name starts with a hyphen", () => {
      const fn = () => communication.validateRepositoryName("-abc");
      return expect(fn).rejects.toThrow("start with a letter");
    });

    test("should fail if the name ends with a hyphen", () => {
      const fn = () => communication.validateRepositoryName("abc-");
      return expect(fn).rejects.toThrow("Must end in a letter or a number");
    });

    test("Max length 30 characters", () => {
      const repoName = Array.from({ length: 31 }, () => "a").join("");
      const fn = () => communication.validateRepositoryName(repoName);
      return expect(fn).rejects.toThrow("30 characters or less");
    });

    test("multiple errors", () => {
      const repoName = "-abc.d";
      const fn = () => communication.validateRepositoryName(repoName);
      return expect(fn).rejects.toThrow(
        "(1: Must start with a letter. (2: Must contain only lowercase letters, numbers and hyphens."
      );
    });

    test("should fail if repo name is not available", () => {
      const repoName = "test";
      nock(fakeBase)
        .get(`/app/dashboard/repositories/${repoName}/exists`)
        .reply(200, () => false);

      const fn = () => communication.validateRepositoryName(repoName);

      return expect(fn).rejects.toThrow("already in use");
    });

    test("existing repo", () => {
      const repoName = "test";
      nock(fakeBase)
        .get(`/app/dashboard/repositories/${repoName}/exists`)
        .reply(200, () => false);
      return expect(
        communication.validateRepositoryName(repoName, fakeBase, true)
      ).resolves.toEqual(repoName);
    });

    test("existing repo, does not exist", () => {
      const repoName = "test";
      nock(fakeBase)
        .get(`/app/dashboard/repositories/${repoName}/exists`)
        .reply(200, () => true);
      return expect(
        communication.validateRepositoryName(repoName, fakeBase, true)
      ).rejects.toThrow("does not exist");
    });

    test("should pass if repo name is valid and available", () => {
      const repoName = "test";
      nock(fakeBase)
        .get(`/app/dashboard/repositories/${repoName}/exists`)
        .reply(200, () => true);

      return expect(
        communication.validateRepositoryName(repoName)
      ).resolves.toEqual(repoName);
    });

    test("different base", () => {
      const repoName = "test";
      nock("https://example.com")
        .get(`/app/dashboard/repositories/${repoName}/exists`)
        .reply(200, () => true);

      return expect(
        communication.validateRepositoryName(repoName, "https://example.com")
      ).resolves.toEqual(repoName);
    });
  });

  describe("createRepository", () => {
    const cookies = "prismic-auth=biscuit;";
    const repoName = "test";

    test("with default arguments it should call the prismic.io endpoint to create a new repo", async () => {
      const formData = {
        domain: repoName,
        framework: Frameworks.vanillajs,
        plan: "personal",
        isAnnual: "false",
        role: "developer",
      };

      nock("https://prismic.io")
        .post("/authentication/newrepository?app=slicemachine", formData)
        .reply(200, { domain: repoName });

      const result = await communication.createRepository(repoName, cookies);
      expect(result.data.domain).toEqual(repoName);
    });

    test("with framework and different base", async () => {
      const fakeBase = "https://example.com";
      const framework = Frameworks.next;

      const formData = {
        domain: repoName,
        framework,
        plan: "personal",
        isAnnual: "false",
        role: "developer",
      };

      nock(fakeBase)
        .post("/authentication/newrepository?app=slicemachine", formData)
        .reply(200, { domain: repoName });

      const result = await communication.createRepository(
        repoName,
        cookies,
        framework,
        fakeBase
      );
      expect(result.data.domain).toEqual(repoName);
    });
  });
});
Example #21
Source File: framework.test.ts    From slice-machine with Apache License 2.0 4 votes vote down vote up
describe("framework.defineFrameworks", () => {
  afterEach(() => {
    jest.resetAllMocks();
  });

  test("it should take the framework from the pkg json if there isn't in the manifest", () => {
    const fakeManifest = {
      apiEndpoint: "fake api endpoint",
    };

    const mockedFs = mocked(fs, true);
    mockedFs.lstatSync.mockReturnValue({ dev: 1 } as fs.Stats);

    mockedFs.readFileSync.mockReturnValue(
      JSON.stringify({
        dependencies: {
          [Frameworks.next]: "beta",
        },
      })
    );

    const result: Frameworks = FrameworkUtils.defineFramework({
      cwd: "not important",
      manifest: fakeManifest,
    });
    expect(result).toEqual(Frameworks.next);
  });

  test("it should take the framework from the manifest", () => {
    const fakeManifest: Manifest = {
      apiEndpoint: "fake api endpoint",
      framework: Frameworks.next,
    };

    const result: Frameworks = FrameworkUtils.defineFramework({
      cwd: "not important",
      manifest: fakeManifest,
    });
    expect(result).toEqual(Frameworks.next);
  });

  test("it should take the framework from the pkg json if the one in manifest isn't supported", () => {
    const fakeManifest: Manifest = {
      apiEndpoint: "fake api endpoint",
      framework: FrameworkUtils.UnsupportedFrameWorks[0],
    };

    const mockedFs = mocked(fs, true);
    mockedFs.lstatSync.mockReturnValue({ dev: 1 } as fs.Stats);

    mockedFs.readFileSync.mockReturnValue(
      JSON.stringify({
        dependencies: {
          [Frameworks.next]: "beta",
        },
      })
    );

    const result: Frameworks = FrameworkUtils.defineFramework({
      cwd: "not important",
      manifest: fakeManifest,
    });
    expect(result).toEqual(Frameworks.next);
  });

  test("it should default to vanillajs if no manifest and the pkg json framework is unsupported", () => {
    const unsupportedFramework = FrameworkUtils.UnsupportedFrameWorks[0];

    const mockedFs = mocked(fs, true);
    mockedFs.lstatSync.mockReturnValue({ dev: 1 } as fs.Stats);

    mockedFs.readFileSync.mockReturnValue(
      JSON.stringify({
        dependencies: {
          [unsupportedFramework]: "beta",
        },
      })
    );

    const result: Frameworks = FrameworkUtils.defineFramework({
      cwd: "not important",
    });
    expect(result).toEqual(Frameworks.vanillajs);
  });

  test("it should default to vanillajs if package and manifest aren't good", () => {
    const unsupportedFramework = FrameworkUtils.UnsupportedFrameWorks[0];

    const fakeManifest: Manifest = {
      apiEndpoint: "fake api endpoint",
      framework: unsupportedFramework,
    };

    const mockedFs = mocked(fs, true);
    mockedFs.lstatSync.mockReturnValue({ dev: 1 } as fs.Stats);

    mockedFs.readFileSync.mockReturnValue(
      JSON.stringify({
        dependencies: {
          [unsupportedFramework]: "beta",
        },
      })
    );

    const result: Frameworks = FrameworkUtils.defineFramework({
      cwd: "not important",
      manifest: fakeManifest,
    });
    expect(result).toEqual(Frameworks.vanillajs);
  });
});