RedactDocumentSource.js 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. "use strict";
  2. var assert = require("assert"),
  3. async = require("async"),
  4. DocumentSource = require("../../../../lib/pipeline/documentSources/DocumentSource"),
  5. RedactDocumentSource = require("../../../../lib/pipeline/documentSources/RedactDocumentSource"),
  6. CursorDocumentSource = require("../../../../lib/pipeline/documentSources/CursorDocumentSource"),
  7. ArrayRunner = require("../../../../lib/query/ArrayRunner"),
  8. Expressions = require("../../../../lib/pipeline/expressions");
  9. var exampleRedact = {$cond:{
  10. if:{$gt:[0,4]},
  11. then:"$$DESCEND",
  12. else:"$$PRUNE"
  13. }};
  14. var createCursorDocumentSource = function createCursorDocumentSource (input) {
  15. if (!input || input.constructor !== Array) throw new Error('invalid');
  16. return new CursorDocumentSource(null, new ArrayRunner(input), null);
  17. };
  18. var createRedactDocumentSource = function createRedactDocumentSource (src, expression) {
  19. var rds = RedactDocumentSource.createFromJson(expression);
  20. rds.setSource(src);
  21. return rds;
  22. };
  23. module.exports = {
  24. "RedactDocumentSource": {
  25. "constructor()": {
  26. "should not throw Error when constructing without args": function testConstructor() {
  27. assert.doesNotThrow(function() {
  28. new RedactDocumentSource();
  29. });
  30. }
  31. },
  32. "#getSourceName()": {
  33. "should return the correct source name; $redact": function testSourceName() {
  34. var rds = new RedactDocumentSource();
  35. assert.strictEqual(rds.getSourceName(), "$redact");
  36. }
  37. },
  38. "#getNext()": {
  39. "should return EOF": function testEOF(next) {
  40. var rds = RedactDocumentSource.createFromJson(exampleRedact);
  41. rds.setSource({
  42. getNext: function getNext(cb) {
  43. return cb(null, null);
  44. }
  45. });
  46. rds.getNext(function(err, doc) {
  47. assert.equal(null, doc);
  48. next();
  49. });
  50. },
  51. "iterator state accessors consistently report the source is exhausted": function assertExhausted() {
  52. var input = [{}];
  53. var cds = createCursorDocumentSource(input);
  54. var rds = RedactDocumentSource.createFromJson(exampleRedact);
  55. rds.setSource(cds);
  56. rds.getNext(function(err, actual) {
  57. rds.getNext(function(err, actual1) {
  58. assert.equal(null, actual1);
  59. rds.getNext(function(err, actual2) {
  60. assert.equal(null, actual2);
  61. rds.getNext(function(err, actual3) {
  62. assert.equal(null, actual3);
  63. });
  64. });
  65. });
  66. });
  67. },
  68. "callback is required": function requireCallback() {
  69. var rds = new RedactDocumentSource();
  70. assert.throws(rds.getNext.bind(rds));
  71. },
  72. },
  73. "#optimize()": {
  74. "Optimize the expression": function optimizeProject() {
  75. var rds = RedactDocumentSource.createFromJson(exampleRedact);
  76. assert.doesNotThrow(rds.optimize.bind(rds));
  77. }
  78. },
  79. "#createFromJson()": {
  80. "should error if called with non-object": function testNonObjectPassed() {
  81. //Empty args
  82. assert.throws(function() {
  83. var rds = RedactDocumentSource.createFromJson();
  84. });
  85. //Invalid spec
  86. assert.throws(function() {
  87. var rds = RedactDocumentSource.createFromJson({$invalidOperator: 1});
  88. });
  89. }
  90. },
  91. "#redact()": {
  92. "should redact subsection where tag does not match": function (done) {
  93. var cds = createCursorDocumentSource([{
  94. _id: 1,
  95. title: "123 Department Report",
  96. tags: ["G", "STLW"],
  97. year: 2014,
  98. subsections: [
  99. {
  100. subtitle: "Section 1: Overview",
  101. tags: ["SI", "G"],
  102. content: "Section 1: This is the content of section 1."
  103. },
  104. {
  105. subtitle: "Section 2: Analysis",
  106. tags: ["STLW"],
  107. content: "Section 2: This is the content of section 2."
  108. },
  109. {
  110. subtitle: "Section 3: Budgeting",
  111. tags: ["TK"],
  112. content: {
  113. text: "Section 3: This is the content of section3.",
  114. tags: ["HCS"]
  115. }
  116. }
  117. ]
  118. }]);
  119. var expression = {$cond:{
  120. if:{$gt: [{$size: {$setIntersection: ["$tags", [ "STLW", "G" ]]}},0]},
  121. then:"$$DESCEND",
  122. else:"$$PRUNE"
  123. }};
  124. var rds = createRedactDocumentSource(cds, expression);
  125. var result = {
  126. "_id": 1,
  127. "title": "123 Department Report",
  128. "tags": ["G", "STLW"],
  129. "year": 2014,
  130. "subsections": [{
  131. "subtitle": "Section 1: Overview",
  132. "tags": ["SI", "G"],
  133. "content": "Section 1: This is the content of section 1."
  134. }, {
  135. "subtitle": "Section 2: Analysis",
  136. "tags": ["STLW"],
  137. "content": "Section 2: This is the content of section 2."
  138. }]
  139. };
  140. rds.getNext(function (err, actual) {
  141. assert.deepEqual(actual, result);
  142. done();
  143. });
  144. },
  145. "should redact an entire subsection based on a defined access level": function (done) {
  146. var cds = createCursorDocumentSource([{
  147. _id: 1,
  148. level: 1,
  149. acct_id: "xyz123",
  150. cc: {
  151. level: 5,
  152. type: "yy",
  153. exp_date: new Date("2015-11-01"),
  154. billing_addr: {
  155. level: 5,
  156. addr1: "123 ABC Street",
  157. city: "Some City"
  158. },
  159. shipping_addr: [
  160. {
  161. level: 3,
  162. addr1: "987 XYZ Ave",
  163. city: "Some City"
  164. },
  165. {
  166. level: 3,
  167. addr1: "PO Box 0123",
  168. city: "Some City"
  169. }
  170. ]
  171. },
  172. status: "A"
  173. }]);
  174. var expression = {$cond:{
  175. if:{$eq:["$level",5]},
  176. then:"$$PRUNE",
  177. else:"$$DESCEND"
  178. }};
  179. var rds = createRedactDocumentSource(cds, expression);
  180. var result = {
  181. _id:1,
  182. level:1,
  183. acct_id:"xyz123",
  184. status:"A"
  185. };
  186. rds.getNext(function (err, actual) {
  187. assert.deepEqual(actual, result);
  188. done();
  189. });
  190. }
  191. }
  192. }
  193. };
  194. if (!module.parent)(new(require("mocha"))()).ui("exports").reporter("spec").addFile(__filename).grep(process.env.MOCHA_GREP || '').run(process.exit);