Skip to content
This repository has been archived by the owner on May 7, 2021. It is now read-only.

Implement validation constraints #7

Merged
merged 1 commit into from
Feb 9, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@
},
"dependencies": {
"firebase": "^5.8.0",
"lodash": "^4.17.11"
"lodash": "^4.17.11",
"validate.js": "^0.12.0"
},
"devDependencies": {
"@types/lodash": "^4.14.120",
Expand Down
16 changes: 16 additions & 0 deletions src/artworks/artwork.constraints.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
export const ARTWORK_CONSTRAINTS = {
title: {
presence: true
},
imageUrl: {
presence: true,
url: true
},
artistId: {
presence: true,
personExists: true
},
eventbriteId: {
presence: true
}
};
10 changes: 10 additions & 0 deletions src/artworks/artworks.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Artwork } from './artwork';
import { FirebaseArtwork } from './artwork.firebase';
import { PeopleRepository } from '../people/people.repository';
import { withId, QueryFilter, buildQuery } from '../utils';
import { validators } from 'validate.js';
import firebase from 'firebase';
import _ from 'lodash';

Expand All @@ -25,6 +26,15 @@ export class ArtworksRepository {
this.firebaseRepository = firebaseService;
this.peopleRepository = peopleRepository;
this.artworks = this.firebaseRepository.firestore.collection('artworks');

validators.artworkExists = (artworkId: string) => new Promise(async (resolve) => {
const doc = await this.artworks.doc(artworkId).get();
if (doc.exists) {
resolve();
} else {
resolve(`Artwork with ID ${artworkId} does not exist in Firebase`);
}
});
}

