diff --git a/client/src/api.ts b/client/src/api.ts index 89c75c5..e9825bc 100644 --- a/client/src/api.ts +++ b/client/src/api.ts @@ -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 { diff --git a/server/app.ts b/server/app.ts index a2755e8..dc203a1 100644 --- a/server/app.ts +++ b/server/app.ts @@ -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)); } diff --git a/server/endpoints/ModifyArtistEndpointHandler.ts b/server/endpoints/ModifyArtistEndpointHandler.ts index a6e24af..bb70a4a 100644 --- a/server/endpoints/ModifyArtistEndpointHandler.ts +++ b/server/endpoints/ModifyArtistEndpointHandler.ts @@ -10,15 +10,15 @@ export const ModifyArtistEndpointHandler: EndpointHandler = async (req: any, res }; throw e; } - const reqObject: api.ModifyArtistRequest = req.body; + 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); } \ No newline at end of file diff --git a/server/endpoints/ModifySongEndpointHandler.ts b/server/endpoints/ModifySongEndpointHandler.ts index 66349e9..06150e4 100644 --- a/server/endpoints/ModifySongEndpointHandler.ts +++ b/server/endpoints/ModifySongEndpointHandler.ts @@ -57,12 +57,12 @@ export const ModifySongEndpointHandler: EndpointHandler = async (req: any, res: // Start retrieving the song to modify. var songInstancePromise: Promise = 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(() => { diff --git a/server/test/integration/flows/CreateArtistFlow.js b/server/test/integration/flows/CreateArtistFlow.js index c0b1518..7d8f4c2 100644 --- a/server/test/integration/flows/CreateArtistFlow.js +++ b/server/test/integration/flows/CreateArtistFlow.js @@ -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" }) diff --git a/server/test/integration/flows/CreateSongFlow.js b/server/test/integration/flows/CreateSongFlow.js index beef2e6..2f06838 100644 --- a/server/test/integration/flows/CreateSongFlow.js +++ b/server/test/integration/flows/CreateSongFlow.js @@ -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] diff --git a/server/test/integration/flows/ModifyArtistFlow.js b/server/test/integration/flows/ModifyArtistFlow.js index bb83c5f..f2a7fdd 100644 --- a/server/test/integration/flows/ModifyArtistFlow.js +++ b/server/test/integration/flows/ModifyArtistFlow.js @@ -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({