Skip to content

Halfway Through GSOC

Posted on:July 27, 2023 at 06:42 AM

GSoC Logo Horizontal

I have officially hit the halfway mark for my GSOC internship. I thought this would be a good time to write a blog post going over my experience so far!

Table of contents

Open Table of contents

Introduction

I got accepted as a GSOC intern with the Wikimedia Foundation back in May of this year. The project I’m working on is called the Wiki Education Dashboard. Here is a quick summary of the dashboard, taken from the project’s Github repo

The Wiki Education Dashboard is a web application that supports Wikipedia education assignments, edit-a-thons, and other editing projects. It provides data and course management features for groups of editors — instructors, students, and others — who are working on Wikipedia, Wikidata, and other Wikimedia wikis.

For my project proposal, I decided to focus on improving the React codebase by working towards two major improvements:

Refactoring Components

For this part of my project. I set out to refactor every class component that was still a part of the React codebase. Initially, I did a quick regex search to look for all mentions of the react class definition syntax, an example of the syntax I was looking for would be something like:

class Greeting extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

This would allow me to easily get a list of all files that have class components in them. This regex search found 29 React files that were using class components. I created this GitHub issue to track the conversion of each file. However, if you take a look at the github issue, you’ll notice there are a lot more than 29 components being listed. This is actually because my initial search forgot to take into account a much older, legacy way to define react classes.

Before the release of ES6, class syntax was not natively supported by Javascript. To work around this, the React team introduced a create-react-class module that allowed you to define component classes without ES6. Here’s an example that uses this module to create a basic class component.

var createReactClass = require("create-react-class");
var Greeting = createReactClass({
  render: function () {
    return <h1>Hello, {this.props.name}</h1>;
  },
});

Taking this syntax into account, my new regex search found a total of 162 files that needed to be refactored. Which is a lot more than the original 29. So far, I’ve refactored 46 components. So that leaves 116 components to go.

Throughout my experience refactoring class components, I’ve picked up on a lot of useful skills to help formalize the component conversion process. I’ll be working on a blog post that goes more into the technical details of this component refactor which should be released 2 days from now.

Test Problems

For the upgrade to React 18, the main roadblock was the enzyme tests. Enzyme is a Javascript testing utility for react that allows you to unit test your react components. The dashboard has two test suites. The ruby tests and the React Enzyme tests. The main issue is that enzyme does not support react 18. This means that an upgrade to react 18 requires either the removal of all enzyme tests, or the replacement of the tests with a more modern react testing library such as React Testing Library.

You may think that the replacement of the tests is the no-brainer choice here. And that is true in most cases. But it gets a little bit more complicated. It turns out that one of the main ways Enzyme tests components is by comparing component state values with their expected values. This works fine with class components. But my component refactor actually conflicts with this because there is no way to get a functional component’s state in enzyme. Nor is it recommended in any of the more modern testing libraries for React. For example, here is what React Testing Library states in regards to this:

You want to write maintainable tests for your React components. As a part of this goal, you want your tests to avoid including implementation details of your components and rather focus on making your tests give you the confidence for which they are intended. As part of this, you want your testbase to be maintainable in the long run so refactors of your components (changes to implementation but not functionality) don’t break your tests and slow you and your team down.

We have an outdated testing library that doesn’t support react 18, the testing paradigm seems to have shifted from focusing on implementation details to focusing on testing general component behavior. So using a new testing library would require not only a full rewrite of the react testing suite, but also a rethinking in regards to the test logic for a large part of the component tests. Not to mention that the test suite spanned 100+ tests. This would take a lot of work to get done and could probably be its own GSOC project.

So, after some discussions with my mentor and other GSOC interns, the decision was made to remove the enzyme tests completely. This isn’t as big of a loss as it seems because the dashboard also has a very comprehensive ruby test suite that tests both the frontend and backend functionality. Moving forward, any new frontend tests will be written as part of the ruby test suite too.

Upgrading to React 18

Now that the tests are taken care of, it’s time to move on to the upgrade! Initially, I thought that the upgrade would be the most time-consuming portion of my internship because React loves introducing drastic, paradigm-shifting changes into their new versions (remember react hooks and server components?). Surprisingly, the react upgrade was pretty smooth. Some things did break (they always do…). But the fixes were pretty straight-forward:

Then after a bunch of manual testing from both me and my mentor, we decided the upgrade was ready to go, so it was merged!

So everything went according to plan… Except I accidentally removed all the javascript tests and not just the react ones. Of course this wasn’t a big deal because we use Git. But it’s a great reminder as to why developers use version control systems. A quick rollback dealt with the issue and the crisis was averted.

Contributions so far

Here’s a table showing all the merged PRs I’ve made so far to the wiki education repo (during the internship period):

PRTitle
5458Converting EmbedStatsButton into functional component
5457Converting Confirm into functional component
5456Converting Nav and HamburgerMenu into functional components
5454Converting Intro, Permissions and Finished into functional components
5453Mark pagepile test as a pending test
5452Converting AlertsHandler, Article and AvailableArticle into functional components
5449Converting DidYouKnowHandler, PlagiarismHandler, RecentEditsHandler and RecentUploadsHandlerBase into functional components
5443Converting Affix, PeerReviewChecklist and FinalArticleChecklist into functional components
5442Converting ActivityHandler, ActivityTableRow and ActivityTable into functional components
5441fixed ArticleViewer bug related to direct links
5440refactored course embed feature
5437Upgrade to React 18
5435Converting Articles into functional component
5434Converting EnrollButton into functional component
5429Converting Upload and AssignButton into functional component
5427Converting BadWorkAlert and Overview into functional components
5426Converting TicketsHandler and DeleteNote into functional components
5424Converting MyArticlesContainer and MyExercicesContainer into functional components
5423Removed unnecessary display of alert button in article finder’s preview article UI
5419Converting TaggedCourseAlerts, SyllabusUpload and ProgressTracker into functional components
5418Converting RangeGraph and TextResults into functional components
5413Converting ArticleViewer into a functional component
5411Converting TicketShowHandler, NewReplyFrom and NotificationsBell into functional components
5410Added documentation about assigning user roles
5406Converted StudentDrawer, QuestionResults, FollowUpQuestionResults, CourseAlertsList components into functional components
5404Converting StudentRevisionsList and Assignment class components into functional components
5401Converting LanguagePicker and Sidebar class components into functional components
5400Fixed alert table course highlight bug
5397Converting CampaignAlerts class component to functional component
5394Converting AdminAlerts class component to functional component
5392Fixed popover height issue for student details page