New Articles routes working

GET /api/articles/:slug
DELETE /api/articles/:slug
This commit is contained in:
Josh Black 2017-09-23 10:54:38 -06:00
parent d00c1a22c5
commit 31be9ea891
3 changed files with 113 additions and 12 deletions

31
Dockerfile Normal file
View File

@ -0,0 +1,31 @@
# Base image
FROM node:8.5.0
# Create app directory
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
# Bundle app source
COPY . /usr/src/app
## our base image
#FROM node:6.9.1
#
## Create app directory
#RUN mkdir -p /usr/src/app
#WORKDIR /usr/src/app
#
## Install app dependencies
#COPY package.json /usr/src/app/
#RUN npm install && \
# npm install -g nodemon
#
## Bundle app source
#COPY . /usr/src/app
#
## tell the port number the container should expose
#EXPOSE 3000
#
## run the application
#CMD ["nodemon", "app.js"]

View File

@ -1,6 +1,7 @@
import { Request } from 'express';
import { IUserModel } from '../models/user-model';
import { IArticleModel } from '../models/article-model';
// Add jwt payload details to Express Request
@ -14,7 +15,13 @@ export interface JWTRequest extends Request {
}
// Add profile details to Express Request
// Add profile details to JWT Request
export interface ProfileRequest extends JWTRequest {
profile: IUserModel;
}
// Add article details to ProfileRequest
export interface ArticleRequest extends ProfileRequest {
article: IArticleModel;
}

View File

@ -1,7 +1,7 @@
import { Router, NextFunction, Response } from 'express';
import { authentication } from '../utilities/authentication';
import { JWTRequest, ProfileRequest } from '../interfaces/requests-interface';
import { ArticleRequest, JWTRequest, ProfileRequest } from '../interfaces/requests-interface';
import { Article, IArticleModel } from '../models/article-model';
import { IUserModel, User } from '../models/user-model';
import { IQuery } from '../interfaces/article-interface';
@ -13,11 +13,27 @@ const Promise = require('bluebird'); // FIXME: how to handle this in Typescript
/**
* GET /api/articles
* PARAM :slug
*/
// FIXME: authorized user who has favorited own articles showing false.
// Should show true for all returned josh articles
router.get('/', authentication.optional, (req: ProfileRequest, res: Response, next: NextFunction) => {
router.param('slug', (req: ArticleRequest, res: Response, next: NextFunction, slug: string) => {
Article
.findOne({slug})
.populate('author')
.then( (article: IArticleModel) => {
req.article = article;
return next();
})
.catch(next);
});
/**
* Helper function to determine the requesting user (if any)
*/
// FIXME: Not sure there is a req.profile... make this robust...
function establishRequestingUser(req: ProfileRequest): IUserModel {
// Try to determine the user making the request
let thisUser: IUserModel;
@ -27,7 +43,7 @@ router.get('/', authentication.optional, (req: ProfileRequest, res: Response, ne
User
.findById(req.payload.id)
.then( (user: IUserModel) => {
return thisUser = req.profile.formatAsProfileJSON(user);
return thisUser = user.formatAsProfileJSON(user);
})
.catch();
@ -35,6 +51,16 @@ router.get('/', authentication.optional, (req: ProfileRequest, res: Response, ne
} else {
thisUser = req.profile;
}
return thisUser;
}
/**
* GET /api/articles
*/
// FIXME: authorized user who has favorited own articles showing false.
// Should show true for all returned 'josh' articles
router.get('/', authentication.optional, (req: ProfileRequest, res: Response, next: NextFunction) => {
// Parse URL query strings and create a query object
const limit: number = req.query.limit ? Number(req.query.limit) : 20;
@ -95,7 +121,7 @@ router.get('/', authentication.optional, (req: ProfileRequest, res: Response, ne
// Define promises
const p1 = thisUser;
const p1 = establishRequestingUser(req);
const p2 = Article.count(query).exec();
/* ISSUE: Should count be MIN(count, limit)? or should it count all results,
@ -165,13 +191,50 @@ router.post('/', authentication.required, (req: JWTRequest, res: Response, next:
});
/**
* GET /api/articles/:slug
*/
// ISSUE: Possibly not showing following correctly for auth user...
router.get('/:slug', authentication.optional, (req: ArticleRequest, res: Response, next: NextFunction) => {
const user = establishRequestingUser(req);
console.log(user);
console.log(req.article);
const article: IArticleModel = req.article;
if (article) {
res.json(article.formatAsArticleJSON(user));
} else {
return next();
}
});
/**
* DELETE /api/articles/:slug
*/
router.delete('/:slug', authentication.required, (req: ArticleRequest, res: Response, next: NextFunction) => {
Article
.findOneAndRemove({slug: req.article.slug}, () => {
return res.json();
})
.catch(next);
});
/**
* PUT /api/articles/:slug
*/
router.put('/:slug', authentication.required, (req: ArticleRequest, res: Response, next: NextFunction) => {
});
// TODO: Remaining routes
// GET /api/articles/feed
// GET /api/articles/:slug
// PUT /api/articles/:slug
// DELETE /api/articles/:slug
// POST /api/articles/:slug/comments
// GET /api/articles/:slug/comments
// DELETE /api/articles/:slug/comments/:id