2016-05-15 10 views
1

Мне нужно загрузить файл в s3 из koa, я довольно новичок в koa и, вероятно, отсутствует что-то очевидное. На самом деле это завершено с 200, но файл никогда не отображается на s3.aws-sdk upload to S3 работает в KOA, но перестает работать при вызове через Mocha

Вот фрагмент из моего app.js:

'use strict'; 

var jwt = require('koa-jwt'); 


var bodyParser = require('koa-bodyparser'); 
var koaBody = require('koa-body'); 

const app = module.exports = require('koa')() 
    .use(koaBody({multipart:true})) // this is to pase only multipart forms 
    .use(require('./routes/common')) 
    .use(require('./routes/auth')) 
    .use(require('./routes/users_public')) 
    .use(jwt({ secret: SECRET })) 
    //protected routes below this line 
    .use(require('./routes/subcontractors_private')) 

    .listen(process.env.PORT || 3000); 

subcontractors_private.js выглядит следующим образом:

'use strict'; 

var AWS = require('aws-sdk'); 
var fs = require('fs'); 
var zlib = require('zlib'); 


var S3_BUCKET = require('../consts').S3_BUCKET; 
var S3_OPTIONS = require('../consts').S3_OPTIONS; 


module.exports = require('koa-router')() 

.post('/subcontractors/:subcontractor_id/coi', function *(next) { 
    var body = JSON.stringify(this.request.body, null, 2) 

    let subcontractor_id = this.params.subcontractor_id; 
    var file = this.request.body.files.coi.path; 
    var body = fs.createReadStream(file).pipe(zlib.createGzip()); 


    var s3obj = new AWS.S3(
    {params: 
    { 
     Bucket: 'coi-test', 
     Key: 'i/' + subcontractor_id + '.png.zgip' 
    } 
    });   

    s3obj.upload({Body: body}) 
    .on('httpUploadProgress', function(evt) { 
     console.log(evt); 
    }) 
    .send(function(err, data) { 
     console.log(err, data); 
    }); 


    this.response.status = 200; 
    this.body = { "result": "subcontractor CIO successfully uploaded"}; 
    }) 
    .routes(); 

И, наконец, фрагменты subcontractor_private.js из папки теста:

'use strict'; 

const supertest = require('co-supertest'); // SuperAgent-driven library for testing HTTP servers 
const expect = require('chai').expect; // BDD/TDD assertion library 
require('co-mocha');      // enable support for generators in mocha tests using co 
var uuid = require('uuid'); 

var db = require('../../consts').DB; 
var moment = require('moment'); 

const app = require('../../app.js'); 

const request = supertest.agent(app.listen()); 

var assert = require('assert'); 

describe('/subcontractors private routes testing', function() { 

    it.only('should be able to upload COI for subcontractor', function*() { 

    const coi_expires_at = moment().add(1, 'd').format(); 
    const response = 
     yield request.post('/subcontractors') 
    .set('Content-Type', 'application/json') 
    .set('Authorization', 'Bearer ' + token) 
    .send({name: "Joe Doh"}) 
    .end(); 

    //now try to upload the coi file 
    const response1 = 
    yield request.post('/subcontractors/' + response.body.subcontractor.id + "/coi") 
    .set('Authorization', 'Bearer ' + token) 
    .field('Content-Type', 'multipart/form-data') 
    .field('coi_expires_at', coi_expires_at) 
    .attach('coi', './assets/logo-big.png') 
    .end(); 

    expect(response1.status).to.equal(200, response1.text); 
    expect(response1.body).to.be.an('object'); 
    expect(response1.body).to.be.json; 
    expect(response1.body).to.contain.keys('result'); 
    expect(response1.body.result).to.equal('subcontractor CIO successfully uploaded'); 

    }); 
}); 

Я пробовал код загрузки как отдельный файл js (запускался через узел), и он работает fin е. Но когда я запускаю его как приложение-узел из теста mocha - метод завершается с ответом 200 и никогда не заканчивает загрузку. Что я делаю не так?

+0

Удивительно, но нет никакой информации в Интернете, что я могу найти что объясняет, как сделать больше запущенные задачи, как загрузки с узла и имеют узел возврат правильный ответ возвращает код в браузер после завершения задачи. – dmitryame

+0

Можете ли вы опубликовать более полный пример, показывающий, как это происходит от koa/mocha? –

+0

хорошая точка - обновил исходное сообщение с большим количеством примеров – dmitryame

ответ

1

Проблема заключается в асинхронном характере этого материала. Тест заканчивается без ожидания завершения запроса (или даже запускается должным образом). Я не совсем понятно, как это сделать правильно, но добавление этого:

it.only('should be able to upload COI for subcontractor', function*(done) { 

(сделано аргумент обратного вызова) делает тест ожидания для «сделано» обратного вызова, которая будет вызвана, таким образом, позволяя AWS SDK завершить запрос , Однако я не знаю, как исправить ваш тест, потому что это дважды асинхронно. Метод контроллера на вашем сервере koa возвращается асинхронно без ожидания завершения запроса S3, поэтому тест mocha не может ждать завершения обработки S3.

(также см моего связанный с этим вопрос: aws-sdk s3 upload not working from mocha test)

+0

Это он, я смог увидеть файл, загруженный из теста , и, конечно, мой тест завершился неудачно с тайм-аутом, потому что я не вызываю завершенный ответ - я это выясню, но ваш ответ именно то, что я искал. Спасибо много! – dmitryame

+0

Итак, продолжайте копаться в этом. Проблема в том, что обещания и обратные вызовы не должны смешиваться с генераторами. KOA - это основа, основанная на генераторах, тогда как aws-sdk основана на обратных вызовах. Мне интересно, есть ли подходящая оболочка генератора для aws-sdk - пока я не смог ее найти. – dmitryame