Contributing tests to Awesome-Adoption
Published: 2021-11-19 18:14:11

Continuing my open source journey, I was looking for an issue to build upon my experience from `hacktoberfest` and to be an active member in the open source community!

Finding an issue to work on was again quite a challenge, as I was looking for a **"step-up"** from my `hacktoberfest` contributions but I also didn't want to write 10,000 lines of code. Finding a manageable issue was hard as most of the ones that I found were either really small or really big. I eventually, narrowed in on:
- **register and login unit testing**: https://github.com/redxzeta/Awesome-Adoption/issues/222

[Awesome-Adoption](https://github.com/redxzeta/Awesome-Adoption) is a repo that I did one of my pull requests to, for `hacktoberfest`, so I was already *(a little)* familiar with the project. While adding unit tests is not particularly a big task, but the project had almost 0 code coverage and automated testing was a new initiative, so I realized that this would be challenging especially since I was going to write tests on code that I had not written.

## Testing Register
Since the project was `React` based, I used [React Testing Library](https://testing-library.com/docs/react-testing-library/intro/) to help me test the components.

The first challenge that I ran into, was that the project was using [supabase](https://supabase.com/) for the backend. The forms were being submitted to the `supabase` client and I was having a hard time figuring out how to mock the request. After some digging through `supabase` documentation, I found that for authentication, it uses the `auth/v1/signup` endpoint and returns a `new User` if successful.

### Mocking Signup
I was then able to mock the signup request to authenticate a valid user:
```js
rest.post("https://vuxohlizzevgcsxlrggf.supabase.co/auth/v1/signup", (req, res, ctx) => {
    const fake_new_account = {
      id: "fake_acc_id",
      aud: "authenticated",
      role: "authenticated",
      email: "fake_acc_id@test.com",
      phone: "",
      confirmation_sent_at: Date.now(),
      app_metadata: { provider: "email", providers: ["email"] },
      user_metadata: {},
      identities: [],
      created_at: Date.now(),
      updated_at: Date.now(),
    };
    return res(ctx.status(200), ctx.json(fake_new_account));
  })
```

### Finishing the register unit test
Once the request was mocked, I was able to breeze through the register test case. Using `React Testing Library` I entered credentials in the form and expected it to make the sign up request. Once the request was made, the fake server would return a new user object and a `Success` message should be displayed:

```js
test("should register sucessfully", async () => {
  const { getByLabelText, getByText } = render(
    <Provider value={supabase}>
      <Register />
    </Provider>
  );

  fireEvent.change(getByLabelText(/email/i), {
    target: { value: "fake_acc_id" },
  });
  fireEvent.change(getByLabelText(/password/i), {
    target: { value: "fake_password" },
  });

  fireEvent.click(getByText(/submit/i));

  await waitFor(() => {
    expect(screen.getByText(/Success/i)).toBeInTheDocument();
  });
});
```

## Testing Login
Similar to `Register`, I added the following tests for `SLogin`:

```js
test("should show error message for empty fields", async () => {
  const { getByText } = render(
    <Provider value={supabase}>
      <SLogin />
    </Provider>
  );

  fireEvent.click(getByText(/submit/i));

  await waitFor(() => {
    expect(
      screen.getByText(
        /You must provide either an email, phone number or a third-party provider/i
      )
    ).toBeInTheDocument();
  });
});

test("should show error message for incorrect email format", async () => {
  const { getByLabelText, getByText } = render(
    <Provider value={supabase}>
      <SLogin />
    </Provider>
  );

  fireEvent.change(getByLabelText(/email/i), {
    target: { value: "incorrect_format" },
  });

  fireEvent.click(getByText(/submit/i));

  await waitFor(() => {
    expect(
      screen.getByText(/Unable to validate email address: invalid format/i)
    ).toBeInTheDocument();
  });
});
```

## Submitting pull request and review
After I verified the tests locally, I created a pr:
- **Adding tests for login and register**: https://github.com/redxzeta/Awesome-Adoption/pull/224

The initial push ended up failing the CI test run:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9bz59c2aplkjrr4lc3dy.png)

After going through the logs, I found out that I was using the same `supabase` client for testing which was being used by the React application (credentials in `.env`). The tests passed locally, as I had `.env` setup but the GitHub Actions run did not.

My first thought was to simply setup the `supabase` client, just as how the React app was doing. I did that and pushed my changes:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1xu0mg2rs7qhwa5766g3.png)

While the CI run passed, this was not the best approach and the project owner requested changes and suggested that I should look into using fake `supabase` credentials.

To fix this issue, I created a fake `supabase` client for the mock server `src/testServer.js`:

```js
import { createClient } from "@supabase/supabase-js";

const SUPABASE_URL = "https://test.supabase.co";
const KEY = "test";
const supabase = createClient(SUPABASE_URL, KEY);

export { server, rest, supabase };
```

Exporting the fake `supabase` client, I then used it in both my unit tests, replacing the actual client, `src/components/accounts/__tests__/SLogin.test.js` and `src/components/accounts/__tests__/Register.test.js`:

```js
import { supabase } from "../../../testServer";
```
instead of 
```js
import { supabase } from "../../../utils/SupaBaseUtils";
```

Lastly, I modified the baseURL of the mocked requests to `https://test.supabase.co` and I pushed my changes to the pull request:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a60dpct5djwh5a6rwx3v.png) 

The green arrow was nice to see! After re-requesting a review, the project owner accepted and merged my pull request!

## Takeaways
I definitely learned a lot while working on this pull request. I personally had no experience with `supabase`, so going from knowing nothing about it to actually mocking requests and writing unit tests for it was a great learning experience, building upon my contributions from `hacktoberfest`

## References:
Issue: https://github.com/redxzeta/Awesome-Adoption/issues/222
Pull request: https://github.com/redxzeta/Awesome-Adoption/pull/224