Made API more RESTful, got modify working

pull/7/head
Sander Vocke 5 years ago
parent e07a76acc1
commit 74be187db2
  1. 34
      client/src/api.ts
  2. 6
      server/app.ts
  3. 6
      server/endpoints/ModifyArtistEndpointHandler.ts
  4. 12
      server/endpoints/ModifySongEndpointHandler.ts
  5. 8
      server/test/integration/flows/CreateArtistFlow.js
  6. 30
      server/test/integration/flows/CreateSongFlow.js
  7. 12
      server/test/integration/flows/ModifyArtistFlow.js

@ -17,8 +17,8 @@ export function checkQuerySongsRequest(req:any): boolean {
return true;
}
// Get song details.
export const SongDetailsEndpoint = '/song/details/:id';
// Get song details (GET).
export const SongDetailsEndpoint = '/song/:id';
export interface SongDetailsRequest {}
export interface SongDetailsResponse {
title: String,
@ -39,8 +39,8 @@ export function checkQueryArtistsRequest(req:any): boolean {
return true;
}
// Get artist details.
export const ArtistDetailsEndpoint = '/artist/details/:id';
// Get artist details (GET).
export const ArtistDetailsEndpoint = '/artist/:id';
export interface ArtistDetailsRequest {}
export interface ArtistDetailsResponse {
name: String
@ -49,8 +49,8 @@ export function checkArtistDetailsRequest(req:any): boolean {
return true;
}
// Create a new song.
export const CreateSongEndpoint = '/song/create';
// Create a new song (POST).
export const CreateSongEndpoint = '/song';
export interface CreateSongRequest {
title: String;
artistIds?: Number[];
@ -64,18 +64,20 @@ export function checkCreateSongRequest(req:any): boolean {
"title" in req.body;
}
// Modify an existing song.
export const ModifySongEndpoint = '/song/modify';
export interface ModifySongRequest extends CreateSongRequest {
id: Number;
// Modify an existing song (PUT).
export const ModifySongEndpoint = '/song/:id';
export interface ModifySongRequest {
title?: String;
artistIds?: Number[];
albumIds?: Number[];
}
export interface ModifySongResponse {}
export function checkModifySongRequest(req:any): boolean {
return true;
}
// Create a new artist.
export const CreateArtistEndpoint = '/artist/create';
// Create a new artist (POST).
export const CreateArtistEndpoint = '/artist';
export interface CreateArtistRequest {
name: String;
songIds?: Number[];
@ -89,10 +91,10 @@ export function checkCreateArtistRequest(req:any): boolean {
"name" in req.body;
}
// Modify an existing artist.
export const ModifyArtistEndpoint = '/artist/modify';
export interface ModifyArtistRequest extends CreateArtistRequest {
id: Number;
// Modify an existing artist (PUT).
export const ModifyArtistEndpoint = '/artist/:id';
export interface ModifyArtistRequest {
name?: String,
}
export interface ModifyArtistResponse {}
export function checkModifyArtistRequest(req:any): boolean {

@ -14,12 +14,14 @@ import * as endpointTypes from './endpoints/types';
const invokeHandler = (handler:endpointTypes.EndpointHandler) => {
return async (req: any, res: any) => {
console.log("Incoming", req.method, " @ ", req.url);
await handler(req, res)
.catch((_e:endpointTypes.EndpointError) => {
let e:endpointTypes.EndpointError = _e;
console.log("Error handling request: ", e.internalMessage);
res.sendStatus(e.httpStatus);
})
console.log("Finished handling", req.method, "@", req.url);
};
}
@ -32,8 +34,8 @@ const SetupApp = (app: any) => {
app.get(api.QuerySongsEndpoint, invokeHandler(QuerySongsEndpointHandler));
app.post(api.CreateArtistEndpoint, invokeHandler(CreateArtistEndpointHandler));
app.get(api.QueryArtistsEndpoint, invokeHandler(QueryArtistsEndpointHandler));
app.post(api.ModifyArtistEndpoint, invokeHandler(ModifyArtistEndpointHandler));
app.post(api.ModifySongEndpoint, invokeHandler(ModifySongEndpointHandler));
app.put(api.ModifyArtistEndpoint, invokeHandler(ModifyArtistEndpointHandler));
app.put(api.ModifySongEndpoint, invokeHandler(ModifySongEndpointHandler));
app.get(api.SongDetailsEndpoint, invokeHandler(SongDetailsEndpointHandler));
app.get(api.ArtistDetailsEndpoint, invokeHandler(ArtistDetailsEndpointHandler));
}

@ -13,12 +13,12 @@ export const ModifyArtistEndpointHandler: EndpointHandler = async (req: any, res
const reqObject:api.ModifyArtistRequest = req.body;
await models.Artist.findAll({
where: { id: reqObject.id }
where: { id: req.params.id }
})
.then(async (artists: any[]) => {
if (artists.length != 1) {
const e: EndpointError = {
internalMessage: 'There is no artist with id ' + reqObject.id + '.',
internalMessage: 'There is no artist with id ' + req.params.id + '.',
httpStatus: 400
};
throw e;
@ -28,7 +28,7 @@ export const ModifyArtistEndpointHandler: EndpointHandler = async (req: any, res
await artist.save();
})
.then(() => {
res.status(200);
res.status(200).send({});
})
.catch(catchUnhandledErrors);
}

@ -57,12 +57,12 @@ export const ModifySongEndpointHandler: EndpointHandler = async (req: any, res:
// Start retrieving the song to modify.
var songInstancePromise: Promise<any> =
models.Song.findAll({
where: { id: reqObject.id }
where: { id: req.params.id }
})
.then((song: any[]) => {
if (song.length != 1) {
const e: EndpointError = {
internalMessage: 'There is no song with id ' + reqObject.id + '.',
internalMessage: 'There is no song with id ' + req.params.id + '.',
httpStatus: 400
};
throw e;
@ -70,13 +70,13 @@ export const ModifySongEndpointHandler: EndpointHandler = async (req: any, res:
return song[0];
});
// Upon finish retrieving artists and albums, create the song and associate it.
// Upon finish retrieving artists and albums, modify the song.
await Promise.all([artistInstancesPromise, albumInstancesPromise, songInstancePromise])
.then(async (values: any) => {
var [artists, albums, song] = values;
song.setArtists(artists);
song.setAlbums(albums);
song.setTitle(reqObject.title);
if(reqObject.artistIds) { song.setArtists(artists) };
if(reqObject.albumIds) { song.setAlbums(albums) };
if(reqObject.title) { song.setTitle(reqObject.title) };
await song.save();
})
.then(() => {

@ -13,12 +13,12 @@ async function init() {
return app;
}
describe('POST /artist/create with no name', () => {
describe('POST /artist with no name', () => {
it('should fail', done => {
init().then((app) => {
chai
.request(app)
.post('/artist/create')
.post('/artist')
.send({})
.end((err, res) => {
expect(err).to.be.null;
@ -29,12 +29,12 @@ describe('POST /artist/create with no name', () => {
});
});
describe('POST /artist/create with a correct request', () => {
describe('POST /artist with a correct request', () => {
it('should succeed', done => {
init().then((app) => {
chai
.request(app)
.post('/artist/create')
.post('/artist')
.send({
name: "MyArtist"
})

@ -13,12 +13,12 @@ async function init() {
return app;
}
describe('POST /song/create with no title', () => {
describe('POST /song with no title', () => {
it('should fail', done => {
init().then((app) => {
chai
.request(app)
.post('/song/create')
.post('/song')
.send({})
.end((err, res) => {
expect(err).to.be.null;
@ -29,12 +29,12 @@ describe('POST /song/create with no title', () => {
});
});
describe('POST /song/create with only a title', () => {
describe('POST /song with only a title', () => {
it('should return the first available id', done => {
init().then((app) => {
chai
.request(app)
.post('/song/create')
.post('/song')
.send({
title: "MySong"
})
@ -50,12 +50,12 @@ describe('POST /song/create with only a title', () => {
});
});
describe('POST /song/create with a nonexistent artist Id', () => {
describe('POST /song with a nonexistent artist Id', () => {
it('should fail', done => {
init().then((app) => {
chai
.request(app)
.post('/song/create')
.post('/song')
.send({
title: "MySong",
artistIds: [1]
@ -69,12 +69,12 @@ describe('POST /song/create with a nonexistent artist Id', () => {
});
});
describe('POST /song/create with an existing artist Id', () => {
describe('POST /song with an existing artist Id', () => {
it('should succeed', done => {
init().then((app) => {
async function createArtist() {
await chai.request(app)
.post('/artist/create')
.post('/artist')
.send({
name: "MyArtist"
})
@ -88,7 +88,7 @@ describe('POST /song/create with an existing artist Id', () => {
async function createSong() {
chai.request(app)
.post('/song/create')
.post('/song')
.send({
title: "MySong",
artistIds: [1]
@ -109,12 +109,12 @@ describe('POST /song/create with an existing artist Id', () => {
});
});
describe('POST /song/create with two existing artist Ids', () => {
describe('POST /song with two existing artist Ids', () => {
it('should succeed', done => {
init().then((app) => {
async function createArtist(name, expectId) {
await chai.request(app)
.post('/artist/create')
.post('/artist')
.send({
name: name
})
@ -128,7 +128,7 @@ describe('POST /song/create with two existing artist Ids', () => {
async function createSong() {
chai.request(app)
.post('/song/create')
.post('/song')
.send({
title: "MySong",
artistIds: [1, 2]
@ -150,12 +150,12 @@ describe('POST /song/create with two existing artist Ids', () => {
});
});
describe('POST /song/create with an existent and a nonexistent artist Id', () => {
describe('POST /song with an existent and a nonexistent artist Id', () => {
it('should fail', done => {
init().then((app) => {
async function createArtist(name, expectId) {
await chai.request(app)
.post('/artist/create')
.post('/artist')
.send({
name: name
})
@ -169,7 +169,7 @@ describe('POST /song/create with an existent and a nonexistent artist Id', () =>
async function createSong() {
chai.request(app)
.post('/song/create')
.post('/song')
.send({
title: "MySong",
artistIds: [1, 2]

@ -13,12 +13,12 @@ async function init() {
return app;
}
describe('POST /artist/modify on nonexistent artist', () => {
describe('PUT /artist on nonexistent artist', () => {
it('should fail', done => {
init().then((app) => {
chai
.request(app)
.post('/artist/modify')
.put('/artist/1')
.send({
id: 1,
name: "NewArtistName"
@ -31,12 +31,12 @@ describe('POST /artist/modify on nonexistent artist', () => {
});
});
describe('POST /artist/modify with an existing artist', () => {
describe('PUT /artist with an existing artist', () => {
it('should succeed', done => {
init().then((app) => {
async function createArtist(req) {
await req
.post('/artist/create')
.post('/artist')
.send({
name: "MyArtist"
})
@ -50,7 +50,7 @@ describe('POST /artist/modify with an existing artist', () => {
async function modifyArtist(req) {
await req
.post('/artist/modify')
.put('/artist/1')
.send({
name: "MyNewArtist",
id: 1
@ -62,7 +62,7 @@ describe('POST /artist/modify with an existing artist', () => {
async function checkArtist(req) {
await req
.get('/artist/details/1')
.get('/artist/1')
.then((res) => {
expect(res).to.have.status(200);
expect(res.body).to.deep.equal({

Loading…
Cancel
Save