Repository: freeCodeCamp/freeCodeCamp
File: client/src/components/growth-book/growth-book-wrapper.test.tsx (TypeScript)

Code before:

vi.mock('../../../config/growthbook-features-default.json', () => ({
  default: {
    mockFeature: { defaultValue: true }
  }
}));

let currentInitImpl: () =>
  | Promise<{ success: boolean; source?: string }>
  | Promise<never> = () => Promise.resolve({ success: true });

const mockInit = vi.fn(() => currentInitImpl());
const mockSetPayload = vi.fn((_arg: Record<string, unknown>) =>
  Promise.resolve()
);
const mockSetAttributes = vi.fn((_arg: Record<string, unknown>) =>
  Promise.resolve()
);

export function setInitImpl(
  impl: () => Promise<{ success: boolean; source?: string }> | Promise<never>
) {
  currentInitImpl = impl;
}

vi.mock('@growthbook/growthbook-react', () => {
  interface GrowthBookLike {
    init: () => Promise<unknown>;
    setPayload: (arg: Record<string, unknown>) => Promise<void>;
    setAttributes: (arg: Record<string, unknown>) => Promise<void>;
  }

  const GrowthBook = vi.fn().mockImplementation(function (
    this: GrowthBookLike
  ) {
    this.init = vi.fn(() => mockInit());
    this.setPayload = vi.fn((arg: Record<string, unknown>) =>
      mockSetPayload(arg)
    );
    this.setAttributes = vi.fn((arg: Record<string, unknown>) =>
      mockSetAttributes(arg)
    );
  });

  const GrowthBookProvider = ({ children }: { children: React.ReactNode }) => (
    <div>{children}</div>
  );

  return { GrowthBook, GrowthBookProvider };
});


Review comment (suggestion):
Sorry, I can't seem to wrangle github into letting me leave suggestions, but I think the following is simpler:

```tsx
vi.mock('@growthbook/growthbook-react', () => ({
  GrowthBook: class {
    init() {
      return mockInit();
    }
    setPayload(arg: Record<string, unknown>) {
      return mockSetPayload(arg);
    }
    setAttributes(arg: Record<string, unknown>) {
      return mockSetAttributes(arg);
    }
  },

  GrowthBookProvider: ({ children }: { children: React.ReactNode }) => (
    <div>{children}</div>
  )
}));
```

Code after:

vi.mock('../../../config/growthbook-features-default.json', () => ({
  default: {
    mockFeature: { defaultValue: true }
  }
}));

let currentInitImpl: () =>
  | Promise<{ success: boolean; source?: string }>
  | Promise<never> = () => Promise.resolve({ success: true });

const mockInit = vi.fn(() => currentInitImpl());
const mockSetPayload = vi.fn((_arg: Record<string, unknown>) =>
  Promise.resolve()
);
const mockSetAttributes = vi.fn((_arg: Record<string, unknown>) =>
  Promise.resolve()
);

export function setInitImpl(
  impl: () => Promise<{ success: boolean; source?: string }> | Promise<never>
) {
  currentInitImpl = impl;
}

vi.mock('@growthbook/growthbook-react', () => ({
  GrowthBook: class {
    init() {
      return mockInit();
    }
    setPayload(arg: Record<string, unknown>) {
      return mockSetPayload(arg);
    }
    setAttributes(arg: Record<string, unknown>) {
      return mockSetAttributes(arg);
    }
  },

  GrowthBookProvider: ({ children }: { children: React.ReactNode }) => (
    <div>{children}</div>
  )
}));

function renderWrapper(initOptions: { complete: boolean }) {
  return render(
    <UnconnectedTestWrapper
      user={{ completedChallenges: [], email: '', joinDate: '' }}
      userFetchState={{
        pending: false,
        complete: initOptions.complete,
        errored: false,