Skip to content

Instantly share code, notes, and snippets.

@nwwells
Last active September 19, 2015 04:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nwwells/63dfff7dc159aff9d1c8 to your computer and use it in GitHub Desktop.
Save nwwells/63dfff7dc159aff9d1c8 to your computer and use it in GitHub Desktop.
DataController and Test

DataController

The "data" endpoint is part of an Express app (built with Sails) that rolls up a bunch of information about a given client so that it can be pre-populated in the UI's HTML (so it doesn't have to make a bunch of requests).

The test depends on some testing tools that I'll just handwave about instead of including here:

  • poser is my fixture library - it lets me get some data up and running quickly.
  • TestUtils makes it easier to create and delete data in bulk

CC0
To the extent possible under law, Nathan Wells has waived all copyright and related or neighboring rights to DataController.js. This work is published from: United States.

var _ = require('lodash');
var async = require('async');
require('sails.io.js/sails.io');
module.exports = {
get: function (req, res, next) {
async.parallel({
client: function (done) {
Client
.findOne(req.tenant.id)
.populate('users')
.exec(function (err, client) {
var clientObj = {}, report;
if (err || !client) {
sails.log.error("[DataController] Error finding client", req.tenant.id, " -- Error:", err);
return done(err || "No client found, and no error detected!");
}
_.defaults(clientObj, client);
clientObj.projectedDonations = _.sum(clientObj.users, 'payrollDeduction');
clientObj.projectedDonations *= 24; //payperiods per year
clientObj.projectedDonationsUnit = 'USD';
clientObj.enrolledEmployees = clientObj.users.length;
done(null, _.omit(clientObj, 'users'));
});
},
vendor: function (done) {
done(null, {
name: "Purpose Portfolio",
logoUrl: "url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAARAAAAAiCAYAAACXz4YHAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAEJNJREFUeNrsXQd4VUUWnpeEUBUiGldELMuuSglFFI2AIApIRIqURQHBXRFEkBJZa8CIDRRR+QRcCwiodIhEETSJsGIDDCgRsIBKdRUpQhLS9vx5Z8hhvO++m1cS8+We7zvfnXsz7c6d+U+ZMy9RKkg6e9nrvYvy8qqKR4eJDxFv/LnvP7OfXt++AaVzE+MzDiiXXKqkNDE5OYIu/Yn/RXwBcTTx9xOTktqGqP6/0GUY3+ZQvU+WxXtFBVM4Li1l5sGjRwadUCrf4s/5sQtfWT55t7p3fP25vQlI/kHPJhOQvOtOJ5cqGXjE0iWVuJW5RkLYDABkAqchwMsEQCICLdg0LeWJKh7PUD/g1Js4c/LugRvo+gLxywQk090p5VIlo6cN8PiKOIO5QlNAGkiTtJTp0R7PXQ6z1yZeSSDShTSR1yg9hEAkijSRYe68cqkSaB916XIr35Kyrm4g8yKtjPvQjC4P8np/hNrfXG4aCMCjqnPw0FSTeNbOnHoz6ApfSDcCkUHu9HKpElA/sc7eK2vwYFpA3Ie4J6fLx4QJEDw0NVr0S8c2dJ3P96MJRDzu/HKpAmsXRZptssWK9KZy6upFIv23cgEQAo9pQYCHpq7E6Zw+m7i1Ow1dcinsNIK4iHlEmQNI47SUSQQeo0LQXkPiTHF/tfttXXIpzJpSUtJ/lHfbOJrSM0NZt18nKsCjmsfzQIjaa5AYn1FIpou+v9j9vGWudp/OKu1OmkyH3RGpNCCSH456o8oQPEC7jPujDic9NKXbiG/iyV+P+AfibcRv0OC8Y1O2C1268O0qyrvKR75z6XIv32ZTvvvF36A53c23GfS35fwM++6dic8ifome32lR7+106UV8HjHa2En8DfE8u35b1HOH8jrBmhOfQ1xAvJnt6mepriw/5YfT5X7uh36GMXyUyr7ip2wcXUYSX0Ecx49/4LZnUfn3QghwcK734O+M2IZ9xN8Rv0XtLC5FPd15zjQTPgCM0RfEr/pyZlK5GnR5nG9/pHxT6Rmk9z3szwAAZ1uUmyZuqxDncVqa6Z0pXx2xqEdbzPNh/P7Y9o1R3liRLcSf83feHsCYOl0DeM8xxDcQtyQ+jdv/jPlJKntKQKgnWPA4cORwzoncXKfotmx8/bkIcHmf70eRRrLEz8t3o8s0wxFk0lpMcHq5LRblJ6qSABtsYU300U5znlygQ5QvRvytFX9AELzYiGl5mz+wJnzcsaJMR7o8T9zIpt8fEd9B5b62eX+oazMdaGvzMJ5U128WdWCiPmtTdhwWio8J9SxPajtzdwXxIKrjSBDAEQ8QxtSzyYZvMJTaybSppwVdXiS+0k+TCOy6m+raZVEHAKIag2Qn4g+I64dBK/CINrFosUt5vk0R+DAQR/UglT1aivnrdw1QnsHKG69S16b9fAbXJ6iOHJ8+kCZpKRNDrHloWsNSTNOnfiYV9s8XG+ABqZdB/Il41g51s6QMB/0q0tAi3mTwyFYlAUFZRr+XCfDAh1/P+Uwf0Ee++k3P2/JE1+ABcADgJhNPFRMGNID4XSoTY1HVfXyFVHyGtYlXuV+g6yza9jBY3sXz5DiD1AOsqb0oxgXSflEQ4IEtxnQDPLJ4vNaLfl6OxUz5r7DRlNYI8EDcBSKfJylvZGa6yJ7AcybWoqpDfK3D3xrgUcia41b+hiaIZQrOEun9Is9+I5/u9wAeaw0eh/n+ERZCW4XAx7d7k8qcFkKtD9rtawI89hLP4fYhvHYIiyUJQEdlqliaMAQe46p6PElhWITfX1/nsyW8IEDppH3stnmpZjxhNUFNHk3It03kqc+I3J3VyxR61pjyHAtx3+U2XRu+YmINM6UutY/FDqdVdX70Bhah9DdQnqZ0eY64AwPRO9xvmQfq+2qWhFpiQsofNNqDWfe68gbstWbtaIChkp/Nt3OpfKL421K6DCEeaPHOiaxK68Xcj8p+ZbT9MF0+xLSBpIaZRHlmlHLyQmNYKB79l3iE1CYpT23WQiElz4BQAYhQnv0iDyb0crEIsEB7UZ6dFpoOQgkuUF6nPuZVC6NbOXytzao8zJ2BVNdeo64ioU208PF+UvrPMqU//f1S1jxq8SOYtX0o33EL0047QxMYFO8JAXi0Zs1P0xzWivOMfBAaTzGIDWb3wVMRFuAxJQzgAXt9aIta2wewNP2dpagdyYCXGfRCXSR48EfbTdyDP4BiBC+LMwAfUbu3+FDZpwjwmEp5bjWdlXT/JV06snTUWo3pP7lfgAckQHcTPLiuFFUS6Qi6lSelHHtNfzXKphL3Js42Jkt1ljQgvGNfEzy4PPozTjy6O4CxnCTS66BNmqYoxo94CI+JYj/OBKMeHFK7kNM/Ed9oggfXtZ4Fjl78zel9b7bpH0AjwQSPENK/BXh8TO0kmODB/YaQ6C8ejaJ+XxSC9p8WaQiYwSZ4cPtTjDWbCBM3ogzAA2DRdXz9uSdYlQa6DyftY4cNKl4p1PYDxiS1tOGV93yBMhZTuOghH/2GpO8mFkOijf1bxH3Vi3cCmw2oB5qh3K+HRCiwqSuVJdfJySX+lsvSAnQN1b2S+2lHHcWknk91bLVpe7UqCZBqRHWfUQrpB22uq5gn3XhcfLX1JPuNNFBKe12O12OUd49NPVvYBNRkJ8nv0/Z+yH0g3u8tQWGYH5/JUnaca7olyPbjhEYNGuunfWhP3/PtmVjHxSZM07SUUdEBgoenqMjXBy9k59o4Ag+YI7OJf8EgEXh84afaa0V6qikhLV4smwYDJsVjMAlg/oQy3t+C1vl4Lg9MvWa3GLjfv1Ffp7NPoQbb7h/zNVLb8ZRvrYM+pYvF2NjCHHmb1U+ov7uoXXybaVT3JxZ1SYlcg/L28NN2tEjHKeeHxDqI9FKH28pvsu8IPoDLYObx7kVjw9z1R+8KwXSVTb7PwjiP4sXYbbfaBLCgOQL82gTZfhORhvbzi8Nx02DdMorAYzSBx9QAHQNfF3mdagUGcMBDvImAoy47YopY+1hJ4JHnoOraAXxA6ZCNCaf6YaMNSDt4p8Pq5KSpKZxVmjY4rGe9SNf7g6ni9ZW8wr4imEb9iv0ayckA2iGUR4L6BSJ9G3M4KDaA8VrBfi893quN991ltbNiQT+IdJTNt94exqkk58s+h2Xkd6oaZPt/F+lfHZaRINMgqk5E5Cjd+aoqr2ZVlV+jFB3Yt6nHwBWLNvfUx/pX9mm2bK8Qe8dUYKGzgQxMsOdqokIwIaIM0y0UVM1hvuoinW+xEFaygxe/y3IHOwdB0A7T6G/9fcQHfEu8uxT9PVSKvHInIRDHt9bw8ixAOFTjGk4KxDSKDGH7+UHO/8KoEKAYSAPIRnY6hZKiHeaTW3u/BdBOrRD322l9LS0WkVTl47DDYOXYMqi14fizkqZY3NiWm8kaCUwbbBVju/I5etaSd7AgddtrlZmeTSqDxeR04SeIdBa/1wHeEYEQOYt3tLb6qedCkS6viFypNTd0WKajSP8vyPZl/FEDh2WkdrotQv35aagDZxCiA7Xz9KCN/8MuSKdZiPud4KDfZ7I2ADouzJVMIckB8r0ctHeTSH/uwAzD7g3iP74S6my8MBNOTljt3A0zdXWYb7BY9Bt9LMaeDuoZINIZ5TGxeTfuZ76tT+N8nZ/5YjpdPwyyC9I8bsTR1XbtQ2vrIh6tqwgAcjN13N9BPhnxucjGZutgtRg4vDjUgXOJHKDj62PAVJwjNJXHtZbBztdHRfZnfASI6bpGCA0EavEz4m/nE6/haFpzAmNn7Evx6Fy+rhLjBk1ktE3bpxHPJb4+yPG6nOp43s8ExtayDhJbQv2XfoPHRHqMXVAh97WvePRo0GCQnByoJi/n6wwWhr5orNAA8O2WBQlg8AMtFY9e5OhjX/SyKokpQgjFWxUBQBSr1ws5cEx+tIbEkB7ayYfAojFG2dU82FoDmc1ee11HLH+I2DD0+yXsspiLn8OO1wqpi3iKF4yys1TJlhkW9iYqd5lRTzQxfmlK/kzkZPqwP/PfEbm5jTWN1aaE4/M/ncSjXQLApO8K50GmcXyILA+tZR1Lc9Q/MsjxGkl1pJvxDQiqI8Y3ekQIhQdMH4+QyNhKzrACNT4TJI9PLKCyGwPsrzR9RgYIJohn2SfMmE+pfCOjz7WIEcQlYzbGhyg2ZbTwxWC8PrBYZ3WI56lTQyTGBuo4KS9CuHMfepEtvOCAhJcaH/P6PwRFJSXtoDKItNNBTojoS6BnX7J/BYusCqvt3YNwKPkiLMQR1B5U7Gy2vaUpdbTYTDAjWpOSjlEZmEEfs48CkmcDPdNOTQ9LYzlZEXyXLOr4nPJDTcV2H0AMmsgO9pGgzuaibDrlzxBlF/L5DG0yIFZiOD3Dti922nCgT57POcSaS7AEjec7amc7LyyznwXFWqlxqIupF5syDfl9AWr72KejuJ46Ij92+IYE0VcA0e2cnkJtIT4oj30L7RxqAb9SOfx2cCr37RLirfRsK/s4MBehPVY7RTAlJT0XIjPqJ2rrRuXd+o7kufKTWGdYI1epUzcpcJ6mWHOqCBrIdHWqtzqOJ9mlhi3X1ipakukhQ92ry3XEM3gsNlTaUDhU3zecXK25TQke8HW08nU4jCNvL2EtSjrbUM81AjwKWfPqb7HF3FmVHF7Uvo72xqKEz2igRftYXHexf0bxZGrH5SV4QAtB7M03QYwXAuFyxf3FFv0EeLb0FRfDkbEY57ni8TlcT3sDPBCUdrW/GCM/NM5wRCL84ExlfyDNqt/rWRjIszqNuc9tBHhgHdxpdeo7SBDBYUHE1mRZrLN4AR7YnOgmw/ErggYClH9CeX/hvSOr83VZim5n5FxEL1VoM0CHOVwZDihIVa2iIfZgKau/in0tVttkBy1MI3+EiMl+DEyITq3HExhmFhbaSkh5Bx8XkrYzmyP6mLe2U/eyhrJQmy0W5Y8Xa2bJybexqdGB3zGfpfWCYrPOON0pysMuX8JttxVjV8BOzFSHgW7+aA2bov3Z5NLf+QCbVin8nvl+xgvfahD1+XEef4xbTaGlYpGu8BMrAp/I6Q6+zSHsXLFW24TL4PtKQbZKlTjEP7GpC3P5WqqvHc/RVmJ9/qi8cT6Yq752XvaIOZpr/M1vH6hezIXGrPV24vfRCsYOns+LzTB7T9uM1JMhvwHEgawdHDO/r5CQd/Zptmxj0Ijo/W2Fe046PoVq/Wcmpz8dUM59hHZ1HjvBjpZzX2YL/9UY6s805VKFIiDckRK09RSVpnCkKoAElPvH2e6Q/slBLinpd0PtdsmlgClCiVOveSoyt3QAUrhalcQO5JL2keUOqUsuVS4AeV3fFCpPQaGKcPTrYh5V9OMtMQvns72mVIj/34RLLrlUAQBkXfsExBqc/A2NHBXl6EwCmS/YnsT2D7zciLOY5w6nSy5VPg1EEYggiAk/cafyVeSJEyrquH2houEDYhbAM6t/4OVhMl8OusPpkkuVEEAYRPDzdNAqDueoKsesQCRCFe6JVnmdBsW8ga2wqVx+HIHHB+5QuuRS5aNT4kAIRJa3zUhFQE8CgUiTAhXRtLrKrUkaRybxhpbVMlc1qr4N8RgIB8aBrTkEHnvC0C/8uNFsTn9bgcYTJ12Xc3q/O738Es626K3bPe5wVDwq1SnLRZt74od+cWZkGwHHCXf4XHKpctP/BRgAkk8PvRoeeeYAAAAASUVORK5CYII=')",
homePageUrl: "https://www.purposeportfolio.org",
introText: "Purpose Portfolio is your partner in change. Every opportunity you see on this page has been vetted and verified by our team of impact experts, and 100% of your donation goes to the causes you choose to support.",
linkText: ""
});
},
portfolioUnits: function (done) {
// TODO - optimize this by querying the join table directly, since we're
// not using anything on the portfolio model itself.
Portfolio.
findOne(req.tenant.portfolio).
populate('portfolioUnits').
exec(function(err, portfolio) {
if (err) return done(err);
else if (!portfolio || portfolio.portfolioUnits.length === 0) {
return done(null, []);
}
var ids = _.map(portfolio.portfolioUnits, "id");
PortfolioUnit.
find({ id: ids }).
populate('geographies').
populate('tags').
exec(done);
});
},
opportunities: function (done) {
DataService.getOpportunitiesForClient(req.tenant, function (err, result) {
if (err) return done(err);
var opps = !result.rows ? [] : result.rows;
opps = opps.map(function (opp) {
opp.supporterCount = +opp.supporterCount;
opp.typeIconUrl = '<svg class="columbian white" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 100 100" enable-background="new 0 0 100 100" xml:space="preserve"><g><path d="M52.7,57.9c0-9.5,7.7-17.2,17.2-17.2c4,0,7.7,1.4,10.6,3.7c1.9-6.6,0.2-13.8-4.9-18.8c-7.5-7.5-19.7-7.4-27.1,0.1c-7.5-7.5-19.6-7.5-27.1-0.1c-7.5,7.5-7.7,19.5,0.6,27.8c9.2,9.2,24,24,26.6,26.6c1.2-1.2,5-5,9.6-9.6C54.7,67.3,52.7,62.8,52.7,57.9z"/><path d="M79.5,47.2c-2.6-2.3-5.9-3.7-9.6-3.7c-8,0-14.4,6.5-14.4,14.4c0,4.2,1.8,7.9,4.6,10.5c2.6,2.4,6,3.9,9.8,3.9c8,0,14.4-6.5,14.4-14.4C84.3,53.6,82.4,49.8,79.5,47.2z M70.9,65.2v2.5h-2.3v-2.3c-1.6,0-3.2-0.5-4.1-1l0.1-0.6l0.6-2.2c0.3,0.2,0.7,0.4,1.1,0.5c0.8,0.3,1.8,0.5,2.8,0.5c1.4,0,2.3-0.6,2.3-1.5c0-0.9-0.7-1.4-2.2-2c-0.1,0-0.2-0.1-0.3-0.1c-2.6-0.9-4.3-2.1-4.3-4.4c0-2.1,1.5-3.8,4.1-4.3v-2.3h2.3v2.1c1.6,0,2.7,0.4,3.5,0.8l-0.7,2.7c-0.6-0.3-1.7-0.8-3.5-0.8c-1.6,0-2.1,0.7-2.1,1.4c0,0.8,0.8,1.3,2.9,2c0.2,0.1,0.5,0.2,0.7,0.3c2.4,1,3.3,2.2,3.3,4.2C75.2,62.9,73.7,64.7,70.9,65.2z"/></g></svg>';
return opp;
});
done(null, opps);
});
},
pusAndOpps: function (done) {
Portfolio
.findOne(req.tenant.portfolio)
.populate('portfolioUnits')
.exec(function(err, portfolio) {
if (err) return done(err);
else if (!portfolio || portfolio.portfolioUnits.length === 0) {
return done(null, {
portfolioUnits: [],
opportunities: []
});
}
var ids = _.map(portfolio.portfolioUnits, "id");
PortfolioUnit
.find({ id: ids })
.populate('geographies')
.populate('tags')
.populate('opportunities')
.exec(function (err, pus) {
var oppIds = _.map(_.flatten(_.map(pus, "opportunities")), "id");
var pusForBody = pus.map(function (pu) {
var result = {}, tempPu = {};
_.defaults(tempPu, pu);
_.defaults(result, _.omit(tempPu, "opportunities", "portfolios"));
return result;
});
Opportunity
.find({ id: oppIds })
.populate('engagements')
.sort({ amount: 'asc' })
.exec(function(err, opps) {
if (!opps) {
body('opportunities', []);
return;
}
opps = opps.map(function (oppIn) {
var opp = {};
_.defaults(opp, oppIn);
// create a set of owners of engagements for this opportunity
var supporters = oppIn.engagements.reduce(function (memo, e) {
memo[e.owner] = true;
return memo;
}, {});
opp.supporterCount = Object.keys(supporters).length;
opp.typeIconUrl = '<svg class="columbian white" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 100 100" enable-background="new 0 0 100 100" xml:space="preserve"><g><path d="M52.7,57.9c0-9.5,7.7-17.2,17.2-17.2c4,0,7.7,1.4,10.6,3.7c1.9-6.6,0.2-13.8-4.9-18.8c-7.5-7.5-19.7-7.4-27.1,0.1c-7.5-7.5-19.6-7.5-27.1-0.1c-7.5,7.5-7.7,19.5,0.6,27.8c9.2,9.2,24,24,26.6,26.6c1.2-1.2,5-5,9.6-9.6C54.7,67.3,52.7,62.8,52.7,57.9z"/><path d="M79.5,47.2c-2.6-2.3-5.9-3.7-9.6-3.7c-8,0-14.4,6.5-14.4,14.4c0,4.2,1.8,7.9,4.6,10.5c2.6,2.4,6,3.9,9.8,3.9c8,0,14.4-6.5,14.4-14.4C84.3,53.6,82.4,49.8,79.5,47.2z M70.9,65.2v2.5h-2.3v-2.3c-1.6,0-3.2-0.5-4.1-1l0.1-0.6l0.6-2.2c0.3,0.2,0.7,0.4,1.1,0.5c0.8,0.3,1.8,0.5,2.8,0.5c1.4,0,2.3-0.6,2.3-1.5c0-0.9-0.7-1.4-2.2-2c-0.1,0-0.2-0.1-0.3-0.1c-2.6-0.9-4.3-2.1-4.3-4.4c0-2.1,1.5-3.8,4.1-4.3v-2.3h2.3v2.1c1.6,0,2.7,0.4,3.5,0.8l-0.7,2.7c-0.6-0.3-1.7-0.8-3.5-0.8c-1.6,0-2.1,0.7-2.1,1.4c0,0.8,0.8,1.3,2.9,2c0.2,0.1,0.5,0.2,0.7,0.3c2.4,1,3.3,2.2,3.3,4.2C75.2,62.9,73.7,64.7,70.9,65.2z"/></g></svg>';
return _.omit(opp, 'engagements');
})
done(null, {
portfolioUnits: pusForBody,
opportunities: opps
});
}); // end Opportunity Query.
}); // end PortfolioUnit Query
});// end Portfolio Query
},
quotes: function (done) {
if (req.tenant.isDemo) {
done(null, [{
avatarUrl: "http://image.guardian.co.uk/sys-images/Society/Pix/pictures/2007/04/23/MarcelloBanos128x128.jpg",
firstName: "Marcello",
lastName: "Cameron",
text: "I know I’m only one person but whatever I can do, I’ve got to do."
}, {
avatarUrl: "https://pbs.twimg.com/profile_images/426540101464633346/InYWSjgE.jpeg",
firstName: "Kira",
lastName: "Lee",
text: "I give because I’ve been to Thailand and seen first-hand what a pervasive problem this is."
}]);
return;
}
Quote.query([
'SELECT q.*, u."firstName", u."lastName", u."avatarUrl"',
'FROM quote q, ppuser u',
'WHERE u.id = q.owner',
'AND \'' + req.tenant.id + '\' = u.owner',
'ORDER BY random()',
'LIMIT 2'
].join(' '), function (err, result) {
if (err) return done(err);
done(null, !result.rows ? [] : result.rows);
});
}
}, function (err, results) {
if (err) return next(err);
sails.log.debug("executing callback in DataController");
res.status(200);
res.json({
client: results.client,
vendor: results.vendor,
portfolioUnits: results.portfolioUnits,
opportunities: results.opportunities,
quotes: results.quotes
});
});
}//get
}
var _ = require('lodash');
var async = require('async');
var faker = require('faker');
var assert = require('assert');
var request = require('supertest');
var compare = require('compare-property');
var testUtils = require('../../lib/TestUtils');
var clients = require('../../fixtures/Client');
var vendors = require('../../fixtures/Vendor');
var poser = require('../../fixtures/poser');
var financialIcon = "<svg class=\"columbian white\" version=\"1.1\" id=\"Layer_1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\" viewBox=\"0 0 100 100\" enable-background=\"new 0 0 100 100\" xml:space=\"preserve\"><g><path d=\"M52.7,57.9c0-9.5,7.7-17.2,17.2-17.2c4,0,7.7,1.4,10.6,3.7c1.9-6.6,0.2-13.8-4.9-18.8c-7.5-7.5-19.7-7.4-27.1,0.1c-7.5-7.5-19.6-7.5-27.1-0.1c-7.5,7.5-7.7,19.5,0.6,27.8c9.2,9.2,24,24,26.6,26.6c1.2-1.2,5-5,9.6-9.6C54.7,67.3,52.7,62.8,52.7,57.9z\"/><path d=\"M79.5,47.2c-2.6-2.3-5.9-3.7-9.6-3.7c-8,0-14.4,6.5-14.4,14.4c0,4.2,1.8,7.9,4.6,10.5c2.6,2.4,6,3.9,9.8,3.9c8,0,14.4-6.5,14.4-14.4C84.3,53.6,82.4,49.8,79.5,47.2z M70.9,65.2v2.5h-2.3v-2.3c-1.6,0-3.2-0.5-4.1-1l0.1-0.6l0.6-2.2c0.3,0.2,0.7,0.4,1.1,0.5c0.8,0.3,1.8,0.5,2.8,0.5c1.4,0,2.3-0.6,2.3-1.5c0-0.9-0.7-1.4-2.2-2c-0.1,0-0.2-0.1-0.3-0.1c-2.6-0.9-4.3-2.1-4.3-4.4c0-2.1,1.5-3.8,4.1-4.3v-2.3h2.3v2.1c1.6,0,2.7,0.4,3.5,0.8l-0.7,2.7c-0.6-0.3-1.7-0.8-3.5-0.8c-1.6,0-2.1,0.7-2.1,1.4c0,0.8,0.8,1.3,2.9,2c0.2,0.1,0.5,0.2,0.7,0.3c2.4,1,3.3,2.2,3.3,4.2C75.2,62.9,73.7,64.7,70.9,65.2z\"/></g></svg>";
var quotes = [
poser.quote(),
poser.quote(),
poser.quote(),
poser.quote(),
poser.quote(),
poser.quote(),
];
var fakeOtherClient = poser.client();
var users = [
poser.user({ id: quotes[0].owner, owner: clients.fakeTenant.id, team: clients.fakeTenant.teams[0] }),
poser.user({ id: quotes[1].owner, owner: clients.fakeTenant.id, team: clients.fakeTenant.teams[0] }),
poser.user({ owner: clients.fakeTenant.id, team: clients.fakeTenant.teams[1] }),
poser.user({ owner: clients.fakeTenant.id, team: clients.fakeTenant.teams[1] }),
poser.user({ id: quotes[2].owner, owner: fakeOtherClient.id, team: fakeOtherClient.teams[0] }),
poser.user({ id: quotes[3].owner, owner: fakeOtherClient.id, team: fakeOtherClient.teams[0] }),
poser.user({ id: quotes[4].owner, owner: fakeOtherClient.id, team: fakeOtherClient.teams[0] }),
poser.user({ id: quotes[5].owner, owner: fakeOtherClient.id, team: fakeOtherClient.teams[0] })
];
var expectedUsers = users.slice(0, 4);
var portfolioUnits = [
poser.portfolioUnit(),
poser.portfolioUnit(),
poser.portfolioUnit(),
poser.portfolioUnit(),
poser.portfolioUnit()
]
var portfolio = poser.portfolio({
clients: [ clients.fakeTenant.id ],
portfolioUnits: _.map(portfolioUnits.slice(0, 3), "id"),
});
var geographies = [
poser.geography({ owner: portfolioUnits[0].id }),
poser.geography({ owner: portfolioUnits[1].id })
];
var tags = [
poser.tag({ owner: portfolioUnits[0].id }),
poser.tag({ owner: portfolioUnits[1].id })
];
var opportunities = [
poser.opportunity({ typeIconUrl: financialIcon, supporterCount: 3, owner: portfolioUnits[0].id }),
poser.opportunity({ typeIconUrl: financialIcon, supporterCount: 2, owner: portfolioUnits[0].id }),
poser.opportunity({ typeIconUrl: financialIcon, supporterCount: 4, owner: portfolioUnits[1].id }),
poser.opportunity({ typeIconUrl: financialIcon, supporterCount: 3, owner: portfolioUnits[2].id }),
poser.opportunity({ typeIconUrl: financialIcon, supporterCount: 1, owner: portfolioUnits[2].id }),
poser.opportunity({ typeIconUrl: financialIcon, supporterCount: 1, owner: portfolioUnits[2].id }),
poser.opportunity({ typeIconUrl: financialIcon, supporterCount: 0, owner: portfolioUnits[3].id }),
poser.opportunity({ typeIconUrl: financialIcon, supporterCount: 0, owner: portfolioUnits[4].id })
];
var engagements = [
poser.engagement({ opportunityId: opportunities[0].id, owner: users[0].id }),
poser.engagement({ opportunityId: opportunities[0].id, owner: users[1].id }),
poser.engagement({ opportunityId: opportunities[0].id, owner: users[2].id }),
poser.engagement({ opportunityId: opportunities[1].id, owner: users[1].id }),
poser.engagement({ opportunityId: opportunities[1].id, owner: users[2].id }),
poser.engagement({ opportunityId: opportunities[2].id, owner: users[2].id }),
poser.engagement({ opportunityId: opportunities[2].id, owner: users[3].id }),
poser.engagement({ opportunityId: opportunities[2].id, owner: users[0].id }),
poser.engagement({ opportunityId: opportunities[2].id, owner: users[5].id }),
poser.engagement({ opportunityId: opportunities[2].id, owner: users[4].id }),
poser.engagement({ opportunityId: opportunities[2].id, owner: users[3].id }),
poser.engagement({ opportunityId: opportunities[3].id, owner: users[2].id }),
poser.engagement({ opportunityId: opportunities[3].id, owner: users[1].id }),
poser.engagement({ opportunityId: opportunities[3].id, owner: users[0].id }),
poser.engagement({ opportunityId: opportunities[3].id, owner: users[7].id }),
poser.engagement({ opportunityId: opportunities[3].id, owner: users[6].id }),
poser.engagement({ opportunityId: opportunities[4].id, owner: users[7].id }),
poser.engagement({ opportunityId: opportunities[4].id, owner: users[6].id }),
poser.engagement({ opportunityId: opportunities[4].id, owner: users[5].id }),
poser.engagement({ opportunityId: opportunities[4].id, owner: users[4].id }),
poser.engagement({ opportunityId: opportunities[4].id, owner: users[3].id }),
poser.engagement({ opportunityId: opportunities[5].id, owner: users[2].id }),
poser.engagement({ opportunityId: opportunities[6].id, owner: users[7].id }),
poser.engagement({ opportunityId: opportunities[6].id, owner: users[6].id })
];
var expected = {
get client() {
return _.extend({}, clients.fakeTenant, {
enrolledEmployees: expectedUsers.length,
projectedDonations: _.sum(expectedUsers, 'payrollDeduction') * 24,
projectedDonationsUnit: "USD",
portfolio: portfolio.id
});
},
vendor: vendors.one,
portfolioUnits: portfolio.portfolioUnits.map(function (idIn) {
return _.find(portfolioUnits, { id: idIn });
}),
opportunities: opportunities.slice(0,6),
quotes: [
_.defaults(
{},
_.pick(quotes[0], "id", "text", "owner"),
_.pick(users[0], "avatarUrl", "firstName", "lastName")
),
_.defaults(
{},
_.pick(quotes[1], "id", "text", "owner"),
_.pick(users[1], "avatarUrl", "firstName", "lastName")
)
]
};
describe('DataController', function() {
before(function (done) {
async.series(
[].concat(
testUtils.createAll([fakeOtherClient], Client),
testUtils.createAll(portfolioUnits, PortfolioUnit),
testUtils.createAll([portfolio], Portfolio),
testUtils.createAll(opportunities, Opportunity),
testUtils.createAll(quotes, Quote),
testUtils.createAll(users, User),
testUtils.createAll(geographies, Geography),
testUtils.createAll(tags, Tag),
[]
), function (err, results) {
if (err) return sails.log.error(JSON.stringify(err, 0, 2)), done(err);
async.parallel([].concat(
testUtils.createAll(engagements, Engagement)
), done);
geographies.forEach(function (geo) {
var pu = _.find(portfolioUnits, { id: geo.owner });
pu.geographies.push(geo);
});
tags.forEach(function (tag) {
var pu = _.find(portfolioUnits, { id: tag.owner });
pu.tags.push(tag);
});
}
);
});
after(function (done) {
async.parallel(
[].concat(
testUtils.destroyAll(portfolioUnits, PortfolioUnit),
testUtils.destroyAll([portfolio], Portfolio),
testUtils.destroyAll(opportunities, Opportunity),
testUtils.destroyAll(engagements, Engagement),
testUtils.destroyAll(quotes, Quote),
testUtils.destroyAll(users, User),
testUtils.destroyAll(geographies, Geography),
testUtils.destroyAll(tags, Tag),
[]
), done
);
});
describe('GET /data', function(){
it('should return all data for the Payroll Signup page', function(done) {
this.timeout(10000);
request(sails.hooks.http.app)
.get('/data')
.expect(200)
.expect(function (res) {
var body = res.body;
var actualClient = _.omit(body.client, "createdAt", "updatedAt");
assert.deepEqual(actualClient, expected.client, "client mismatch");
assert.deepEqual(body.vendor, expected.vendor, "vendor mismatch");
var actualPus = body.portfolioUnits.map(function (pu) {
return _.defaults({
geographies: pu.geographies.map(omitted("createdAt", "updatedAt")),
tags: pu.tags.map(omitted("createdAt", "updatedAt")),
}, _.omit(pu, "createdAt", "updatedAt"));
});
actualPus.sort(compare.property('id'));
expected.portfolioUnits.sort(compare.property('id'));
assert.deepEqual(actualPus, expected.portfolioUnits, "portfolioUnits mismatch");
var actualOpportunities = body.opportunities.map(omitted("createdAt", "updatedAt"));
actualOpportunities.sort(compare.property('id'));
expected.opportunities.sort(compare.property('id'));
assert.deepEqual(actualOpportunities, expected.opportunities, "opportunities mismatch");
var actualQuotes = body.quotes.map(omitted("createdAt", "updatedAt"));
actualQuotes.sort(compare.property('id'));
expected.quotes.sort(compare.property('id'));
assert.deepEqual(actualQuotes, expected.quotes, "quotes mismatch");
})
.end(done)
})
});
});
function omitted () {
var args = _.flatten(_.slice(arguments));
return function (it) { return _.omit(it, args) };
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment