ronantakizawa/codereview-bench huggingface dataset:
Repository: freeCodeCamp/freeCodeCamp
File: api/src/routes/settings.ts (TypeScript)

Code before:
      try {
        await fastify.prisma.user.update({
          where: { id: req.session.user.id },
          data: {
            theme: req.body.theme
          }
        });

        return {
          message: 'flash.updated-themes',
          type: 'success'
        } as const;
      } catch (err) {
        fastify.log.error(err);
        void reply.code(500);
        return { message: 'flash.wrong-updating', type: 'danger' } as const;
      }
    }
  );

  fastify.put(
    '/update-my-honesty',
    {
      schema: {
        body: Type.Object({
          isHonest: Type.Boolean()
        }),
        response: {
          200: Type.Object({
            message: Type.Literal('buttons.accepted-honesty'),
            type: Type.Literal('success')
          }),
          500: Type.Object({
            message: Type.Literal('flash.wrong-updating'),
            type: Type.Literal('danger')
          })
        }
      }
    },
    async (req, reply) => {
      try {
        await fastify.prisma.user.update({
          where: { id: req.session.user.id },
          data: {
            isHonest: req.body.isHonest
          }
        });

        return {
          message: 'buttons.accepted-honesty',
          type: 'success'

Review comment (suggestion):
```suggestion
          isHonest: Type.Literal(true)
```
Sorry, I missed this the first time around. We need to follow the old api's validation where possible.

Code after:
      try {
        await fastify.prisma.user.update({
          where: { id: req.session.user.id },
          data: {
            theme: req.body.theme
          }
        });

        return {
          message: 'flash.updated-themes',
          type: 'success'
        } as const;
      } catch (err) {
        fastify.log.error(err);
        void reply.code(500);
        return { message: 'flash.wrong-updating', type: 'danger' } as const;
      }
    }
  );

  fastify.put(
    '/update-my-keyboard-shortcuts',
    {
      schema: {
        body: Type.Object({
          keyboardShortcuts: Type.Boolean()
        }),
        response: {
          200: Type.Object({
            message: Type.Literal('flash.keyboard-shortcut-updated'),
            type: Type.Literal('success')
          }),
          500: Type.Object({
            message: Type.Literal('flash.wrong-updating'),
            type: Type.Literal('danger')
          })
        }
      }
    },
    async (req, reply) => {
      try {
        await fastify.prisma.user.update({
          where: { id: req.session.user.id },
          data: {
            keyboardShortcuts: req.body.keyboardShortcuts
          }
        });

        return {
          message: 'flash.keyboard-shortcut-updated',
          type: 'success'
Repository: freeCodeCamp/freeCodeCamp
File: api/src/routes/settings.test.ts (TypeScript)

Code before:
          .set('Cookie', cookies)
          .send({ sendQuincyEmail: 'invalid' });

        expect(response?.statusCode).toEqual(400);
      });
    });

    describe('/update-my-honesty', () => {
      test('PUT returns 200 status code with "success" message', async () => {
        const response = await request(fastify?.server)
          .put('/update-my-honesty')
          .set('Cookie', cookies)
          .send({ honesty: true });

        expect(response?.statusCode).toEqual(200);

        expect(response?.body).toEqual({
          type: 'success'
        });
      });

      test('PUT returns 400 status code with invalid honesty', async () => {
        const response = await request(fastify?.server)
          .put('/update-my-honesty')
          .set('Cookie', cookies)
          .send({ honesty: 'invalid' });

        expect(response?.statusCode).toEqual(400);
      });
    });
  });

  describe('Unauthenticated User', () => {
    test('PUT /update-my-profileui returns 401 status code for un-authenticated users', async () => {
      const response = await request(fastify?.server).put(
        '/update-my-profileui'
      );

      expect(response?.statusCode).toEqual(401);
    });

    test('PUT /update-my-theme returns 401 status code for un-authenticated users', async () => {
      const response = await request(fastify?.server).put('/update-my-theme');

      expect(response?.statusCode).toEqual(401);
    });
  });
});


