1편에서도 언급했듯이 다음과 같은 API가 필요하다
1. 특정 Directory를 스캔하여 해당 Directory의 Hierachy를 Json형태로 반환
2. 해당 Hierachy에 맞게 경로값을 인자로 보내주면 그 경로에 있는 pdf파일 다운로드
//app.js
const manualRouter = require('./routes/manualRoutes');
const app = express();
app.use('/api', manualRouter);
기본적인 app 설정. manualRouter의 기본 baseUrl은 '/api'로 설정했다.
//routes/manualRoutes.js
const express = require('express');
const router = express.Router();
const manualController = require('../controllers/manualController');
const checkToken = require('../auth/checkToken');
router.get('/download', checkToken.check, manualController.downloadAPI);
router.get('/directory', checkToken.check, manualController.scanDirectoryAPI);
module.exports = router;
Router에서는 해당 Request 요청이 정상적인지 체크(Access token)하는 로직을
미들웨어에 넣고 정상적이라면 Controller 함수를 호출 가능하게 한다.
//controllers/manualController.js
const fs = require('fs');
const directory = require('../models/Directory');
const ROOTPATH = 'directoryName';
function scanDirectoryAPI(req, res) {
if (fs.existsSync(ROOTPATH)) {
var dirObject = directory.scan();
const PdfTotalCount = dirObject.PdfTotalCount;
const DirectoryTree = dirObject.JsonTree;
res.status(200).json({ PdfTotalCount, DirectoryTree });
} else {
console.log("There are no files in that path");
res.status(404).end();
}
}
module.exports = { downloadAPI, scanDirectoryAPI }
Controller에서는 Directory라는 Model의 정보가 접근 가능하며 request에 대한 response를 담당한다.
//models/Directory.js
const dirTree = require('directory-tree');
const ROOTPATH = 'directoryName';
function scan() {
var PdfTotalCount = 0;
const JsonTree = dirTree(ROOTPATH, { extensions: /\.(pdf)$/, normalizePath: true },
//Each File
(item, PATH, stats) => {
item['path'] = splitPath(item['path']);
if (item['extension'] === '.pdf') { PdfTotalCount++; }
},
//Each Directory
(item, PATH, stats) => { item['path'] = splitPath(item['path']); }
);
const dirObject = { JsonTree, PdfTotalCount };
return dirObject;
}
function splitPath(originPath) {
return originPath.substr(ROOTPATH.length + 1, originPath.length) || '/';
}
module.exports = { scan }
Model에서는 실제로 해당 디렉토리에 대한 Hierachy 정보를 JSON 형태로 가공한다.
사용 Module은 NPM에서 가져온 'directory-tree' 라이브러리다.
https://www.npmjs.com/package/directory-tree
이렇게 디렉토리 정보를 JSON 형태로 응답하는 첫번째 API에 대한 구현이 끝났다.
API 테스트를 위해 Supertest라는 모듈을 사용하였다.
supertest는 node.js에서 통합 테스트로 사용되는 라이브러리이며 mocha, should와 함께
TDD 필수 라이브러리라고 할 수 있다.
npm install mocha -D
npm install supertest -D
//manual.spec.js
const app = require('../app');
const request = require('supertest');
describe('GET /api/download는', () => {
it('다운로드한 파일을 리턴한다.', (done) => {
request(app)
.get('/api/download?path=A/engineA/engineA.pdf')
.expect('Content-Type', 'application/pdf')
.expect(200)
.end((err, res) => {
if (err) {
done(err);
} else {
done();
}
});
});
it('파일이 없을때 404를 반환한다. ', (done) => {
request(app)
.get('/api/download?path=B/uiB/uiB.pdf')
.expect(404)
.end((err, res) => {
if (err) {
done(err);
} else {
done();
}
});
});
});
describe('GET /api/directory은', () => {
it('json을 리턴한다.', (done) => {
request(app)
.get('/api/directory')
.expect('Content-Type', /json/)
.expect(200)
.end((err, res) => {
if (err) {
done(err);
} else {
done();
console.log(res.body);
}
});
});
});
app 모듈을 가져온 후 api 테스트를 진행한다. 실제로 HTTP Request 요청을 보낼 수 있으며
어떤 결과 값이 나와야 하는지 .expect() 명세를 통해 해당 함수를 체크할 수 있다.
주로 response에 대한 status code값이나 body값을 비교하여 체크한다.
npm run mocha ./manual.spec.js
간단한 API 구현과 함께 Test Module을 도입하였다.
다음 포스팅은 프로젝트 패키징과 Auth관련 내용을 적을 예정이다.