Skip to content

Commit

Permalink
all tests defined
Browse files Browse the repository at this point in the history
  • Loading branch information
Xunnamius committed May 31, 2020
1 parent 7ddea03 commit 5f40ac6
Show file tree
Hide file tree
Showing 3 changed files with 254 additions and 18 deletions.
135 changes: 128 additions & 7 deletions src/__test__/election.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import * as Election from 'universe/pages/api/v1/election/[id]'
import { getEnv } from 'universe/backend/env'

import type { PublicElection, InternalElection } from 'types/global'
import { getInternalElection, getPublicElection, doesElectionExist } from 'universe/backend'
import { ObjectId } from 'mongodb'

const { getHydratedData } = setupJest();

Expand Down Expand Up @@ -49,7 +51,7 @@ const internalToPublic = (e: InternalElection[]) => {
});
};

describe('api/v1/election', () => {
describe('api/v1/election', async () => {
it('requests without a key return 401', async () => {
await testApiEndpoint({
next: electionEndpoint,
Expand Down Expand Up @@ -96,19 +98,138 @@ describe('api/v1/election', () => {
const { success, ...election } = await response.json();

expect(response.status).toBe(200);
expect(success).toBe(true);
expect(success).toBeTrue();
expect(containsOnlyPublicData(election)).toBeTrue();
}
});
});

test.todo('can use PUT to mutate an election');
it('can use PUT to mutate an election', async () => {
const election_id = getHydratedData().elections[52].election_id;

test.todo('can use DELETE to delete an election');
await testApiEndpoint({
next: electionEndpoint,
params: { id: election_id },
test: async ({ fetch }) => {
const mutation = {
election_id,
title: 'Flip mode!',
description: 'Flip mode family ties',
options: ['A', 'B', 'Z'],
closes: Date.now() + 10**8
};

const response = await fetch({
method: 'PUT',
headers: { KEY, 'Content-Type': 'application/json' },
body: JSON.stringify(mutation)
});

expect(response.status).toBe(200);

expect(await getPublicElection({
electionId: election_id, key: KEY
})).toContainEntries(Object.entries(mutation));
}
});
});

it('can use DELETE to delete an election', async () => {
const election_id = getHydratedData().elections[52].election_id;

await testApiEndpoint({
next: electionEndpoint,
params: { id: election_id },
test: async ({ fetch }) => {
expect(await doesElectionExist(election_id)).toBeTrue();

test.todo('returns a 400 error on invalid data during PUT');
const response = await fetch({ method: 'DELETE', headers: { KEY }});

expect(response.status).toBe(200);
expect(await doesElectionExist(election_id)).toBeFalse();
}
});
});

test.todo('returns a 403 error when trying to PUT or DELETE with an election_id owned by a different key');
it('returns a 400 error on invalid data during PUT', async () => {
const election_id = getHydratedData().elections[52].election_id;

const getInvalidData = function*() {
yield { data: 1 };
yield { title: '', created: Date.now() };
yield { title: 'test election', options: [{}, {}], opens: Date.now() + 10**4, closes: Date.now() + 10**5 };
yield { title: 'my title', opens: Date.now() - 1000, closes: Date.now() + 10**5 };
yield { title: 'my title #2', opens: Date.now() + 10**7, closes: Date.now() + 10**5 };
yield { title: 'my title #3', opens: Date.now() + 10**5, closes: Date.now() + 10**7, description: 54 };
yield { title: 'my title #4', opens: Date.now() + 10**5, closes: Date.now() + 10**7, options: [54] };
yield { title: 'my title #5', opens: Date.now() + 10**5, closes: Infinity };
yield { title: 'my title #6', opens: Date.now() + 10**5, closes: NaN };
yield { title: 'my title #7', opens: undefined, closes: undefined };
yield { title: 'my title #7', election_id: (new ObjectId()).toHexString() };
yield {};
}();

test.todo('returns a 404 error if election_id does not exist');
await testApiEndpoint({
next: electionEndpoint,
params: { id: election_id },
test: async ({ fetch }) => {
const responses = await Promise.all([...Array(12)].map(_ => fetch({
method: 'PUT',
headers: { KEY, 'Content-Type': 'application/json' },
body: JSON.stringify(getInvalidData.next().value)
}).then(r => r.status)));

expect(responses).toEqual([
...[...Array(12)].map(_ => 400)
]);
}
});
});

it('returns a 403 error when trying to PUT or DELETE with an election_id owned by a different key', async () => {
const election_id = getHydratedData().elections[0].election_id;

await testApiEndpoint({
next: electionEndpoint,
params: { id: election_id },
test: async ({ fetch }) => {
expect(await doesElectionExist(election_id)).toBeTrue();

let response = await fetch({ method: 'DELETE', headers: { KEY }});

expect(response.status).toBe(403);
expect(await doesElectionExist(election_id)).toBeTrue();

response = await fetch({
method: 'PUT',
headers: { KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({ title: 'UPDATED TITLE SUPER COOL' })
});

expect(response.status).toBe(403);
}
});
});

it('returns a 404 error if election_id does not exist', async () => {
const election_id = (new ObjectId()).toHexString();

await testApiEndpoint({
next: electionEndpoint,
params: { id: election_id },
test: async ({ fetch }) => {
const responses = await Promise.all([
fetch({ method: 'GET', headers: { KEY }}),
fetch({ method: 'DELETE', headers: { KEY }}),
fetch({
method: 'PUT',
headers: { KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({ title: 'UPDATED TITLE SUPER COOL' })
}),
].map(p => p.then(r => r.status)));

expect(responses).toEqual([ 404, 404, 404 ]);
}
});
});
});
6 changes: 4 additions & 2 deletions src/__test__/elections.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -310,19 +310,21 @@ describe('api/v1/elections', () => {
yield { title: 'my title #5', opens: Date.now() + 10**5, closes: Infinity };
yield { title: 'my title #6', opens: Date.now() + 10**5, closes: NaN };
yield { title: 'my title #7', opens: undefined, closes: undefined };
yield { title: 'my title #7', election_id: (new ObjectId()).toHexString() };
yield {};
}();

await testApiEndpoint({
next: electionsEndpoint,
test: async ({ fetch }) => {
const responses = await Promise.all([...Array(10)].map(_ => fetch({
const responses = await Promise.all([...Array(12)].map(_ => fetch({
method: 'POST',
headers: { KEY, 'Content-Type': 'application/json' },
body: JSON.stringify(getInvalidData.next().value)
}).then(r => r.status)));

expect(responses).toEqual([
...[...Array(10)].map(_ => 400)
...[...Array(12)].map(_ => 400)
]);
}
});
Expand Down
131 changes: 122 additions & 9 deletions src/__test__/voters.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { setupJest } from 'universe/__test__/db'
import { testApiEndpoint } from 'multiverse/test-api-endpoint'
import * as Voters from 'universe/pages/api/v1/election/[id]/voters'
import { getEnv } from 'universe/backend/env'
import { getRankings, upsertElection } from 'universe/backend';
import { ObjectId } from 'mongodb';

const { getHydratedData } = setupJest();

Expand Down Expand Up @@ -54,28 +56,139 @@ describe('api/v1/election/voters', () => {
});

it('returns only public voter and ranking data on election_id', async () => {
const election_id = getHydratedData().elections[22].election_id;

await testApiEndpoint({
next: votersEndpoint,
params: { id: election_id },
test: async ({ fetch }) => {
const response = await fetch({ headers: { KEY } });
const json = await response.json();
const { success, votes, ...rest } = await response.json();

expect(response.status).toBe(200);
expect(success).toBeTrue();
expect(Object.keys(rest).length).toBe(0);
expect(votes).toEqual((await getRankings(election_id)));
}
});
});

const elections = getHydratedData().elections;
void elections;
it('can use PUT to mutate election rankings', async () => {
const election_id = getHydratedData().elections[52].election_id;

await testApiEndpoint({
next: votersEndpoint,
params: { id: election_id },
test: async ({ fetch }) => {
const mutation = [{ voter_id: 'X', ranking: ['Walking Dead'] }];

const response = await fetch({
method: 'PUT',
headers: { KEY, 'Content-Type': 'application/json' },
body: JSON.stringify(mutation)
});

expect(response.status).toBe(200);
expect(await getRankings(election_id)).toEqual(mutation);
}
});
});

it('returns an empty array when querying a brand new election_id', async () => {
const { election_id } = await upsertElection({
key: KEY,
election: {
title: 'Mine!',
opens: Date.now() + 10**5,
closes: Date.now() + 10**6
}
});

await testApiEndpoint({
next: votersEndpoint,
params: { id: election_id },
test: async ({ fetch }) => {
const response = await fetch({ headers: { KEY } });
const { success, votes } = await response.json();

expect(response.status).toBe(200);
expect(json.success).toBe(true);
expect(success).toBeTrue();
expect(votes).toEqual([]);
}
});
});

test.todo('can use PUT to mutate election rankings');
it('returns a 400 error on invalid data during PUT', async () => {
const election_id = getHydratedData().elections[52].election_id;

const getInvalidData = function*() {
yield { data: 1 };
yield { 1: '1', 2: '2' };
yield [{ 1: '1', 2: '2' }];
yield undefined;
yield null;
yield NaN;
yield [{}];
yield [[]];
yield [undefined];
yield [{ vote: 1, rank: []}];
yield [{ voter_id: 1, rankings: []}];
yield [{ voter_id: '1', rankings: ['FAKER']}];
}();

test.todo('returns an empty array when querying a brand new election_id');
await testApiEndpoint({
next: votersEndpoint,
params: { id: election_id },
test: async ({ fetch }) => {
const responses = await Promise.all([...Array(12)].map(_ => fetch({
method: 'PUT',
headers: { KEY, 'Content-Type': 'application/json' },
body: JSON.stringify(getInvalidData.next().value)
}).then(r => r.status)));

expect(responses).toEqual([
...[...Array(12)].map(_ => 400)
]);
}
});
});

test.todo('returns a 400 error on invalid data during PUT');
it('returns a 403 error when trying to mutate an unowned election_id', async () => {
const election_id = getHydratedData().elections[0].election_id;

test.todo('returns a 403 error when trying to mutate an unowned election_id');
await testApiEndpoint({
next: votersEndpoint,
params: { id: election_id },
test: async ({ fetch }) => {
const response = await fetch({
method: 'PUT',
headers: { KEY, 'Content-Type': 'application/json' },
body: JSON.stringify([])
});

test.todo('returns a 404 error if election_id does not exist');
expect(response.status).toBe(403);
}
});
});

it('returns a 404 error if election_id does not exist', async () => {
const election_id = (new ObjectId()).toHexString();

await testApiEndpoint({
next: votersEndpoint,
params: { id: election_id },
test: async ({ fetch }) => {
const responses = await Promise.all([
fetch({ method: 'GET', headers: { KEY }}),
fetch({
method: 'PUT',
headers: { KEY, 'Content-Type': 'application/json' },
body: JSON.stringify([])
}),
].map(p => p.then(r => r.status)));

expect(responses).toEqual([ 404, 404 ]);
}
});
});
});

0 comments on commit 5f40ac6

Please sign in to comment.