Review comment (suggestion):
```suggestion
          .send({ isHonest: 'invalid' });
```

Code after:
          .set('Cookie', cookies)
          .send({ sendQuincyEmail: 'invalid' });

        expect(response?.statusCode).toEqual(400);
      });
    });

    describe('/update-my-honesty', () => {
      test('PUT returns 200 status code with "success" message', async () => {
        const response = await request(fastify?.server)
          .put('/update-my-honesty')
          .set('Cookie', cookies)
          .send({ isHonest: true });

        expect(response?.statusCode).toEqual(200);

        expect(response?.body).toEqual({
          message: 'buttons.accepted-honesty',
          type: 'success'
        });
      });

      test('PUT returns 400 status code with invalid honesty', async () => {
        const response = await request(fastify?.server)
          .put('/update-my-honesty')
          .set('Cookie', cookies)
          .send({ isHonest: false });

        expect(response?.statusCode).toEqual(400);
      });
    });
  });

  describe('Unauthenticated User', () => {
    test('PUT /update-my-profileui returns 401 status code for un-authenticated users', async () => {
      const response = await request(fastify?.server).put(
        '/update-my-profileui'
      );

      expect(response?.statusCode).toEqual(401);
    });

    test('PUT /update-my-theme returns 401 status code for un-authenticated users', async () => {
      const response = await request(fastify?.server).put('/update-my-theme');

      expect(response?.statusCode).toEqual(401);
    });
  });
});
Repository: freeCodeCamp/freeCodeCamp
File: api/src/routes/settings.ts (TypeScript)

Code before:
        void reply.code(500);
        return { message: 'flash.wrong-updating', type: 'danger' } as const;
      }
    }
  );

  fastify.put(
    '/update-my-quincy-email',
    {
      schema: {
        body: Type.Object({
          sendQuincyEmail: Type.Boolean()
        }),
        response: {
          200: Type.Object({
            message: Type.Literal('flash.subscribe-to-quincy-updated'),
            type: Type.Literal('success')
          }),
          500: Type.Object({
            message: Type.Literal('flash.wrong-updating'),
            type: Type.Literal('danger')
          })
        }
      }
    },
    async (req, reply) => {
      try {
        await fastify.prisma.user.update({
          where: { id: req.session.user.id },
          data: {
            sendQuincyEmail: req.body.sendQuincyEmail
          }
        });

        return {
          message: 'flash.subscribe-to-quincy-updated',
          type: 'success'
        } as const;
      } catch (err) {
        fastify.log.error(err);
        void reply.code(500);
        return { message: 'flash.wrong-updating', type: 'danger' } as const;
      }
    }
  );

  done();
};


Review comment (suggestion):
Because I keep forgetting why we need to check protocol, I am just repeating what the validation do in the validation library 

https://github.com/validatorjs/validator.js

> `require_protocol` - if set to true isURL will return false if protocol is not present in the URL.

Here is where validation is used. https://github.com/freeCodeCamp/freeCodeCamp/blob/0e927aa9679b050513fe866d38c61a1df6d250c2/api-server/src/server/boot/settings.js#L156

