# 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: [] });
});
});
```