Fixed all except query endpoint. Grouping problems...

pull/14/head
Sander Vocke 5 years ago
parent 4b5c1cdbda
commit 318bd677f0
  1. 4
      server/endpoints/AlbumDetailsEndpointHandler.ts
  2. 3
      server/endpoints/ArtistDetailsEndpointHandler.ts
  3. 1
      server/endpoints/CreateAlbumEndpointHandler.ts
  4. 1
      server/endpoints/CreateArtistEndpointHandler.ts
  5. 1
      server/endpoints/CreateSongEndpointHandler.ts
  6. 5
      server/endpoints/CreateTagEndpointHandler.ts
  7. 15
      server/endpoints/QueryEndpointHandler.ts
  8. 3
      server/endpoints/SongDetailsEndpointHandler.ts
  9. 4
      server/lib/asJson.ts
  10. 24
      server/lib/jasmine_examples/Player.js
  11. 9
      server/lib/jasmine_examples/Song.js
  12. 1
      server/migrations/20200828124218_init_db.ts
  13. 3
      server/test/integration/flows/helpers.js
  14. 11
      server/test/test.sh

@ -1,6 +1,7 @@
import * as api from '../../client/src/api';
import { EndpointError, EndpointHandler, catchUnhandledErrors } from './types';
import Knex from 'knex';
import asJson from '../lib/asJson';
export const AlbumDetailsEndpointHandler: EndpointHandler = async (req: any, res: any, knex: Knex) => {
if (!api.checkAlbumDetailsRequest(req)) {
@ -42,12 +43,13 @@ export const AlbumDetailsEndpointHandler: EndpointHandler = async (req: any, res
await Promise.all([albumPromise, tagIdsPromise, songIdsPromise, artistIdsPromise]);
// Respond to the request.
console.log("ALBUM: ", album);
const response: api.AlbumDetailsResponse = {
name: album['name'],
artistIds: artists,
tagIds: tags,
songIds: songs,
storeLinks: JSON.parse(album['storeLinks']),
storeLinks: asJson(album['storeLinks']),
};
await res.send(response);

@ -1,6 +1,7 @@
import * as api from '../../client/src/api';
import { EndpointError, EndpointHandler, catchUnhandledErrors } from './types';
import Knex from 'knex';
import asJson from '../lib/asJson';
export const ArtistDetailsEndpointHandler: EndpointHandler = async (req: any, res: any, knex: Knex) => {
if (!api.checkArtistDetailsRequest(req)) {
@ -24,7 +25,7 @@ export const ArtistDetailsEndpointHandler: EndpointHandler = async (req: any, re
const response: api.ArtistDetailsResponse = {
name: results[0].name,
tagIds: tagIds,
storeLinks: JSON.parse(results[0].storeLinks),
storeLinks: asJson(results[0].storeLinks),
}
await res.send(response);

@ -51,6 +51,7 @@ export const CreateAlbumEndpointHandler: EndpointHandler = async (req: any, res:
name: reqObject.name,
storeLinks: JSON.stringify(reqObject.storeLinks || []),
})
.returning('id') // Needed for Postgres
)[0];
// Link the artists via the linking table.

@ -41,6 +41,7 @@ export const CreateArtistEndpointHandler: EndpointHandler = async (req: any, res
name: reqObject.name,
storeLinks: JSON.stringify(reqObject.storeLinks || []),
})
.returning('id') // Needed for Postgres
)[0];
// Link the tags via the linking table.

@ -60,6 +60,7 @@ export const CreateSongEndpointHandler: EndpointHandler = async (req: any, res:
title: reqObject.title,
storeLinks: JSON.stringify(reqObject.storeLinks || []),
})
.returning('id') // Needed for Postgres
)[0];
// Link the artists via the linking table.