Code after:
          type: 'success',
          username: newUsernameDisplay
        } as const;
      } catch (err) {
        fastify.log.error(err);
        void reply.code(500);
        return { message: 'flash.wrong-updating', type: 'danger' } as const;
      }
    }
  );
  fastify.put(
    '/update-my-about',
    {
      schema: schemas.updateMyAbout
    },
    async (req, reply) => {
      const hasProtocol = isPictureWithProtocol(req.body.picture);

      try {
        await fastify.prisma.user.update({
          where: { id: req.session.user.id },
          data: {
            about: req.body.about,
            name: req.body.name,
            location: req.body.location,
            ...(hasProtocol && { picture: req.body.picture })
          }
        });

        return {
          message: 'flash.updated-about-me',
          type: 'success'
        } as const;
      } catch (err) {
        fastify.log.error(err);
        void reply.code(500);
        return { message: 'flash.wrong-updating', type: 'danger' } as const;
      }
    }
  );

  fastify.put(
    '/update-my-keyboard-shortcuts',
    {
      schema: schemas.updateMyKeyboardShortcuts
    },
    async (req, reply) => {
      try {
        await fastify.prisma.user.update({
          where: { id: req.session.user.id },
          data: {
Repository: freeCodeCamp/freeCodeCamp
File: api/src/routes/settings.ts (TypeScript)

Code before:
          return {
            message: 'flash.username-taken',
            type: 'info'
          } as const;
        }

        await fastify.prisma.user.update({
          where: { id: req.session.user.id },
          data: {
            username: newUsername,
            usernameDisplay: newUsernameDisplay
          }
        });

        return {
          message: 'flash.username-updated',
          type: 'success',
          username: newUsernameDisplay
        } as const;
      } catch (err) {
        fastify.log.error(err);
        void reply.code(500);
        return { message: 'flash.wrong-updating', type: 'danger' } as const;
      }
    }
  ),
    fastify.put(
      '/update-my-about',
      {
        schema: schemas.updateMyAbout
      },
      async (req, reply) => {
        const hasProtocol = isPictureWithProtocol(req.body.picture);

        try {
          await fastify.prisma.user.update({
            where: { id: req.session.user.id },
            data: {
              about: req.body.about,
              name: req.body.name,
              location: req.body.location,
              ...(hasProtocol && { picture: req.body.picture })
            }
          });

          return {
            message: 'flash.updated-about-me',
            type: 'success'
          } as const;
        } catch (err) {
          fastify.log.error(err);

Review comment (suggestion):
```suggestion
  );
```
This means the following call will be less indented.

Code after:
            type: 'info'
          } as const;
        }

        await fastify.prisma.user.update({
          where: { id: req.session.user.id },
          data: {
            username: newUsername,
            usernameDisplay: newUsernameDisplay
          }
        });

        return {
          message: 'flash.username-updated',
          type: 'success',
          username: newUsernameDisplay
        } as const;
      } catch (err) {
        fastify.log.error(err);
        void reply.code(500);
        return { message: 'flash.wrong-updating', type: 'danger' } as const;
      }
    }
  );
  fastify.put(
    '/update-my-about',
    {
      schema: schemas.updateMyAbout
    },
    async (req, reply) => {
      const hasProtocol = isPictureWithProtocol(req.body.picture);

      try {
        await fastify.prisma.user.update({
          where: { id: req.session.user.id },
          data: {
            about: req.body.about,
            name: req.body.name,
            location: req.body.location,
            ...(hasProtocol && { picture: req.body.picture })
          }
        });

        return {
          message: 'flash.updated-about-me',
          type: 'success'
        } as const;
      } catch (err) {
        fastify.log.error(err);
        void reply.code(500);
        return { message: 'flash.wrong-updating', type: 'danger' } as const;
Repository: freeCodeCamp/freeCodeCamp
File: client/src/components/profile/components/portfolio-projects.tsx (TypeScript)

Code before:
import React from 'react';
import { useTranslation } from 'react-i18next';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faArrowUpRightFromSquare } from '@fortawesome/free-solid-svg-icons';
import type { PortfolioProjectData } from '../../../redux/prop-types';
import { FullWidthRow } from '../../helpers';

import './portfolio-projects.css';

interface PortfolioProjectsProps {
  portfolioProjects: PortfolioProjectData[];
}

export const PortfolioProjects = ({
  portfolioProjects
}: PortfolioProjectsProps): JSX.Element | null => {
  const { t } = useTranslation();
  if (!portfolioProjects.length) {
    return null;
  }
  return (
    <FullWidthRow>
      <h2 className='text-center'>{t('profile.portfolio')}</h2>
      {portfolioProjects.map(({ title, url, image, description, id }) => (
        <div className='portfolio-container' key={id}>
          <h3>{title}</h3>
          <p>{description}</p>
          <a href={url} rel='nofollow noopener noreferrer' target='_blank'>
            {t('buttons.view')}
            <span className='sr-only'>
              {title}, {t('aria.opens-new-window')}
            </span>
            <FontAwesomeIcon id='link-icon' icon={faArrowUpRightFromSquare} />
          </a>

          {image && (
            <img alt='' className='portfolio-screen-shot' src={image} />
          )}
        </div>
      ))}
      <hr />
    </FullWidthRow>
  );
};


Review comment (suggestion):
This change is out of scope for this pr. When reverting this change, please alter the css accordingly to make sure the button does not go out of the card. 

Code after:
import React from 'react';
import { useTranslation } from 'react-i18next';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faArrowUpRightFromSquare } from '@fortawesome/free-solid-svg-icons';
import type { PortfolioProjectData } from '../../../redux/prop-types';

import './portfolio-projects.css';

interface PortfolioProjectsProps {
  portfolioProjects: PortfolioProjectData[];
}

export const PortfolioProjects = ({
  portfolioProjects
}: PortfolioProjectsProps): JSX.Element | null => {
  const { t } = useTranslation();
  if (!portfolioProjects.length) {
    return null;
  }
  return (
    <>
      <h2 className='text-center'>{t('profile.portfolio')}</h2>
      {portfolioProjects.map(({ title, url, image, description, id }) => (
        <div className='portfolio-container' key={id}>
          <h3>{title}</h3>
          <p>{description}</p>
          <a href={url} rel='nofollow noopener noreferrer' target='_blank'>
            {t('buttons.view')}
            <span className='sr-only'>
              {title}, {t('aria.opens-new-window')}
            </span>
            <FontAwesomeIcon id='link-icon' icon={faArrowUpRightFromSquare} />
          </a>

          {image && (
            <img alt='' className='portfolio-screen-shot' src={image} />
          )}
        </div>
      ))}
      <hr />
    </>
  );
};
Repository: freeCodeCamp/freeCodeCamp
File: client/src/client-only-routes/show-profile-or-four-oh-four.tsx (TypeScript)

Code before:
const mapDispatchToProps: {
  fetchProfileForUser: ShowProfileOrFourOhFourProps['fetchProfileForUser'];
} = {
  fetchProfileForUser
};

function ShowProfileOrFourOhFour({
  requestedUser,
  maybeUser,
  fetchProfileForUser,
  isSessionUser
}: ShowProfileOrFourOhFourProps) {
  useEffect(() => {
    // If the user is not already in the store, fetch it
    if (isEmpty(requestedUser)) {
      if (maybeUser) {
        fetchProfileForUser(maybeUser);
      }
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  if (!isBrowser()) {
    return null;
  }
  const hasPorfile = isEmpty(requestedUser) || isEmpty(maybeUser);

  return hasPorfile ? (
    <Suspense fallback={<Loader fullScreen={true} />}>
      <FourOhFour />
    </Suspense>
  ) : (
    <Suspense fallback={<Loader fullScreen={true} />}>
      <Profile isSessionUser={isSessionUser} user={requestedUser} />
    </Suspense>
  );
}

export default connect(
  makeMapStateToProps,
  mapDispatchToProps
)(ShowProfileOrFourOhFour);


Review comment (suggestion):
```suggestion
  const hasProfile = isEmpty(requestedUser) || isEmpty(maybeUser);
```

Code after:
const mapDispatchToProps: {
  fetchProfileForUser: ShowProfileOrFourOhFourProps['fetchProfileForUser'];
} = {
  fetchProfileForUser
};

type ErrorBoundaryProps = {
  fallback: React.ReactNode;
};

class ErrorBoundary extends React.Component<
  ErrorBoundaryProps,
  { hasError: boolean }
> {
  constructor(props: ErrorBoundaryProps) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError() {
    return { hasError: true };
  }

  render() {
    if (this.state.hasError) {
      return this.props.fallback;
    }

    return this.props.children;
  }
}

function ShowProfileOrFourOhFour({
  requestedUser,
  maybeUser,
  fetchProfileForUser,
  isSessionUser
}: ShowProfileOrFourOhFourProps) {
  useEffect(() => {
    // If the user is not already in the store, fetch it
    if (isEmpty(requestedUser)) {
      if (maybeUser) {
        fetchProfileForUser(maybeUser);
      }
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  if (!isBrowser()) {
    return null;
  }
Repository: freeCodeCamp/freeCodeCamp
File: client/src/components/Donation/donation-modal.tsx (TypeScript)

Code before:
    show,
    recentlyClaimedBlock
  })
);

const mapDispatchToProps = (dispatch: Dispatch<AnyAction>) =>
  bindActionCreators(
    {
      closeDonationModal,
      executeGA
    },
    dispatch
  );

type DonateModalProps = {
  activeDonors?: number;
  closeDonationModal: typeof closeDonationModal;
  executeGA: typeof executeGA;
  location?: WindowLocation;
  recentlyClaimedBlock: RecentlyClaimedBlock;
  show: boolean;
};

const GetCommonDonationText = ({ ctaNumber }: { ctaNumber: number }) => {
  const { t } = useTranslation();
  const rotateProgressModalCta = useFeature('rotate-progress-modal-cta').on;
  if (rotateProgressModalCta)
    return <b>{t(`donate.progress-modal-cta-${ctaNumber}`)}</b>;

  const donationDuration = modalDefaultDonation.donationDuration;
  switch (donationDuration) {
    case 'one-time':
      return <b>{t('donate.duration')}</b>;
    case 'month':
      return <b>{t('donate.duration-2')}</b>;
    default:
      return <b>{t('donate.duration-4')}</b>;
  }
};

const RenderIlustration = ({
  recentlyClaimedBlock
}: {
  recentlyClaimedBlock: RecentlyClaimedBlock;
}) => {
  const showModalBears = useFeature('show-modal-bear').on;
  if (showModalBears && recentlyClaimedBlock !== null) {
    if (recentlyClaimedBlock !== null) return <BearBlockCompletion />;
    else return <BearProgressModal />;
  } else if (recentlyClaimedBlock) {
    return <Cup className='donation-icon' />;

Review comment (suggestion):
```suggestion
  const rotateProgressModalCta = useFeature('progress-modal-cta-rotation').on;
```

Code after:
    show,
    recentlyClaimedBlock
  })
);

const mapDispatchToProps = (dispatch: Dispatch<AnyAction>) =>
  bindActionCreators(
    {
      closeDonationModal,
      executeGA
    },
    dispatch
  );

type DonateModalProps = {
  activeDonors?: number;
  closeDonationModal: typeof closeDonationModal;
  executeGA: typeof executeGA;
  location?: WindowLocation;
  recentlyClaimedBlock: RecentlyClaimedBlock;
  show: boolean;
};

const GetCommonDonationText = ({ ctaNumber }: { ctaNumber: number }) => {
  const { t } = useTranslation();
  const rotateProgressModalCta = useFeature('progress-modal-cta-rotation').on;
  if (rotateProgressModalCta)
    return <b>{t(`donate.progress-modal-cta-${ctaNumber}`)}</b>;

  const donationDuration = modalDefaultDonation.donationDuration;
  switch (donationDuration) {
    case 'one-time':
      return <b>{t('donate.duration')}</b>;
    case 'month':
      return <b>{t('donate.duration-2')}</b>;
    default:
      return <b>{t('donate.duration-4')}</b>;
  }
};

const RenderIlustration = ({
  recentlyClaimedBlock
}: {
  recentlyClaimedBlock: RecentlyClaimedBlock;
}) => {
  const showModalBears = useFeature('show-modal-bears').on;
  if (showModalBears) {
    if (recentlyClaimedBlock !== null) return <BearBlockCompletion />;
    else return <BearProgressModal />;
  } else if (recentlyClaimedBlock !== null) {
    return <Cup className='donation-icon' />;
Repository: freeCodeCamp/freeCodeCamp
File: client/src/components/Donation/donation-modal.tsx (TypeScript)

Code before:
  show: boolean;
};

const GetCommonDonationText = ({ ctaNumber }: { ctaNumber: number }) => {
  const { t } = useTranslation();
  const rotateProgressModalCta = useFeature('progress-modal-cta-rotation').on;
  if (rotateProgressModalCta)
    return <b>{t(`donate.progress-modal-cta-${ctaNumber}`)}</b>;

  const donationDuration = modalDefaultDonation.donationDuration;
  switch (donationDuration) {
    case 'one-time':
      return <b>{t('donate.duration')}</b>;
    case 'month':
      return <b>{t('donate.duration-2')}</b>;
    default:
      return <b>{t('donate.duration-4')}</b>;
  }
};

const RenderIlustration = ({
  recentlyClaimedBlock
}: {
  recentlyClaimedBlock: RecentlyClaimedBlock;
}) => {
  const showModalBears = useFeature('show-modal-bear').on;
  if (showModalBears && recentlyClaimedBlock !== null) {
    if (recentlyClaimedBlock !== null) return <BearBlockCompletion />;
    else return <BearProgressModal />;
  } else if (recentlyClaimedBlock) {
    return <Cup className='donation-icon' />;
  } else {
    return <Heart className='donation-icon' />;
  }
};

function getctaNumberBetween1To10() {
  const min = 1;
  const max = 10;
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

function DonateModal({
  show,
  closeDonationModal,
  executeGA,
  location,
  recentlyClaimedBlock
}: DonateModalProps): JSX.Element {
  const [closeLabel, setCloseLabel] = React.useState(false);
  const [ctaNumber, setCtaNumber] = React.useState(0);

Review comment (suggestion):
```suggestion
  const showModalBears = useFeature('show-modal-bears').on;
```

Code after:
  show: boolean;
};

const GetCommonDonationText = ({ ctaNumber }: { ctaNumber: number }) => {
  const { t } = useTranslation();
  const rotateProgressModalCta = useFeature('progress-modal-cta-rotation').on;
  if (rotateProgressModalCta)
    return <b>{t(`donate.progress-modal-cta-${ctaNumber}`)}</b>;

  const donationDuration = modalDefaultDonation.donationDuration;
  switch (donationDuration) {
    case 'one-time':
      return <b>{t('donate.duration')}</b>;
    case 'month':
      return <b>{t('donate.duration-2')}</b>;
    default:
      return <b>{t('donate.duration-4')}</b>;
  }
};

const RenderIlustration = ({
  recentlyClaimedBlock
}: {
  recentlyClaimedBlock: RecentlyClaimedBlock;
}) => {
  const showModalBears = useFeature('show-modal-bears').on;
  if (showModalBears) {
    if (recentlyClaimedBlock !== null) return <BearBlockCompletion />;
    else return <BearProgressModal />;
  } else if (recentlyClaimedBlock !== null) {
    return <Cup className='donation-icon' />;
  } else {
    return <Heart className='donation-icon' />;
  }
};

function getctaNumberBetween1To10() {
  const min = 1;
  const max = 10;
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

function DonateModal({
  show,
  closeDonationModal,
  executeGA,
  location,
  recentlyClaimedBlock
}: DonateModalProps): JSX.Element {
  const [closeLabel, setCloseLabel] = React.useState(false);
  const [ctaNumber, setCtaNumber] = React.useState(0);