Skip to content

Commit

Permalink
Add more documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
zichongkao committed Jun 15, 2023
1 parent 49356c0 commit 3422ba6
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 0 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,11 @@ yarn seed-db # May take a few minutes to download a large database file
yarn serve
```

#### Navigating the codebase
These links explain the structure and key abstractions of our codebase. It's a good place to start before you go spelunking in the code.
- [Layers](documentation/layers.md).
- [Testing](documentation/testing.md).

### Troubleshooting

- Fix "permissions on /opt/keyfile/keyfile are too open" error
Expand Down
26 changes: 26 additions & 0 deletions documentation/layers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Layers

## Overview
One way to think of our backend is comprising three layers wrapping the raw data sitting in Mongo DB.
1. GraphQL
2. Datasources
3. Models

Incoming data (API requests) pass through GraphQL > Datasource > Model and then the resulting data exit in reverse order from Model > Datasource > GraphQL.

When you change our data model, eg adding a new field to a climb object, you should expect to update each of the three layes as well.

## GraphQL
The outermost GraphQL layer that receives API calls. Our big integration tests (see [Testing](documentation/testing.md)) call this layer.

Code is in `src/graphql`.

## Datasources
The middle Mongoose datastore objects that expose commands to the GraphQL resolvers. Mongoose is our MongoDB NodeJS ORM. Our small integration tests test this layer down.

Code is in `src/model`.

## Models
The inner Mongoose models/schemas that represent how data is stored in the MongoDB.

Code is in `src/db/`
22 changes: 22 additions & 0 deletions documentation/testing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Testing
*Updated 2023-06-15*

## Overview
There are currently two broad classes of tests in this repo: Big integration tests and small ones. Both sets are integration tests because they validate long chains of functionality as opposed to single classes or functions (unit tests).

The big set is called "big" because it is truly end-to-end. It posts GraphQL queries and checks their output, which is literally what the API does in production. The small set skips the GraphQL layer (you might want to read more about layers [here](documentation/layers.md)) and instead calls datasource functions directly.

## Big Integration Tests
These tests mock up a GraphQL backend, and make HTTP calls to it. Since these tests are so realistic, they are immensely protective, illustrative and confidence-building. Open-tacos developers can cut and paste the GraphQL queries in these tests and use them to build the frontend.

These tests are stored in `/src/__tests__/`. The setup code is in `/src/utils/testUtils.ts`. Note how most of the code is oriented around setting up and tearing down a GraphQL server and an in-memory Mongo DB.

We rely on `mongo-memory-server` (a node package) for the in-memory Mongo DB. By running it in memory, it is lightweight and easily setup during `beforeAll`. Early on, we were hampered by the fact that the standard Mongo server that `mongo-memory-server` offers doesn't support Mongo transactions, which we use extensively. This is why we wrote small integration tests which rely on a local instance of MongoDB. However, in 2021, the package started to offer an in-memory replset which does support Mongo transactions. From then on, we've been able to write big integration tests which set up a replset which supports everything we need to do.


## Small Integration Tests
These essentially test datasource functions. Eg. the key line in such a test could be `await users.createOrUpdateUserProfile(updater, input)`([Source](src/model/__tests__/UserDataSource.ts)). This tests the `createOrUpdateUserProfile` function of the `user` datasource. Datasources sit one layer below the GraphQL layer (another plug to read [Layers]((documentation/layers.md))). In `src/graphql/resolvers.ts`, you can see how the GraphQL layer calls datasource functions to resolve entities in the queries.

Other than their inability to test how the GraphQL layer resolves queries, the main shortcoming of these tests are their poor portability. To use them, you need to set up a Mongo DB locally for the tests to read and write from. This is why the the main [README](README.md) page gets developers to spin up a Docker instance and edit `/etc/hosts` mongod mappings.

In general, we should phase these out in favor of big integration tests. In case you need to debug them or, god forbid, write new ones, they reside in `/src/model/__tests__/`.

0 comments on commit 3422ba6

Please sign in to comment.