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 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 to help me test the components.
The first challenge that I ran into, was that the project was using supabase 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:
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:
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
:
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:
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:
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
:
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
:
import { supabase } from "../../../testServer";
instead of
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:
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
Top comments (0)