@ -40,7 +40,10 @@ export const CreateTagEndpointHandler: EndpointHandler = async (req: any, res: a
if (maybeParent) {
tag['parentId'] = maybeParent;
}
const tagId = (await trx('tags').insert(tag))[0];
const tagId = (await trx('tags')
.insert(tag)
.returning('id') // Needed for Postgres
)[0];
// Respond to the request.
const responseObject: api.CreateTagResponse = {

@ -1,6 +1,7 @@
import * as api from '../../client/src/api';
import { EndpointError, EndpointHandler, catchUnhandledErrors } from './types';
import Knex from 'knex';
import asJson from '../lib/asJson';
enum ObjectType {
Song = 0,
@ -176,13 +177,13 @@ function constructQuery(knex: Knex, queryFor: ObjectType, queryElem: api.QueryEl
joinObjects.delete(queryFor); // We are already querying this object in the base query.
// Figure out what data we want to select from the results.
var columns: string[] = [];
var columns: any[] = [];
joinObjects.forEach((obj: ObjectType) => columns.push(...objectColumns[obj]));
columns.push(...objectColumns[queryFor]);
// First, we create a base query for the type of object we need to yield.
var q = knex.select(columns)
.distinct(objectTables[queryFor] + '.' + 'id')
.groupBy(objectTables[queryFor] + '.' + 'id')
.from(objectTables[queryFor]);
// Now, we need to add join statements for other objects we want to filter on.
@ -213,11 +214,13 @@ async function getLinkedObjects(knex: Knex, base: ObjectType, linked: ObjectType
const columns = objectColumns[linked];
await Promise.all(baseIds.map((baseId: number) => {
return knex.select(columns).distinct(otherTable + '.id').from(otherTable)
return knex.select(columns).groupBy(otherTable + '.id').from(otherTable)
.join(linkingTable, { [linkingTable + '.' + linkingTableIdNames[linked]]: otherTable + '.id' })
.where({ [linkingTable + '.' + linkingTableIdNames[base]]: baseId })
.then((others: any) => { result[baseId] = others; })
}))
console.log("Query results for", baseIds, ":", result);
return result;
}
@ -309,12 +312,12 @@ export const QueryEndpointHandler: EndpointHandler = async (req: any, res: any,
return <api.SongDetails>{
songId: song['songs.id'],
title: song['songs.title'],
storeLinks: JSON.parse(song['songs.storeLinks']),
storeLinks: asJson(song['songs.storeLinks']),
artists: songsArtists[song['songs.id']].map((artist: any) => {
return <api.ArtistDetails>{
artistId: artist['artists.id'],
name: artist['artists.name'],
storeLinks: JSON.parse(artist['artists.storeLinks']),
storeLinks: asJson(artist['artists.storeLinks']),
};
}),
tags: songsTags[song['songs.id']].map((tag: any) => {
@ -330,7 +333,7 @@ export const QueryEndpointHandler: EndpointHandler = async (req: any, res: any,
return <api.ArtistDetails>{
artistId: artist['artists.id'],
name: artist['artists.name'],
storeLinks: JSON.parse(artist['artists.storeLinks']),
storeLinks: asJson(artist['artists.storeLinks']),
}
}),
tags: tags.map((tag: any) => {

@ -1,6 +1,7 @@
import * as api from '../../client/src/api';
import { EndpointError, EndpointHandler, catchUnhandledErrors } from './types';
import Knex from 'knex';
import asJson from '../lib/asJson';
export const SongDetailsEndpointHandler: EndpointHandler = async (req: any, res: any, knex: Knex) => {
if (!api.checkSongDetailsRequest(req)) {
@ -51,7 +52,7 @@ export const SongDetailsEndpointHandler: EndpointHandler = async (req: any, res:
tagIds: tags,
artistIds: artists,
albumIds: albums,
storeLinks: JSON.parse(song.storeLinks),
storeLinks: asJson(song.storeLinks),
}
await res.send(response);

@ -0,0 +1,4 @@
export default function asJson(s: Object | string) {
return (typeof s === 'string') ?
JSON.parse(s) : s;
}

@ -1,24 +0,0 @@
function Player() {
}
Player.prototype.play = function(song) {
this.currentlyPlayingSong = song;
this.isPlaying = true;
};
Player.prototype.pause = function() {
this.isPlaying = false;
};
Player.prototype.resume = function() {
if (this.isPlaying) {
throw new Error("song is already playing");
}
this.isPlaying = true;
};
Player.prototype.makeFavorite = function() {
this.currentlyPlayingSong.persistFavoriteStatus(true);
};
module.exports = Player;

@ -1,9 +0,0 @@
function Song() {
}
Song.prototype.persistFavoriteStatus = function(value) {
// something complicated
throw new Error("not yet implemented");
};
module.exports = Song;

@ -114,5 +114,6 @@ export async function down(knex: Knex): Promise<void> {
await knex.schema.dropTable('songs_tags');
await knex.schema.dropTable('artists_tags');
await knex.schema.dropTable('albums_tags');
await knex.schema.dropTable('artists_albums');
}

@ -7,6 +7,9 @@ export async function initTestDB() {
{ client: 'sqlite3', connection: ':memory:' };
console.log("Running tests with DB config: ", config);
const knex = await require('knex')(config);
// Undoing and doing the migrations is a test in itself.
await knex.migrate.rollback(undefined, true);
await knex.migrate.latest();
return knex;
}

@ -3,6 +3,8 @@
# Wrapper around the Jasmine test scripts.
# Can test with different types of databases.
set -x
SCRIPT=`realpath $0`
SCRIPTPATH=`dirname $SCRIPT`
SOURCEPATH="$SCRIPTPATH/.."
@ -36,17 +38,18 @@ while (( "$#" )); do
shift
;;
*) # preserve positional arguments
PARAMS="$PARAMS $1"
echo "Preserving params: $1"
PARAMS="$PARAMS \"$1\""
shift
;;
esac
done
# Set positional arguments in their proper place
# set positional arguments in their proper place
eval set -- "$PARAMS"
pushd $SOURCEPATH
if [ ! -z "${DO_SQLITE}" ]; then
MUDBASE_DB_CONFIG="$SQLITE_CONFIG" ./node_modules/.bin/ts-node node_modules/jasmine/bin/jasmine --config=test/jasmine.json $@
MUDBASE_DB_CONFIG="$SQLITE_CONFIG" ./node_modules/.bin/ts-node node_modules/jasmine/bin/jasmine --config=test/jasmine.json "$@"
SQLITE_RESULT=$(echo $?)
fi
if [ ! -z "${DO_POSTGRES}" ]; then
@ -66,7 +69,7 @@ if [ ! -z "${DO_POSTGRES}" ]; then
sleep 1;
done
MUDBASE_DB_CONFIG="$POSTGRES_CONFIG" ./node_modules/.bin/ts-node node_modules/jasmine/bin/jasmine --config=test/jasmine.json $@ 2>&1
MUDBASE_DB_CONFIG="$POSTGRES_CONFIG" ./node_modules/.bin/ts-node node_modules/jasmine/bin/jasmine --config=test/jasmine.json "$@"
POSTGRES_RESULT=$(echo $?)
docker stop ${CONTAINERID}

Loading…
Cancel
Save