Use end to end tests to understand new codebases

This is part of the Semicolon&Sons Code Diary - consisting of lessons learned on the job. You're in the workflows category.

Last Updated: 2024-04-25

When staring Project M, I felt completely lost. Eventually I stumbled on a file that did an end2end integration test that explained how the entire system fits together.

import AWS from 'aws-sdk'
import JWT from 'jsonwebtoken'
import request from 'supertest'
import { emptyDb } from './testHelpers/emptyDb'

const token = JWT.sign(
  {
    features: [],
    id: 1,
    role: 'ADMIN'
  },
  'secret',
  { algorithm: 'HS256', expiresIn: '1 hour' }
)

describe('Event Sorcerer End-to-end test', () => {
  const dynamodb = new AWS.DynamoDB()
  afterAll(async () => {
    await emptyDb(dynamodb, 'test')
  })
  const server = request('https://e2e-test.Project M.de/event-sorcer')
  it('sends a command to the command lambda', async () => {
    await server
      .post('/command')
      .send({
        command: 'confirmPayment',
        id: 'test command 002',
        payload: {
          amount: 666,
          coreTransactionData: {
            customersHipTransactionId: 'what is this?',
            accountId: 2,
            productCategory: 'payment',
            productId: 123
          },
          customerId: '1',
          eventCreatedAt: '2012-10-06T04:13:00+00:00',
          paymentMethod: 'CreditCard',
          paymentReceivedAt: '2012-10-06T06:13:00+00:00'
        }
      })
      .set('Authorization', `Bearer ${token}`)
      .expect(200)

    ...

    await server
      .get('/query?billingUpTo=2016-04-28')
      .send()
      .set('Authorization', `Bearer ${token}`)
      .expect(200)
  }, 30000)
})

By looking at this code, I saw what endpoints were used (/query and /command), what their parameters look like, and what typical data might look like, as well as what components interacted with the system .

Lesson:

Integration tests are the best way to get an overview of how to interact with an unseen new system.