---
# System prepended metadata

title: 23T3 tut05 tests

---


# 23T1 tut05 test 

```javascript=
import request, { HttpVerb } from 'sync-request';

import { port, url } from './src/config.json';

const SERVER_URL = `${url}:${port}`;

interface PersonAddReturn {
  personId: number;
}

/**
 * Make an object that has the error structure together with a status code, as this will
 * be compared with errors that the requestHelper function will create..
 */
const makeCustomErrorForTest = (status: number) => ({ status, error: expect.any(String) });

/**
 * Sends a request to the given route and return its results
 * Errors will be returned in the form { status: number, error: string }
 */
const requestHelper = (method: HttpVerb, path: string, payload: object) => {
  let qs = {};
  let body = {};
  if (['GET', 'DELETE'].includes(method)) {
    qs = payload;
  } else {
    // PUT/POST
    body = payload;
  }
  const res = request(method, SERVER_URL + path, { qs, body, timeout: 20000 });
  const bodyString = res.body.toString();
  let bodyObject: any;
  try {
    // Return if valid JSON
    bodyObject = JSON.parse(bodyString);
  } catch (error: any) {
    bodyObject = {
      error: `Server responded with ${res.statusCode}, but body is not JSON! Given: ${bodyString}. Reason: ${error.message}. HINT: Did you res.json(undefined)?`
    };
  }
  if ('error' in bodyObject) {
    return { status: res.statusCode, ...bodyObject };
  }
  return bodyObject;
};

// ========================================================================= //

// Wrapper functions
const requestPeopleAdd = (id: int, name: string, age: number) =>  {
  return requestHelper('PUT', `/people/add/add/${id}`, {name,age});
};
const requestPeopleList = (minAge: number) =>  {
  return '';
};

const requestPersonView = (personId: number) =>  {
  return '';
};

const requestPersonEdit = (personId: number, name: string, age: number) =>  {
  return '';
};

const requestPersonRemove = (personId: number) => {
  return '';
};

const requestPeopleStats = () => {
  return '';
};

const requestClear = () =>  {
  return '';
};

// ========================================================================= //

beforeEach(() => {
  requestClear();
});

describe('/people/add', () => {
  describe('error', () => {
    test.each([
      { name: '', age: 20 },
      { name: 'valid', age: 0 },
    ])('name=$name, age=$age', ({ name, age }) => {
      expect(requestPeopleAdd(name, age)).toStrictEqual(makeCustomErrorForTest(400));
    });
  });

  test('return value', () => {
    const person = requestPeopleAdd('valid', 20);
    expect(person).toStrictEqual({ personId: expect.any(Number)});
    expect(requestPeopleList(0)).toStrictEqual({ people: [{ personId: person.personId, name: 'valid', age: 20 }] });
  });
});

describe('/people/list', () => {
  describe('minAge 0', () => {
    test('empty', () => {
      expect(requestPeopleList(0)).toStrictEqual({ people: [] });
    });

    test('one item', () => {
      const { personId } = requestPeopleAdd('one', 1);
      expect(requestPeopleList(0)).toStrictEqual({ people: [{ personId, name: 'one', age: 1 }] });
    });

    test('multiple items', () => {
      const p1 = requestPeopleAdd('alsothree', 3);
      const p2 = requestPeopleAdd('two', 2);
      const p3 = requestPeopleAdd('one', 1);
      const p4 = requestPeopleAdd('three', 3);
      expect(requestPeopleList(0)).toStrictEqual({
        people:
          [
            { personId: p1.personId, name: 'alsothree', age: 3 },
            { personId: p4.personId, name: 'three', age: 3 },
            { personId: p2.personId, name: 'two', age: 2 },
            { personId: p3.personId, name: 'one', age: 1 },
          ]
      });
    });
  });

  describe('with minAge', () => {
    test('error: minAge negative', () => {
      requestPeopleAdd('three', 3);
      expect(requestPeopleList(-1)).toStrictEqual(makeCustomErrorForTest(400));
    });

    test('higher minAge than existing people means empty', () => {
      requestPeopleAdd('three', 3);
      expect(requestPeopleList(4)).toStrictEqual({ people: [] });
    });

    test('minAge filter', () => {
      requestPeopleAdd('three', 3);
      const p2 = requestPeopleAdd('five', 5);
      expect(requestPeopleList(4)).toStrictEqual({ people: [{ personId: p2.personId, name: 'five', age: 5 }] });
    });
  });
});

describe('GET /person/:personid', () => {
  let person: PersonAddReturn;
  beforeEach(() => {
    person = requestPeopleAdd('Tam', 22);
  });
  describe('error', () => {
    test('does not exist', () => {
      expect(requestPersonView(person.personId + 1)).toStrictEqual(makeCustomErrorForTest(400));
    });
  });
  describe('success', () => {
    test('valid view', () => {
      expect(requestPersonView(person.personId)).toStrictEqual({
        person: {
          personId: person.personId,
          name: 'Tam',
          age: 22,
        }
      });
    });
  });
});

describe('PUT /person/:personid', () => {
  let person: PersonAddReturn;
  beforeEach(() => {
    person = requestPeopleAdd('Tam', 22);
  });
  describe('error', () => {
    test('does not exist', () => {
      expect(requestPersonEdit(person.personId + 1, 'invalid', 20)).toStrictEqual(makeCustomErrorForTest(400));
    });

    test('negative age', () => {
      expect(requestPersonEdit(person.personId, 'valid', -20)).toStrictEqual(makeCustomErrorForTest(400));
    });

    test('empty name', () => {
      expect(requestPersonEdit(person.personId, '', 20)).toStrictEqual(makeCustomErrorForTest(400));
    });

    test('name already taken', () => {
      requestPeopleAdd('Rani', 22);
      expect(requestPersonEdit(person.personId, 'Rani', 20)).toStrictEqual(makeCustomErrorForTest(400));
    });
  });

  test('successful edit', () => {
    expect(requestPeopleList(0)).toStrictEqual({ people: [{ personId: person.personId, name: 'Tam', age: 22 }] });
    expect(requestPersonEdit(person.personId, 'valid', 20)).toStrictEqual({});
    expect(requestPeopleList(0)).toStrictEqual({ people: [{ personId: person.personId, name: 'valid', age: 20 }] });
  });

  test('editing just age is okay', () => {
    expect(requestPeopleList(0)).toStrictEqual({ people: [{ personId: person.personId, name: 'Tam', age: 22 }] });
    expect(requestPersonEdit(person.personId, 'Tam', 20)).toStrictEqual({});
    expect(requestPeopleList(0)).toStrictEqual({ people: [{ personId: person.personId, name: 'Tam', age: 20 }] });
  });
});

describe('DELETE person/:personid', () => {
  let person: PersonAddReturn;
  beforeEach(() => {
    person = requestPeopleAdd('Tam', 22);
  });
  describe('error', () => {
    test('does not exist', () => {
      expect(requestPersonRemove(person.personId + 1)).toStrictEqual(makeCustomErrorForTest(400));
    });

    test('double remove', () => {
      expect(requestPersonRemove(person.personId)).toStrictEqual({});
      expect(requestPersonRemove(person.personId)).toStrictEqual(makeCustomErrorForTest(400));
    });
  });

  test('successful remove', () => {
    expect(requestPeopleList(0)).toStrictEqual({ people: [{ personId: person.personId, name: 'Tam', age: 22 }] });
    requestPersonRemove(person.personId);
    expect(requestPeopleList(0)).toStrictEqual({ people: [] });
  });
});

describe('/getstats', () => {
  describe('error', () => {
    test('empty data', () => {
      expect(requestPeopleStats()).toStrictEqual(makeCustomErrorForTest(400));
    });
  });

  test('single entry', () => {
    requestPeopleAdd('valid', 10);
    expect(requestPeopleStats()).toStrictEqual({
      stats: {
        minAge: 10,
        maxAge: 10,
        averageAge: 10,
      }
    });
  });

  test('multiple entries', () => {
    requestPeopleAdd('one', 1);
    requestPeopleAdd('five', 5);
    requestPeopleAdd('three', 3);
    requestPeopleAdd('two', 2);
    requestPeopleAdd('four', 4);
    expect(requestPeopleStats()).toStrictEqual({
      stats: {
        minAge: 1,
        maxAge: 5,
        averageAge: 3,
      }
    });
  });
});

describe('clear', () => {
  test('clear on empty', () => {
    expect(requestClear()).toStrictEqual({});
  });

  test('clear success', () => {
    requestPeopleAdd('one', 1);
    expect(requestClear()).toStrictEqual({});
    expect(requestPeopleList(0)).toStrictEqual({ people: [] });
  });
});
```
