-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
using import_map.json instead of deps.ts
- Loading branch information
Showing
28 changed files
with
378 additions
and
430 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,106 +1,106 @@ | ||
import {superoak} from "./deps.ts"; | ||
import {superoak} from "superoak"; | ||
import {app} from "./app.ts"; | ||
import {makeAccessToken} from "./util/jwt.ts"; | ||
import {User} from "./entity/user.ts"; | ||
import {Authority, AuthorityName} from "./entity/authority.ts"; | ||
|
||
async function generateAdminToken() { | ||
const user = new User(); | ||
user.username = "admin"; | ||
user.email = "[email protected]"; | ||
const user = new User(); | ||
user.username = "admin"; | ||
user.email = "[email protected]"; | ||
|
||
const roleAdmin = new Authority(); | ||
roleAdmin.name = AuthorityName.ADMIN; | ||
const roleUser = new Authority(); | ||
const roleAdmin = new Authority(); | ||
roleAdmin.name = AuthorityName.ADMIN; | ||
const roleUser = new Authority(); | ||
|
||
user.authorities = [roleAdmin, roleUser]; | ||
user.authorities = [roleAdmin, roleUser]; | ||
|
||
return await makeAccessToken(user); | ||
return await makeAccessToken(user); | ||
} | ||
|
||
async function generateUserToken() { | ||
const user = new User(); | ||
user.username = "user"; | ||
user.email = "[email protected]"; | ||
const user = new User(); | ||
user.username = "user"; | ||
user.email = "[email protected]"; | ||
|
||
const roleUser = new Authority(); | ||
const roleUser = new Authority(); | ||
|
||
user.authorities = [roleUser]; | ||
user.authorities = [roleUser]; | ||
|
||
return await makeAccessToken(user); | ||
return await makeAccessToken(user); | ||
} | ||
|
||
const adminToken = await generateAdminToken(); | ||
const userToken = await generateUserToken(); | ||
|
||
Deno.test("Unauthorized Error", async () => { | ||
const request = await superoak(app); | ||
await request.get("/api/heroes").expect(401); | ||
const request = await superoak(app); | ||
await request.get("/api/heroes").expect(401); | ||
}); | ||
|
||
Deno.test("Forbidden Error", async () => { | ||
const request = await superoak(app); | ||
await request.post("/api/heroes").auth(userToken, {type: "bearer"}).send({name: "Jack"}) | ||
.expect(403); | ||
const request = await superoak(app); | ||
await request.post("/api/heroes").auth(userToken, {type: "bearer"}).send({name: "Jack"}) | ||
.expect(403); | ||
}); | ||
|
||
Deno.test("should get token successfully", async () => { | ||
const request = await superoak(app); | ||
await request.post("/api/auth").send({username: "admin", password: "admin"}) | ||
.expect('Content-Type', 'application/json; charset=utf-8') | ||
.expect(/{"token":.*,"refresh_token":.*}/i); | ||
const request = await superoak(app); | ||
await request.post("/api/auth").send({username: "admin", password: "admin"}) | ||
.expect('Content-Type', 'application/json; charset=utf-8') | ||
.expect(/{"token":.*,"refresh_token":.*}/i); | ||
}); | ||
|
||
Deno.test("should provide correct credential", async () => { | ||
const request = await superoak(app); | ||
await request.post("/api/auth").send({username: "admin", password: "111111"}) | ||
.expect(401); | ||
const request = await superoak(app); | ||
await request.post("/api/auth").send({username: "admin", password: "111111"}) | ||
.expect(401); | ||
}); | ||
|
||
Deno.test("crud should be executed successfully", async () => { | ||
// add hero | ||
let request = await superoak(app); | ||
await request.post("/api/heroes").auth(adminToken, {type: "bearer"}).send({name: "Jack"}) | ||
.expect(200).expect(/{"name":"Jack","id":11,.*}/); | ||
|
||
// update hero | ||
request = await superoak(app); | ||
await request.post("/api/heroes").auth(adminToken, {type: "bearer"}).send({name: "Jacky", id: 11}) | ||
.expect(200).expect(/{"name":"Jacky","id":11,.*}/); | ||
|
||
// find heroes by name | ||
request = await superoak(app); | ||
await request.get("/api/heroes/?name=m").auth(adminToken, {type: "bearer"}) | ||
.expect(200); | ||
|
||
// find heroes by page | ||
request = await superoak(app); | ||
await request.get("/api/heroes").auth(adminToken, {type: "bearer"}).send({page: 0, size: 10}) | ||
.expect(200).expect(/{.*"totalElements":11.*}/); | ||
|
||
// get hero by id | ||
request = await superoak(app); | ||
await request.get("/api/heroes/11").auth(adminToken, {type: "bearer"}) | ||
.expect(200).expect(/{"id":11,"name":"Jacky",.*}/); | ||
|
||
// delete hero | ||
request = await superoak(app); | ||
await request.delete("/api/heroes/11").auth(adminToken, {type: "bearer"}).expect(200); | ||
// add hero | ||
let request = await superoak(app); | ||
await request.post("/api/heroes").auth(adminToken, {type: "bearer"}).send({name: "Jack"}) | ||
.expect(200).expect(/{"name":"Jack","id":11,.*}/); | ||
|
||
// update hero | ||
request = await superoak(app); | ||
await request.post("/api/heroes").auth(adminToken, {type: "bearer"}).send({name: "Jacky", id: 11}) | ||
.expect(200).expect(/{"name":"Jacky","id":11,.*}/); | ||
|
||
// find heroes by name | ||
request = await superoak(app); | ||
await request.get("/api/heroes/?name=m").auth(adminToken, {type: "bearer"}) | ||
.expect(200); | ||
|
||
// find heroes by page | ||
request = await superoak(app); | ||
await request.get("/api/heroes").auth(adminToken, {type: "bearer"}).send({page: 0, size: 10}) | ||
.expect(200).expect(/{.*"totalElements":11.*}/); | ||
|
||
// get hero by id | ||
request = await superoak(app); | ||
await request.get("/api/heroes/11").auth(adminToken, {type: "bearer"}) | ||
.expect(200).expect(/{"id":11,"name":"Jacky",.*}/); | ||
|
||
// delete hero | ||
request = await superoak(app); | ||
await request.delete("/api/heroes/11").auth(adminToken, {type: "bearer"}).expect(200); | ||
}); | ||
|
||
Deno.test("validation failed", async () => { | ||
// add hero | ||
const request = await superoak(app); | ||
await request.post("/api/heroes").auth(adminToken, {type: "bearer"}).send({name: "J"}) | ||
.expect(400).expect(/.*,"message":"name characters length must be between 3-30; ",.*/i); | ||
// add hero | ||
const request = await superoak(app); | ||
await request.post("/api/heroes").auth(adminToken, {type: "bearer"}).send({name: "J"}) | ||
.expect(400).expect(/.*,"message":"name characters length must be between 3-30; ",.*/i); | ||
}); | ||
|
||
Deno.test("Path not found", async () => { | ||
const request = await superoak(app); | ||
await request.get("/api/test").auth(adminToken, {type: "bearer"}).expect(404); | ||
const request = await superoak(app); | ||
await request.get("/api/test").auth(adminToken, {type: "bearer"}).expect(404); | ||
}); | ||
|
||
Deno.test("Entity not found", async () => { | ||
const request = await superoak(app); | ||
await request.get("/api/test/9999").auth(adminToken, {type: "bearer"}).expect(404); | ||
const request = await superoak(app); | ||
await request.get("/api/test/9999").auth(adminToken, {type: "bearer"}).expect(404); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
import { config as loadConfig } from "../deps.ts"; | ||
import {config as loadConfig} from "dotenv"; | ||
|
||
export const config = loadConfig({ safe: true }); | ||
export const config = loadConfig({safe: true}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,18 @@ | ||
import {Request, required, Response} from "../deps.ts"; | ||
import {Request, Response} from "oak"; | ||
import {required} from "validasaur"; | ||
import {LoginCredential} from "../interfaces/LoginCredential.ts"; | ||
import * as authService from "../service/user_service.ts"; | ||
import {validateRequest} from "../util/validator.ts"; | ||
|
||
async function login({request, response}: { request: Request; response: Response }) { | ||
const credential = (await request.body().value) as LoginCredential; | ||
await validateCredential(credential); | ||
response.body = await authService.authenticate(credential); | ||
async function login({request, response}: { request: Request; response: Response }): Promise<void> { | ||
const credential = (await request.body().value) as LoginCredential; | ||
await validateCredential(credential); | ||
response.body = await authService.authenticate(credential); | ||
} | ||
|
||
async function validateCredential(credential: LoginCredential): Promise<void> { | ||
const credentialSchema = {username: [required], password: [required]}; | ||
await validateRequest(credential, credentialSchema); | ||
const credentialSchema = {username: [required], password: [required]}; | ||
await validateRequest(credential, credentialSchema); | ||
} | ||
|
||
export {login}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,83 +1,84 @@ | ||
import {lengthBetween, match, oakHelpers, required, RouterContext, Status} from "../deps.ts"; | ||
import {helpers as oakHelpers, RouterContext, Status} from "oak"; | ||
import {lengthBetween, match, required} from "validasaur"; | ||
import {deleteHeroById, findHeroesByName, getHeroById, getHeroesByPage, saveHero} from "../service/hero_service.ts"; | ||
import {Hero} from "../entity/hero.ts"; | ||
import {parsePageQuery} from "../util/pages.ts"; | ||
import {validateRequest} from "../util/validator.ts"; | ||
|
||
// get heroes | ||
async function getHeroes(context: RouterContext) { | ||
const query = oakHelpers.getQuery(context); | ||
context.response.body = await getHeroesByPage(parsePageQuery(query)); | ||
async function getHeroes(context: RouterContext): Promise<void> { | ||
const query = oakHelpers.getQuery(context); | ||
context.response.body = await getHeroesByPage(parsePageQuery(query)); | ||
} | ||
|
||
// get hero by id | ||
async function getHero(context: RouterContext) { | ||
const {id} = context.params; | ||
await validateId(id); | ||
async function getHero(context: RouterContext): Promise<void> { | ||
const {id} = context.params; | ||
await validateId(id); | ||
|
||
if (id) { | ||
context.response.body = await getHeroById(parseInt(id)); | ||
} | ||
if (id) { | ||
context.response.body = await getHeroById(parseInt(id)); | ||
} | ||
} | ||
|
||
// search heroes by name | ||
async function searchHeroes(context: RouterContext) { | ||
const {name} = oakHelpers.getQuery(context); | ||
await validateName(name); | ||
context.response.body = await findHeroesByName(name); | ||
async function searchHeroes(context: RouterContext): Promise<void> { | ||
const {name} = oakHelpers.getQuery(context); | ||
await validateName(name); | ||
context.response.body = await findHeroesByName(name); | ||
} | ||
|
||
// add a new hero | ||
async function addHero(context: RouterContext) { | ||
const hero: Hero = await context.request.body().value; | ||
await validateHero(hero); | ||
context.response.body = await saveHero(hero); | ||
async function addHero(context: RouterContext): Promise<void> { | ||
const hero: Hero = await context.request.body().value; | ||
await validateHero(hero); | ||
context.response.body = await saveHero(hero); | ||
} | ||
|
||
// update a hero information | ||
async function updateHero(context: RouterContext) { | ||
const hero: Hero = await context.request.body().value; | ||
await validateHero(hero); | ||
context.response.body = await saveHero(hero); | ||
async function updateHero(context: RouterContext): Promise<void> { | ||
const hero: Hero = await context.request.body().value; | ||
await validateHero(hero); | ||
context.response.body = await saveHero(hero); | ||
} | ||
|
||
// Delete a hero by id | ||
async function deleteHero(context: RouterContext) { | ||
const {id} = context.params; | ||
await validateId(id); | ||
async function deleteHero(context: RouterContext): Promise<void> { | ||
const {id} = context.params; | ||
await validateId(id); | ||
|
||
if (id) { | ||
await deleteHeroById(parseInt(id)); | ||
context.response.status = Status.OK; | ||
} | ||
if (id) { | ||
await deleteHeroById(parseInt(id)); | ||
context.response.status = Status.OK; | ||
} | ||
} | ||
|
||
async function validateHero(hero: Hero): Promise<void> { | ||
const heroSchema = {name: [required, lengthBetween(3, 30)]}; | ||
await validateRequest(hero, heroSchema); | ||
const heroSchema = {name: [required, lengthBetween(3, 30)]}; | ||
await validateRequest(hero, heroSchema); | ||
} | ||
|
||
async function validateId(id: string | undefined): Promise<void> { | ||
await validateRequest( | ||
{id}, | ||
{id: [match(/^\d*$/)]}, | ||
{messages: {"id": "id must be a number"}} | ||
); | ||
await validateRequest( | ||
{id}, | ||
{id: [match(/^\d*$/)]}, | ||
{messages: {"id": "id must be a number"}} | ||
); | ||
} | ||
|
||
async function validateName(name: string | undefined): Promise<void> { | ||
await validateRequest( | ||
{name}, | ||
{name: [required]}, | ||
{messages: {"name.required": "Required parameter 'name' is not present"}} | ||
); | ||
await validateRequest( | ||
{name}, | ||
{name: [required]}, | ||
{messages: {"name.required": "Required parameter 'name' is not present"}} | ||
); | ||
} | ||
|
||
export { | ||
addHero, | ||
deleteHero, | ||
getHero, | ||
getHeroes, | ||
searchHeroes, | ||
updateHero, | ||
addHero, | ||
deleteHero, | ||
getHero, | ||
getHeroes, | ||
searchHeroes, | ||
updateHero, | ||
}; |
Oops, something went wrong.