Skip to content
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
Empty file added src/Commons/utils/isTest.js
Empty file.
59 changes: 34 additions & 25 deletions src/Infrastructures/http/createServer.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,33 @@
const Hapi = require("@hapi/hapi");
const Jwt = require("@hapi/jwt");

let HapiSwagger;
let Inert;
let Vision;

if (process.env.NODE_ENV !== "test") {
HapiSwagger = require("hapi-swagger");
Inert = require("@hapi/inert");
Vision = require("@hapi/vision");
}

const ClientError = require("../../Commons/exceptions/ClientError");
const DomainErrorTranslator = require("../../Commons/exceptions/DomainErrorTranslator");
const Jwt = require("@hapi/jwt");

const users = require("../../Interfaces/http/api/users");
const authentications = require("../../Interfaces/http/api/authentications");
const threads = require("../../Interfaces/http/api/threads");
const comments = require("../../Interfaces/http/api/comments");
const replies = require("../../Interfaces/http/api/replies");
const likes = require("../../Interfaces/http/api/likes");

const swaggerOptions = {
info: {
title: "Forum API Documentation",
version: "1.0.0",
},
};

const createServer = async (container) => {
const server = Hapi.server({
host: process.env.HOST,
Expand Down Expand Up @@ -47,32 +66,22 @@ const createServer = async (container) => {
});

await server.register([
{
plugin: users,
options: { container },
},
{
plugin: authentications,
options: { container },
},
{
plugin: threads,
options: { container },
},
{
plugin: comments,
options: { container },
},
{
plugin: replies,
options: { container },
},
{
plugin: likes,
options: { container },
},
{ plugin: users, options: { container } },
{ plugin: authentications, options: { container } },
{ plugin: threads, options: { container } },
{ plugin: comments, options: { container } },
{ plugin: replies, options: { container } },
{ plugin: likes, options: { container } },
]);

if (process.env.NODE_ENV !== "test") {
await server.register([
{ plugin: Inert },
{ plugin: Vision },
{ plugin: HapiSwagger, options: swaggerOptions },
]);
}

server.ext("onPreResponse", (request, h) => {
// mendapatkan konteks response dari request
const { response } = request;
Expand Down
20 changes: 18 additions & 2 deletions src/Interfaces/http/api/authentications/routes.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,35 @@
const routes = (handler) => ([
const Joi = require('joi');
const swaggerDocs = require("./swagger/authentication");

const isTest = process.env.NODE_ENV === 'test';

const routes = (handler) => [
{
method: 'POST',
path: '/authentications',
handler: handler.postAuthenticationHandler,
options: isTest
? {}
: swaggerDocs.postAuthentication
},

{
method: 'PUT',
path: '/authentications',
handler: handler.putAuthenticationHandler,
options: isTest
? {}
: swaggerDocs.putAuthentication
},

{
method: 'DELETE',
path: '/authentications',
handler: handler.deleteAuthenticationHandler,
options: isTest
? {}
: swaggerDocs.deleteAuthentication
},
]);
];

module.exports = routes;
63 changes: 63 additions & 0 deletions src/Interfaces/http/api/authentications/swagger/authentication.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
const Joi = require("joi");

const postAuthentication = {
tags: ["api", "Authentications"],
description: "Membuat authentication baru (login)",
notes: "User mengirimkan username dan password, akan dikembalikan accessToken & refreshToken",

validate: {
payload: Joi.object({
username: Joi.string().required().description("Username user"),
password: Joi.string().required().description("Password user"),
}),
},

response: {
schema: Joi.object({
accessToken: Joi.string().required(),
refreshToken: Joi.string().required(),
}).label("PostAuthenticationResponse"),
},
};

const putAuthentication = {
tags: ["api", "Authentications"],
description: "Memperbarui access token menggunakan refresh token",
notes: "User mengirimkan refreshToken yang valid, akan dikembalikan accessToken baru",

validate: {
payload: Joi.object({
refreshToken: Joi.string().required().description("Refresh token yang valid"),
}),
},

response: {
schema: Joi.object({
accessToken: Joi.string().required(),
}).label("PutAuthenticationResponse"),
},
};

const deleteAuthentication = {
tags: ["api", "Authentications"],
description: "Menghapus refresh token (logout)",
notes: "User mengirimkan refreshToken yang ingin dihapus",

validate: {
payload: Joi.object({
refreshToken: Joi.string().required().description("Refresh token yang ingin dihapus"),
}),
},

response: {
schema: Joi.object({
status: Joi.string().valid("success").required(),
}).label("DeleteAuthenticationResponse"),
},
};

module.exports = {
postAuthentication,
putAuthentication,
deleteAuthentication,
};
44 changes: 26 additions & 18 deletions src/Interfaces/http/api/comments/routes.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,28 @@
const routes = (handler) => ([
{
method:'POST',
path:'/threads/{thread_id}/comments',
handler: handler.postAddCommentHandler,
options: {
auth: 'forumapi_jwt',
},
},
{
method:'DELETE',
path:'/threads/{thread_id}/comments/{comment_id}',
handler: handler.deleteCommentHandler,
options: {
auth: 'forumapi_jwt',
},
}
]);
const swaggerDocs = require('./swagger/comments');

const isTest = process.env.NODE_ENV === 'test';

const routes = (handler) => [
{
method: 'POST',
path: '/threads/{thread_id}/comments',
handler: handler.postAddCommentHandler,
options: isTest
? {
auth: 'forumapi_jwt'
}
: swaggerDocs.postAddComment,
},
{
method: 'DELETE',
path: '/threads/{thread_id}/comments/{comment_id}',
handler: handler.deleteCommentHandler,
options: isTest
? {
auth: 'forumapi_jwt'
}
: swaggerDocs.deleteComment,
},
];

module.exports = routes;
55 changes: 55 additions & 0 deletions src/Interfaces/http/api/comments/swagger/comments.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
const Joi = require('joi');

const postAddComment = {
auth: 'forumapi_jwt',
tags: ['api', 'Comments'],
description: 'Menambah komentar pada sebuah thread',
notes: 'User harus login (JWT). Komentar akan ditambahkan ke thread tertentu.',

validate: {
params: Joi.object({
thread_id: Joi.string().required().description('ID thread target'),
}),
payload: Joi.object({
content: Joi.string().required().description('Isi komentar'),
}),
},

response: {
schema: Joi.object({
status: Joi.string().valid('success').required(),
data: Joi.object({
addedComment: Joi.object({
id: Joi.string().required(),
content: Joi.string().required(),
owner: Joi.string().required(),
}),
}),
}).label('AddCommentResponse'),
},
};

const deleteComment = {
auth: 'forumapi_jwt',
tags: ['api', 'Comments'],
description: 'Menghapus komentar dari thread',
notes: 'User harus login. Hanya pemilik komentar yang dapat menghapus.',

validate: {
params: Joi.object({
thread_id: Joi.string().required().description('ID thread'),
comment_id: Joi.string().required().description('ID komentar yang akan dihapus'),
}),
},

response: {
schema: Joi.object({
status: Joi.string().valid('success').required(),
}).label('DeleteCommentResponse'),
},
};

module.exports = {
postAddComment,
deleteComment,
};
28 changes: 17 additions & 11 deletions src/Interfaces/http/api/likes/routes.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
const routes = (handler) => ([
{
method:'PUT',
path:'/threads/{thread_id}/comments/{comment_id}/likes',
handler: handler.putCommentLikeHandler,
options: {
auth: 'forumapi_jwt',
},
}
]);
const swaggerDocs = require('./swagger/likes');

module.exports = routes;
const isTest = process.env.NODE_ENV === 'test';

const routes = (handler) => [
{
method: 'PUT',
path: '/threads/{thread_id}/comments/{comment_id}/likes',
handler: handler.putCommentLikeHandler,
options: isTest
? {
auth: 'forumapi_jwt'
}
: swaggerDocs.putCommentLike,
},
];

module.exports = routes;
25 changes: 25 additions & 0 deletions src/Interfaces/http/api/likes/swagger/likes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
const Joi = require('joi');

const putCommentLike = {
auth: 'forumapi_jwt',
tags: ['api', 'CommentLikes'],
description: 'Memberikan atau menghapus like pada komentar',
notes: 'User harus login. Like bersifat toggle: jika sudah di-like, maka unlike.',

validate: {
params: Joi.object({
thread_id: Joi.string().required().description('ID thread'),
comment_id: Joi.string().required().description('ID komentar'),
}),
},

response: {
schema: Joi.object({
status: Joi.string().valid('success').required(),
}).label('PutCommentLikeResponse'),
},
};

module.exports = {
putCommentLike,
};
46 changes: 27 additions & 19 deletions src/Interfaces/http/api/replies/routes.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,28 @@
const routes = (handler) => ([
{
method:'POST',
path:'/threads/{thread_id}/comments/{comment_id}/replies',
handler: handler.postAddReplyHandler,
options: {
auth: 'forumapi_jwt',
},
},
{
method:'DELETE',
path:'/threads/{thread_id}/comments/{comment_id}/replies/{reply_id}',
handler: handler.deleteReplyHandler,
options: {
auth: 'forumapi_jwt',
},
}
]);
const swaggerDocs = require('./swagger/replies');

module.exports = routes;
const isTest = process.env.NODE_ENV === 'test';

const routes = (handler) => [
{
method: 'POST',
path: '/threads/{thread_id}/comments/{comment_id}/replies',
handler: handler.postAddReplyHandler,
options: isTest
? {
auth: 'forumapi_jwt'
}
: swaggerDocs.postAddReply,
},
{
method: 'DELETE',
path: '/threads/{thread_id}/comments/{comment_id}/replies/{reply_id}',
handler: handler.deleteReplyHandler,
options: isTest
? {
auth: 'forumapi_jwt'
}
: swaggerDocs.deleteReply,
},
];

module.exports = routes;
Loading