var request = require('supertest');
var jwt = require('jsonwebtoken');
var User = require('../user/user.model');
+var Report = require('../report/report.model');
var config = require('../../config/environment');
+var fs = require('fs');
+var path = require('path');
-var user = new User({
- provider: 'local',
- name: 'Fake User',
- email: 'test@test.com',
- password: 'password'
+var appDir = path.dirname(require.resolve('../../app'));
+
+var localMock = (function () {
+ var privUser;
+ var privReport;
+
+ var base64PDFData =
+ 'JVBERi0xLjEKJcKlwrHDqwoKMSAwIG9iagogIDw8IC9UeXBlIC9DYXRhbG9nCiAgICAgL1BhZ2Vz' +
+ 'IDIgMCBSCiAgPj4KZW5kb2JqCgoyIDAgb2JqCiAgPDwgL1R5cGUgL1BhZ2VzCiAgICAgL0tpZHMg' +
+ 'WzMgMCBSXQogICAgIC9Db3VudCAxCiAgICAgL01lZGlhQm94IFswIDAgMzAwIDE0NF0KICA+Pgpl' +
+ 'bmRvYmoKCjMgMCBvYmoKICA8PCAgL1R5cGUgL1BhZ2UKICAgICAgL1BhcmVudCAyIDAgUgogICAg' +
+ 'ICAvUmVzb3VyY2VzCiAgICAgICA8PCAvRm9udAogICAgICAgICAgIDw8IC9GMQogICAgICAgICAg' +
+ 'ICAgICA8PCAvVHlwZSAvRm9udAogICAgICAgICAgICAgICAgICAvU3VidHlwZSAvVHlwZTEKICAg' +
+ 'ICAgICAgICAgICAgICAgL0Jhc2VGb250IC9UaW1lcy1Sb21hbgogICAgICAgICAgICAgICA+Pgog' +
+ 'ICAgICAgICAgID4+CiAgICAgICA+PgogICAgICAvQ29udGVudHMgNCAwIFIKICA+PgplbmRvYmoK' +
+ 'CjQgMCBvYmoKICA8PCAvTGVuZ3RoIDU1ID4+CnN0cmVhbQogIEJUCiAgICAvRjEgMTggVGYKICAg' +
+ 'IDAgMCBUZAogICAgKEhlbGxvIFdvcmxkKSBUagogIEVUCmVuZHN0cmVhbQplbmRvYmoKCnhyZWYK' +
+ 'MCA1CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwMDAxOCAwMDAwMCBuIAowMDAwMDAwMDc3IDAw' +
+ 'MDAwIG4gCjAwMDAwMDAxNzggMDAwMDAgbiAKMDAwMDAwMDQ1NyAwMDAwMCBuIAp0cmFpbGVyCiAg' +
+ 'PDwgIC9Sb290IDEgMCBSCiAgICAgIC9TaXplIDUKICA+PgpzdGFydHhyZWYKNTY1CiUlRU9GCg==';
+
+
+ var token = function () {
+ privUser.authenticate('password');
+ return jwt.sign({_id: privUser._id}, config.secrets.session, {expiresIn: 60 * 60 * 5});
+ };
+
+
+ var generateUserObj = function (isAdmin) {
+ return new User({
+ provider: 'local',
+ name: 'Fake User',
+ email: 'test@test.com',
+ password: 'password',
+ role: isAdmin ? 'admin' : undefined
+ });
+ };
+
+ var generateReportObj = function () {
+ return new Report({
+ uuid: 'fakeuuid',
+ user: privUser._id,
+ time: Date.now(),
+ referential: privUser.referential ? privUser.referential : {},
+ filename: 'fakefile.pdf',
+ content: 'fakefile.pdf',
+ signatures: [],
+ isGenerated: true
+ });
+ };
+
+ var createReport = function (cb) {
+ //Clear reports before testing
+ Report.remove().exec().then(function () {
+ privReport = generateReportObj();
+ privReport.save(cb)
+ });
+ };
+
+ var setUserId = function (userid, cb) {
+ privReport.user = userid;
+ privReport.save(cb)
+ };
+
+ var createUser = function (cb) {
+ // Clear users before testing
+ User.remove().exec().then(function () {
+ privUser = generateUserObj(false);
+ privUser.save(cb);
+ });
+ };
+
+ var makeUserAdmin = function (done) {
+ privUser.role = 'admin';
+ privUser.save(done);
+ };
+
+ var makeGenerating = function (done) {
+ privReport.isGenerated = false;
+ privReport.save(done);
+ };
+
+ var createEmptyPDF = function (done) {
+ var file = appDir + "/components/worker/generator/output/" + privReport.uuid + ".pdf";
+ fs.writeFile(file, base64PDFData, 'base64', done);
+ };
+
+ var getUser = function () {
+ return privUser;
+ };
+
+ var getReport = function () {
+ return privReport;
+ };
+
+ var beforeEach = function (cb) {
+ createUser(function () {
+ createReport(function () {
+ cb();
+ })
+ });
+ };
+
+ var afterEach = function (cb) {
+ User.remove().exec().then(function () {
+ Report.remove().exec().then(function () {
+ var filename = appDir + "/components/worker/generator/output/" + privReport.uuid + ".pdf";
+ try {
+ fs.accessSync(filename, fs.F_OK);
+ fs.unlinkSync(filename);
+ } catch (e) {
+ //Do nothing
+ }
+ cb();
+ });
+ });
+ };
+
+ privUser = generateUserObj(false);
+
+ return {
+ afterEach: afterEach,
+ beforeEach: beforeEach,
+ base64PDF: base64PDFData,
+ user: {
+ token: token,
+ create: createUser,
+ get: getUser,
+ admin: makeUserAdmin
+ },
+ report: {
+ setUserId: setUserId,
+ get: getReport,
+ makeGenerating: makeGenerating,
+ createEmptyPDF: createEmptyPDF
+ }
+ }
+})();
+
+describe('GET /api/reports', function () {
+ beforeEach(localMock.beforeEach);
+
+ afterEach(localMock.afterEach);
+
+ it('should list with JSON array for admin', function (done) {
+ localMock.user.admin(function () {
+ request(app)
+ .get('/api/reports?access_token=' + localMock.user.token())
+ .expect(200)
+ .expect('Content-Type', /json/)
+ .end(function (err, res) {
+ if (err) return done(err);
+ res.body.should.be.instanceof(Array);
+ res.body.length.should.be.exactly(1);
+ done();
+ });
+ });
+ });
+
+ it('should be forbidden for non admin users', function (done) {
+ request(app)
+ .get('/api/reports?access_token=' + localMock.user.token())
+ .expect(403, done);
+ });
});
-describe('GET /api/reports', function() {
- before(function(done) {
- // Clear users before testing
- User.remove().exec().then(function() {
- user.save(function() {
- done();
- });
- });
- });
-
- afterEach(function(done) {
- User.remove().exec().then(function() {
- done();
- });
- });
-
-
- it('should respond with JSON array', function(done) {
- user.authenticate('password');
- var token = jwt.sign({_id: user._id }, config.secrets.session, { expiresIn: 60*60*5 });
- request(app)
- .get('/api/reports?access_token=' + token)
- .expect(200)
- .expect('Content-Type', /json/)
- .end(function(err, res) {
- if (err) return done(err);
- res.body.should.be.instanceof(Array);
- done();
- });
- });
+describe('GET /api/reports/:id', function () {
+ beforeEach(localMock.beforeEach);
+
+ afterEach(localMock.afterEach);
+
+ it('should be forbidden for guest users', function (done) {
+ request(app)
+ .get('/api/reports/' + localMock.report.get()._id)
+ .expect(401, done);
+ });
+
+ it('should be forbidden for not owner users', function (done) {
+ localMock.report.setUserId('fakeUserId', function () {
+ request(app)
+ .get('/api/reports/' + localMock.report.get()._id + '?access_token=' + localMock.user.token())
+ .expect(403, done);
+ });
+ });
+
+ it('should be not found for fake report ID', function (done) {
+ request(app)
+ .get('/api/reports/000000000000000000000001?access_token=' + localMock.user.token())
+ .expect(404, done);
+ });
+
+ it('should be \'gone\' for not existing file', function (done) {
+ request(app)
+ .get('/api/reports/' + localMock.report.get()._id + '?access_token=' + localMock.user.token())
+ .expect(410, done);
+ });
+
+ it('should be \'accepted\' for generating report', function (done) {
+ localMock.report.makeGenerating(function () {
+ request(app)
+ .get('/api/reports/' + localMock.report.get()._id + '?access_token=' + localMock.user.token())
+ .expect(202, done);
+ });
+ });
+
+ it('should be authorized for not owner admin', function (done) {
+ localMock.report.createEmptyPDF(function () {
+ localMock.report.setUserId('fakeUserId', function () {
+ localMock.user.admin(function () {
+ request(app)
+ .get('/api/reports/' + localMock.report.get()._id + '?access_token=' + localMock.user.token())
+ .expect(200)
+ .expect('Content-Type', /pdf/)
+ .end(function (err) {
+ if (err) return done(err);
+ done();
+ });
+ });
+ });
+ });
+ });
+
+ it('should be authorized for owner user', function (done) {
+ localMock.report.createEmptyPDF(function () {
+ request(app)
+ .get('/api/reports/' + localMock.report.get()._id + '?access_token=' + localMock.user.token())
+ .expect(200)
+ .expect('Content-Type', /pdf/)
+ .end(function (err) {
+ if (err) return done(err);
+ done();
+ });
+ });
+ });
+
+ it('should not be possible to download report twice', function (done) {
+ localMock.report.createEmptyPDF(function () {
+ request(app)
+ .get('/api/reports/' + localMock.report.get()._id + '?access_token=' + localMock.user.token())
+ .expect(200)
+ .expect('Content-Type', /pdf/)
+ .end(function (err) {
+ if (err) return done(err);
+ request(app)
+ .get('/api/reports/' + localMock.report.get()._id + '?access_token=' + localMock.user.token())
+ .expect(404, done);
+ });
+ });
+ });
});
+
+describe('POST /api/reports', function () {
+ beforeEach(localMock.beforeEach);
+
+ afterEach(localMock.afterEach);
+
+ it('should be forbidden for guest users', function (done) {
+ request(app)
+ .post('/api/reports')
+ .expect(401, done);
+ });
+
+ it('should be \'bad request\' when posting file is missing', function (done) {
+ request(app)
+ .post('/api/reports?access_token=' + localMock.user.token())
+ .expect(400, done);
+ });
+
+ it('should create report when file is sended', function (done) {
+ request(app)
+ .post('/api/reports?access_token=' + localMock.user.token())
+ .attach('content', appDir + '/api/report/fixtures/minimal.pdf')
+ .expect(200)
+ .end(function (err, res) {
+ if (err) return done(err);
+ res.body.id.should.be.instanceof(String);
+ Report.find(function (err, reports) {
+ if (err) return done(err);
+ reports.length.should.be.exactly(2);
+ done();
+ });
+ });
+ });
+
+ it('should create input directory for generator', function (done) {
+ request(app)
+ .post('/api/reports?access_token=' + localMock.user.token())
+ .attach('content', appDir + '/api/report/fixtures/minimal.pdf')
+ .expect(200)
+ .end(function (err, res) {
+ if (err) return done(err);
+ Report.findById(res.body.id, function (err, report) {
+ var file = appDir + '/components/worker/generator/input/' + report.uuid + '/minimal.pdf';
+ var ex;
+ try {
+ fs.accessSync(file, fs.F_OK);
+ } catch (e) {
+ ex = e;
+ }
+ done(ex);
+ });
+
+ });
+ });
+
+ it('should update report counter for user', function (done) {
+ request(app)
+ .post('/api/reports?access_token=' + localMock.user.token())
+ .attach('content', appDir + '/api/report/fixtures/minimal.pdf')
+ .expect(200)
+ .end(function (err) {
+ if (err) return done(err);
+ User.findById(localMock.user.get()._id, function (err, userFound) {
+ userFound.reportCounter.should.be.exactly(1);
+ done();
+ });
+
+ });
+
+ });
+
+});
\ No newline at end of file