async getArtworks(
Expand Down
150 changes: 150 additions & 0 deletions src/events/event.constraints.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
import { EVENT_STATUSES, PROFICIENCIES } from './event';

export const PREREQUISITE_CONSTRAINTS = {
label: {
presence: true,
},
proficiency: {
presence: true,
inclusion: PROFICIENCIES
},
referenceUrl: {
presence: true,
url: true
}
};

export const DEPENDENCY_CONSTRAINTS = {
label: {
presence: true,
},
specification: {
presence: true,
},
referenceUrl: {
presence: true,
url: true
}
};

export const SPEAKER_CONSTRAINTS = {
personId: {
presence: true,
personExists: true
},
organisationId: {
presence: true,
organisationExists: true
},
position: {
presence: true
}
};

export const PUBLICATION_CONSTRAINTS = {
status: {
presence: true,
inclusion: EVENT_STATUSES
},
url: {
url: true
}
};

export const EVENT_CONSTRAINTS = {
tgif: {
presence: true,
numericality: {
onlyInteger: true,
},
tgifUnique: true
},
title: {
presence: true,
length: { maximum: 64 } // Facebook: 64, Eventbrite: 75
},
speakers: {
presence: true,
length: {
minimum: 1,
tooShort: 'needs to have at least 1 speaker',
},
array: {
constraints: SPEAKER_CONSTRAINTS
}
},
tagline: {
presence: true
},
bannerId: {
presence: true,
artworkExists: true
},
description: {
presence: true
},
prerequisites: {
presence: true,
array: {
constraints: PREREQUISITE_CONSTRAINTS
}
},
dependencies: {
presence: true,
array: {
constraints: DEPENDENCY_CONSTRAINTS
}
},
promotion: {
presence: true
},
venueId: {
presence: true,
locationExists: true
},
startTime: {
presence: true,
beforeTime: {
timeAttribute: 'endTime'
}
},
endTime: {
presence: true,
afterTime: {
timeAttribute: 'startTime'
}
},
githubUrl: {
presence: true,
url: true
},
status: {
presence: true,
inclusion: EVENT_STATUSES
},
isPublic: {
presence: true
},
isExternal: {
presence: true
},
hasFood: {
presence: true
},
hasDrinks: {
presence: true
},
remarks: {
presence: true
},
eventbrite: {
object: {
constraints: PUBLICATION_CONSTRAINTS
}
},
facebook: {
object: {
constraints: PUBLICATION_CONSTRAINTS
}
}
};
2 changes: 2 additions & 0 deletions src/events/event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,6 @@ export class Publication {
}

export type Proficiency = 'basic' | 'intermediate' | 'advanced';
export const PROFICIENCIES: Proficiency[] = ['basic', 'intermediate', 'advanced'];
export type EventStatus = 'draft' | 'live' | 'completed';
export const EVENT_STATUSES: EventStatus[] = ['draft', 'live', 'completed'];
10 changes: 10 additions & 0 deletions src/events/events.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { FirebaseEvent, FirebaseEventSpeaker } from './event.firebase';
import { OrganisationsRepository } from '../organisations/organisations.repository';
import { ArtworksRepository } from '../artworks/artworks.repository';
import { withId, QueryFilter, buildQuery } from '../utils';
import { validators } from 'validate.js';
import firebase from 'firebase';
import _ from 'lodash';

Expand Down Expand Up @@ -38,6 +39,15 @@ export class EventsRepository {
this.artworksRepository = artworksRepository;

this.events = this.firebaseRepository.firestore.collection('events');

validators.tgifUnique = (tgif: number) => new Promise(async (resolve) => {
const doc = await this.events.where('tgif', '==', tgif).get();
if (doc.docs.length === 0) {
resolve();
} else {
resolve(`Event with TGIFHacks # ${tgif} already exists in Firebase`);
}
});
}

async getEvents(
Expand Down
7 changes: 5 additions & 2 deletions src/hackoss.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@


export * from './events/event';
export * from './events/event.constraints';
export * from './events/events.repository';

export * from './locations/location';
export * from './locations/location.constraints';
export * from './locations/locations.repository';

export * from './people/person';
export * from './people/person.constraints';
export * from './people/people.repository';

export * from './organisations/organisation';
export * from './organisations/organisation.constraints';
export * from './organisations/organisations.repository';

export * from './artworks/artwork';
export * from './artworks/artwork.constraints';
export * from './artworks/artworks.repository';

export * from './firebase/firebase.config';
Expand Down
25 changes: 25 additions & 0 deletions src/locations/location.constraints.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
export const LOCATION_CONSTRAINTS = {
name: {
presence: true
},
seatingCapacity: {
presence: true,
numericality: {
onlyInteger: true,
greaterThan: 0
}
},
addressLine1: {
presence: true
},
addressLine2: {
presence: true
},
imageUrl: {
presence: true,
url: true
},
eventbriteId: {
presence: true
},
};
10 changes: 10 additions & 0 deletions src/locations/locations.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Location } from './location';
import { FirebaseRepository } from '../firebase/firebase.repository';
import { FirebaseLocation } from './location.firebase';
import { withId, QueryFilter, buildQuery } from '../utils';
import { validators } from 'validate.js';
import firebase from 'firebase';
import _ from 'lodash';

Expand All @@ -19,6 +20,15 @@ export class LocationsRepository {
constructor(firebaseRepository: FirebaseRepository) {
this.firebaseRepository = firebaseRepository;
this.locations = this.firebaseRepository.firestore.collection('locations');

validators.locationExists = (locationId: string) => new Promise(async (resolve) => {
const doc = await this.locations.doc(locationId).get();
if (doc.exists) {
resolve();
} else {
resolve(`Location with ID ${locationId} does not exist in Firebase`);
}
});
}

async getLocations(
Expand Down
20 changes: 20 additions & 0 deletions src/organisations/organisation.constraints.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
export const ORGANISATION_CONSTRAINTS = {
name: {
presence: true
},
about: {
presence: true
},
websiteUrl: {
presence: true,
url: true
},
avatarUrl: {
presence: true,
url: true
},
githubUrl: {
presence: true,
url: true
}
};
10 changes: 10 additions & 0 deletions src/organisations/organisations.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { FirebaseRepository } from '../firebase/firebase.repository';
import { Organisation } from './organisation';
import { FirebaseOrganisation } from './organisation.firebase';
import { withId, QueryFilter, buildQuery } from '../utils';
import { validators } from 'validate.js';
import firebase from 'firebase';
import _ from 'lodash';

Expand All @@ -19,6 +20,15 @@ export class OrganisationsRepository {
constructor(firebaseService: FirebaseRepository) {
this.firebaseRepository = firebaseService;
this.organisations = this.firebaseRepository.firestore.collection('organisations');

validators.organisationExists = (organisationId: string) => new Promise(async (resolve) => {
const doc = await this.organisations.doc(organisationId).get();
if (doc.exists) {
resolve();
} else {
resolve(`Organisation with ID ${organisationId} does not exist in Firebase`);
}
});
}

async getOrganisations(
Expand Down
10 changes: 10 additions & 0 deletions src/people/people.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Person } from './person';
import { FirebaseRepository } from '../firebase/firebase.repository';
import { FirebasePerson } from './person.firebase';
import { withId, QueryFilter, buildQuery } from '../utils';
import { validators } from 'validate.js';
import firebase from 'firebase';
import _ from 'lodash';

Expand All @@ -19,6 +20,15 @@ export class PeopleRepository {
constructor(firebaseService: FirebaseRepository) {
this.firebaseRepository = firebaseService;
this.people = this.firebaseRepository.firestore.collection('people');

validators.personExists = (personId: string) => new Promise(async (resolve) => {
const doc = await this.people.doc(personId).get();
if (doc.exists) {
resolve();
} else {
resolve(`Person with ID ${personId} does not exist in Firebase`);
}
});
}

async getPeople(
Expand Down
Loading